From f1dee718da95836ffa5c0985c9e8f5643e0f3f6f Mon Sep 17 00:00:00 2001 From: GeckoEidechse Date: Sun, 22 Dec 2024 23:55:52 +0100 Subject: dev: Replace with sample Tauri 2.0 project as a first step to convert FlightCore to Tauri 2.0 --- src-vue/src/plugins/modules/notifications.ts | 31 -- src-vue/src/plugins/modules/pull_requests.ts | 94 ----- src-vue/src/plugins/modules/search.ts | 20 - src-vue/src/plugins/store.ts | 529 --------------------------- 4 files changed, 674 deletions(-) delete mode 100644 src-vue/src/plugins/modules/notifications.ts delete mode 100644 src-vue/src/plugins/modules/pull_requests.ts delete mode 100644 src-vue/src/plugins/modules/search.ts delete mode 100644 src-vue/src/plugins/store.ts (limited to 'src-vue/src/plugins') diff --git a/src-vue/src/plugins/modules/notifications.ts b/src-vue/src/plugins/modules/notifications.ts deleted file mode 100644 index ed57f8af..00000000 --- a/src-vue/src/plugins/modules/notifications.ts +++ /dev/null @@ -1,31 +0,0 @@ -type NotificationType = 'success' | 'warning' | 'info' | 'error'; - -export interface Notification { - title: string; - text: string; - type: NotificationType; -} - -interface NotificationsStoreState { - notifications: Notification[]; -} - - -/** - * This notification module is meant to host the list of notifications that have been fired while the application was - * not focused. - * This list is then used by the [NotificationButton] component to display notifications to user. - **/ -export const notificationsModule = { - state: () => ({ - notifications: [] - }) as NotificationsStoreState, - mutations: { - addNotification(state: NotificationsStoreState, payload: Notification) { - state.notifications.push(payload); - }, - removeNotification(state: NotificationsStoreState, index: number): void { - state.notifications.splice(index, 1); - } - } - } diff --git a/src-vue/src/plugins/modules/pull_requests.ts b/src-vue/src/plugins/modules/pull_requests.ts deleted file mode 100644 index 4caec0b0..00000000 --- a/src-vue/src/plugins/modules/pull_requests.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { invoke, shell } from "@tauri-apps/api"; -import { PullsApiResponseElement } from "../../../../src-tauri/bindings/PullsApiResponseElement"; -import { PullRequestType } from '../../../../src-tauri/bindings/PullRequestType'; -import { store } from "../store"; -import { showErrorNotification, showNotification } from "../../utils/ui"; - -interface PullRequestStoreState { - searchValue: string, - pull_requests_launcher: PullsApiResponseElement[], - pull_requests_mods: PullsApiResponseElement[], -} - -export const pullRequestModule = { - state: () => ({ - pull_requests_launcher: [], - pull_requests_mods: [], - }), - mutations: { - async getPullRequests(state: PullRequestStoreState, pull_request_type: PullRequestType) { - await invoke("get_pull_requests_wrapper", { installType: pull_request_type }) - .then((message) => { - switch (pull_request_type) { - case "Mods": - state.pull_requests_mods = message; - break; - - case "Launcher": - state.pull_requests_launcher = message; - break; - - default: - console.error("We should never end up here"); - } - }) - .catch((error) => { - showErrorNotification(error); - }); - }, - async downloadLauncherPR(state: PullRequestStoreState, pull_request: PullsApiResponseElement) { - await invoke("get_launcher_download_link", { commitSha: pull_request.head.sha }) - .then((url) => { - // Open URL in default HTTPS handler (i.e. default browser) - shell.open(url); - }) - .catch((error) => { - showErrorNotification(error); - }); - }, - async downloadModsPR(state: PullRequestStoreState, pull_request: PullsApiResponseElement) { - let url = `https://github.com/${pull_request.head.repo.full_name}/archive/refs/heads/${pull_request.head.ref}.zip` - shell.open(url); - }, - async installLauncherPR(state: PullRequestStoreState, pull_request: PullsApiResponseElement) { - // Send notification telling the user to wait for the process to finish - const notification = showNotification(`Installing launcher PR ${pull_request.number}`, 'Please wait', 'info', 0); - - await invoke("apply_launcher_pr", { pullRequest: pull_request, gameInstall: store.state.game_install }) - .then((message) => { - console.log(message); - // Show user notification if mod install completed. - showNotification(`Done`, `Installed ${pull_request.number}: "${pull_request.title}"`); - }) - .catch((error) => { - showErrorNotification(error); - }) - .finally(() => { - // Clear old notification - notification.close(); - }); - }, - async installModsPR(state: PullRequestStoreState, pull_request: PullsApiResponseElement) { - // Send notification telling the user to wait for the process to finish - const notification = showNotification(`Installing mods PR ${pull_request.number}`, 'Please wait', 'info', 0); - - await invoke("apply_mods_pr", { pullRequest: pull_request, gameInstall: store.state.game_install }) - .then((message) => { - // Show user notification if mod install completed. - showNotification( - `Done`, - `Installed ${pull_request.number}: "${pull_request.title}"\nMake sure to launch via batch file or by specifying correct profile!`, - 'success', - 7000 - ); - }) - .catch((error) => { - showErrorNotification(error); - }) - .finally(() => { - // Clear old notification - notification.close(); - }); - }, - } -} diff --git a/src-vue/src/plugins/modules/search.ts b/src-vue/src/plugins/modules/search.ts deleted file mode 100644 index 9614b0be..00000000 --- a/src-vue/src/plugins/modules/search.ts +++ /dev/null @@ -1,20 +0,0 @@ -interface SearchStoreState { - searchValue: string -} - -export const searchModule = { - state: () => ({ - // This is the treated value of search input - searchValue: '', - // Selected mod categories - selectedCategories: [], - showDeprecatedMods: false, - showNsfwMods: false, - sortValue: {label: '', value: ''} - }), - getters: { - searchWords(state: SearchStoreState): string { - return state.searchValue.toLowerCase(); - } - } - } diff --git a/src-vue/src/plugins/store.ts b/src-vue/src/plugins/store.ts deleted file mode 100644 index b61ac573..00000000 --- a/src-vue/src/plugins/store.ts +++ /dev/null @@ -1,529 +0,0 @@ -import { createStore } from 'vuex'; -import { listen, Event as TauriEvent } from "@tauri-apps/api/event"; -import { Tabs } from "../utils/Tabs"; -import { InstallType } from "../../../src-tauri/bindings/InstallType"; -import { invoke } from "@tauri-apps/api"; -import { GameInstall } from "../utils/GameInstall"; -import { ReleaseCanal } from "../utils/ReleaseCanal"; -import { FlightCoreVersion } from "../../../src-tauri/bindings/FlightCoreVersion"; -import { NotificationHandle } from 'element-plus'; -import { NorthstarState } from '../utils/NorthstarState'; -import { appDir } from '@tauri-apps/api/path'; -import { open } from '@tauri-apps/api/dialog'; -import { Store } from 'tauri-plugin-store-api'; -import { router } from "../main"; -import { ReleaseInfo } from "../../../src-tauri/bindings/ReleaseInfo"; -import { ThunderstoreMod } from "../../../src-tauri/bindings/ThunderstoreMod"; -import { NorthstarMod } from "../../../src-tauri/bindings/NorthstarMod"; -import { NorthstarLaunchOptions } from "../../../src-tauri/bindings/NorthstarLaunchOptions" -import { searchModule } from './modules/search'; -import { i18n } from '../main'; -import { pullRequestModule } from './modules/pull_requests'; -import { showErrorNotification, showNotification } from '../utils/ui'; -import { notificationsModule } from './modules/notifications'; - -const persistentStore = new Store('flight-core-settings.json'); - - -export interface FlightCoreStore { - developer_mode: boolean, - game_install: GameInstall, - - flightcore_version: string, - - installed_northstar_version: string, - northstar_state: NorthstarState, - northstar_release_canal: ReleaseCanal, - enableReleasesSwitch: boolean, - releaseNotes: ReleaseInfo[], - - thunderstoreMods: ThunderstoreMod[], - thunderstoreModsCategories: string[], - installed_mods: NorthstarMod[], - available_profiles: string[], - - northstar_is_running: boolean, - origin_is_running: boolean, - - player_count: number, - server_count: number, - - // user custom settings - mods_per_page: number, -} - -let notification_handle: NotificationHandle; - - -export const store = createStore({ - modules: { - search: searchModule, - pullrequests: pullRequestModule, - notifications: notificationsModule - }, - state(): FlightCoreStore { - return { - developer_mode: false, - game_install: {game_path: undefined, profile: undefined, install_type: "UNKNOWN"} as unknown as GameInstall, - - available_profiles: [], - - flightcore_version: "", - - installed_northstar_version: "", - northstar_state: NorthstarState.GAME_NOT_FOUND, - northstar_release_canal: ReleaseCanal.RELEASE, - enableReleasesSwitch: false, - releaseNotes: [], - - thunderstoreMods: [], - thunderstoreModsCategories: [], - installed_mods: [], - - northstar_is_running: false, - origin_is_running: false, - - player_count: -1, - server_count: -1, - - mods_per_page: 20, - } - }, - mutations: { - checkNorthstarUpdates(state) { - _get_northstar_version_number(state); - }, - async toggleDebugMode(_state) { - let menu_bar_handle = document.querySelector('#fc_menu-bar'); - if (menu_bar_handle !== null) { - menu_bar_handle.classList.toggle('developer_build'); - } - }, - async toggleDeveloperMode(state) { - state.developer_mode = !state.developer_mode; - - // Reset tab when closing dev mode. - if (!state.developer_mode) { - store.commit('updateCurrentTab', Tabs.PLAY); - } - - // Save dev mode state in persistent store - await persistentStore.set('dev_mode', state.developer_mode); - await persistentStore.save(); - }, - initialize(state) { - _initializeApp(state); - _checkForFlightCoreUpdates(state); - _initializeListeners(state); - }, - updateCurrentTab(state: any, newTab: Tabs) { - router.push({ path: newTab }); - }, - async updateGamePath(state: FlightCoreStore) { - // Open a selection dialog for directories - const selected = await open({ - directory: true, - multiple: false, - defaultPath: await appDir(), - }); - if (Array.isArray(selected)) { - // user selected multiple directories - alert("Please only select a single directory"); - } else if (selected === null) { - // user cancelled the selection - } else { - // user selected a single directory - - // Verify if valid Titanfall2 install location - let is_valid_titanfall2_install = await invoke("verify_install_location", { gamePath: selected }) as boolean; - if (is_valid_titanfall2_install) { - state.game_install.game_path = selected; - showNotification( - i18n.global.tc('notification.game_folder.new.title'), - i18n.global.tc('notification.game_folder.new.text') - ); - try { - notification_handle.close(); - } - catch { - console.warn("Nothing to close"); - } - state.game_install.install_type = "UNKNOWN"; - - // Save change in persistent store - await persistentStore.set('game-install', { value: state.game_install }); - await persistentStore.save(); // explicit save to disk - - // We can no longer be sure if our last profile is valid, lets reset to be sure - state.game_install.profile = "R2Northstar"; - - // Check for Northstar install - store.commit('checkNorthstarUpdates'); - - // Since we are in a new game directory, lets see if there are any profiles - store.commit('fetchProfiles'); - - } - else { - // Not valid Titanfall2 install - showErrorNotification( - i18n.global.tc('notification.game_folder.wrong.text'), - i18n.global.tc('notification.game_folder.wrong.title') - ); - } - } - }, - async launchGame(state: any, launch_options: NorthstarLaunchOptions = { launch_via_steam: false, bypass_checks: false}) { - - if (launch_options.bypass_checks) { - await invoke("launch_northstar", { gameInstall: state.game_install, launchOptions: launch_options }) - .then((message) => { - console.log("Launched with bypassed checks"); - console.log(message); - }) - .catch((error) => { - console.error(error); - alert(error); - }); - - return; - } - - // TODO update installation if release track was switched - switch (state.northstar_state) { - // Install northstar if it wasn't detected. - case NorthstarState.INSTALL: - let install_northstar_result = invoke("install_northstar_wrapper", { gameInstall: state.game_install, northstarPackageName: state.northstar_release_canal }); - state.northstar_state = NorthstarState.INSTALLING; - - await install_northstar_result.then((message) => { - console.log(message); - }) - .catch((error) => { - console.error(error); - alert(error); - }); - - _get_northstar_version_number(state); - break; - - // Update northstar if it is outdated. - case NorthstarState.MUST_UPDATE: - // Updating is the same as installing, simply overwrites the existing files - let reinstall_northstar_result = invoke("install_northstar_wrapper", { gameInstall: state.game_install, northstarPackageName: state.northstar_release_canal }); - state.northstar_state = NorthstarState.UPDATING; - - await reinstall_northstar_result.then((message) => { - console.log(message); - }) - .catch((error) => { - console.error(error); - alert(error); - }); - - _get_northstar_version_number(state); - break; - - // Game is ready to play. - case NorthstarState.READY_TO_PLAY: - await invoke("launch_northstar", { gameInstall: state.game_install, launchOptions: launch_options }) - .then((message) => { - console.log(message); - // NorthstarState.RUNNING - }) - .catch((error) => { - console.error(error); - showErrorNotification(error); - }); - break; - - case NorthstarState.GAME_NOT_FOUND: - store.commit('updateGamePath'); - break; - } - }, - async launchGameSteam(state: any, launch_options: NorthstarLaunchOptions = { launch_via_steam: true, bypass_checks: false}) { - await invoke("launch_northstar", { gameInstall: state.game_install, launchOptions: launch_options }) - .then((message) => { - showNotification('Success'); - }) - .catch((error) => { - console.error(error); - showErrorNotification(error); - }); - - return; - }, - async fetchReleaseNotes(state: FlightCoreStore) { - if (state.releaseNotes.length !== 0) return; - await invoke("get_northstar_release_notes") - .then((message) => { - state.releaseNotes = message; - }) - .catch((error) => { - showErrorNotification(error); - }); - }, - async fetchThunderstoreMods(state: FlightCoreStore) { - // To check if some Thunderstore mods are already installed/outdated, we need to load locally-installed mods. - await store.commit('loadInstalledMods'); - if (state.thunderstoreMods.length !== 0) return; - - let mods: ThunderstoreMod[] = []; - await invoke("query_thunderstore_packages_api") - .then((message) => { - mods = message; - }) - .catch((error) => { - showErrorNotification(error); - console.error(error); - return; - }); - - if (mods == undefined) { - return; - } - - // Remove some mods from listing - state.thunderstoreMods = mods; - - // Retrieve categories from mods - state.thunderstoreModsCategories = mods - .map((mod: ThunderstoreMod) => mod.categories) - .filter((modCategories: string[]) => modCategories.length !== 0) - .reduce((accumulator: string[], modCategories: string[]) => { - accumulator.push( ...modCategories.filter((cat: string) => !accumulator.includes(cat)) ); - return accumulator; - }, []) - .sort(); - }, - async loadInstalledMods(state: FlightCoreStore) { - // If there's no game path, prevent looking for installed mods. - if (state.game_install.game_path === undefined) { - console.warn('Cannot load installed mods since no game path is selected.'); - return; - } - - // Clear installed mod list first so we don't end up with leftovers - state.installed_mods = []; - - // Call back-end for installed mods - await invoke("get_installed_mods_and_properties", { gameInstall: state.game_install }) - .then((message) => { - state.installed_mods = (message as NorthstarMod[]); - }) - .catch((error) => { - console.error(error); - showErrorNotification(error); - }); - }, - async toggleReleaseCandidate(state: FlightCoreStore) { - // Flip between RELEASE and RELEASE_CANDIDATE - state.northstar_release_canal = state.northstar_release_canal === ReleaseCanal.RELEASE - ? ReleaseCanal.RELEASE_CANDIDATE - : ReleaseCanal.RELEASE; - - // Save change in persistent store - await persistentStore.set('northstar-release-canal', { value: state.northstar_release_canal }); - await persistentStore.save(); // explicit save to disk - - // Update current state so that update check etc can be performed - store.commit("checkNorthstarUpdates"); - - // Display notification to highlight change - showNotification( - i18n.global.tc(`channels.names.${state.northstar_release_canal}`), - i18n.global.tc('channels.release.switch.text', {canal: state.northstar_release_canal}), - ); - }, - async fetchProfiles(state: FlightCoreStore) { - // To fetch profiles we need a valid game path - if (!state.game_install.game_path) { - return; - } - - - await invoke("fetch_profiles", { gameInstall: state.game_install }) - .then((message) => { - state.available_profiles = message as string[]; - }) - .catch((error) => { - console.error(error); - showErrorNotification(error); - }); - } - } -}); - -/** - * This is called when application root component has been mounted. - * It invokes all Rust methods that are needed to initialize UI. - */ -async function _initializeApp(state: any) { - // Display dev view if dev mode was previously enabled. - const devModeEnabled: boolean = await persistentStore.get('dev_mode') ?? false; - const debugModeEnabled: boolean = await invoke("is_debug_mode"); - if (devModeEnabled) { - store.commit('toggleDeveloperMode'); - } - if (debugModeEnabled) { - store.commit('toggleDebugMode'); - } - - // Disable context menu in release build. - if (!debugModeEnabled) { - document.addEventListener('contextmenu', event => event.preventDefault()); - } - - // Grab Northstar release canal value from store if exists - var persistent_northstar_release_canal = (await persistentStore.get('northstar-release-canal')) as any; - if (persistent_northstar_release_canal) { // For some reason, the plugin-store doesn't throw an eror but simply returns `null` when key not found - // Put value from peristent store into current store - state.northstar_release_canal = persistent_northstar_release_canal.value as string; - } - else { - console.log("Value not found in store"); - } - - // Grab "Enable releases switching" setting from store if possible - const valueFromStore: { value: boolean } | null = await persistentStore.get('northstar-releases-switching'); - if (valueFromStore) { - state.enableReleasesSwitch = valueFromStore.value; - } - - // Grab "Thunderstore mods per page" setting from store if possible - const perPageFromStore: { value: number } | null = await persistentStore.get('thunderstore-mods-per-page'); - if (perPageFromStore && perPageFromStore.value) { - state.mods_per_page = perPageFromStore.value; - } - - // Get FlightCore version number - state.flightcore_version = await invoke("get_flightcore_version_number"); - - var result = undefined; - var persistent_game_install = (await persistentStore.get('game-install')) as any; - - if ( // Safety checks for value from store - persistent_game_install - && persistent_game_install.value !== undefined - && persistent_game_install.value.game_path !== undefined - && persistent_game_install.value.install_type !== undefined - ) { // For some reason, the plugin-store doesn't throw an eror but simply returns `null` when key not found - - // Add profile to existing storage - if (persistent_game_install.value.profile === undefined) { - persistent_game_install.value.profile = "R2Northstar" - } - - let game_install = persistent_game_install.value as GameInstall; - // check if valid path - let is_valid_titanfall2_install = await invoke("verify_install_location", { gamePath: game_install.game_path }) as boolean; - if (is_valid_titanfall2_install) { - // Use value from peristent store - result = game_install; - } - - } - - if (result === undefined) { // No (valid) value found in persistent store - result = await invoke("find_game_install_location") - .catch((err) => { - // Gamepath not found or other error - console.error(err); - notification_handle = showNotification( - i18n.global.tc('notification.game_folder.not_found.title'), - i18n.global.tc('notification.game_folder.not_found.text'), - 'error', - 0 // Duration `0` means the notification will not auto-vanish - ); - }); - } - - if (result !== undefined) { // Found some form of value for gameinstall - - const typedResult: GameInstall = result as GameInstall; - - // Save change in persistent store - await persistentStore.set('game-install', { value: typedResult }); - await persistentStore.save(); // explicit save to disk - - // Update UI store - state.game_install = typedResult; - - // Check installed Northstar version if found - await _get_northstar_version_number(state); - } - - await invoke<[number, number]>("get_server_player_count") - .then((message) => { - state.player_count = message[0]; - state.server_count = message[1]; - }) - .catch((error) => { - console.warn("Failed getting player/server count"); - console.warn(error); - }); -} - -async function _checkForFlightCoreUpdates(state: FlightCoreStore) { - // Check if FlightCore up-to-date - let flightcore_is_outdated = await invoke("check_is_flightcore_outdated") as boolean; - - if (flightcore_is_outdated) { - let newest_flightcore_version = await invoke("get_newest_flightcore_version") as FlightCoreVersion; - showNotification( - i18n.global.tc('notification.flightcore_outdated.title'), - i18n.global.tc('notification.flightcore_outdated.text', {oldVersion: state.flightcore_version, newVersion: newest_flightcore_version.tag_name}), - 'warning', - 0 // Duration `0` means the notification will not auto-vanish - ); - } -} - -/** - * This registers callbacks listening to events from Rust-backend. - * Those events include Origin and Northstar running state. - */ -function _initializeListeners(state: any) { - listen("ea-app-running-ping", function (evt: TauriEvent) { - state.origin_is_running = evt.payload as boolean; - }); - - listen("northstar-running-ping", function (evt: TauriEvent) { - state.northstar_is_running = evt.payload as boolean; - }); - - listen("northstar-statistics", function (evt: TauriEvent<{Ok: [number, number]}>) { - state.player_count = evt.payload.Ok[0]; - state.server_count = evt.payload.Ok[1]; - }); -} - -/** - * This retrieves Northstar version tag, and stores it in application - * state, for it to be displayed in UI. - */ -async function _get_northstar_version_number(state: any) { - state.installed_northstar_version = ""; - - await invoke("get_northstar_version_number", { gameInstall: state.game_install }) - .then((message) => { - let northstar_version_number: string = message as string; - state.installed_northstar_version = northstar_version_number; - state.northstar_state = NorthstarState.READY_TO_PLAY; - - invoke("check_is_northstar_outdated", { gameInstall: state.game_install, northstarPackageName: state.northstar_release_canal }) - .then((message) => { - if (message) { - state.northstar_state = NorthstarState.MUST_UPDATE; - } - }) - .catch((error) => { - console.error(error); - alert(error); - }); - }) - .catch((error) => { - state.northstar_state = NorthstarState.INSTALL; - }) -} -- cgit v1.2.3