Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
43ebc8d74c | ||
|
|
ee2dc19daa |
@@ -2,9 +2,18 @@ import { resolve } from 'node:path'
|
|||||||
import { defineConfig, externalizeDepsPlugin } from 'electron-vite'
|
import { defineConfig, externalizeDepsPlugin } from 'electron-vite'
|
||||||
import react from '@vitejs/plugin-react'
|
import react from '@vitejs/plugin-react'
|
||||||
|
|
||||||
|
// Bake the Gitea update token into the main bundle at build time so
|
||||||
|
// electron-updater can fetch latest.yml from the private repo. The token
|
||||||
|
// only needs read access to releases. Falls back to empty string if not set
|
||||||
|
// (dev/local builds), in which case auto-update is silently disabled.
|
||||||
|
const updateToken = JSON.stringify(process.env.UPDATE_TOKEN ?? '')
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
main: {
|
main: {
|
||||||
plugins: [externalizeDepsPlugin()],
|
plugins: [externalizeDepsPlugin()],
|
||||||
|
define: {
|
||||||
|
__UPDATE_TOKEN__: updateToken
|
||||||
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'@shared': resolve('src/shared')
|
'@shared': resolve('src/shared')
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "laude",
|
"name": "laude",
|
||||||
"version": "0.3.3",
|
"version": "0.3.5",
|
||||||
"description": "Exercise reminder — Windows desktop app",
|
"description": "Exercise reminder — Windows desktop app",
|
||||||
"main": "out/main/index.js",
|
"main": "out/main/index.js",
|
||||||
"author": "AnRil",
|
"author": "AnRil",
|
||||||
|
|||||||
@@ -3,6 +3,10 @@ import { autoUpdater } from 'electron-updater'
|
|||||||
import { IPC } from '@shared/ipc'
|
import { IPC } from '@shared/ipc'
|
||||||
import type { UpdaterStatus } from '@shared/types'
|
import type { UpdaterStatus } from '@shared/types'
|
||||||
|
|
||||||
|
// Build-time defined in electron.vite.config.ts.
|
||||||
|
// Read-only Gitea token, used to fetch latest.yml from the private repo.
|
||||||
|
declare const __UPDATE_TOKEN__: string
|
||||||
|
|
||||||
let currentStatus: UpdaterStatus = { kind: 'idle' }
|
let currentStatus: UpdaterStatus = { kind: 'idle' }
|
||||||
let wired = false
|
let wired = false
|
||||||
let checkInterval: NodeJS.Timeout | null = null
|
let checkInterval: NodeJS.Timeout | null = null
|
||||||
@@ -38,6 +42,14 @@ export function initUpdater(): void {
|
|||||||
autoUpdater.autoInstallOnAppQuit = true
|
autoUpdater.autoInstallOnAppQuit = true
|
||||||
autoUpdater.allowDowngrade = false
|
autoUpdater.allowDowngrade = false
|
||||||
|
|
||||||
|
// Gitea private-repo release assets require a token in Authorization
|
||||||
|
// header — without it Gitea responds 404 (not 401) on download URLs.
|
||||||
|
if (typeof __UPDATE_TOKEN__ === 'string' && __UPDATE_TOKEN__.length > 0) {
|
||||||
|
autoUpdater.requestHeaders = {
|
||||||
|
Authorization: `token ${__UPDATE_TOKEN__}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
autoUpdater.on('checking-for-update', () => setStatus({ kind: 'checking' }))
|
autoUpdater.on('checking-for-update', () => setStatus({ kind: 'checking' }))
|
||||||
|
|
||||||
autoUpdater.on('update-available', (info) => {
|
autoUpdater.on('update-available', (info) => {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<title>Exercise Reminder</title>
|
<title>Exercise Reminder</title>
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&family=Fraunces:opsz,wght@9..144,400;9..144,500;9..144,600;9..144,700&family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=Bricolage+Grotesque:opsz,wght@12..96,500;12..96,600;12..96,700;12..96,800&family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ function ExerciseReminder({
|
|||||||
<div className="text-[13px] uppercase tracking-[0.18em] text-accent font-bold">
|
<div className="text-[13px] uppercase tracking-[0.18em] text-accent font-bold">
|
||||||
Время тренировки
|
Время тренировки
|
||||||
</div>
|
</div>
|
||||||
<h1 className="font-serif text-[28px] leading-tight tracking-tight mt-2 mb-3 font-medium">
|
<h1 className="font-serif text-[30px] leading-tight tracking-tight mt-2 mb-3 font-bold">
|
||||||
{exercise.name}
|
{exercise.name}
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
@@ -238,7 +238,7 @@ function MatchSummaryView({
|
|||||||
<Gamepad2 size={26} strokeWidth={2} />
|
<Gamepad2 size={26} strokeWidth={2} />
|
||||||
)}
|
)}
|
||||||
</motion.div>
|
</motion.div>
|
||||||
<h1 className="font-serif text-[24px] tracking-tight font-medium">
|
<h1 className="font-serif text-[26px] tracking-tight font-bold">
|
||||||
{won ? 'Победа' : lost ? 'Поражение' : 'Матч завершён'}
|
{won ? 'Победа' : lost ? 'Поражение' : 'Матч завершён'}
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-[13px] text-text/65 mt-1.5 font-medium">
|
<p className="text-[13px] text-text/65 mt-1.5 font-medium">
|
||||||
|
|||||||
@@ -97,10 +97,10 @@ function SidebarContent({ onNav }: { onNav?: () => void }): JSX.Element {
|
|||||||
<>
|
<>
|
||||||
{/* Brand */}
|
{/* Brand */}
|
||||||
<div className="px-5 pt-7 pb-6">
|
<div className="px-5 pt-7 pb-6">
|
||||||
<div className="font-serif text-[34px] leading-none tracking-tight font-medium">
|
<div className="font-serif text-[36px] leading-none tracking-tight font-bold">
|
||||||
Laude
|
Laude
|
||||||
</div>
|
</div>
|
||||||
<div className="text-[12px] text-text/45 mt-2 tracking-tight">
|
<div className="text-[13px] text-text/55 mt-2 font-medium">
|
||||||
Двигайся осознанно
|
Двигайся осознанно
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ export default function ChallengesPage(): JSX.Element {
|
|||||||
<div className="text-[14px] text-text/65 font-semibold">
|
<div className="text-[14px] text-text/65 font-semibold">
|
||||||
Правила за матч
|
Правила за матч
|
||||||
</div>
|
</div>
|
||||||
<h1 className="font-serif text-[32px] sm:text-[36px] leading-[1.05] tracking-tight mt-1 font-medium">
|
<h1 className="font-serif text-[34px] sm:text-[40px] leading-[1.02] tracking-tight mt-1 font-bold">
|
||||||
Челленджи
|
Челленджи
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-[15px] text-text/65 mt-2 font-medium">
|
<p className="text-[15px] text-text/65 mt-2 font-medium">
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ export default function Dashboard(): JSX.Element {
|
|||||||
<div className="text-[14px] text-text/65 font-semibold capitalize">
|
<div className="text-[14px] text-text/65 font-semibold capitalize">
|
||||||
{today}
|
{today}
|
||||||
</div>
|
</div>
|
||||||
<h1 className="font-serif text-[32px] sm:text-[36px] leading-[1.05] tracking-tight mt-1 font-medium">
|
<h1 className="font-serif text-[34px] sm:text-[40px] leading-[1.02] tracking-tight mt-1 font-bold">
|
||||||
Сегодня
|
Сегодня
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export default function Exercises(): JSX.Element {
|
|||||||
<div className="text-[14px] text-text/65 font-semibold">
|
<div className="text-[14px] text-text/65 font-semibold">
|
||||||
Программа
|
Программа
|
||||||
</div>
|
</div>
|
||||||
<h1 className="font-serif text-[32px] sm:text-[36px] leading-[1.05] tracking-tight mt-1 font-medium">
|
<h1 className="font-serif text-[34px] sm:text-[40px] leading-[1.02] tracking-tight mt-1 font-bold">
|
||||||
Упражнения
|
Упражнения
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ export default function GamesPage(): JSX.Element {
|
|||||||
<div className="text-[14px] text-text/65 font-semibold">
|
<div className="text-[14px] text-text/65 font-semibold">
|
||||||
Трекинг матчей
|
Трекинг матчей
|
||||||
</div>
|
</div>
|
||||||
<h1 className="font-serif text-[32px] sm:text-[36px] leading-[1.05] tracking-tight mt-1 font-medium">
|
<h1 className="font-serif text-[34px] sm:text-[40px] leading-[1.02] tracking-tight mt-1 font-bold">
|
||||||
Игры
|
Игры
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-[15px] text-text/65 mt-2 font-medium leading-relaxed">
|
<p className="text-[15px] text-text/65 mt-2 font-medium leading-relaxed">
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export default function SettingsPage(): JSX.Element {
|
|||||||
<div className="text-[14px] text-text/65 font-semibold">
|
<div className="text-[14px] text-text/65 font-semibold">
|
||||||
Конфигурация
|
Конфигурация
|
||||||
</div>
|
</div>
|
||||||
<h1 className="font-serif text-[32px] sm:text-[36px] leading-[1.05] tracking-tight mt-1 font-medium">
|
<h1 className="font-serif text-[34px] sm:text-[40px] leading-[1.02] tracking-tight mt-1 font-bold">
|
||||||
Настройки
|
Настройки
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ body,
|
|||||||
|
|
||||||
body {
|
body {
|
||||||
font-family:
|
font-family:
|
||||||
'Manrope',
|
'Plus Jakarta Sans',
|
||||||
-apple-system,
|
-apple-system,
|
||||||
'SF Pro Text',
|
'SF Pro Text',
|
||||||
'Segoe UI Variable Text',
|
'Segoe UI Variable Text',
|
||||||
@@ -79,28 +79,38 @@ body {
|
|||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 1.45;
|
line-height: 1.5;
|
||||||
letter-spacing: -0.005em;
|
letter-spacing: -0.005em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Display — same Manrope but slightly tighter for headings */
|
/* Display — Bricolage Grotesque for headings and brand. Variable opsz axis
|
||||||
|
gives bigger glyphs slightly more character. */
|
||||||
.font-display {
|
.font-display {
|
||||||
font-family:
|
font-family:
|
||||||
'Manrope',
|
'Bricolage Grotesque',
|
||||||
|
'Plus Jakarta Sans',
|
||||||
-apple-system,
|
-apple-system,
|
||||||
'SF Pro Display',
|
'SF Pro Display',
|
||||||
'Segoe UI Variable Display',
|
|
||||||
system-ui,
|
system-ui,
|
||||||
sans-serif;
|
sans-serif;
|
||||||
|
font-optical-sizing: auto;
|
||||||
|
font-variation-settings: 'opsz' 24;
|
||||||
letter-spacing: -0.02em;
|
letter-spacing: -0.02em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Serif — Fraunces for hero titles with optical-size axis */
|
/* Serif → repurposed for the "hero" big titles. Same Bricolage but with the
|
||||||
|
opsz axis pushed to 96 for distinctive display feel. */
|
||||||
.font-serif {
|
.font-serif {
|
||||||
font-family: 'Fraunces', 'Iowan Old Style', 'New York', Georgia, serif;
|
font-family:
|
||||||
|
'Bricolage Grotesque',
|
||||||
|
'Plus Jakarta Sans',
|
||||||
|
-apple-system,
|
||||||
|
'SF Pro Display',
|
||||||
|
system-ui,
|
||||||
|
sans-serif;
|
||||||
font-optical-sizing: auto;
|
font-optical-sizing: auto;
|
||||||
font-variation-settings: 'opsz' 144;
|
font-variation-settings: 'opsz' 96;
|
||||||
letter-spacing: -0.025em;
|
letter-spacing: -0.035em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.font-mono-num {
|
.font-mono-num {
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export default {
|
|||||||
},
|
},
|
||||||
fontFamily: {
|
fontFamily: {
|
||||||
sans: [
|
sans: [
|
||||||
'Manrope',
|
'Plus Jakarta Sans',
|
||||||
'-apple-system',
|
'-apple-system',
|
||||||
'SF Pro Text',
|
'SF Pro Text',
|
||||||
'Segoe UI Variable Text',
|
'Segoe UI Variable Text',
|
||||||
@@ -43,19 +43,20 @@ export default {
|
|||||||
'sans-serif'
|
'sans-serif'
|
||||||
],
|
],
|
||||||
display: [
|
display: [
|
||||||
'Manrope',
|
'Bricolage Grotesque',
|
||||||
|
'Plus Jakarta Sans',
|
||||||
'-apple-system',
|
'-apple-system',
|
||||||
'SF Pro Display',
|
'SF Pro Display',
|
||||||
'Segoe UI Variable Display',
|
|
||||||
'system-ui',
|
'system-ui',
|
||||||
'sans-serif'
|
'sans-serif'
|
||||||
],
|
],
|
||||||
serif: [
|
serif: [
|
||||||
'Fraunces',
|
'Bricolage Grotesque',
|
||||||
'Iowan Old Style',
|
'Plus Jakarta Sans',
|
||||||
'New York',
|
'-apple-system',
|
||||||
'Georgia',
|
'SF Pro Display',
|
||||||
'serif'
|
'system-ui',
|
||||||
|
'sans-serif'
|
||||||
],
|
],
|
||||||
mono: [
|
mono: [
|
||||||
'JetBrains Mono',
|
'JetBrains Mono',
|
||||||
|
|||||||
Reference in New Issue
Block a user