mirror of
https://github.com/an-anime-team/an-anime-game-launcher.git
synced 2024-12-20 17:01:47 +03:00
Several changes
- fixed `constants.paths.prefix.current` value - made `Tray` class to manage tray features - added tray icon
This commit is contained in:
parent
3904a86381
commit
7fafddffac
6 changed files with 169 additions and 11 deletions
|
@ -6,7 +6,7 @@
|
|||
"scripts": {
|
||||
"neu": "neu",
|
||||
"dev": "vite build && neu run --disable-auto-reload",
|
||||
"build": "vite build && rm -rf dist/an-anime-game-launcher/public && mkdir dist/an-anime-game-launcher/public && cp public/runners.json dist/an-anime-game-launcher/public && cp public/dxvks.json dist/an-anime-game-launcher/public && cp -r public/locales dist/an-anime-game-launcher/public/locales && cp -r public/shaders dist/an-anime-game-launcher/public/shaders && cp -r public/discord-rpc dist/an-anime-game-launcher/public/discord-rpc && neu build --release",
|
||||
"build": "vite build && rm -rf dist/an-anime-game-launcher/public && mkdir dist/an-anime-game-launcher/public && cp public dist/an-anime-game-launcher/public && neu build --release",
|
||||
"bundle": "node scripts/bundle-appimage.cjs",
|
||||
"check": "svelte-check --tsconfig ./tsconfig.json"
|
||||
},
|
||||
|
|
|
@ -12,7 +12,7 @@ class Prefix
|
|||
*/
|
||||
public static get current(): Promise<string>
|
||||
{
|
||||
return new Promise(async (resolve) => resolve(await Configs.get('prefix') as string));
|
||||
return new Promise(async (resolve) => resolve(await Configs.get('folders.prefix') as string));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,25 +1,30 @@
|
|||
import Window from './neutralino/Window';
|
||||
import Process from './neutralino/Process';
|
||||
import Tray from './neutralino/Tray';
|
||||
|
||||
import constants from './Constants';
|
||||
import Configs from './Configs';
|
||||
|
||||
import ProgressBar from './launcher/ProgressBar';
|
||||
import State from './launcher/State';
|
||||
import Debug from './core/Debug';
|
||||
import IPC from './core/IPC';
|
||||
import DiscordRPC from './core/DiscordRPC';
|
||||
|
||||
import ProgressBar from './launcher/ProgressBar';
|
||||
import State from './launcher/State';
|
||||
|
||||
export default class Launcher
|
||||
{
|
||||
public state?: State;
|
||||
public progressBar?: ProgressBar;
|
||||
public rpc?: DiscordRPC;
|
||||
public tray: Tray;
|
||||
|
||||
protected settingsMenu?: Process;
|
||||
|
||||
public constructor(onMount)
|
||||
{
|
||||
this.tray = new Tray('/public/icons/256x256.png');
|
||||
this.tray.update();
|
||||
|
||||
this.updateDiscordRPC('in-launcher');
|
||||
|
||||
onMount(() => {
|
||||
|
|
|
@ -39,6 +39,10 @@ export default (launcher: Launcher): Promise<void> => {
|
|||
|
||||
launcher.updateDiscordRPC('in-game');
|
||||
|
||||
launcher.tray.update([
|
||||
{ text: 'Starting the game...', disabled: true }
|
||||
]);
|
||||
|
||||
/**
|
||||
* Selecting wine executable
|
||||
*/
|
||||
|
@ -131,15 +135,45 @@ export default (launcher: Launcher): Promise<void> => {
|
|||
});
|
||||
|
||||
// Game was started by the launcher.bat file
|
||||
// so we just need to wait until GenshinImpact process
|
||||
// so we just need to wait until AnimeGame.e process
|
||||
// will be closed
|
||||
process.finish(() => {
|
||||
const processName = `${constants.placeholders.uppercase.first + constants.placeholders.uppercase.second}.e`;
|
||||
|
||||
let closeGameCounter = 0;
|
||||
|
||||
const waiter = async () => {
|
||||
const processes: string = (await Neutralino.os.execCommand('ps -A')).stdOut;
|
||||
|
||||
// Game is still running
|
||||
if (processes.includes('GenshinImpact'))
|
||||
if (processes.includes(processName))
|
||||
{
|
||||
const playtime = Math.round((Date.now() - startTime) / 1000);
|
||||
|
||||
let hours: string|number = Math.floor(playtime / 3600);
|
||||
let minutes: string|number = Math.floor((playtime - hours * 3600) / 60);
|
||||
let seconds: string|number = playtime - hours * 3600 - minutes * 60;
|
||||
|
||||
if (hours < 10)
|
||||
hours = `0${hours}`;
|
||||
|
||||
if (minutes < 10)
|
||||
minutes = `0${minutes}`;
|
||||
|
||||
if (seconds < 10)
|
||||
seconds = `0${seconds}`;
|
||||
|
||||
launcher.tray.update([
|
||||
{ text: `Playing for ${hours}:${minutes}:${seconds}`, disabled: true },
|
||||
{
|
||||
text: `Close game${closeGameCounter > 0 ? ` (${closeGameCounter})` : ''}`,
|
||||
|
||||
click: () => Neutralino.os.execCommand(`kill ${++closeGameCounter < 3 ? '-15' : '-9'} $(pidof ${processName})`)
|
||||
}
|
||||
]);
|
||||
|
||||
setTimeout(waiter, 3000);
|
||||
}
|
||||
|
||||
// Game was closed
|
||||
else
|
||||
|
@ -147,8 +181,10 @@ export default (launcher: Launcher): Promise<void> => {
|
|||
const stopTime = Date.now();
|
||||
|
||||
Window.current.show();
|
||||
Window.current.center(1280, 700);
|
||||
|
||||
launcher.updateDiscordRPC('in-launcher');
|
||||
launcher.tray.hide();
|
||||
|
||||
// TODO
|
||||
|
||||
|
|
|
@ -199,11 +199,8 @@ class Process
|
|||
|
||||
// Set env variables
|
||||
if (options.env)
|
||||
{
|
||||
Object.keys(options.env).forEach((key) => {
|
||||
for (const key of Object.keys(options.env))
|
||||
command = `${key}="${this.addSlashes(options.env![key].toString())}" ${command}`;
|
||||
});
|
||||
}
|
||||
|
||||
// Set output redirection to the temp file
|
||||
command = `${command} > "${this.addSlashes(tmpFile)}" 2>&1`;
|
||||
|
|
120
src/ts/neutralino/Tray.ts
Normal file
120
src/ts/neutralino/Tray.ts
Normal file
|
@ -0,0 +1,120 @@
|
|||
declare const Neutralino;
|
||||
|
||||
type Item = {
|
||||
/**
|
||||
* Item text
|
||||
*/
|
||||
text: string;
|
||||
|
||||
/**
|
||||
* Item id
|
||||
*/
|
||||
id?: string;
|
||||
|
||||
/**
|
||||
* Whether the item disabled or not
|
||||
*
|
||||
* If yes, then it will be a string
|
||||
*/
|
||||
disabled?: boolean;
|
||||
|
||||
/**
|
||||
* Is this item a checkbox or not
|
||||
*/
|
||||
checked?: boolean;
|
||||
|
||||
/**
|
||||
* Event on click
|
||||
*
|
||||
* If specified, then will generate random
|
||||
* item id if it is not specified
|
||||
*/
|
||||
click?: (item: Item) => void;
|
||||
};
|
||||
|
||||
Neutralino.events.on('trayMenuItemClicked', (item) => {
|
||||
for (const tray of Tray.trays)
|
||||
for (const trayItem of tray.items)
|
||||
if (trayItem.id === item.detail.id)
|
||||
{
|
||||
if (trayItem.click)
|
||||
{
|
||||
trayItem.click({
|
||||
id: item.detail.id,
|
||||
text: item.detail.text,
|
||||
disabled: item.detail['isDisabled'],
|
||||
checked: item.detail['isChecked'],
|
||||
click: trayItem.click
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
export default class Tray
|
||||
{
|
||||
public static trays: Tray[] = [];
|
||||
|
||||
public icon: string;
|
||||
|
||||
protected _items: Item[] = [];
|
||||
|
||||
public get items(): Item[]
|
||||
{
|
||||
return this._items.map((item) => {
|
||||
return {
|
||||
id: item.id,
|
||||
text: item.text,
|
||||
disabled: item['isDisabled'],
|
||||
checked: item['isChecked'],
|
||||
click: item.click
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
public set items(items: Item[])
|
||||
{
|
||||
this._items = items.map((item) => {
|
||||
if (item.id === undefined && item.click !== undefined)
|
||||
item.id = 'click:' + Math.random().toString().substring(2);
|
||||
|
||||
return {
|
||||
id: item.id,
|
||||
text: item.text,
|
||||
isDisabled: item.disabled,
|
||||
isChecked: item.checked,
|
||||
click: item.click
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
public constructor(icon: string, items: Item[] = [])
|
||||
{
|
||||
this.icon = icon;
|
||||
this.items = items;
|
||||
|
||||
Tray.trays.push(this);
|
||||
}
|
||||
|
||||
public update(items: Item[]|null = null): Promise<void>
|
||||
{
|
||||
if (items !== null)
|
||||
this.items = items;
|
||||
|
||||
return Neutralino.os.setTray({
|
||||
icon: this.icon,
|
||||
menuItems: this._items
|
||||
});
|
||||
}
|
||||
|
||||
public hide(): Promise<void>
|
||||
{
|
||||
return Neutralino.os.setTray({
|
||||
icon: this.icon,
|
||||
menuItems: []
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export type { Item };
|
Loading…
Reference in a new issue