no usage display notice implemented

remembering the last known position implemented
This commit is contained in:
Slavomir Durej 2025-12-17 08:41:19 +00:00
parent 5680558060
commit 2cfa69cc5d
5 changed files with 107 additions and 12 deletions

View file

@ -117,8 +117,8 @@ const UPDATE_INTERVAL = 5 * 60 * 1000; // Change to your preference (in millisec
- Try re-logging in from the system tray menu
### Widget position not saving
- Position is reset on each launch
- Future version will include position memory
- Window position is now saved automatically when you drag it
- Position will be restored when you restart the app
### Build errors
```bash
@ -158,7 +158,7 @@ https://claude.ai/api/organizations/{org_id}/usage
- [ ] Linux support
- [ ] Custom themes
- [ ] Notification alerts at usage thresholds
- [ ] Remember window position
- [x] Remember window position
- [ ] Settings panel
- [ ] Usage history graphs
- [ ] Multiple account support

20
main.js
View file

@ -16,7 +16,9 @@ const WIDGET_WIDTH = 480;
const WIDGET_HEIGHT = 140;
function createMainWindow() {
mainWindow = new BrowserWindow({
// Load saved position or use defaults
const savedPosition = store.get('windowPosition');
const windowOptions = {
width: WIDGET_WIDTH,
height: WIDGET_HEIGHT,
frame: false,
@ -30,7 +32,15 @@ function createMainWindow() {
contextIsolation: true,
preload: path.join(__dirname, 'preload.js')
}
});
};
// Apply saved position if it exists
if (savedPosition) {
windowOptions.x = savedPosition.x;
windowOptions.y = savedPosition.y;
}
mainWindow = new BrowserWindow(windowOptions);
mainWindow.loadFile('src/renderer/index.html');
@ -38,6 +48,12 @@ function createMainWindow() {
mainWindow.setAlwaysOnTop(true, 'floating');
mainWindow.setVisibleOnAllWorkspaces(true);
// Save position when window is moved
mainWindow.on('move', () => {
const position = mainWindow.getBounds();
store.set('windowPosition', { x: position.x, y: position.y });
});
mainWindow.on('closed', () => {
mainWindow = null;
});

View file

@ -9,6 +9,7 @@ const UPDATE_INTERVAL = 5 * 60 * 1000; // 5 minutes
const elements = {
loadingContainer: document.getElementById('loadingContainer'),
loginContainer: document.getElementById('loginContainer'),
noUsageContainer: document.getElementById('noUsageContainer'),
mainContent: document.getElementById('mainContent'),
loginBtn: document.getElementById('loginBtn'),
refreshBtn: document.getElementById('refreshBtn'),
@ -130,17 +131,30 @@ async function fetchUsageData() {
}
}
// Update UI with usage data
// Check if there's no usage data
function hasNoUsage(data) {
const sessionUtilization = data.five_hour?.utilization || 0;
const sessionResetsAt = data.five_hour?.resets_at;
const weeklyUtilization = data.seven_day?.utilization || 0;
const weeklyResetsAt = data.seven_day?.resets_at;
return sessionUtilization === 0 && !sessionResetsAt &&
weeklyUtilization === 0 && !weeklyResetsAt;
}
// Update UI with usage data
function updateUI(data) {
latestUsageData = data;
// Check if there's no usage data
if (hasNoUsage(data)) {
showNoUsage();
return;
}
showMainContent();
refreshTimers();
startCountdown();
// Update timestamp
// Update timestamp
// const now = new Date();
// elements.lastUpdate.textContent = `Updated ${now.toLocaleTimeString()}`;
}
// Track if we've already triggered a refresh for expired timers
@ -301,19 +315,29 @@ function updateTimer(timerElement, textElement, resetsAt, totalMinutes) {
function showLoading() {
elements.loadingContainer.style.display = 'block';
elements.loginContainer.style.display = 'none';
elements.noUsageContainer.style.display = 'none';
elements.mainContent.style.display = 'none';
}
function showLoginRequired() {
elements.loadingContainer.style.display = 'none';
elements.loginContainer.style.display = 'flex'; // Use flex to preserve centering
elements.noUsageContainer.style.display = 'none';
elements.mainContent.style.display = 'none';
stopAutoUpdate();
}
function showNoUsage() {
elements.loadingContainer.style.display = 'none';
elements.loginContainer.style.display = 'none';
elements.noUsageContainer.style.display = 'flex';
elements.mainContent.style.display = 'none';
}
function showMainContent() {
elements.loadingContainer.style.display = 'none';
elements.loginContainer.style.display = 'none';
elements.noUsageContainer.style.display = 'none';
elements.mainContent.style.display = 'block';
}

View file

@ -56,6 +56,19 @@
</div>
</div>
<!-- No Usage State -->
<div class="no-usage-container" id="noUsageContainer" style="display: none;">
<div class="no-usage-content">
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
</svg>
<div class="no-usage-text-group">
<h3>No Usage Yet</h3>
<p>Start chatting with Claude to see your usage stats</p>
</div>
</div>
</div>
<!-- Main Content -->
<div class="content" id="mainContent" style="display: none;">
<!-- Session Usage -->

View file

@ -56,7 +56,7 @@ body {
}
.app-logo {
width: 19px;
width: 19px;npm
height: 19px;
border-radius: 6px;
opacity: 0.8;
@ -188,6 +188,48 @@ body {
box-shadow: 0 4px 12px rgba(139, 92, 246, 0.3);
}
/* No Usage State */
.no-usage-container {
padding: 0 16px;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
.no-usage-content {
display: flex;
align-items: center;
gap: 16px;
text-align: left;
width: 100%;
}
.no-usage-content svg {
color: #8b5cf6;
width: 32px;
height: 32px;
flex-shrink: 0;
}
.no-usage-text-group {
display: flex;
flex-direction: column;
justify-content: center;
}
.no-usage-content h3 {
color: #e0e0e0;
font-size: 14px;
margin-bottom: 2px;
}
.no-usage-content p {
color: #a0a0a0;
font-size: 11px;
margin-bottom: 0;
}
/* Main Content */
.content {
padding: 20px;