mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-10-31 12:55:13 +08:00
🌴 Sync 2026-05-13 20:46:46
This commit is contained in:
1 parent
88814b43f1
commit
0ab04d37bb
16 files changed
+886
-315
No files matched your search
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="85" height="20" role="img" aria-label="JavaScript"><title>JavaScript</title><g shape-rendering="crispEdges"><rect width="0" height="20" fill="#555"/><rect x="0" width="85" height="20" fill="#323330"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><image x="5" y="3" width="14" height="14" href="data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjZjdkZjFlIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+SmF2YVNjcmlwdDwvdGl0bGU+PHBhdGggZD0iTTAgMGgyNHYyNEgwVjB6bTIyLjAzNCAxOC4yNzZjLS4xNzUtMS4wOTUtLjg4OC0yLjAxNS0zLjAwMy0yLjg3My0uNzM2LS4zNDUtMS41NTQtLjU4NS0xLjc5Ny0xLjE0LS4wOTEtLjMzLS4xMDUtLjUxLS4wNDYtLjcwNS4xNS0uNjQ2LjkxNS0uODQgMS41MTUtLjY2LjM5LjEyLjc1LjQyLjk3Ni45IDEuMDM0LS42NzYgMS4wMzQtLjY3NiAxLjc1NS0xLjEyNS0uMjctLjQyLS40MDQtLjYwMS0uNTg2LS43OC0uNjMtLjcwNS0xLjQ2OS0xLjA2NS0yLjgzNC0xLjAzNGwtLjcwNS4wODljLS42NzYuMTY1LTEuMzIuNTI1LTEuNzEgMS4wMDUtMS4xNCAxLjI5MS0uODExIDMuNTQxLjU2OSA0LjQ3MSAxLjM2NSAxLjAyIDMuMzYxIDEuMjQ0IDMuNjE2IDIuMjA1LjI0IDEuMTctLjg3IDEuNTQ1LTEuOTY2IDEuNDEtLjgxMS0uMTgtMS4yNi0uNTg2LTEuNzU1LTEuMzM2bC0xLjgzIDEuMDUxYy4yMS40OC40NS42ODkuODEgMS4xMDkgMS43NCAxLjc1NiA2LjA5IDEuNjY2IDYuODcxLTEuMDA0LjAyOS0uMDkuMjQtLjcwNS4wNzQtMS42NWwuMDQ2LjA2N3ptLTguOTgzLTcuMjQ1aC0yLjI0OGMwIDEuOTM4LS4wMDkgMy44NjQtLjAwOSA1LjgwNSAwIDEuMjMyLjA2MyAyLjM2My0uMTM4IDIuNzExLS4zMy42ODktMS4xOC42MDEtMS41NjYuNDgtLjM5Ni0uMTk2LS41OTctLjQ2Ni0uODMtLjg1NS0uMDYzLS4xMDUtLjExLS4xOTYtLjEyNy0uMTk2bC0xLjgyNSAxLjEyNWMuMzA1LjYzLjc1IDEuMTcyIDEuMzI0IDEuNTE3Ljg1NS41MSAyLjAwNC42NzUgMy4yMDcuNDA1Ljc4My0uMjI2IDEuNDU4LS42OTEgMS44MTEtMS40MTEuNTEtLjkzLjQwMi0yLjA3LjM5Ny0zLjM0Ni4wMTItMi4wNTQgMC00LjEwOSAwLTYuMTc5bC4wMDQtLjA1NnoiLz48L3N2Zz4="/><text x="515" y="140" transform="scale(.1)" fill="#fff" textLength="570">JavaScript</text></g></svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="47" height="20" role="img" aria-label="Lua"><title>Lua</title><g shape-rendering="crispEdges"><rect width="0" height="20" fill="#555"/><rect x="0" width="47" height="20" fill="#2c2d72"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><image x="5" y="3" width="14" height="14" href="data:image/svg+xml;base64,PHN2ZyBmaWxsPSJ3aGl0ZSIgcm9sZT0iaW1nIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHRpdGxlPkx1YTwvdGl0bGU+PHBhdGggZD0iTS4zOCAxMC4zNzdsLS4yNzItLjAzN2MtLjA0OC4zNDQtLjA4Mi42OTUtLjEwMSAxLjA0MWwuMjc1LjAxNmMuMDE4LS4zNC4wNTEtLjY4Mi4wOTgtMS4wMnpNNC4xMzYgMy4yODlsLS4xODQtLjIwNWMtLjI1OC4yMzItLjUwOS40OC0uNzQ2LjczNGwuMjAyLjE4OGMuMjMxLS4yNDguNDc2LS40OS43MjgtLjcxN3pNNS43NjkgMi4wNTlsLS4xNDYtLjIzNWMtLjI5Ni4xODYtLjU4Ni4zODUtLjg2My41OTRsLjE2Ni4yMTljLjI3LS4yMDMuNTU0LS4zOTkuODQzLS41Nzh6TTEuODI0IDE4LjM2OWMuMTg1LjI5Ny4zODQuNTg2LjU5My44NjNsLjIyLS4xNjRjLS4yMDUtLjI3MS0uMzk5LS41NTUtLjU4LS44NDRsLS4yMzMuMTQ1ek0xLjEyNyAxNi40MDJsLS4yNTUuMTA0Yy4xMjkuMzE4LjI3NC42MzUuNDMxLjk0M2wuMDA1LjAxLjI0NS0uMTI1LS4wMDUtLjAxYy0uMTUzLS4zMDEtLjI5NS0uNjExLS40MjEtLjkyMnpNLjI5OCA5LjMwOWwuMjY5LjA2M2MuMDc2LS4zMzIuMTY4LS42NjQuMjcyLS45ODZsLS4yNjEtLjA4N2MtLjEwOC4zMzItLjIwMi42NzItLjI4IDEuMDF6TS4yNzQgMTIuNDJsLS4yNzUuMDFjLjAxMi4zNDguMDQuNjk5LjA4MyAxLjA0M2wuMjczLS4wMzNjLS4wNDItLjMzNi0uMDY5LS42OC0uMDgxLTEuMDJ6TS4yNTYgMTQuNTA2Yy4wNzMuMzQuMTYyLjY4Mi4yNjQgMS4wMTRsLjI2My0uMDhjLS4xLS4zMjYtLjE4Ny0uNjU4LS4yNTgtLjk5bC0uMjY5LjA1NnpNMTEuNTczLjI3NUwxMS41NjMgMGMtLjM0OC4wMTItLjY5OS4wMzktMS4wNDQuMDgybC4wMzQuMjczYy4zMzgtLjA0MS42OC0uMDY4IDEuMDItLjA4ek0yMy4yMjEgOC41NjZjLjEuMzI2LjE4Ni42Ni4yNTYuOTkybC4yNy0uMDU5Yy0uMDcyLS4zNC0uMTYtLjY4Mi0uMjYyLTEuMDE0bC0uMjY0LjA4MXpNMTcuNjIxIDEuMzg5Yy0uMzA5LS4xNjQtLjYyNy0uMzE0LS45NDctLjQ0OWwtLjEwNy4yNTJjLjMxNC4xMzMuNjI1LjI4MS45MjYuNDM5bC4xMjgtLjI0MnpNMTUuNjkzLjU3MmMtLjMzMi0uMTA1LS42Ny0uMTk5LTEuMDEtLjI3N2wtLjA2My4yNjhjLjMzMi4wNzYuNjY0LjE2OC45ODguMjczbC4wODUtLjI2NHpNNi42NzQgMS41NDVjLjI5OC0uMTUuNjA2LS4yOTEuOTE2LS40MThMNy40ODYuODczYy0uMzE3LjEyNy0uNjMyLjI3Mi0uOTM3LjQyOGwtLjAxNS4wMDguMTI1LjI0NC4wMTUtLjAwOHpNMjMuNzI3IDExLjU4OGwuMjc1LS4wMWExMS43OTcgMTEuNzk3IDAgMCAwLS4wODItMS4wNDVsLS4yNzMuMDMzYy4wNDEuMzM4LjA2OC42ODIuMDggMS4wMjJ6TTEzLjY1NC4xMDVjLS4zNDYtLjA0Ny0uNjk2LS4wOC0xLjA0My0uMDk4bC0uMDE0LjI3M2MuMzM5LjAxOC42ODMuMDUxIDEuMDE5LjA5OGwuMDM4LS4yNzN6TTkuNTQ0LjUyN2wtLjA1OC0uMjdjLS4zNC4wNzItLjY4MS4xNi0xLjAxNC4yNjRsLjA4MS4yNjJjLjMyNS0uMDk5LjY1OS0uMTg1Ljk5MS0uMjU2ek0xLjkyMSA1LjQ2OWwuMjMxLjE1Yy4xODUtLjI4NS4zODQtLjU2Ni41OTItLjgzNGwtLjIxNy0uMTdjLS4yMTMuMjc2LS40MTcuNTYzLS42MDYuODU0ek0uOTQzIDcuMzE4bC4yNTMuMTA3Yy4xMzItLjMxMy4yOC0uNjI1LjQzOS0uOTI0bC0uMjQzLS4xMjhjLS4xNjMuMzA3LS4zMTQuNjI1LS40NDkuOTQ1ek0xOC4yMjMgMjEuOTQzbC4xNDUuMjM0Yy4yOTUtLjE4Ni41ODYtLjM4NS44NjMtLjU5NGwtLjE2NC0uMjE5Yy0uMjcyLjIwNC0uNTU3LjQtLjg0NC41Nzl6TTIxLjI0OCAxOS4yMTlsLjIxNy4xN2MuMjE1LS4yNzMuNDE4LS41NjEuNjA3LS44NTRsLS4yMy0uMTQ4Yy0uMTg2LjI4NS0uMzg1LjU2NC0uNTk0LjgzMnpNMTkuODU1IDIwLjcxNWwuMTg0LjIwM2MuMjU4LS4yMy41MS0uNDc5Ljc0Ni0uNzMybC0uMjAxLS4xODhjLS4yMy4yNDgtLjQ3Ny40ODgtLjcyOS43MTd6TTIyLjM1OSAxNy41MDRsLjI0NC4xMjljLjE2Mi0uMzA3LjMxNC0uNjI1LjQ0OS0uOTQ1bC0uMjU0LS4xMDdhMTEuMjcgMTEuMjcgMCAwIDEtLjQzOS45MjN6TTIzLjYxNyAxMy42MjlsLjI3My4wMzljLjA0OS0uMzQ2LjA4Mi0uNjk1LjEwMi0xLjA0M2wtLjI3NS0uMDE0Yy0uMDE4LjMzOC0uMDUxLjY4Mi0uMSAxLjAxOHpNMjMuMTU2IDE1LjYyMWwuMjY0LjA4NmMuMTA3LS4zMzIuMjAxLS42Ny4yNzktMS4wMWwtLjI2OC0uMDYzYy0uMDc3LjMzMy0uMTY5LjY2NS0uMjc1Ljk4N3pNMjIuNDUzIDYuNjcyYy4xNTQuMzAzLjI5Ny42MTcuNDI0LjkzMmwuMjU2LS4xMDRjLS4xMzEtLjMyMi0uMjc3LS42NDMtLjQzNi0uOTUzbC0uMjQ0LjEyNXpNOC4yOTYgMjMuNDE4Yy4zMzEuMTA3LjY3LjIwMSAxLjAwOS4yNzlsLjA2Mi0uMjY4Yy0uMzMxLS4wNzYtLjY2My0uMTY4LS45ODYtLjI3M2wtLjA4NS4yNjJ6TTEwLjMzNSAyMy44ODljLjM0NS4wNDkuNjk2LjA4MiAxLjA0My4xMDJsLjAxNC0uMjc1Yy0uMzM5LS4wMTgtLjY4Mi0uMDUxLTEuMDE5LS4wOThsLS4wMzguMjcxek0xNy4zMjYgMjIuNDQ5Yy0uMzAzLjE1NC0uNjEzLjI5Ny0uOTI2LjQyNGwuMTA0LjI1NmMuMzE4LS4xMzEuNjM5LS4yNzUuOTQ3LS40MzRsLjAwNC0uMDAyLS4xMjMtLjI0Ni0uMDA2LjAwMnpNNC42MTMgMjEuNDY3Yy4yNzQuMjEzLjU2Mi40MTguODU0LjYwNWwuMTQ5LS4yM2MtLjI4NS0uMTg0LS41NjUtLjM4NS0uODMzLS41OTJsLS4xNy4yMTd6TTEyLjQxNyAyMy43MjVsLjAwOS4yNzVjLjM0OC0uMDE0LjY5OS0uMDQxIDEuMDQ1LS4wODRsLS4wMzUtLjI3MWMtLjMzNi4wNDEtLjY4LjA2OC0xLjAxOS4wOHpNNi4zNyAyMi42MDRjLjMwNy4xNjIuNjI1LjMxNC45NDYuNDQ5bC4xMDctLjI1NGMtLjMxMy0uMTMzLS42MjQtLjI3OS0uOTI0LS40MzlsLS4xMjkuMjQ0ek0zLjA4MyAyMC4wNDFjLjIzMy4yNTguNDguNTEuNzM0Ljc0NmwuMTg4LS4yMDFjLS4yNDktLjIzLS40OS0uNDc3LS43MTctLjcyOWwtLjIwNS4xODR6TTE0LjQ0NSAyMy40NzVsLjA1OS4yN2MuMzQtLjA3NC42OC0uMTYyIDEuMDE0LS4yNjZsLS4wODItLjI2MmMtLjMyNS4wOTktLjY1OS4xODUtLjk5MS4yNTh6TTIxLjE4LjEyOUEyLjY4OSAyLjY4OSAwIDEgMCAyMS4xOCA1LjUwNyAyLjY4OSAyLjY4OSAwIDEgMCAyMS4xOC4xMjl6TTE1LjMyNCAxNS40NDdjMCAuNDcxLjMxNC42Ni44NTIuNjYuNjcgMCAxLjI5Ny0uMzk2IDEuMjk3LTEuMDE2di0uNjQ1Yy0uMjMuMTA3LS4zNzkuMTQxLTEuMTA3LjI0LS43MzUuMTA5LTEuMDQyLjMwNi0xLjA0Mi43NjF6TTEyIDIuODE4Yy01LjA3IDAtOS4xOCA0LjEwOS05LjE4IDkuMTggMCA1LjA2OCA0LjExIDkuMTggOS4xOCA5LjE4IDUuMDcgMCA5LjE4LTQuMTExIDkuMTgtOS4xOCAwLTUuMDctNC4xMS05LjE4LTkuMTgtOS4xOHptLTIuLine truncated
|
||||
|
After Width: | Height: | Size: 5.9 KiB |
@@ -283,7 +283,6 @@ return view.extend({
|
||||
var verPlugin = E('span', _('Collecting data...'));
|
||||
var verKernel = E('span', _('Collecting data...'));
|
||||
var verRescue = E('span', _('Collecting data...'));
|
||||
var branchSpan = E('span');
|
||||
|
||||
// Per-action status spans (right side, updated by poll)
|
||||
var statusFw = E('span');
|
||||
@@ -419,8 +418,7 @@ return view.extend({
|
||||
E('p', _('Provide OpenWrt Firmware, Kernel and Plugin online check, download and update service.')),
|
||||
E('div', { class: 'cbi-section' }, [
|
||||
E('p', { style: 'text-align:center' }, [
|
||||
_('Update plugins first, then update the kernel or firmware. More options can be configured in [Plugin Settings].'),
|
||||
' ', branchSpan
|
||||
_('Update plugins first, then update the kernel or firmware. More options can be configured in [Plugin Settings].')
|
||||
]),
|
||||
E('table', { class: 'amlogic-row-table' }, [
|
||||
E('tr', [
|
||||
@@ -461,10 +459,6 @@ return view.extend({
|
||||
dom.content(verKernel, s && s.current_kernel_version
|
||||
? E('span', { class: 'amlogic-status-ok' }, _('Current Version') + ' [ ' + s.current_kernel_version + ' ] ')
|
||||
: E('span', { class: 'amlogic-status-err' }, _('Invalid value.')));
|
||||
var branchLabel = s && s.plugin_branch
|
||||
? (s.plugin_branch === 'lua' ? 'Lua' : 'JavaScript')
|
||||
: (s && s.has_luci_js ? 'JavaScript' : 'Lua');
|
||||
dom.content(branchSpan, ' [ ' + branchLabel + ' ] ');
|
||||
|
||||
// Rescue row: show same kernel version directly via the verRescue span
|
||||
dom.content(verRescue, s && s.current_kernel_version
|
||||
|
||||
@@ -23,6 +23,9 @@ const callAuthor = rpc.declare({
|
||||
// Called on every info page load so the sidebar menu is correct from first visit.
|
||||
const callSyncMenu = rpc.declare({ object: 'luci.amlogic', method: 'sync_menu' });
|
||||
|
||||
// Get runtime state to determine plugin_branch for the language badge.
|
||||
const callState = rpc.declare({ object: 'luci.amlogic', method: 'state' });
|
||||
|
||||
// Static list of supported boxes (display only, not used in any logic).
|
||||
const SUPPORTED_BOXES = [
|
||||
_('Amlogic s922x --- [ Beelink, Beelink-Pro, Ugoos-AM6-Plus, ODROID-N2, Khadas-VIM3, Ali-CT2000 ]'),
|
||||
@@ -57,9 +60,27 @@ return view.extend({
|
||||
handleReset: null,
|
||||
|
||||
load: function () {
|
||||
// Fire sync_menu in background (don't block render on it).
|
||||
callSyncMenu().catch(function () {});
|
||||
return callAuthor();
|
||||
// Call sync_menu and wait for it. sync_menu writes menu_install /
|
||||
// menu_armcpu into UCI and clears the LuCI index cache on the server.
|
||||
// On first boot from USB the install menu may be missing from the
|
||||
// browser-side navigation (built before sync_menu ran). After the RPC
|
||||
// returns we check if the sidebar already has an install link; if not,
|
||||
// reload once so the browser re-fetches the updated menu tree.
|
||||
// A URL hash flag (#menu-synced) prevents an infinite reload loop.
|
||||
const alreadyReloaded = window.location.hash === '#menu-synced';
|
||||
const syncMenuPromise = callSyncMenu().then(function (res) {
|
||||
if (alreadyReloaded) return;
|
||||
if (res && res.show_install === 'yes') {
|
||||
// Check if the sidebar navigation already contains the install link.
|
||||
const installLink = document.querySelector('a[href*="amlogic/install"]');
|
||||
if (!installLink) {
|
||||
// Server has updated the index cache; reload to pick up new nav.
|
||||
window.location.replace(window.location.pathname + '#menu-synced');
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
}).catch(function () {});
|
||||
return Promise.all([callAuthor(), syncMenuPromise]).then(function (r) { return r[0]; });
|
||||
},
|
||||
|
||||
render: function (authorUrl) {
|
||||
@@ -67,6 +88,23 @@ return view.extend({
|
||||
amlogicShared.ensureCss();
|
||||
const res = L.resource('amlogic');
|
||||
|
||||
// Language badge image — default to javascript.svg (JS version),
|
||||
// will be confirmed/corrected after the state RPC resolves.
|
||||
var langsImg = E('img', {
|
||||
id: 'Langs',
|
||||
src: res + '/javascript.svg', alt: 'javascript',
|
||||
width: '86', height: '20',
|
||||
style: 'margin:0 5px; vertical-align:middle; border-radius:3px'
|
||||
});
|
||||
|
||||
// Fetch plugin_branch from state and update the language badge.
|
||||
callState().then(function (s) {
|
||||
var isLua = s && s.plugin_branch === 'lua';
|
||||
langsImg.src = res + (isLua ? '/lua.svg' : '/javascript.svg');
|
||||
langsImg.alt = isLua ? 'lua' : 'javascript';
|
||||
langsImg.setAttribute('width', isLua ? '46' : '86');
|
||||
}).catch(function () {});
|
||||
|
||||
// Flatten the supported-boxes list to [text, <br>, text, <br>, ...].
|
||||
const boxRows = [];
|
||||
for (let i = 0; i < SUPPORTED_BOXES.length; i++)
|
||||
@@ -86,13 +124,13 @@ return view.extend({
|
||||
E('img', {
|
||||
src: res + '/packit.svg', alt: 'Packit',
|
||||
width: '168', height: '20',
|
||||
style: 'cursor:pointer; margin:0 5px',
|
||||
style: 'cursor:pointer; margin:0 5px; vertical-align:middle; border-radius:3px',
|
||||
click: function () { openExternal('https://github.com/unifreq/openwrt_packit'); }
|
||||
}),
|
||||
E('img', {
|
||||
src: res + '/author.svg', alt: 'Author',
|
||||
width: '168', height: '20',
|
||||
style: 'cursor:pointer; margin:0 5px',
|
||||
style: 'cursor:pointer; margin:0 5px; vertical-align:middle; border-radius:3px',
|
||||
click: function () {
|
||||
callAuthor().then(function (repo) {
|
||||
let url = String(repo || '').trim();
|
||||
@@ -106,9 +144,10 @@ return view.extend({
|
||||
E('img', {
|
||||
src: res + '/plugin.svg', alt: 'luci-app-amlogic',
|
||||
width: '160', height: '20',
|
||||
style: 'cursor:pointer; margin:0 5px',
|
||||
style: 'cursor:pointer; margin:0 5px; vertical-align:middle; border-radius:3px',
|
||||
click: function () { openExternal('https://github.com/ophub/luci-app-amlogic'); }
|
||||
})
|
||||
}),
|
||||
langsImg
|
||||
])
|
||||
]),
|
||||
E('tr', [
|
||||
|
||||
@@ -69,7 +69,7 @@ return view.extend({
|
||||
value: _('Update OpenWrt firmware'), style: 'display:none',
|
||||
click: ui.createHandlerFn(this, function (ev) {
|
||||
return doButton(ev.currentTarget,
|
||||
_('Updating...'), _('Successful Update'), _('Update Failed'),
|
||||
_('Updating...'), _('Update Failed'),
|
||||
function () { return callStartUpd('auto@updated@/tmp'); });
|
||||
})
|
||||
});
|
||||
@@ -78,7 +78,7 @@ return view.extend({
|
||||
value: _('Replace OpenWrt Kernel'), style: 'display:none; margin-left:5px',
|
||||
click: ui.createHandlerFn(this, function (ev) {
|
||||
return doButton(ev.currentTarget,
|
||||
_('Updating...'), _('Successful Update'), _('Update Failed'),
|
||||
_('Updating...'), _('Update Failed'),
|
||||
function () { return callStartKnl(); });
|
||||
})
|
||||
});
|
||||
@@ -86,13 +86,23 @@ return view.extend({
|
||||
const knLog = E('span');
|
||||
const fwVer = E('span', _('Collecting data...'));
|
||||
|
||||
function doButton(btn, busyText, ok, fail, fn) {
|
||||
// Shared button state machine: disabled -> RPC -> success/fail label.
|
||||
function doButton(btn, busyText, fail, fn) {
|
||||
// Shared button state machine: disabled -> RPC -> updating/fail label.
|
||||
// On success (code==0) the button stays in busyText state and
|
||||
// remains disabled — the device is about to reboot, so there is
|
||||
// nothing to restore. Only on failure do we surface an error and
|
||||
// re-enable the button so the user can retry.
|
||||
btn.disabled = true; btn.value = busyText;
|
||||
return Promise.resolve(fn()).then(function (r) {
|
||||
btn.value = (r && r.code == 0) ? ok : fail;
|
||||
}).catch(function () { btn.value = fail; })
|
||||
.finally(function () { btn.disabled = false; });
|
||||
if (!r || r.code !== 0) {
|
||||
btn.value = fail;
|
||||
btn.disabled = false;
|
||||
}
|
||||
// code == 0 → keep busyText + disabled (update in progress)
|
||||
}).catch(function () {
|
||||
btn.value = fail;
|
||||
btn.disabled = false;
|
||||
});
|
||||
}
|
||||
|
||||
function refreshList() {
|
||||
|
||||
Reference in new issue
Block a user