mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-10-05 17:35:33 -03:00
The owner could not tell from the UI what "Buzz Price Tracking" enabled, what the "Price alert threshold" number meant, or what "Price Alerts" was alerting about. That was not a copy problem: the implementation exposed our mechanism (a page scrape) and our SQL predicates as the user's concepts. Two concrete defects came from the same root: - the alert population included versions the user already owns (neither the event generator nor the query filtered on is_in_library; in the owner's library 28 of 52 gated versions were already downloaded, so most "alerts" were about files already on disk, which cannot become cheaper *for them*); - a threshold-filtered state list lived in a notification surface, so an empty panel had three indistinguishable causes and read as a broken feature. The information model is now the version plus ownership: cost is shown only where a decision exists. Owned -> nothing. Not owned and free -> nothing. Not owned and gated -> the price when it is known, `Paid` without a number when it is not, and early access keeps its countdown because "free on <date>" decides between waiting and paying. The numeric threshold has no place in that model: every decision is categorical (wait / pay / skip), so the setting, the comparison and the whole alert-state machine are gone. - both alert-state columns are removed from the schema rather than left dead; a database created by an unreleased build has them dropped on open (native ALTER TABLE ... DROP COLUMN, guarded), which is a no-op for everyone else - gate events are emitted only for versions the user does not have, and the price-drop event goes with the threshold it belonged to - both alert endpoints, PriceAlertsHandler and the service-registry adapter field it needed are removed: events already reach the UI through the refresh response - the bell tab, panel, CSS, both entry points, the unread watermark and their locales are removed; the setting keeps only the enable flag and the refresh interval and is framed as plumbing - "Price unavailable" is replaced by `Paid`: the gate is certain from the public API, only the number is best-effort, and that is our plumbing, not the user's problem Verified against a copy of the owner's real database: 52 gated versions -> 28 owned (now silent) + 24 the feature is actually about; the drop migration ran and both removed endpoints 404.
100 lines
5.7 KiB
HTML
100 lines
5.7 KiB
HTML
<!-- Update Modal -->
|
|
<div id="updateModal" class="modal">
|
|
<div class="modal-content update-modal">
|
|
<button class="close" onclick="modalManager.closeModal('updateModal')">×</button>
|
|
<div class="update-header">
|
|
<i class="fas fa-bell update-icon"></i>
|
|
<h2 data-i18n="update.notificationsTitle">{{ t('update.notificationsTitle') }}</h2>
|
|
</div>
|
|
<div class="notification-tabs" role="tablist">
|
|
<button type="button" class="notification-tab active" id="updatesTab" role="tab" aria-selected="true" aria-controls="updatesPanel" tabindex="0" data-notification-tab="updates">
|
|
<span>{{ t('update.tabs.updates') }}</span>
|
|
<span class="notification-tab-badge is-dot" id="updatesTabBadge"></span>
|
|
</button>
|
|
<button type="button" class="notification-tab" id="bannersTab" role="tab" aria-selected="false" aria-controls="bannersPanel" tabindex="-1" data-notification-tab="banners">
|
|
<span>{{ t('update.tabs.messages') }}</span>
|
|
<span class="notification-tab-badge" id="bannerTabBadge"></span>
|
|
</button>
|
|
</div>
|
|
<div class="notification-panels">
|
|
<div class="notification-panel active" id="updatesPanel" role="tabpanel" aria-labelledby="updatesTab" aria-hidden="false" tabindex="0" data-notification-panel="updates">
|
|
<div class="update-content">
|
|
|
|
<!-- Channel Selector -->
|
|
<div class="update-channels" id="updateChannels">
|
|
<div class="channels-label">{{ t('update.channel') }}</div>
|
|
<div class="channel-toggle">
|
|
<button type="button" class="channel-btn" data-channel="release" id="channelRelease">
|
|
<i class="fas fa-tag"></i> {{ t('update.channels.release') }}
|
|
</button>
|
|
<button type="button" class="channel-btn" data-channel="nightly" id="channelNightly">
|
|
<i class="fas fa-moon"></i> {{ t('update.channels.nightly') }}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="update-info">
|
|
<div class="version-info">
|
|
<div class="current-version">
|
|
<span class="label">{{ t('update.currentVersion') }}:</span>
|
|
<span class="version-number">v0.0.0</span>
|
|
</div>
|
|
<div class="git-info" style="display:none;">{{ t('update.commit') }}: unknown</div>
|
|
<div class="new-version">
|
|
<span class="label">{{ t('update.newVersion') }}:</span>
|
|
<span class="version-number">v0.0.0</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="update-actions">
|
|
<a href="https://github.com/willmiao/ComfyUI-Lora-Manager" target="_blank" class="update-link">
|
|
<i class="fas fa-external-link-alt"></i> {{ t('update.viewOnGitHub') }}
|
|
</a>
|
|
<button id="updateBtn" class="primary-btn disabled">
|
|
<i class="fas fa-download"></i>
|
|
<span id="updateBtnText" data-i18n="update.updateNow">{{ t('update.updateNow') }}</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Update Progress Section -->
|
|
<div class="update-progress" id="updateProgress" style="display: none;">
|
|
<div class="progress-info">
|
|
<div class="progress-text" id="updateProgressText" data-i18n="update.preparingUpdate">{{ t('update.preparingUpdate') }}</div>
|
|
<div class="update-progress-bar">
|
|
<div class="progress-fill" id="updateProgressFill"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="changelog-section">
|
|
<h3>{{ t('update.changelog') }}</h3>
|
|
<div class="changelog-content">
|
|
<!-- Dynamic changelog content will be inserted here -->
|
|
<div class="changelog-item">
|
|
<h4>{{ t('update.checkingUpdates') }}</h4>
|
|
<p>{{ t('update.checkingMessage') }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="update-preferences">
|
|
<label class="toggle-switch">
|
|
<input type="checkbox" id="updateNotifications" checked>
|
|
<span class="toggle-slider"></span>
|
|
<span class="toggle-label">{{ t('update.showNotifications') }}</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="notification-panel" id="bannersPanel" role="tabpanel" aria-labelledby="bannersTab" aria-hidden="true" tabindex="-1" data-notification-panel="banners">
|
|
<div class="banner-history">
|
|
<h3>{{ t('update.banners.recent') }}</h3>
|
|
<p class="banner-history-empty" id="bannerHistoryEmpty" data-i18n="update.banners.empty">{{ t('update.banners.empty') }}</p>
|
|
<ul class="banner-history-list" id="bannerHistoryList"></ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|