From 82830d02ee486149eb5a25548d4204d86a6a77cd Mon Sep 17 00:00:00 2001 From: LynithDev <61880709+LynithDev@users.noreply.github.com> Date: Thu, 20 Jun 2024 15:50:50 +0200 Subject: [PATCH] feat: Program info --- desktop/package.json | 1 + desktop/src-tauri/Cargo.toml | 1 + desktop/src-tauri/build.rs | 5 +- desktop/src-tauri/capabilities/default.json | 3 +- .../permissions/onelauncher/default.toml | 3 +- desktop/src-tauri/src/api/commands.rs | 70 +++++++++++++------ desktop/src-tauri/src/lib.rs | 21 +++--- desktop/src/index.tsx | 22 +++--- desktop/src/ui/App.tsx | 5 +- .../ui/components/base/Tooltip.module.scss | 4 +- desktop/src/ui/components/base/Tooltip.tsx | 2 +- .../src/ui/pages/settings/SettingsRoot.tsx | 50 +++++++++++-- .../settings/about/SettingsChangelog.tsx | 33 +++++++++ .../pages/settings/about/SettingsFeedback.tsx | 11 +++ desktop/src/utils/environment.ts | 3 - desktop/src/utils/program-info.ts | 10 +++ pnpm-lock.yaml | 10 +++ 17 files changed, 194 insertions(+), 60 deletions(-) create mode 100644 desktop/src/ui/pages/settings/about/SettingsChangelog.tsx create mode 100644 desktop/src/ui/pages/settings/about/SettingsFeedback.tsx delete mode 100644 desktop/src/utils/environment.ts create mode 100644 desktop/src/utils/program-info.ts diff --git a/desktop/package.json b/desktop/package.json index 17068071..f63286bb 100644 --- a/desktop/package.json +++ b/desktop/package.json @@ -26,6 +26,7 @@ "@solidjs/router": "^0.13.5", "@tanstack/solid-query": "^5.45.0", "@tauri-apps/api": "^2.0.0-beta.13", + "@tauri-apps/plugin-clipboard-manager": "2.1.0-beta.3", "@tauri-apps/plugin-shell": "github:tauri-apps/tauri-plugin-shell#v2", "@thisbeyond/solid-dnd": "^0.7.5", "@unocss/reset": "^0.61.0", diff --git a/desktop/src-tauri/Cargo.toml b/desktop/src-tauri/Cargo.toml index dc47afc6..1a40be5a 100644 --- a/desktop/src-tauri/Cargo.toml +++ b/desktop/src-tauri/Cargo.toml @@ -55,6 +55,7 @@ uuid = { workspace = true } tracing = { workspace = true } tracing-error = { workspace = true } +tauri-plugin-clipboard-manager = "2.1.0-beta.4" [target.'cfg(target_os = "macos")'.dependencies] cocoa = "0.25.0" diff --git a/desktop/src-tauri/build.rs b/desktop/src-tauri/build.rs index e1cf8e1b..d9d32f34 100644 --- a/desktop/src-tauri/build.rs +++ b/desktop/src-tauri/build.rs @@ -12,8 +12,9 @@ fn main() { "get_clusters", "get_cluster", "get_manifest", - "get_settings", - "set_settings" + "get_settings", + "set_settings", + "get_program_info" ]), ), ) diff --git a/desktop/src-tauri/capabilities/default.json b/desktop/src-tauri/capabilities/default.json index cd3889b6..b7275760 100644 --- a/desktop/src-tauri/capabilities/default.json +++ b/desktop/src-tauri/capabilities/default.json @@ -16,6 +16,7 @@ "window:allow-toggle-maximize", "window:allow-internal-toggle-maximize", "event:default", - "shell:allow-open" + "shell:allow-open", + "clipboard-manager:allow-write-text" ] } diff --git a/desktop/src-tauri/permissions/onelauncher/default.toml b/desktop/src-tauri/permissions/onelauncher/default.toml index 14f20147..16d1a80a 100644 --- a/desktop/src-tauri/permissions/onelauncher/default.toml +++ b/desktop/src-tauri/permissions/onelauncher/default.toml @@ -9,5 +9,6 @@ permissions = [ "allow-get-manifest", "allow-login-msa", "allow-get-settings", - "allow-set-settings" + "allow-set-settings", + "allow-get-program-info" ] diff --git a/desktop/src-tauri/src/api/commands.rs b/desktop/src-tauri/src/api/commands.rs index dcef7fe9..32fa0d99 100644 --- a/desktop/src-tauri/src/api/commands.rs +++ b/desktop/src-tauri/src/api/commands.rs @@ -3,6 +3,7 @@ use std::path::PathBuf; use std::str::FromStr; use chrono::DateTime; +use onelauncher::constants::{NATIVE_ARCH, TARGET_OS, VERSION}; use onelauncher::data::{ClusterMeta, Loader, PackageData, Settings}; use onelauncher::store::{Cluster, ClusterPath}; use onelauncher::{cluster, settings}; @@ -12,27 +13,22 @@ use uuid::Uuid; #[macro_export] macro_rules! collect_commands { - () => { - { - use $crate::api::commands::*; - tauri_specta::ts::builder() - .config(specta::ts::ExportConfig::default().bigint(specta::ts::BigIntExportBehavior::BigInt)) - .commands(tauri_specta::collect_commands![ - is_dev, - create_cluster, - get_cluster, - get_clusters, - get_settings, - set_settings, - ]) - } - }; -} - -#[specta::specta] -#[tauri::command] -pub fn is_dev() -> bool { - cfg!(debug_assertions) + () => {{ + use $crate::api::commands::*; + tauri_specta::ts::builder() + .config( + specta::ts::ExportConfig::default() + .bigint(specta::ts::BigIntExportBehavior::BigInt), + ) + .commands(tauri_specta::collect_commands![ + create_cluster, + get_cluster, + get_clusters, + get_settings, + set_settings, + get_program_info + ]) + }}; } #[derive(Serialize, Deserialize, Type)] @@ -128,11 +124,39 @@ pub async fn get_clusters() -> Result, String> { #[specta::specta] #[tauri::command] pub async fn get_settings() -> Result { - settings::get().await.map_err(|err| err.into()) + settings::get().await.map_err(|err| err.into()) } #[specta::specta] #[tauri::command] pub async fn set_settings(settings: Settings) -> Result<(), String> { - settings::set(settings).await.map_err(|err| err.into()) + settings::set(settings).await.map_err(|err| err.into()) +} + + +#[derive(Serialize, Deserialize, Type)] +pub struct ProgramInfo { + launcher_version: String, + webview_version: String, + tauri_version: String, + dev_build: bool, + platform: String, + arch: String +} + +#[specta::specta] +#[tauri::command] +pub fn get_program_info() -> ProgramInfo { + let webview_version = tauri::webview_version().unwrap_or("UNKNOWN".into()); + let tauri_version = tauri::VERSION; + let dev_build = tauri::is_dev(); + + ProgramInfo { + launcher_version: VERSION.into(), + webview_version, + tauri_version: tauri_version.into(), + dev_build, + platform: TARGET_OS.into(), + arch: NATIVE_ARCH.into() + } } diff --git a/desktop/src-tauri/src/lib.rs b/desktop/src-tauri/src/lib.rs index 5d5766a4..addb5a97 100644 --- a/desktop/src-tauri/src/lib.rs +++ b/desktop/src-tauri/src/lib.rs @@ -37,13 +37,14 @@ pub async fn run() { pub async fn run_app(setup: F) { let builder = tauri::Builder::default() - .plugin(tauri_plugin_shell::init()) - .plugin(tauri_plugin_single_instance::init(|app, argv, cwd| { - println!("{}, {argv:?}, {cwd}", app.package_info().name); - app.emit("single-instance", SingleInstancePayload { args: argv, cwd }) - .unwrap(); - })) - .plugin(tauri_plugin_updater::Builder::new().build()) + .plugin(tauri_plugin_shell::init()) + .plugin(tauri_plugin_single_instance::init(|app, argv, cwd| { + println!("{}, {argv:?}, {cwd}", app.package_info().name); + app.emit("single-instance", SingleInstancePayload { args: argv, cwd }) + .unwrap(); + })) + .plugin(tauri_plugin_updater::Builder::new().build()) + .plugin(tauri_plugin_clipboard_manager::init()) .plugin(ext::updater::plugin()) .manage(ext::updater::State::default()) .plugin(tauri_plugin_window_state::Builder::default().build()) @@ -66,9 +67,9 @@ pub async fn run_app(setup: F) { .build(tauri::tauri_build_context!()) .expect("failed to build tauri application"); - if let Err(err) = initialize_state(app.app_handle().clone()).await { - tracing::error!("{err}"); - }; + if let Err(err) = initialize_state(app.app_handle().clone()).await { + tracing::error!("{err}"); + }; app.run(|_app_handle, _event| {}) } diff --git a/desktop/src/index.tsx b/desktop/src/index.tsx index 765ccd83..f6a1e051 100644 --- a/desktop/src/index.tsx +++ b/desktop/src/index.tsx @@ -10,15 +10,19 @@ import UpdatesPage from './ui/pages/Updates'; import ClusterRoot from '~ui/pages/cluster/ClusterRoot'; import SettingsRoot from '~ui/pages/settings/SettingsRoot'; import BrowserRoot from '~ui/pages/browser/BrowserRoot'; +import { initAppInfo } from '~utils/program-info'; export * as bridge from './bindings'; -render(() => ( - - - - } /> - } /> - } /> - -), document.getElementById('root') as HTMLElement); +initAppInfo() + .then(() => { + render(() => ( + + + + } /> + } /> + } /> + + ), document.getElementById('root') as HTMLElement); + }); diff --git a/desktop/src/ui/App.tsx b/desktop/src/ui/App.tsx index 91593949..f5231bb4 100644 --- a/desktop/src/ui/App.tsx +++ b/desktop/src/ui/App.tsx @@ -6,14 +6,13 @@ import ErrorBoundary from './components/ErrorBoundary'; import AnimatedRoutes from './components/AnimatedRoutes'; import NotificationOverlay from './components/overlay/notifications/NotificationOverlay'; import { SettingsProvider } from './hooks/useSettings'; -import { bridge } from '~index'; +import { AppInfo } from '~utils/program-info'; function App(props: ParentProps) { - if (!bridge.commands.isDev()) { + if (AppInfo.dev_build !== true) document.addEventListener('contextmenu', (event) => { event.preventDefault(); }); - } return ( diff --git a/desktop/src/ui/components/base/Tooltip.module.scss b/desktop/src/ui/components/base/Tooltip.module.scss index 09cb9fa6..65b0de44 100644 --- a/desktop/src/ui/components/base/Tooltip.module.scss +++ b/desktop/src/ui/components/base/Tooltip.module.scss @@ -9,9 +9,9 @@ content: attr(data-text); @apply pointer-events-none; @apply opacity-0 transition-opacity; - @apply absolute left-1/2 -translate-x-1/2 bottom-6; + @apply absolute left-1/2 -translate-x-1/2 top-0 -translate-y-6/5; @apply min-w-44 w-max max-w-52; - @apply backdrop-blur-lg rounded-md bg-black/60 p-2 text-center text-sm text-wrap text-white shadow shadow-black/30; + @apply backdrop-blur-lg rounded-md bg-black/50 p-2 text-center text-sm text-wrap text-white shadow shadow-black/30; } } \ No newline at end of file diff --git a/desktop/src/ui/components/base/Tooltip.tsx b/desktop/src/ui/components/base/Tooltip.tsx index c354081f..0b27567e 100644 --- a/desktop/src/ui/components/base/Tooltip.tsx +++ b/desktop/src/ui/components/base/Tooltip.tsx @@ -9,7 +9,7 @@ function Tooltip(props: TooltipProps) { const [split, rest] = splitProps(props, ['class']); return ( -
+
); } diff --git a/desktop/src/ui/pages/settings/SettingsRoot.tsx b/desktop/src/ui/pages/settings/SettingsRoot.tsx index 08f460ab..f4154b3b 100644 --- a/desktop/src/ui/pages/settings/SettingsRoot.tsx +++ b/desktop/src/ui/pages/settings/SettingsRoot.tsx @@ -1,14 +1,21 @@ -import type { ParentProps } from 'solid-js'; -import { Brush01Icon, CodeSnippet02Icon, Globe01Icon, Key01Icon, MessageTextSquare01Icon, RefreshCcw02Icon, Rocket02Icon, Sliders04Icon, Users01Icon } from '@untitled-theme/icons-solid'; +import { type ParentProps, createSignal } from 'solid-js'; +import { Brush01Icon, CodeSnippet02Icon, MessageTextSquare01Icon, RefreshCcw02Icon, Rocket02Icon, Sliders04Icon, Users01Icon } from '@untitled-theme/icons-solid'; import { Route } from '@solidjs/router'; +import { writeText } from '@tauri-apps/plugin-clipboard-manager'; import Sidebar from '../../components/Sidebar'; import SettingsGeneral from './launcher/SettingsGeneral'; import SettingsAppearance from './launcher/SettingsAppearance'; import SettingsAccounts from './game/SettingsAccounts'; import SettingsMinecraft from './game/SettingsMinecraft'; import SettingsDeveloper from './about/SettingsDeveloper'; +import SettingsFeedback from './about/SettingsFeedback'; +import SettingsChangelog from './about/SettingsChangelog'; import AnimatedRoutes from '~ui/components/AnimatedRoutes'; import ErrorBoundary from '~ui/components/ErrorBoundary'; +import Tooltip from '~ui/components/base/Tooltip'; +import { bridge } from '~index'; +import useCommand from '~ui/hooks/useCommand'; +import { AppInfo } from '~utils/program-info'; function SettingsRoutes() { return ( @@ -22,6 +29,8 @@ function SettingsRoutes() { {/* About */} + + ); @@ -30,7 +39,7 @@ function SettingsRoutes() { function SettingsRoot(props: ParentProps) { return (
-
+
, 'General', '/'], [, 'Appearance', '/appearance'], - [, 'APIs', '/apis'], - [, 'Language', '/language'], + // [, 'APIs', '/apis'], + // [, 'Language', '/language'], ], 'Game Settings': [ [, 'Minecraft settings', '/minecraft'], @@ -52,6 +61,7 @@ function SettingsRoot(props: ParentProps) { ], }} /> +
@@ -65,6 +75,36 @@ function SettingsRoot(props: ParentProps) { ); } +function Info() { + const [copied, setCopied] = createSignal(false); + + return ( +
+ +
{ + const info = e.target.innerHTML; + writeText(info) + .finally(() => { + setCopied(true); + setTimeout(() => setCopied(false), 3000); + }); + }} + > + {` +Launcher Version: ${AppInfo.launcher_version} +Tauri Version: ${AppInfo.tauri_version} +Webview Version: ${AppInfo.webview_version} +Platform: ${AppInfo.platform} ${AppInfo.arch} bit +Build: ${AppInfo.dev_build ? 'dev' : 'release'} +`.trim()} +
+
+
+ ); +} + SettingsRoot.Routes = SettingsRoutes; export default SettingsRoot; diff --git a/desktop/src/ui/pages/settings/about/SettingsChangelog.tsx b/desktop/src/ui/pages/settings/about/SettingsChangelog.tsx new file mode 100644 index 00000000..482eead6 --- /dev/null +++ b/desktop/src/ui/pages/settings/about/SettingsChangelog.tsx @@ -0,0 +1,33 @@ +import ScrollableContainer from '~ui/components/ScrollableContainer'; +import Sidebar from '~ui/components/Sidebar'; + +function SettingsChangelog() { + return ( + +

Changelog

+ + + + + +
+ ); +} + +// TODO: Implement markdown support? +function UpdatePost() { + return ( +
+

New Feature

+

+ {` +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus fringilla, enim nec lobortis ornare, dui dolor convallis ante, eget blandit dolor purus eget nisi. Nullam malesuada sem purus, nec placerat velit luctus nec. Nullam quis consequat mi. Pellentesque in mi nec ligula rhoncus ullamcorper. Morbi vehicula, magna in lobortis imperdiet, diam orci sodales massa, sed convallis sapien diam id lorem. Cras condimentum tincidunt felis non suscipit. Morbi rhoncus enim nec felis sagittis, sed semper tortor interdum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut sed lacinia est. Etiam a est vitae diam laoreet dapibus. Cras eu dignissim felis. Nam quis magna tempor, convallis nibh eu, sagittis quam. + +Aliquam ullamcorper libero sem, ac pellentesque nulla gravida eget. Phasellus volutpat lectus sit amet dictum gravida. Vivamus ligula magna, venenatis vitae elementum ut, elementum quis dolor. Pellentesque congue urna nibh, quis mollis nunc sagittis eu. Maecenas lacinia, velit quis euismod pulvinar, eros diam eleifend metus, quis porta nisi ligula ut ipsum. Proin eget diam mi. Cras sed rutrum est, in pellentesque lacus. Donec vitae egestas nibh. Vivamus vulputate convallis dui, vitae tempus velit sagittis eget. Ut sit amet magna a risus ultrices sagittis. Duis imperdiet erat felis, a pretium velit egestas in. Nulla facilisi. Praesent fringilla sem orci, ac elementum magna sollicitudin at. Phasellus convallis gravida est, at venenatis quam maximus id. Cras euismod purus vel massa consequat, sit amet porttitor odio accumsan. +`.trim()} +

+
+ ); +} + +export default SettingsChangelog; diff --git a/desktop/src/ui/pages/settings/about/SettingsFeedback.tsx b/desktop/src/ui/pages/settings/about/SettingsFeedback.tsx new file mode 100644 index 00000000..761adbec --- /dev/null +++ b/desktop/src/ui/pages/settings/about/SettingsFeedback.tsx @@ -0,0 +1,11 @@ +import Sidebar from '~ui/components/Sidebar'; + +function SettingsFeedback() { + return ( + +

Feedback

+
+ ); +} + +export default SettingsFeedback; diff --git a/desktop/src/utils/environment.ts b/desktop/src/utils/environment.ts deleted file mode 100644 index 4d82dd77..00000000 --- a/desktop/src/utils/environment.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const isDev = () => window.location.host.startsWith('localhost:'); - -export default { isDev }; diff --git a/desktop/src/utils/program-info.ts b/desktop/src/utils/program-info.ts new file mode 100644 index 00000000..e8e9d328 --- /dev/null +++ b/desktop/src/utils/program-info.ts @@ -0,0 +1,10 @@ +import type { ProgramInfo } from '~bindings'; +import { bridge } from '~index'; + +// eslint-disable-next-line import/no-mutable-exports -- because yes +export let AppInfo!: ProgramInfo; +export default AppInfo; + +export async function initAppInfo() { + AppInfo = await bridge.commands.getProgramInfo(); +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b318f3e7..48b62fa4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -107,6 +107,9 @@ importers: '@tauri-apps/api': specifier: ^2.0.0-beta.13 version: 2.0.0-beta.13 + '@tauri-apps/plugin-clipboard-manager': + specifier: 2.1.0-beta.3 + version: 2.1.0-beta.3 '@tauri-apps/plugin-shell': specifier: github:tauri-apps/tauri-plugin-shell#v2 version: https://codeload.github.com/tauri-apps/tauri-plugin-shell/tar.gz/5b496abe090f771847887edc8dd2e5eeee0af270 @@ -1075,6 +1078,9 @@ packages: engines: {node: '>= 10'} hasBin: true + '@tauri-apps/plugin-clipboard-manager@2.1.0-beta.3': + resolution: {integrity: sha512-j48jTdZWeX5BylIGLYbXtg6ynZAcFKDKK6dguHAbG3zviqNE/XMf2vHOPJeFDZsDE5kVOZZS7nKOj7T2WiCpvw==} + '@tauri-apps/plugin-shell@https://codeload.github.com/tauri-apps/tauri-plugin-shell/tar.gz/5b496abe090f771847887edc8dd2e5eeee0af270': resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-shell/tar.gz/5b496abe090f771847887edc8dd2e5eeee0af270} version: 2.0.0-beta.2 @@ -4234,6 +4240,10 @@ snapshots: '@tauri-apps/cli-win32-ia32-msvc': 2.0.0-beta.20 '@tauri-apps/cli-win32-x64-msvc': 2.0.0-beta.20 + '@tauri-apps/plugin-clipboard-manager@2.1.0-beta.3': + dependencies: + '@tauri-apps/api': 2.0.0-beta.13 + '@tauri-apps/plugin-shell@https://codeload.github.com/tauri-apps/tauri-plugin-shell/tar.gz/5b496abe090f771847887edc8dd2e5eeee0af270': dependencies: '@tauri-apps/api': 2.0.0-beta.8