diff --git a/client/cypress.config.js b/client/cypress.config.ts similarity index 85% rename from client/cypress.config.js rename to client/cypress.config.ts index bd8d24a..8aec956 100644 --- a/client/cypress.config.js +++ b/client/cypress.config.ts @@ -4,7 +4,7 @@ export default defineConfig({ e2e: { baseUrl: 'http://localhost:5173', supportFile: 'tests/e2e/support/e2e.js', - specPattern: 'tests/e2e/specs/**/*.cy.{js,jsx}', + specPattern: 'tests/e2e/specs/**/*.cy.{js,jsx,ts,tsx}', videosFolder: 'tests/e2e/videos', screenshotsFolder: 'tests/e2e/screenshots', setupNodeEvents(on, config) { diff --git a/client/index.html b/client/index.html index 6278995..f0d98ea 100644 --- a/client/index.html +++ b/client/index.html @@ -24,7 +24,7 @@
- + diff --git a/client/src/App.vue b/client/src/App.vue index 230a084..2e8bbcb 100644 --- a/client/src/App.vue +++ b/client/src/App.vue @@ -5,5 +5,5 @@ diff --git a/client/src/config.js b/client/src/config.ts similarity index 54% rename from client/src/config.js rename to client/src/config.ts index 475f7c8..b34c81c 100644 --- a/client/src/config.js +++ b/client/src/config.ts @@ -1,7 +1,7 @@ import { appLocalDataDir } from '@tauri-apps/api/path'; -export async function getDB_URL() { - // Функция верёнт путь до бд +/** Возвращает URL подключения к SQLite */ +export async function getDB_URL(): Promise { const appDir = await appLocalDataDir(); return `sqlite:${appDir}/timer.db`; diff --git a/client/src/db/crud/timerCrud.js b/client/src/db/crud/timerCrud.js deleted file mode 100644 index 8b0edc2..0000000 --- a/client/src/db/crud/timerCrud.js +++ /dev/null @@ -1,10 +0,0 @@ -import { getDb } from "../initDb"; -import { SELECT_TIMERS } from "../dml/timerDML"; - - -export async function getTimers() { - // Функция для получения списка таймеров - - const db = await getDb(); - return await db.select(SELECT_TIMERS); -} diff --git a/client/src/db/crud/timerCrud.ts b/client/src/db/crud/timerCrud.ts new file mode 100644 index 0000000..43b8535 --- /dev/null +++ b/client/src/db/crud/timerCrud.ts @@ -0,0 +1,10 @@ +import { getDb } from "@/db/initDb"; +import { SELECT_TIMERS } from "@/db/dml/timerDML"; +import { TimersRow } from "@/types/timerType" + + +/** Получает список таймеров */ +export async function getTimers(): Promise { + const db = await getDb(); + return await db.select(SELECT_TIMERS); +} diff --git a/client/src/db/ddl/timerDDL.js b/client/src/db/ddl/timerDDL.ts similarity index 100% rename from client/src/db/ddl/timerDDL.js rename to client/src/db/ddl/timerDDL.ts diff --git a/client/src/db/dml/timerDML.js b/client/src/db/dml/timerDML.ts similarity index 100% rename from client/src/db/dml/timerDML.js rename to client/src/db/dml/timerDML.ts diff --git a/client/src/db/initDb.js b/client/src/db/initDb.ts similarity index 56% rename from client/src/db/initDb.js rename to client/src/db/initDb.ts index ce90442..2e0fa0f 100644 --- a/client/src/db/initDb.js +++ b/client/src/db/initDb.ts @@ -1,13 +1,12 @@ import Database from '@tauri-apps/plugin-sql'; -import { CREATE_TIMER } from './ddl/timerDDL'; -import { getDB_URL } from '../config'; -import { seedDb } from './seed'; +import { CREATE_TIMER } from '@/db/ddl/timerDDL'; +import { getDB_URL } from '@/config'; +import { seedDb } from '@/db/seed'; -let dbPromise = null; - -export async function getDb() { - // Функция для получения подключения к базе данных +let dbPromise: Promise | null = null; +/** Получает подключение к бд */ +export async function getDb(): Promise { if (!dbPromise) { dbPromise = (async () => { try { @@ -22,5 +21,5 @@ export async function getDb() { } })(); } - return await dbPromise; // await для консистентности + return await dbPromise; } diff --git a/client/src/db/seed.js b/client/src/db/seed.js deleted file mode 100644 index 927b161..0000000 --- a/client/src/db/seed.js +++ /dev/null @@ -1,11 +0,0 @@ -import { INSERT_SEED_DB, COUNT_TIMERS } from './dml/timerDML' - - -export async function seedDb(db) { - // Функция для заполнения бд данными - - const count = await db.select(COUNT_TIMERS); - if (count[0].cnt === 0) { - await db.execute(INSERT_SEED_DB); - } -} diff --git a/client/src/db/seed.ts b/client/src/db/seed.ts new file mode 100644 index 0000000..580e4a0 --- /dev/null +++ b/client/src/db/seed.ts @@ -0,0 +1,14 @@ +import Database from '@tauri-apps/plugin-sql'; +import { INSERT_SEED_DB, COUNT_TIMERS } from '@/db/dml/timerDML' +import { CountRow } from '@/types/timerType' + + +/** Заполняет бд данными (демо таймерами) */ +export async function seedDb(db: Database) { + + const count = await db.select(COUNT_TIMERS); + const cnt = count[0]?.cnt ?? 0; + if (cnt === 0) { + await db.execute(INSERT_SEED_DB); + } +} diff --git a/client/src/main.js b/client/src/main.ts similarity index 89% rename from client/src/main.js rename to client/src/main.ts index 42eb043..9738bea 100644 --- a/client/src/main.js +++ b/client/src/main.ts @@ -1,6 +1,6 @@ import { createApp } from 'vue' -import App from './App.vue' -import router from './router'; +import App from '@/App.vue' +import router from '@/router'; import { IonicVue } from '@ionic/vue'; @@ -21,7 +21,7 @@ import '@ionic/vue/css/flex-utils.css'; import '@ionic/vue/css/display.css'; /* Theme variables */ -import './theme/variables.css'; +import '@/theme/variables.css'; const app = createApp(App) .use(IonicVue) diff --git a/client/src/router/index.js b/client/src/router/index.ts similarity index 68% rename from client/src/router/index.js rename to client/src/router/index.ts index 9a5afee..81a13c5 100644 --- a/client/src/router/index.js +++ b/client/src/router/index.ts @@ -1,7 +1,8 @@ import { createRouter, createWebHistory } from '@ionic/vue-router'; -import TimersList from '../views/TimersList/TimersList.vue'; +import type { RouteRecordRaw } from 'vue-router'; +import TimersList from '@/views/TimersList/TimersList.vue'; -const routes = [ +const routes: RouteRecordRaw[] = [ { path: '/', redirect: '/timers' diff --git a/client/src/types/timerType.ts b/client/src/types/timerType.ts new file mode 100644 index 0000000..3ceedca --- /dev/null +++ b/client/src/types/timerType.ts @@ -0,0 +1,8 @@ +export type TimersRow = { + id: number; + title: string; + pomodoro_time: number; + count_pomodoro: number; +}; + +export type CountRow = { cnt: number }; diff --git a/client/src/views/TimersList/TimersList.js b/client/src/views/TimersList/TimersList.js deleted file mode 100644 index 47bde1e..0000000 --- a/client/src/views/TimersList/TimersList.js +++ /dev/null @@ -1,66 +0,0 @@ -import { IonIcon } from '@ionic/vue'; -import { - timerOutline, - chevronUp, - chevronDown, - playCircleOutline, - pencilOutline, - trashOutline -} from 'ionicons/icons'; - -import { ref, onMounted } from 'vue'; -import { getTimers } from '../../db/crud/timerCrud'; - -export default { - name: 'TimersList', - components: { - IonIcon, - }, - setup() { - const timers = ref([]); - const loading = ref(true); - const error = ref(null); - const expandedId = ref(null); - - const loadTimers = async () => { - loading.value = true; - error.value = null; - - try { - const result = await getTimers(); - timers.value = result; - } catch (err) { - error.value = err.message || 'Ошибка загрузки таймеров'; - } finally { - loading.value = false; - } - }; - - const toggleExpand = (id) => { - expandedId.value = expandedId.value === id ? null : id; - }; - - onMounted(() => { - loadTimers(); - }); - - return { - // состояние - timers, - loading, - error, - expandedId, - - // методы - toggleExpand, - - // иконки - timerOutline, - chevronUp, - chevronDown, - playCircleOutline, - pencilOutline, - trashOutline, - }; - }, -}; diff --git a/client/src/views/TimersList/TimersList.ts b/client/src/views/TimersList/TimersList.ts new file mode 100644 index 0000000..88057dd --- /dev/null +++ b/client/src/views/TimersList/TimersList.ts @@ -0,0 +1,60 @@ +import { defineComponent, onMounted, ref } from 'vue' +import { IonIcon } from '@ionic/vue' +import { + timerOutline, + chevronUp, + chevronDown, + playCircleOutline, + pencilOutline, + trashOutline, +} from 'ionicons/icons' + +import { getTimers } from '@/db/crud/timerCrud' +import type { TimersRow } from '@/types/timerType' + +export default defineComponent({ + name: 'TimersList', + components: { IonIcon }, + setup() { + const timers = ref([]) + const loading = ref(true) + const error = ref(null) + const expandedId = ref(null) + + const loadTimers = async (): Promise => { + loading.value = true + error.value = null + + try { + const result = await getTimers() + timers.value = result + } catch (e: unknown) { + error.value = e instanceof Error ? e.message : 'Ошибка загрузки таймеров' + } finally { + loading.value = false + } + } + + const toggleExpand = (id: number): void => { + expandedId.value = expandedId.value === id ? null : id + } + + onMounted(loadTimers) + + return { + timers, + loading, + error, + expandedId, + + toggleExpand, + + timerOutline, + chevronUp, + chevronDown, + playCircleOutline, + pencilOutline, + trashOutline, + } + }, +}) diff --git a/client/src/views/TimersList/TimersList.vue b/client/src/views/TimersList/TimersList.vue index ffbc5bd..b062d61 100644 --- a/client/src/views/TimersList/TimersList.vue +++ b/client/src/views/TimersList/TimersList.vue @@ -1,4 +1,4 @@ - - - + + + diff --git a/client/src/vite-env.d.ts b/client/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/client/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/client/tsconfig.json b/client/tsconfig.json new file mode 100644 index 0000000..3e1e131 --- /dev/null +++ b/client/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/*": ["src/*"] + }, + "module": "ESNext", + "target": "ES2020", + "moduleResolution": "Bundler" + } +} diff --git a/desktop/src-tauri/Cargo.lock b/desktop/src-tauri/Cargo.lock index e9ec492..a4b89eb 100644 --- a/desktop/src-tauri/Cargo.lock +++ b/desktop/src-tauri/Cargo.lock @@ -81,19 +81,6 @@ version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" -[[package]] -name = "app" -version = "0.1.0" -dependencies = [ - "log", - "serde", - "serde_json", - "tauri", - "tauri-build", - "tauri-plugin-log", - "tauri-plugin-sql", -] - [[package]] name = "arrayvec" version = "0.7.6" @@ -1849,6 +1836,19 @@ dependencies = [ "serde_json", ] +[[package]] +name = "kawai-focus" +version = "0.1.0" +dependencies = [ + "log", + "serde", + "serde_json", + "tauri", + "tauri-build", + "tauri-plugin-log", + "tauri-plugin-sql", +] + [[package]] name = "keyboard-types" version = "0.7.0" diff --git a/desktop/src-tauri/Cargo.toml b/desktop/src-tauri/Cargo.toml index 166124e..f19483c 100644 --- a/desktop/src-tauri/Cargo.toml +++ b/desktop/src-tauri/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "app" +name = "kawai-focus" version = "0.1.0" description = "Kawai-Focus - приложение для фокусировки внимания на основе таймера Pomodoro." authors = ["Arduinum"] @@ -11,7 +11,7 @@ rust-version = "1.77.2" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] -name = "app_lib" +name = "kawai_focus" crate-type = ["staticlib", "cdylib", "rlib"] [build-dependencies] diff --git a/desktop/src-tauri/assets/io.github.arduinum.KawaiFocus.metainfo.xml b/desktop/src-tauri/assets/io.github.arduinum.KawaiFocus.metainfo.xml new file mode 100644 index 0000000..86ef91e --- /dev/null +++ b/desktop/src-tauri/assets/io.github.arduinum.KawaiFocus.metainfo.xml @@ -0,0 +1,22 @@ + + + io.github.arduinum.KawaiFocus + + Kawai-Focus + Focus timer for working sessions + + +

Kawai-Focus is a focus-training app based on the Pomodoro timer.

+
+ + + Kaddo Eugene + + + FSFAP + MIT + + io.github.arduinum.KawaiFocus.desktop + + https://github.com/Arduinum/kawai-focus-v2 +
diff --git a/desktop/src-tauri/src/flags.rs b/desktop/src-tauri/src/flags.rs new file mode 100644 index 0000000..2adf97c --- /dev/null +++ b/desktop/src-tauri/src/flags.rs @@ -0,0 +1,44 @@ +#[cfg(target_os = "linux")] +pub fn apply_linux_cli_flags() { + let disable_webkit_compositing_mode = std::env::args().any(|a| a == "--webkit-disable-compositing-mode"); + if disable_webkit_compositing_mode { + unsafe { std::env::set_var("WEBKIT_DISABLE_COMPOSITING_MODE", "1"); } + } + + let webkit_disable_dmabuf_renderer = std::env::args().any(|a| a == "--webkit-disable-dmabuf-renderer"); + if webkit_disable_dmabuf_renderer { + unsafe { std::env::set_var("WEBKIT_DISABLE_DMABUF_RENDERER", "1"); } + } + + let nv_disable_explicit_sync = std::env::args().any(|a| a == "--nv-disable-explicit-sync"); + if nv_disable_explicit_sync { + unsafe { std::env::set_var("__NV_DISABLE_EXPLICIT_SYNC", "1"); } + } +} + +#[cfg(target_os = "linux")] +pub fn print_help() { + println!( +r#"Kawai Focus — Pomodoro таймер + +Использование: + kawai-focus [FLAGS] + +Флаги (Linux): + + --webkit-disable-compositing-mode + Отключает WebKit compositing mode. + Помогает при графических артефактах на некоторых GPU. + + --webkit-disable-dmabuf-renderer + Отключает DMA-BUF renderer WebKit. + Полезно при проблемах с Wayland и с отсутствием GBM. + + --nv-disable-explicit-sync + Отключает explicit sync драйвера NVIDIA. + Иногда исправляет: зависания интерфейса, проблемы с отсутствием GBM. + + --help + Показать эту справку и выйти. +"#); +} diff --git a/desktop/src-tauri/src/lib.rs b/desktop/src-tauri/src/lib.rs index b19aaa4..7ee0a2a 100644 --- a/desktop/src-tauri/src/lib.rs +++ b/desktop/src-tauri/src/lib.rs @@ -1,5 +1,16 @@ +mod flags; + #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { + #[cfg(target_os = "linux")] + if std::env::args().any(|a| a == "--help" || a == "-h") { + flags::print_help(); + std::process::exit(0); + } + + #[cfg(target_os = "linux")] + flags::apply_linux_cli_flags(); + tauri::Builder::default() .plugin(tauri_plugin_sql::Builder::default().build()) .run(tauri::generate_context!()) diff --git a/desktop/src-tauri/src/main.rs b/desktop/src-tauri/src/main.rs index d36aec3..b6f8acf 100644 --- a/desktop/src-tauri/src/main.rs +++ b/desktop/src-tauri/src/main.rs @@ -3,5 +3,5 @@ fn main() { println!("Запуск приложения Tauri..."); - app_lib::run(); + kawai_focus::run(); } diff --git a/desktop/src-tauri/tauri.conf.json b/desktop/src-tauri/tauri.conf.json index 9b9fdd0..271040d 100644 --- a/desktop/src-tauri/tauri.conf.json +++ b/desktop/src-tauri/tauri.conf.json @@ -2,7 +2,7 @@ "$schema": "https://schema.tauri.app/config/2", "productName": "Kawai-Focus", "version": "0.1.0", - "identifier": "com.kawai.focus", + "identifier": "io.github.arduinum.KawaiFocus", "build": { "frontendDist": "../../client/dist", "devUrl": "http://localhost:8100", @@ -29,7 +29,15 @@ }, "bundle": { "active": true, - "targets": "all", + "targets": ["deb", "rpm"], + "linux": { + "deb": { + "files": { + "/usr/share/metainfo/io.github.arduinum.KawaiFocus.metainfo.xml": "assets/io.github.arduinum.KawaiFocus.metainfo.xml" + } + } + }, + "shortDescription": "Kawai-Focus - приложение для фокусировки внимания на основе таймера Pomodoro.", "icon": [ "icons/32x32.png", "icons/128x128.png",