mirror of
https://github.com/Kvan7/Exiled-Exchange-2.git
synced 2025-10-30 14:17:55 +00:00
add About page, refactor updates
This commit is contained in:
35
ipc/types.ts
35
ipc/types.ts
@@ -34,6 +34,24 @@ export interface ShortcutAction {
|
||||
}
|
||||
}
|
||||
|
||||
export type UpdateInfo =
|
||||
{
|
||||
state: 'initial' | 'checking-for-update'
|
||||
} | {
|
||||
state: 'update-available' | 'update-downloaded'
|
||||
version: string
|
||||
} | {
|
||||
state: 'update-not-available' | 'error'
|
||||
checkedAt: number
|
||||
}
|
||||
|
||||
export interface HostState {
|
||||
contents: string | null
|
||||
version: string
|
||||
portable: boolean
|
||||
updater: UpdateInfo
|
||||
}
|
||||
|
||||
export type IpcEvent =
|
||||
// events that have meaning only in Overlay mode:
|
||||
IpcOverlayAttached |
|
||||
@@ -44,7 +62,7 @@ export type IpcEvent =
|
||||
IpcTrackArea |
|
||||
// events used by any type of Client:
|
||||
IpcSaveConfig |
|
||||
IpcUpdateInfo |
|
||||
IpcUpdaterState |
|
||||
IpcStashSearch |
|
||||
IpcGameLog |
|
||||
IpcClientIsActive |
|
||||
@@ -52,7 +70,8 @@ export type IpcEvent =
|
||||
IpcHostConfig |
|
||||
IpcWidgetAction |
|
||||
IpcItemText |
|
||||
IpcConfigChanged
|
||||
IpcConfigChanged |
|
||||
IpcUserAction
|
||||
|
||||
export type IpcEventPayload<Name extends IpcEvent['name'], T extends IpcEvent = IpcEvent> =
|
||||
T extends { name: Name, payload: infer P } ? P : never
|
||||
@@ -134,10 +153,14 @@ type IpcGameLog =
|
||||
lines: string[]
|
||||
}>
|
||||
|
||||
export type IpcUpdateInfo =
|
||||
Event<'MAIN->CLIENT::update-available', {
|
||||
auto: boolean
|
||||
version: string
|
||||
type IpcUpdaterState =
|
||||
Event<'MAIN->CLIENT::updater-state', UpdateInfo>
|
||||
|
||||
// Hotkeyable actions are defined in `ShortcutAction`.
|
||||
// Actions below are triggered by user interaction with the UI.
|
||||
type IpcUserAction =
|
||||
Event<'CLIENT->MAIN::user-action', {
|
||||
action: 'check-for-update' | 'update-and-restart'
|
||||
}>
|
||||
|
||||
interface Event<TName extends string, TPayload = undefined> {
|
||||
|
||||
@@ -10,7 +10,7 @@ export class AppTray {
|
||||
this.tray = new Tray(
|
||||
nativeImage.createFromPath(path.join(__dirname, process.env.STATIC!, process.platform === 'win32' ? 'icon.ico' : 'icon.png'))
|
||||
)
|
||||
this.tray.setToolTip('Awakened PoE Trade')
|
||||
this.tray.setToolTip(`Awakened PoE Trade v${app.getVersion()}`)
|
||||
this.rebuildMenu()
|
||||
}
|
||||
|
||||
@@ -32,38 +32,12 @@ export class AppTray {
|
||||
}
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: `APT v${app.getVersion()}`,
|
||||
click: () => {
|
||||
shell.openExternal('https://github.com/SnosMe/awakened-poe-trade/releases')
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Open config folder',
|
||||
click: () => {
|
||||
shell.openPath(path.join(app.getPath('userData'), 'apt-data'))
|
||||
}
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Patreon (Donate)',
|
||||
click: () => {
|
||||
shell.openExternal('https://patreon.com/awakened_poe_trade')
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Discord',
|
||||
submenu: [
|
||||
{
|
||||
label: 'The Forbidden Trove',
|
||||
click: () => { shell.openExternal('https://discord.gg/KNpmhvk') }
|
||||
},
|
||||
{
|
||||
label: 'r/pathofexile',
|
||||
click: () => { shell.openExternal('https://discord.gg/fSwfqN5') }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Quit',
|
||||
click: () => {
|
||||
|
||||
@@ -1,66 +1,63 @@
|
||||
import { autoUpdater } from 'electron-updater'
|
||||
import type { ServerEvents } from './server'
|
||||
import type { UpdateInfo } from '../../ipc/types'
|
||||
|
||||
export class AppUpdater {
|
||||
private canCheck = true
|
||||
private checkedAtStartup = false
|
||||
private _checkedAtStartup = false
|
||||
private _info: UpdateInfo = { state: 'initial' }
|
||||
|
||||
get info () { return this._info }
|
||||
set info (info: UpdateInfo) {
|
||||
this._info = info
|
||||
this.server.sendEventTo('broadcast', {
|
||||
name: 'MAIN->CLIENT::updater-state',
|
||||
payload: info
|
||||
})
|
||||
}
|
||||
|
||||
constructor (
|
||||
private server: ServerEvents
|
||||
) {
|
||||
setInterval(this.check, 16 * 60 * 60 * 1000)
|
||||
|
||||
autoUpdater.on('update-available', async (info: { version: string }) => {
|
||||
this.canCheck = false
|
||||
if (autoUpdater.autoDownload) {
|
||||
// this.status = `Downloading v${info.version} ...`
|
||||
} else {
|
||||
// this.status = `Update v${info.version} available on GitHub`
|
||||
this.server.sendEventTo('broadcast', {
|
||||
name: 'MAIN->CLIENT::update-available',
|
||||
payload: { auto: false, version: info.version }
|
||||
})
|
||||
this.server.onEventAnyClient('CLIENT->MAIN::user-action', ({ action }) => {
|
||||
if (action === 'check-for-update') {
|
||||
this.check()
|
||||
} else if (action === 'update-and-restart') {
|
||||
autoUpdater.quitAndInstall(false)
|
||||
}
|
||||
})
|
||||
|
||||
autoUpdater.on('checking-for-update', () => {
|
||||
this.info = { state: 'checking-for-update' }
|
||||
})
|
||||
autoUpdater.on('update-available', (info: { version: string }) => {
|
||||
this.info = { state: 'update-available', version: info.version }
|
||||
})
|
||||
autoUpdater.on('update-not-available', () => {
|
||||
this.canCheck = true
|
||||
// this.status = 'No updates available'
|
||||
this.info = { state: 'update-not-available', checkedAt: Date.now() }
|
||||
})
|
||||
|
||||
autoUpdater.on('error', () => {
|
||||
this.canCheck = true
|
||||
// this.status = 'Something went wrong, check logs'
|
||||
this.info = { state: 'error', checkedAt: Date.now() }
|
||||
})
|
||||
|
||||
autoUpdater.on('update-downloaded', async (info: { version: string }) => {
|
||||
this.canCheck = false
|
||||
// this.status = `v${info.version} will be installed on exit`
|
||||
this.server.sendEventTo('broadcast', {
|
||||
name: 'MAIN->CLIENT::update-available',
|
||||
payload: { auto: true, version: info.version }
|
||||
})
|
||||
autoUpdater.on('update-downloaded', (info: { version: string }) => {
|
||||
this.info = { state: 'update-downloaded', version: info.version }
|
||||
})
|
||||
|
||||
// on('download-progress') https://github.com/electron-userland/electron-builder/issues/2521
|
||||
}
|
||||
|
||||
updateOps (autoDownload: boolean) {
|
||||
updateOpts (autoDownload: boolean) {
|
||||
autoUpdater.autoDownload = (
|
||||
!process.env.PORTABLE_EXECUTABLE_DIR && // https://www.electron.build/configuration/nsis.html#portable
|
||||
autoDownload
|
||||
)
|
||||
if (!this.checkedAtStartup) {
|
||||
this.checkedAtStartup = true
|
||||
if (!this._checkedAtStartup) {
|
||||
this._checkedAtStartup = true
|
||||
this.check()
|
||||
}
|
||||
}
|
||||
|
||||
private check = async () => {
|
||||
if (!this.canCheck) return
|
||||
this.canCheck = false
|
||||
// this.status = 'Checking for update...'
|
||||
|
||||
try {
|
||||
await autoUpdater.checkForUpdates()
|
||||
} catch {
|
||||
|
||||
@@ -40,11 +40,11 @@ app.on('ready', async () => {
|
||||
shortcuts.updateActions(cfg.shortcuts, cfg.stashScroll, cfg.restoreClipboard)
|
||||
gameLogWatcher.restart(cfg.clientLog)
|
||||
gameConfig.readConfig(cfg.gameConfig)
|
||||
appUpdater.updateOps(!cfg.disableUpdateDownload)
|
||||
appUpdater.updateOpts(!cfg.disableUpdateDownload)
|
||||
tray.overlayKey = cfg.overlayKey
|
||||
})
|
||||
uIOhook.start()
|
||||
const port = await startServer()
|
||||
const port = await startServer(appUpdater)
|
||||
overlay.loadAppPage(port)
|
||||
tray.serverPort = port
|
||||
},
|
||||
|
||||
@@ -6,9 +6,11 @@ import fastifyStatic from '@fastify/static'
|
||||
import type { WebSocket } from 'ws'
|
||||
import type { AddressInfo } from 'net'
|
||||
import { EventEmitter } from 'events'
|
||||
import { IpcEvent, IpcEventPayload } from '../../ipc/types'
|
||||
import { app } from 'electron'
|
||||
import { IpcEvent, IpcEventPayload, HostState } from '../../ipc/types'
|
||||
import { ConfigStore } from './host-files/ConfigStore'
|
||||
import { addFileUploadRoutes } from './host-files/file-uploads'
|
||||
import type { AppUpdater } from './AppUpdater'
|
||||
|
||||
const server = fastify()
|
||||
let lastActiveClient: WebSocket
|
||||
@@ -81,12 +83,6 @@ export const eventPipe = {
|
||||
sendEventTo
|
||||
}
|
||||
|
||||
const configStore = new ConfigStore(eventPipe)
|
||||
|
||||
server.get('/config', async (_req) => {
|
||||
return { contents: await configStore.load() }
|
||||
})
|
||||
|
||||
server.register(async (instance) => {
|
||||
instance.get('/events', { websocket: true }, (connection) => {
|
||||
lastActiveClient = connection.socket
|
||||
@@ -107,7 +103,22 @@ server.register(async (instance) => {
|
||||
})
|
||||
})
|
||||
|
||||
export async function startServer (): Promise<number> {
|
||||
export async function startServer (
|
||||
appUpdater: AppUpdater
|
||||
): Promise<number> {
|
||||
const configStore = new ConfigStore(eventPipe)
|
||||
|
||||
server.get<{
|
||||
Reply: HostState
|
||||
}>('/config', async (_req) => {
|
||||
return {
|
||||
version: app.getVersion(),
|
||||
portable: Boolean(process.env.PORTABLE_EXECUTABLE_DIR),
|
||||
updater: appUpdater.info,
|
||||
contents: await configStore.load()
|
||||
}
|
||||
})
|
||||
|
||||
await server.listen({
|
||||
port: (process.env.VITE_DEV_SERVER_URL) ? 8584 : 0
|
||||
})
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
{
|
||||
"please_wait": "Please wait\u2026",
|
||||
|
||||
"map.mods.heist": "heist",
|
||||
"map.mods.outdated": "outdated",
|
||||
"Support development on": "Support development\u00A0on"
|
||||
"Support development on": "Support development\u00A0on",
|
||||
|
||||
"updates.maybe_outdated": "You may have an outdated version",
|
||||
"updates.latest": "You have the latest version",
|
||||
"updates.error": "Error while checking for updates",
|
||||
"updates.checking": "Checking for updates",
|
||||
"updates.downloading": "Downloading\u2026",
|
||||
"updates.available": "Update available: {0}",
|
||||
"updates.never_checked": "Last checked: never",
|
||||
"updates.last_checked": "Last checked: {0}",
|
||||
"updates.check_now": "Check now",
|
||||
"updates.install_now": "Install now",
|
||||
"updates.downloads_page": "Open the Downloads page",
|
||||
"updates.installed_on_exit": "It will be installed automatically on exit",
|
||||
"updates.download_manually": "You can download it from GitHub",
|
||||
"updates.download_disabled": "You have disabled automatic updates download"
|
||||
}
|
||||
@@ -25,10 +25,26 @@
|
||||
"scourge": "преображен",
|
||||
"Not recognized modifier": "Нераспознанное свойство",
|
||||
"Refresh": "Обновить",
|
||||
"please_wait": "Пожалуйста, подождите\u2026",
|
||||
"map.mods.heist": "кража",
|
||||
"map.mods.outdated": "устарело",
|
||||
"Support development on": "Поддержите разработку\u00A0на",
|
||||
|
||||
"updates.maybe_outdated": "У вас может быть устаревшая версия",
|
||||
"updates.latest": "У вас самая последняя версия",
|
||||
"updates.error": "Ошибка при проверке наличия обновлений",
|
||||
"updates.checking": "Проверка наличия обновлений",
|
||||
"updates.downloading": "Скачивание\u2026",
|
||||
"updates.available": "Доступно обновление: {0}",
|
||||
"updates.never_checked": "Последняя проверка: никогда",
|
||||
"updates.last_checked": "Последняя проверка: {0}",
|
||||
"updates.check_now": "Проверить сейчас",
|
||||
"updates.install_now": "Установить сейчас",
|
||||
"updates.downloads_page": "Открыть страницу скачивания",
|
||||
"updates.installed_on_exit": "Оно будет установлено автоматически при выходе",
|
||||
"updates.download_manually": "Вы можете загрузить его с GitHub",
|
||||
"updates.download_disabled": "Вы отключили автоматическую загрузку обновлений",
|
||||
|
||||
"Anomalous": "Аномальный",
|
||||
"Divergent": "Искривлённый",
|
||||
"Phantasmal": "Фантомный"
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
import type { IpcUpdateInfo } from '@ipc/types'
|
||||
import { MainProcess } from '@/web/background/IPC'
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
export const updateInfo = shallowRef<IpcUpdateInfo['payload'] | null>(null)
|
||||
|
||||
MainProcess.onEvent('MAIN->CLIENT::update-available', (e) => {
|
||||
updateInfo.value = e
|
||||
})
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { IpcEvent, IpcEventPayload } from '@ipc/types'
|
||||
import type { IpcEvent, IpcEventPayload, UpdateInfo, HostState } from '@ipc/types'
|
||||
import { shallowRef } from 'vue'
|
||||
import Sockette from 'sockette'
|
||||
|
||||
@@ -6,6 +6,9 @@ class HostTransport {
|
||||
private evBus = new EventTarget()
|
||||
private socket: Sockette
|
||||
logs = shallowRef('')
|
||||
version = shallowRef('0.0.00000')
|
||||
isPortable = shallowRef(false)
|
||||
updateInfo = shallowRef<UpdateInfo>({ state: 'initial' })
|
||||
|
||||
constructor () {
|
||||
this.socket = new Sockette(`ws://${window.location.host}/events`, {
|
||||
@@ -16,6 +19,9 @@ class HostTransport {
|
||||
this.onEvent('MAIN->CLIENT::log-entry', (entry) => {
|
||||
this.logs.value += (entry.message + '\n')
|
||||
})
|
||||
this.onEvent('MAIN->CLIENT::updater-state', (info) => {
|
||||
this.updateInfo.value = info
|
||||
})
|
||||
}
|
||||
|
||||
selfDispatch (event: IpcEvent) {
|
||||
@@ -45,7 +51,11 @@ class HostTransport {
|
||||
|
||||
async getConfig (): Promise<string | null> {
|
||||
const response = await fetch('/config')
|
||||
const config = await response.json() as { contents: string | null }
|
||||
const config = await response.json() as HostState
|
||||
// TODO: 1) refactor this 2) add logs
|
||||
this.version.value = config.version
|
||||
this.updateInfo.value = config.updater
|
||||
this.isPortable.value = config.portable
|
||||
return config.contents
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,6 @@ import WidgetSettings from '../settings/SettingsWindow.vue'
|
||||
import { AppConfig, saveConfig, pushHostConfig } from '@/web/Config'
|
||||
import LoadingAnimation from './LoadingAnimation.vue'
|
||||
// ---
|
||||
import '@/web/background/AutoUpdates'
|
||||
import '@/web/background/Prices'
|
||||
import { load as loadLeagues } from '@/web/background/Leagues'
|
||||
import { handleLine } from '@/web/client-log/client-log'
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
<template>
|
||||
<div v-if="updateInfo" class="bg-gray-900 mt-2 mx-4 rounded flex items-baseline py-1 px-2">
|
||||
<div class="flex-1 font-sans">
|
||||
<div>{{ t('Update available: {0}', [updateInfo.version]) }}</div>
|
||||
<p class="text-gray-500">{{ t(updateInfo.auto
|
||||
? 'It will be installed automatically on exit'
|
||||
: 'You can download it from GitHub') }}</p>
|
||||
</div>
|
||||
<button @click="updateInfo = null"><i class="fas fa-times"></i></button>
|
||||
<div v-if="updateInfo" class="bg-gray-900 mt-2 mx-4 rounded py-1 px-2">
|
||||
<p>{{ updateInfo.str1 }}</p>
|
||||
<p class="text-gray-500">{{ updateInfo.str2 }}</p>
|
||||
</div>
|
||||
<div v-if="loadingLeagues" class="pt-2 px-4">
|
||||
<i class="fas fa-info-circle text-gray-600"></i> {{ t('Loading leagues...') }}</div>
|
||||
@@ -21,11 +16,11 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, inject } from 'vue'
|
||||
import { defineComponent, computed, inject } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import * as Leagues from '@/web/background/Leagues'
|
||||
import { updateInfo } from '@/web/background/AutoUpdates'
|
||||
import { poeWebApi } from '@/web/Config'
|
||||
import { Host } from '@/web/background/IPC'
|
||||
import { poeWebApi, AppConfig } from '@/web/Config'
|
||||
|
||||
export default defineComponent({
|
||||
setup () {
|
||||
@@ -33,6 +28,20 @@ export default defineComponent({
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const updateInfo = computed(() => {
|
||||
const rawInfo = Host.updateInfo.value
|
||||
switch (rawInfo.state) {
|
||||
case 'update-downloaded':
|
||||
return { str1: t('updates.available', [rawInfo.version]), str2: t('updates.installed_on_exit') }
|
||||
case 'update-available':
|
||||
return (Host.isPortable.value || AppConfig().disableUpdateDownload)
|
||||
? { str1: t('updates.available', [rawInfo.version]), str2: (Host.isPortable.value) ? t('updates.download_manually') : t('updates.download_disabled') }
|
||||
: null
|
||||
default:
|
||||
return null
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
t,
|
||||
updateInfo,
|
||||
@@ -55,9 +64,6 @@ export default defineComponent({
|
||||
"leagues_failed": "Make sure the realm is not under maintenance. Also try clicking on the \"Browser\" button, you may need to complete a CAPTCHA there."
|
||||
},
|
||||
"ru": {
|
||||
"Update available: {0}": "Доступно обновление: {0}",
|
||||
"It will be installed automatically on exit": "Оно будет установлено автоматически при выходе",
|
||||
"You can download it from GitHub": "Вы можете загрузить его с GitHub",
|
||||
"Loading leagues...": "Загрузка лиг...",
|
||||
"Failed to load leagues": "Не удалось загрузить лиги",
|
||||
"leagues_failed": "Убедитесь, что сервера не находятся на обслуживании. Попробуйте нажать на кнопку \"Браузер\", возможно, там будет CAPTCHA."
|
||||
|
||||
@@ -55,6 +55,7 @@ import type { Widget, WidgetManager } from '@/web/overlay/interfaces'
|
||||
import SettingsHotkeys from './hotkeys.vue'
|
||||
import SettingsChat from './chat.vue'
|
||||
import SettingsGeneral from './general.vue'
|
||||
import SettingsAbout from './about.vue'
|
||||
import SettingsPricecheck from './price-check.vue'
|
||||
import SettingsItemcheck from './item-check.vue'
|
||||
import SettingsDebug from './debug.vue'
|
||||
@@ -183,7 +184,7 @@ function menuByType (type?: string) {
|
||||
[SettingsHotkeys, SettingsChat],
|
||||
[SettingsGeneral],
|
||||
[SettingsPricecheck, SettingsMaps, SettingsItemcheck],
|
||||
[SettingsDebug]
|
||||
[SettingsDebug, SettingsAbout]
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -324,6 +325,7 @@ function flatJoin<T, J> (arr: T[][], joinEl: () => J) {
|
||||
"Settings - Awakened PoE Trade": "Настройки - Awakened PoE Trade",
|
||||
"Hotkeys": "Быстрые клавиши",
|
||||
"General": "Общие",
|
||||
"About": "О программе",
|
||||
"Price check": "Прайс-чек",
|
||||
"Maps": "Карты",
|
||||
"Item info": "Проверка предмета",
|
||||
|
||||
104
renderer/src/web/settings/about.vue
Normal file
104
renderer/src/web/settings/about.vue
Normal file
@@ -0,0 +1,104 @@
|
||||
<template>
|
||||
<div class="p-2 flex flex-col h-full items-center">
|
||||
<div class="flex flex-col items-center p-2 mb-4">
|
||||
<img class="w-12 h-12" src="/images/TransferOrb.png">
|
||||
<p class="text-base">Awakened PoE Trade</p>
|
||||
<p class="">{{ t('Version {0}', [version]) }}</p>
|
||||
<div class="flex gap-2">
|
||||
<a class="border-b" href="https://github.com/SnosMe/awakened-poe-trade/releases" target="_blank">{{ t('Release notes') }}</a>
|
||||
<a class="border-b" href="https://github.com/SnosMe/awakened-poe-trade/issues" target="_blank">{{ t('Report a bug on GitHub') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border border-gray-600 rounded p-2 whitespace-nowrap min-w-min w-72">
|
||||
<p>{{ info.str1 }}</p>
|
||||
<p>{{ info.str2 }}</p>
|
||||
<button v-if="info.action" @click="info.action"
|
||||
class="btn w-full mt-1">{{ info.actionText }}</button>
|
||||
</div>
|
||||
<div class="text-center mt-auto py-8">
|
||||
<p>{{ t('contact_in_discord') }} <br><span class="font-sans text-gray-500 select-all"><@295216259795124225></span></p>
|
||||
<ul class="flex gap-4">
|
||||
<li><img class="rounded inline" src="https://cdn.discordapp.com/icons/645607528297922560/a_c177897c1751abde48b893844811a1a7.gif?size=32"> <a class="border-b" href="https://discord.gg/tftrove" target="_blank">The Forbidden Trove</a></li>
|
||||
<li><img class="rounded inline" src="https://cdn.discordapp.com/icons/174993814845521922/53a393aa8b4f386bad2b41878dc324b5.webp?size=32"> <a class="border-b" href="https://discord.gg/pathofexile" target="_blank">r/pathofexile</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { Host } from '@/web/background/IPC'
|
||||
import { AppConfig } from '@/web/Config'
|
||||
import { DateTime } from 'luxon'
|
||||
|
||||
function checkForUpdates () {
|
||||
Host.sendEvent({
|
||||
name: 'CLIENT->MAIN::user-action',
|
||||
payload: { action: 'check-for-update' }
|
||||
})
|
||||
}
|
||||
|
||||
function openDownloadPage () {
|
||||
window.open('https://snosme.github.io/awakened-poe-trade/download')
|
||||
}
|
||||
|
||||
function quitAndInstall () {
|
||||
Host.sendEvent({
|
||||
name: 'CLIENT->MAIN::user-action',
|
||||
payload: { action: 'update-and-restart' }
|
||||
})
|
||||
}
|
||||
|
||||
function fmtTime (millis: number) {
|
||||
return DateTime.fromMillis(millis).toRelative({ style: 'long' }) ?? 'n/a'
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'About',
|
||||
inheritAttrs: false,
|
||||
setup () {
|
||||
const { t } = useI18n()
|
||||
|
||||
const info = computed(() => {
|
||||
const rawInfo = Host.updateInfo.value
|
||||
switch (rawInfo.state) {
|
||||
case 'initial':
|
||||
return { str1: t('updates.maybe_outdated'), str2: t('updates.never_checked'), action: checkForUpdates, actionText: t('updates.check_now') }
|
||||
case 'checking-for-update':
|
||||
return { str1: t('updates.checking'), str2: t('please_wait') }
|
||||
case 'update-not-available':
|
||||
return { str1: t('updates.latest'), str2: t('updates.last_checked', [fmtTime(rawInfo.checkedAt)]), action: checkForUpdates, actionText: t('updates.check_now') }
|
||||
case 'error':
|
||||
return { str1: t('updates.maybe_outdated'), str2: t('updates.error'), action: openDownloadPage, actionText: t('updates.downloads_page') }
|
||||
case 'update-downloaded':
|
||||
return { str1: t('updates.available', [rawInfo.version]), str2: t('updates.installed_on_exit'), action: quitAndInstall, actionText: t('updates.install_now') }
|
||||
case 'update-available':
|
||||
return (Host.isPortable.value || AppConfig().disableUpdateDownload)
|
||||
? { str1: t('updates.available', [rawInfo.version]), str2: (Host.isPortable.value) ? t('updates.download_manually') : t('updates.download_disabled'), action: openDownloadPage, actionText: t('updates.downloads_page') }
|
||||
: { str1: t('updates.available', [rawInfo.version]), str2: t('updates.downloading') }
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
t,
|
||||
info,
|
||||
version: Host.version
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<i18n>
|
||||
{
|
||||
"en": {
|
||||
"contact_in_discord": "Contact me on one of the PoE Discords,"
|
||||
},
|
||||
"ru": {
|
||||
"Version {0}": "Версия {0}",
|
||||
"Release notes": "Список изменений",
|
||||
"Report a bug on GitHub": "Сообщить о баге на GitHub",
|
||||
"contact_in_discord": "Пишите мне в дискорде по PoE,"
|
||||
}
|
||||
}
|
||||
</i18n>
|
||||
Reference in New Issue
Block a user