add button to check for updates

This commit is contained in:
marlon-erler
2026-09-25 00:03:20 +02:00
parent 57da5681d3
commit 7cb816d9e3
8 changed files with 128 additions and 67 deletions
+42 -9
View File
@@ -377,7 +377,8 @@
}, },
version: "Version", version: "Version",
language: "Language", language: "Language",
firstDayOfWeekLabel: "First day of week" firstDayOfWeekLabel: "First day of week",
checkUpdatesButton: "Check for updates"
}, },
connectionModal: { connectionModal: {
connectionModalHeadline: "Manage Connections", connectionModalHeadline: "Manage Connections",
@@ -623,7 +624,8 @@
}, },
version: "Version", version: "Version",
language: "Sprache", language: "Sprache",
firstDayOfWeekLabel: "Erster Wochentag" firstDayOfWeekLabel: "Erster Wochentag",
checkUpdatesButton: "Nach updates suchen"
}, },
connectionModal: { connectionModal: {
connectionModalHeadline: "Verbindungen verwalten", connectionModalHeadline: "Verbindungen verwalten",
@@ -851,7 +853,8 @@
}, },
version: "Versi\xF3n", version: "Versi\xF3n",
language: "Idioma", language: "Idioma",
firstDayOfWeekLabel: "Primer d\xEDa de la semana" firstDayOfWeekLabel: "Primer d\xEDa de la semana",
checkUpdatesButton: "Buscar actualizaciones"
}, },
connectionModal: { connectionModal: {
connectionModalHeadline: "Gestionar Conexiones", connectionModalHeadline: "Gestionar Conexiones",
@@ -1221,6 +1224,9 @@
event.preventDefault(); event.preventDefault();
}); });
canvas.addEventListener("mousedown", (event) => { canvas.addEventListener("mousedown", (event) => {
const target = event.target;
if (!target || !target.classList.contains("allow-drag-move")) return;
event.preventDefault();
initialZoom = data.value.zoom; initialZoom = data.value.zoom;
initialX = data.value.x; initialX = data.value.x;
initialY = data.value.y; initialY = data.value.y;
@@ -1233,6 +1239,7 @@
}); });
canvas.addEventListener("mousemove", (event) => { canvas.addEventListener("mousemove", (event) => {
if (!dragging) return; if (!dragging) return;
event.preventDefault();
apply(data.value.zoom, [ apply(data.value.zoom, [
initialX + (event.clientX - initialTouchX) / initialZoom, initialX + (event.clientX - initialTouchX) / initialZoom,
initialY + (event.clientY - initialTouchY) / initialZoom initialY + (event.clientY - initialTouchY) / initialZoom
@@ -1335,6 +1342,7 @@
this.noUpdateAvailable = createProxyState([this.latestVersion], () => { this.noUpdateAvailable = createProxyState([this.latestVersion], () => {
return this.latestVersion.value == "" || this.latestVersion.value == this.version.value; return this.latestVersion.value == "" || this.latestVersion.value == this.version.value;
}); });
this.updateText = new State("");
// CONTEXT // CONTEXT
this.contextStack = /* @__PURE__ */ new Map(); this.contextStack = /* @__PURE__ */ new Map();
this.closeContext = (contextId, fromHistoryEvent = false) => { this.closeContext = (contextId, fromHistoryEvent = false) => {
@@ -1393,12 +1401,13 @@
console.error(`Could not install service worker: ${error}`); console.error(`Could not install service worker: ${error}`);
} }
} }
};
this.checkUpdates = () => {
fetch("/version").then(async (response) => { fetch("/version").then(async (response) => {
this.version.value = await response.text(); this.version.value = await response.text();
}); });
fetch("/latestVersion").then(async (response) => { fetch("/latestVersion").then(async (response) => {
this.latestVersion.value = (await response.text()).replace("\n", ""); this.latestVersion.value = (await response.text()).replace("\n", "");
console.log("LATEST", this.latestVersion.value);
}); });
}; };
this.update = async () => { this.update = async () => {
@@ -1407,12 +1416,16 @@
window.location.reload(); window.location.reload();
}; };
this.translations = allTranslations[settingsModel2.language] || allTranslations.en; this.translations = allTranslations[settingsModel2.language] || allTranslations.en;
this.latestVersion.subscribe((latestVersion) => {
this.updateText.value = this.translations.homePage.updateButton(latestVersion);
});
document.body.addEventListener("keydown", this.handleKeyDown); document.body.addEventListener("keydown", this.handleKeyDown);
window.onpopstate = () => { window.onpopstate = () => {
if (!this.context) return; if (!this.context) return;
this.closeContext(this.context.contextId, true); this.closeContext(this.context.contextId, true);
}; };
this.configureServiceWorker(); this.configureServiceWorker();
this.checkUpdates();
this.noUpdateAvailable.subscribe(() => { this.noUpdateAvailable.subscribe(() => {
console.log(this.noUpdateAvailable.value, this.latestVersion.value, this.version.value); console.log(this.noUpdateAvailable.value, this.latestVersion.value, this.version.value);
}); });
@@ -5045,7 +5058,6 @@
// src/View/homePage.tsx // src/View/homePage.tsx
function HomePage(coreViewModel2, storageViewModel2, settingsViewModel2, connectionViewModel2, fileTransferViewModel2, chatListViewModel2) { function HomePage(coreViewModel2, storageViewModel2, settingsViewModel2, connectionViewModel2, fileTransferViewModel2, chatListViewModel2) {
const updateText = createProxyState([coreViewModel2.latestVersion], () => coreViewModel2.translations.homePage.updateButton(coreViewModel2.latestVersion.value));
const overviewSection = /* @__PURE__ */ createElement("div", { id: "overview-section" }, /* @__PURE__ */ createElement("h2", null, coreViewModel2.translations.homePage.overviewHeadline), /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "cell_tower"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, coreViewModel2.translations.homePage.serverAddress), /* @__PURE__ */ createElement( const overviewSection = /* @__PURE__ */ createElement("div", { id: "overview-section" }, /* @__PURE__ */ createElement("h2", null, coreViewModel2.translations.homePage.overviewHeadline), /* @__PURE__ */ createElement("label", { class: "tile flex-no" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "cell_tower"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, coreViewModel2.translations.homePage.serverAddress), /* @__PURE__ */ createElement(
"input", "input",
{ {
@@ -5130,7 +5142,7 @@
/* @__PURE__ */ createElement( /* @__PURE__ */ createElement(
"span", "span",
{ {
"subscribe:innerText": updateText "subscribe:innerText": coreViewModel2.updateText
} }
), ),
/* @__PURE__ */ createElement("span", { class: "icon" }, "update") /* @__PURE__ */ createElement("span", { class: "icon" }, "update")
@@ -5473,7 +5485,7 @@
taskViewModels, taskViewModels,
categoryName categoryName
); );
const view = /* @__PURE__ */ createElement("div", { class: "flex-row flex-no large-gap" }, /* @__PURE__ */ createElement("div", { class: "property-input-wrapper" }, /* @__PURE__ */ createElement( const view = /* @__PURE__ */ createElement("div", { class: "flex-row flex-no large-gap" }, /* @__PURE__ */ createElement("div", { class: "property-input-wrapper allow-drag-move" }, /* @__PURE__ */ createElement(
"input", "input",
{ {
placeholder: coreViewModel2.translations.chatPage.task.renameCategoryInputPlaceholder, placeholder: coreViewModel2.translations.chatPage.task.renameCategoryInputPlaceholder,
@@ -5552,7 +5564,7 @@
return /* @__PURE__ */ createElement( return /* @__PURE__ */ createElement(
"div", "div",
{ {
class: "kanban-board-wrapper zoom", class: "kanban-board-wrapper zoom allow-drag-move",
"children:append": [categories, categoryNameConverter] "children:append": [categories, categoryNameConverter]
} }
); );
@@ -5981,7 +5993,7 @@
} }
}) })
); );
const wrapper = /* @__PURE__ */ createElement("div", { class: "content main-content", "children:set": pages }); const wrapper = /* @__PURE__ */ createElement("div", { class: "content main-content allow-drag-move", "children:set": pages });
implementPinchZoom(wrapper, boardViewModel.pinchToZoomData); implementPinchZoom(wrapper, boardViewModel.pinchToZoomData);
const taskSettingsModal = createProxyState( const taskSettingsModal = createProxyState(
[boardViewModel.selectedTaskViewModel], [boardViewModel.selectedTaskViewModel],
@@ -7361,6 +7373,27 @@
"build", "build",
coreViewModel2.translations.settings.version, coreViewModel2.translations.settings.version,
settingsViewModel2.coreViewModel.version settingsViewModel2.coreViewModel.version
), /* @__PURE__ */ createElement(
"button",
{
class: "primary",
"on:click": coreViewModel2.update,
"toggle:hidden": coreViewModel2.noUpdateAvailable
},
/* @__PURE__ */ createElement(
"span",
{
"subscribe:innerText": coreViewModel2.updateText
}
),
/* @__PURE__ */ createElement("span", { class: "icon" }, "update")
), /* @__PURE__ */ createElement(
"button",
{
class: "standard",
"on:click": coreViewModel2.checkUpdates
},
coreViewModel2.translations.settings.checkUpdatesButton
))); )));
} }
function SettingsRegionalPane(coreViewModel2, settingsViewModel2) { function SettingsRegionalPane(coreViewModel2, settingsViewModel2) {
Vendored
+1 -1
View File
@@ -1,4 +1,4 @@
const VERSION = "2610 Beta 2" const VERSION = "2610 Beta 3"
function processUrl(event) { function processUrl(event) {
const url = event.request.url; const url = event.request.url;
+1 -1
View File
@@ -1 +1 @@
2610 Beta 2 2610 Beta 3
-1
View File
@@ -10,7 +10,6 @@ import { TaskCategoryBulkChangeViewModel } from "../../ViewModel/Utility/taskPro
import TaskViewModel from "../../ViewModel/Pages/taskViewModel"; import TaskViewModel from "../../ViewModel/Pages/taskViewModel";
import BoardViewModel from "../../ViewModel/Pages/boardViewModel"; import BoardViewModel from "../../ViewModel/Pages/boardViewModel";
import CoreViewModel from "../../ViewModel/Global/coreViewModel"; import CoreViewModel from "../../ViewModel/Global/coreViewModel";
import * as Utility from "../../Model/Utility/utility";
export function BoardKanbanPage( export function BoardKanbanPage(
coreViewModel: CoreViewModel, coreViewModel: CoreViewModel,
+68 -50
View File
@@ -124,8 +124,26 @@ function SettingsInfoPane(
coreViewModel.translations.settings.version, coreViewModel.translations.settings.version,
settingsViewModel.coreViewModel.version, settingsViewModel.coreViewModel.version,
)} )}
</div>
</div> <button
class="primary"
on:click={coreViewModel.update}
toggle:hidden={coreViewModel.noUpdateAvailable}
>
<span
subscribe:innerText={coreViewModel.updateText}
></span>
<span class="icon">update</span>
</button>
<button
class="standard"
on:click={coreViewModel.checkUpdates}
>
{coreViewModel.translations.settings.checkUpdatesButton}
</button>
</div>
</div>
); );
} }
@@ -134,30 +152,30 @@ function SettingsRegionalPane(
settingsViewModel: SettingsViewModel, settingsViewModel: SettingsViewModel,
) { ) {
return ( return (
<div class="slide-up"> <div class="slide-up">
<h2>{coreViewModel.translations.settings.pages.regional}</h2> <h2>{coreViewModel.translations.settings.pages.regional}</h2>
<hr></hr> <hr></hr>
<h3>{coreViewModel.translations.settings.language}</h3> <h3>{coreViewModel.translations.settings.language}</h3>
{OptionButtonList( {OptionButtonList(
new React.ListState<[string, string]>( new React.ListState<[string, string]>(
Object.values(Languages).map((x) => [languageNames[x], x]), Object.values(Languages).map((x) => [languageNames[x], x]),
), ),
settingsViewModel.language, settingsViewModel.language,
)} )}
<hr></hr> <hr></hr>
<h3>{coreViewModel.translations.settings.firstDayOfWeekLabel}</h3> <h3>{coreViewModel.translations.settings.firstDayOfWeekLabel}</h3>
{OptionButtonList( {OptionButtonList(
new React.ListState<[string, string]>( new React.ListState<[string, string]>(
coreViewModel.translations.regional.weekdays.full.map( coreViewModel.translations.regional.weekdays.full.map(
(x, i) => [x, i.toString()], (x, i) => [x, i.toString()],
), ),
), ),
settingsViewModel.firstDayOfWeek, settingsViewModel.firstDayOfWeek,
)} )}
</div> </div>
); );
} }
function SettingsAppearancePane( function SettingsAppearancePane(
@@ -165,30 +183,30 @@ function SettingsAppearancePane(
settingsViewModel: SettingsViewModel, settingsViewModel: SettingsViewModel,
) { ) {
return ( return (
<div class="slide-up"> <div class="slide-up">
<h2>{coreViewModel.translations.settings.pages.appearance}</h2> <h2>{coreViewModel.translations.settings.pages.appearance}</h2>
<hr></hr> <hr></hr>
{OptionButtonList( {OptionButtonList(
new React.ListState<[string, string]>([ new React.ListState<[string, string]>([
[ [
coreViewModel.translations.settings.themes.dynamic, coreViewModel.translations.settings.themes.dynamic,
ThemeSettings.Dynamic, ThemeSettings.Dynamic,
], ],
[ [
coreViewModel.translations.settings.themes.dark, coreViewModel.translations.settings.themes.dark,
ThemeSettings.Dark, ThemeSettings.Dark,
], ],
[ [
coreViewModel.translations.settings.themes.light, coreViewModel.translations.settings.themes.light,
ThemeSettings.Light, ThemeSettings.Light,
], ],
[ [
coreViewModel.translations.settings.themes.system, coreViewModel.translations.settings.themes.system,
ThemeSettings.System, ThemeSettings.System,
], ],
]), ]),
settingsViewModel.theme, settingsViewModel.theme,
)} )}
</div> </div>
); );
} }
+1 -3
View File
@@ -19,8 +19,6 @@ export function HomePage(
chatListViewModel: ChatListViewModel, chatListViewModel: ChatListViewModel,
) { ) {
// sections // sections
const updateText = React.createProxyState([coreViewModel.latestVersion], ()=>coreViewModel.translations.homePage.updateButton(coreViewModel.latestVersion.value));
const overviewSection = ( const overviewSection = (
<div id="overview-section"> <div id="overview-section">
<h2>{coreViewModel.translations.homePage.overviewHeadline}</h2> <h2>{coreViewModel.translations.homePage.overviewHeadline}</h2>
@@ -144,7 +142,7 @@ export function HomePage(
toggle:hidden={coreViewModel.noUpdateAvailable} toggle:hidden={coreViewModel.noUpdateAvailable}
> >
<span <span
subscribe:innerText={updateText} subscribe:innerText={coreViewModel.updateText}
></span> ></span>
<span class="icon">update</span> <span class="icon">update</span>
</button> </button>
+6
View File
@@ -104,6 +104,8 @@ const englishTranslations = {
language: "Language", language: "Language",
firstDayOfWeekLabel: "First day of week", firstDayOfWeekLabel: "First day of week",
checkUpdatesButton: "Check for updates",
}, },
connectionModal: { connectionModal: {
@@ -446,6 +448,8 @@ export const allTranslations: {
language: "Sprache", language: "Sprache",
firstDayOfWeekLabel: "Erster Wochentag", firstDayOfWeekLabel: "Erster Wochentag",
checkUpdatesButton: "Nach updates suchen",
}, },
connectionModal: { connectionModal: {
@@ -756,6 +760,8 @@ export const allTranslations: {
language: "Idioma", language: "Idioma",
firstDayOfWeekLabel: "Primer día de la semana", firstDayOfWeekLabel: "Primer día de la semana",
checkUpdatesButton: "Buscar actualizaciones",
}, },
connectionModal: { connectionModal: {
connectionModalHeadline: "Gestionar Conexiones", connectionModalHeadline: "Gestionar Conexiones",
+8 -1
View File
@@ -16,6 +16,7 @@ export default class CoreViewModel {
noUpdateAvailable: React.State<boolean> = React.createProxyState([this.latestVersion], () => { noUpdateAvailable: React.State<boolean> = React.createProxyState([this.latestVersion], () => {
return (this.latestVersion.value == "" || this.latestVersion.value == this.version.value) return (this.latestVersion.value == "" || this.latestVersion.value == this.version.value)
}) })
updateText: React.State<string> = new React.State("");
translations: Translations; translations: Translations;
@@ -107,13 +108,14 @@ export default class CoreViewModel {
console.error(`Could not install service worker: ${error}`); console.error(`Could not install service worker: ${error}`);
} }
} }
}
checkUpdates = (): void => {
fetch("/version").then(async response => { fetch("/version").then(async response => {
this.version.value = await response.text(); this.version.value = await response.text();
}); });
fetch("/latestVersion").then(async response => { fetch("/latestVersion").then(async response => {
this.latestVersion.value = (await response.text()).replace("\n", ""); this.latestVersion.value = (await response.text()).replace("\n", "");
console.log("LATEST", this.latestVersion.value);
}) })
} }
@@ -134,6 +136,10 @@ export default class CoreViewModel {
this.translations = this.translations =
allTranslations[settingsModel.language] || allTranslations.en; allTranslations[settingsModel.language] || allTranslations.en;
this.latestVersion.subscribe(latestVersion => {
this.updateText.value = this.translations.homePage.updateButton(latestVersion);
});
document.body.addEventListener("keydown", this.handleKeyDown); document.body.addEventListener("keydown", this.handleKeyDown);
window.onpopstate = () => { window.onpopstate = () => {
@@ -142,6 +148,7 @@ export default class CoreViewModel {
}; };
this.configureServiceWorker(); this.configureServiceWorker();
this.checkUpdates();
this.noUpdateAvailable.subscribe(() => { this.noUpdateAvailable.subscribe(() => {
console.log(this.noUpdateAvailable.value, this.latestVersion.value, this.version.value); console.log(this.noUpdateAvailable.value, this.latestVersion.value, this.version.value);
}) })