mirror of
https://github.com/System-End/hackatime-desktop.git
synced 2026-04-19 22:05:10 +00:00
Compare commits
5 commits
app-v1.7.3
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
832a610693 | ||
|
|
472867d58f | ||
|
|
d037bdb529 | ||
|
|
6509fc85e0 | ||
|
|
e84c1d6a37 |
9 changed files with 102 additions and 35 deletions
2
.github/workflows/release.yaml
vendored
2
.github/workflows/release.yaml
vendored
|
|
@ -250,7 +250,7 @@ jobs:
|
|||
- name: Generate update manifest
|
||||
id: generate_manifest
|
||||
env:
|
||||
DOWNLOAD_URL_BASE: 'https://pub-d35fbe65a5b5426bb6d62ff02a8c7d03.r2.dev'
|
||||
DOWNLOAD_URL_BASE: 'https://desktop.hackatime.hackclub-assets.com'
|
||||
VERSION: '${{ steps.get_version.outputs.version }}'
|
||||
run: >
|
||||
# Read signatures into variables
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"app": "0.0.0",
|
||||
".": "1.7.3"
|
||||
".": "1.7.5"
|
||||
}
|
||||
15
CHANGELOG.md
15
CHANGELOG.md
|
|
@ -1,5 +1,20 @@
|
|||
# Changelog
|
||||
|
||||
## [1.7.5](https://github.com/hackclub/hackatime-desktop/compare/app-v1.7.4...app-v1.7.5) (2025-10-24)
|
||||
|
||||
|
||||
### 🐛 Bugfixes
|
||||
|
||||
* eliminate duplicate discord definitions ([472867d](https://github.com/hackclub/hackatime-desktop/commit/472867d58f306d70241b07b5f3135c34055ad555))
|
||||
* make option enabled by default ([d037bdb](https://github.com/hackclub/hackatime-desktop/commit/d037bdb529a4a078a5d10f7daa68698da9726e5f))
|
||||
|
||||
## [1.7.4](https://github.com/hackclub/hackatime-desktop/compare/app-v1.7.3...app-v1.7.4) (2025-10-24)
|
||||
|
||||
|
||||
### 🐛 Bugfixes
|
||||
|
||||
* update hackatime url ([e84c1d6](https://github.com/hackclub/hackatime-desktop/commit/e84c1d6a37fdef397189e8a9108f68d4ddb11641))
|
||||
|
||||
## [1.7.3](https://github.com/hackclub/hackatime-desktop/compare/app-v1.7.2...app-v1.7.3) (2025-10-24)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "desktop",
|
||||
"private": true,
|
||||
"version": "1.7.3",
|
||||
"version": "1.7.5",
|
||||
"type": "module",
|
||||
"packageManager": "pnpm@10.18.0",
|
||||
"scripts": {
|
||||
|
|
|
|||
|
|
@ -283,26 +283,3 @@ pub async fn discord_rpc_auto_disconnect(
|
|||
rpc_service.disconnect()
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn get_discord_rpc_enabled(
|
||||
discord_rpc_state: State<'_, Arc<tauri::async_runtime::Mutex<DiscordRpcService>>>,
|
||||
) -> Result<bool, String> {
|
||||
let rpc_service = discord_rpc_state.lock().await;
|
||||
Ok(rpc_service.is_connected())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn set_discord_rpc_enabled(
|
||||
enabled: bool,
|
||||
discord_rpc_state: State<'_, Arc<tauri::async_runtime::Mutex<DiscordRpcService>>>,
|
||||
) -> Result<(), String> {
|
||||
let mut rpc_service = discord_rpc_state.lock().await;
|
||||
|
||||
if enabled {
|
||||
|
||||
let default_client_id = "1234567890123456789";
|
||||
rpc_service.connect(default_client_id)
|
||||
} else {
|
||||
rpc_service.disconnect()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -140,6 +140,10 @@ pub fn run() {
|
|||
preferences::get_preferences,
|
||||
preferences::set_autostart_enabled,
|
||||
preferences::get_autostart_enabled,
|
||||
preferences::set_notifications_enabled,
|
||||
preferences::get_notifications_enabled,
|
||||
preferences::set_discord_rpc_enabled,
|
||||
preferences::get_discord_rpc_enabled,
|
||||
|
||||
setup::setup_hackatime_macos_linux,
|
||||
setup::setup_hackatime_windows,
|
||||
|
|
@ -166,8 +170,6 @@ pub fn run() {
|
|||
discord_rpc::discord_rpc_update_from_heartbeat,
|
||||
discord_rpc::discord_rpc_auto_connect,
|
||||
discord_rpc::discord_rpc_auto_disconnect,
|
||||
discord_rpc::get_discord_rpc_enabled,
|
||||
discord_rpc::set_discord_rpc_enabled,
|
||||
|
||||
projects::get_projects,
|
||||
projects::get_project_details,
|
||||
|
|
|
|||
|
|
@ -9,12 +9,16 @@ use crate::push_log;
|
|||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct Preferences {
|
||||
pub autostart_enabled: bool,
|
||||
pub notifications_enabled: bool,
|
||||
pub discord_rpc_enabled: bool,
|
||||
}
|
||||
|
||||
impl Default for Preferences {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
autostart_enabled: false,
|
||||
autostart_enabled: true,
|
||||
notifications_enabled: true,
|
||||
discord_rpc_enabled: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -86,3 +90,45 @@ pub fn get_autostart_enabled() -> Result<bool, String> {
|
|||
Ok(preferences.autostart_enabled)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn set_notifications_enabled(enabled: bool) -> Result<(), String> {
|
||||
let mut preferences = load_preferences().unwrap_or_default();
|
||||
preferences.notifications_enabled = enabled;
|
||||
save_preferences(&preferences)?;
|
||||
|
||||
if enabled {
|
||||
push_log("info", "backend", "Notifications enabled".to_string());
|
||||
} else {
|
||||
push_log("info", "backend", "Notifications disabled".to_string());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn get_notifications_enabled() -> Result<bool, String> {
|
||||
let preferences = load_preferences().unwrap_or_default();
|
||||
Ok(preferences.notifications_enabled)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn set_discord_rpc_enabled(enabled: bool) -> Result<(), String> {
|
||||
let mut preferences = load_preferences().unwrap_or_default();
|
||||
preferences.discord_rpc_enabled = enabled;
|
||||
save_preferences(&preferences)?;
|
||||
|
||||
if enabled {
|
||||
push_log("info", "backend", "Discord RPC enabled".to_string());
|
||||
} else {
|
||||
push_log("info", "backend", "Discord RPC disabled".to_string());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn get_discord_rpc_enabled() -> Result<bool, String> {
|
||||
let preferences = load_preferences().unwrap_or_default();
|
||||
Ok(preferences.discord_rpc_enabled)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "Hackatime Desktop",
|
||||
"version": "1.7.3",
|
||||
"version": "1.7.5",
|
||||
"identifier": "com.hackclub.hackatime",
|
||||
"build": {
|
||||
"beforeDevCommand": "pnpm dev",
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
}
|
||||
],
|
||||
"security": {
|
||||
"csp": "default-src 'self' ipc: http://ipc.localhost; connect-src 'self' ipc: http://ipc.localhost https://hackatime.hackclub.com https://pub-d35fbe65a5b5426bb6d62ff02a8c7d03.r2.dev wss://*.ingest.us.sentry.io https://us.i.posthog.com https://fonts.googleapis.com https://fonts.gstatic.com; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: https:; font-src 'self' data: https://fonts.gstatic.com; worker-src 'self' blob:;"
|
||||
"csp": "default-src 'self' ipc: http://ipc.localhost; connect-src 'self' ipc: http://ipc.localhost https://hackatime.hackclub.com https://desktop.hackatime.hackclub-assets.com wss://*.ingest.us.sentry.io https://us.i.posthog.com https://fonts.googleapis.com https://fonts.gstatic.com; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: https:; font-src 'self' data: https://fonts.gstatic.com; worker-src 'self' blob:;"
|
||||
},
|
||||
"withGlobalTauri": true
|
||||
},
|
||||
|
|
@ -64,7 +64,7 @@
|
|||
"updater": {
|
||||
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDdERjg4QTFCNTJFMDk0MUQKUldRZGxPQlNHNHI0ZlRkMDN0MGI1MnllY1dUVStZalV3dVdhcTFuREx5SGtBc0txQ2xnTWs3WU4K",
|
||||
"endpoints": [
|
||||
"https://pub-d35fbe65a5b5426bb6d62ff02a8c7d03.r2.dev/update-manifest.json"
|
||||
"https://desktop.hackatime.hackclub-assets.com/update-manifest.json"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,9 +45,9 @@
|
|||
<h4 class="font-medium text-text-primary mb-1">Notifications</h4>
|
||||
<p class="text-sm text-text-secondary">Show desktop notifications</p>
|
||||
</div>
|
||||
<label class="switch">
|
||||
<input type="checkbox" checked>
|
||||
<span class="slider"></span>
|
||||
<label class="switch" :class="{ 'opacity-50 cursor-not-allowed': isLoading }">
|
||||
<input type="checkbox" :checked="notificationsEnabled" :disabled="isLoading" @change="toggleNotifications">
|
||||
<span class="slider" :class="{ 'animate-pulse': isLoading }"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -291,6 +291,7 @@ const emit = defineEmits<{
|
|||
|
||||
const discordRpcEnabled = ref(false);
|
||||
const autostartEnabled = ref(false);
|
||||
const notificationsEnabled = ref(false);
|
||||
const isLoading = ref(false);
|
||||
const appVersion = ref('...');
|
||||
const isClearingCache = ref(false);
|
||||
|
|
@ -565,6 +566,14 @@ async function loadAutostartState() {
|
|||
}
|
||||
}
|
||||
|
||||
async function loadNotificationsState() {
|
||||
try {
|
||||
notificationsEnabled.value = await invoke("get_notifications_enabled");
|
||||
} catch (error) {
|
||||
console.error("Failed to load notifications state:", error);
|
||||
}
|
||||
}
|
||||
|
||||
async function toggleAutostart() {
|
||||
if (isLoading.value) return;
|
||||
|
||||
|
|
@ -599,6 +608,23 @@ async function toggleDiscordRpc() {
|
|||
}
|
||||
}
|
||||
|
||||
async function toggleNotifications() {
|
||||
if (isLoading.value) return;
|
||||
|
||||
isLoading.value = true;
|
||||
try {
|
||||
const newState = !notificationsEnabled.value;
|
||||
await invoke("set_notifications_enabled", { enabled: newState });
|
||||
notificationsEnabled.value = newState;
|
||||
} catch (error) {
|
||||
console.error("Failed to toggle notifications:", error);
|
||||
|
||||
notificationsEnabled.value = !notificationsEnabled.value;
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function copyApiKey() {
|
||||
emit('copyApiKey')
|
||||
}
|
||||
|
|
@ -689,6 +715,7 @@ async function downloadAndInstallUpdate() {
|
|||
onMounted(async () => {
|
||||
loadDiscordRpcState();
|
||||
loadAutostartState();
|
||||
loadNotificationsState();
|
||||
try {
|
||||
appVersion.value = await getVersion();
|
||||
} catch (error) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue