small-packages/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe.htm
2026-05-10 09:48:30 +08:00

257 lines
6.2 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<%+cbi/valueheader%>
<%
local dsp = require "luci.dispatcher"
local subscribe_url = dsp.build_url("admin", "services", "shadowsocksr", "subscribe")
local get_log_url = dsp.build_url("admin", "services", "shadowsocksr", "get_log")
local servers_url = dsp.build_url("admin", "services", "shadowsocksr", "servers")
local autostart = self.map and self.map.ssr_subscribe_autostart
-%>
<div id="ssr-subscribe-modal-wrap">
<style type="text/css">
#ssr-subscribe-modal-mask {
display: none;
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.35);
z-index: 2000;
}
#ssr-subscribe-modal {
display: none;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: min(900px, calc(100vw - 32px));
max-height: min(720px, calc(100vh - 80px));
overflow: auto;
background: #fff;
border-radius: 10px;
box-shadow: 0 16px 40px rgba(0, 0, 0, 0.18);
z-index: 2001;
padding: 12px 16px 14px;
}
#ssr-subscribe-modal-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
margin-bottom: 8px;
}
#ssr-subscribe-modal-title {
font-size: 17px;
font-weight: 600;
color: #333;
}
#ssr-subscribe-modal-status {
margin: 0 0 8px;
color: #666;
}
#ssr-subscribe-modal-status.ssr-subscribe-highlight {
font-size: 18px;
font-weight: 700;
line-height: 1.5;
}
#ssr-subscribe-log {
margin: 0;
padding: 14px 16px;
min-height: 420px;
max-height: min(520px, calc(100vh - 220px));
overflow: auto;
background: #111827;
color: #e5e7eb;
border-radius: 8px;
box-sizing: border-box;
white-space: pre-wrap;
word-break: break-word;
font: 13px/1.5 Menlo, Monaco, Consolas, monospace;
}
@media (max-width: 700px) {
#ssr-subscribe-modal {
width: calc(100vw - 16px);
max-height: calc(100vh - 24px);
padding: 10px 12px 12px;
}
#ssr-subscribe-modal-header {
flex-direction: column;
align-items: flex-start;
}
#ssr-subscribe-log {
max-height: calc(100vh - 260px);
min-height: 280px;
}
}
</style>
<script type="text/javascript">//<![CDATA[
(function() {
var pollTimer = null;
var running = false;
var autoStart = <%=autostart and "true" or "false"%>;
function getEl(id) {
return document.getElementById(id);
}
function setStatus(text, color) {
var status = getEl('ssr-subscribe-modal-status');
if (!status) {
return;
}
status.className = 'ssr-subscribe-highlight';
status.style.color = color || '#666';
status.textContent = text;
}
function updateLog(text) {
var log = getEl('ssr-subscribe-log');
if (!log) {
return;
}
log.textContent = text || '';
log.scrollTop = log.scrollHeight;
}
function appendLog(text) {
var log = getEl('ssr-subscribe-log');
if (!log || !text) {
return;
}
log.textContent = (log.textContent ? log.textContent.replace(/\s*$/, '') + '\n' : '') + text;
log.scrollTop = log.scrollHeight;
}
function clearPoll() {
if (pollTimer) {
window.clearInterval(pollTimer);
pollTimer = null;
}
}
function fetchLog() {
XHR.get('<%=get_log_url%>', null, function(x) {
if (x && x.status === 200) {
updateLog(x.responseText || '');
}
});
}
function openModal() {
var mask = getEl('ssr-subscribe-modal-mask');
var modal = getEl('ssr-subscribe-modal');
if (mask) {
mask.style.display = 'block';
}
if (modal) {
modal.style.display = 'block';
}
}
function closeModal(force) {
if (running && !force) {
return false;
}
clearPoll();
var mask = getEl('ssr-subscribe-modal-mask');
var modal = getEl('ssr-subscribe-modal');
if (mask) {
mask.style.display = 'none';
}
if (modal) {
modal.style.display = 'none';
}
return false;
}
function finishSubscribe(success) {
running = false;
clearPoll();
fetchLog();
if (success) {
var remain = 5;
appendLog('订阅已结束将在倒数5秒后返回页面');
setStatus('订阅已结束,将在倒数' + remain + '秒后返回页面', '#249400');
var countdown = window.setInterval(function() {
remain = remain - 1;
if (remain <= 0) {
window.clearInterval(countdown);
closeModal(true);
window.location.href = '<%=servers_url%>';
return;
}
setStatus('订阅已结束,将在倒数' + remain + '秒后返回页面', '#249400');
}, 1000);
return;
}
setStatus('<%:Subscribe failed, refreshing page...%>', '#ff0000');
window.setTimeout(function() {
closeModal(true);
window.location.href = '<%=servers_url%>';
}, 1200);
}
function startSubscribe(options, done) {
running = true;
updateLog('');
setStatus('<%:Starting subscription update...%>', '#0072c3');
openModal();
clearPoll();
fetchLog();
pollTimer = window.setInterval(fetchLog, 1000);
XHR.get('<%=subscribe_url%>', null, function(x, rv) {
var ok = !!(rv && typeof rv.ret !== 'undefined' && Number(rv.ret) === 0);
if (typeof done === 'function') {
done(ok);
}
finishSubscribe(ok);
});
}
window.ssrSubscribeRun = startSubscribe;
window.setTimeout(function() {
var closeBtn = getEl('ssr-subscribe-modal-close');
var mask = getEl('ssr-subscribe-modal-mask');
if (closeBtn) {
closeBtn.onclick = function() {
return closeModal(false);
};
}
if (mask) {
mask.onclick = function() {
return closeModal(false);
};
}
if (autoStart) {
startSubscribe();
}
}, 0);
})();
//]]></script>
<input class="btn cbi-button cbi-button-apply" type="submit"<%= attr("name", cbid) .. attr("id", cbid) .. attr("value", self.inputtitle or self.title)%> />
<div id="ssr-subscribe-modal-mask"></div>
<div id="ssr-subscribe-modal" role="dialog" aria-modal="true" aria-labelledby="ssr-subscribe-modal-title">
<div id="ssr-subscribe-modal-header">
<div id="ssr-subscribe-modal-title"><%:Subscribe Log%></div>
<input type="button" id="ssr-subscribe-modal-close" class="btn cbi-button" value="<%:Close%>" />
</div>
<div id="ssr-subscribe-modal-status"><%:Ready.%></div>
<pre id="ssr-subscribe-log"></pre>
</div>
</div>
<%+cbi/valuefooter%>