From 20075264123a75980f525913b58e2432c502e42e Mon Sep 17 00:00:00 2001 From: Anatoly Wein Date: Mon, 31 Aug 2026 13:00:43 +0200 Subject: [PATCH 1/7] create working t-anchor component --- torii-client/.prettierrc | 3 +- torii-client/src/main.ts | 6 ++ .../{views => plugins}/RecentProjectsView.vue | 0 torii-client/src/plugins/TAnchor.vue | 87 +++++++++++++++++++ torii-client/src/plugins/core.ts | 34 ++++++++ torii-client/src/plugins/loader.ts | 51 +++++++++++ .../src/plugins/recent-projects-plugin.ts | 19 ++++ torii-client/src/views/HomeView.vue | 4 +- 8 files changed, 201 insertions(+), 3 deletions(-) rename torii-client/src/{views => plugins}/RecentProjectsView.vue (100%) create mode 100644 torii-client/src/plugins/TAnchor.vue create mode 100644 torii-client/src/plugins/core.ts create mode 100644 torii-client/src/plugins/loader.ts create mode 100644 torii-client/src/plugins/recent-projects-plugin.ts diff --git a/torii-client/.prettierrc b/torii-client/.prettierrc index a24df35..0caaec8 100644 --- a/torii-client/.prettierrc +++ b/torii-client/.prettierrc @@ -2,5 +2,6 @@ "semi": true, "tabWidth": 4, "singleQuote": true, - "endOfLine": "auto" + "endOfLine": "auto", + "printWidth": 120 } \ No newline at end of file diff --git a/torii-client/src/main.ts b/torii-client/src/main.ts index 2363361..8f598cb 100644 --- a/torii-client/src/main.ts +++ b/torii-client/src/main.ts @@ -34,3 +34,9 @@ mainWindow.listen('tauri://close-requested', async (_event) => { import '@/styles/global.scss'; createApp(App).use(router).use(pinia).use(i18n).mount('#app'); + +// TODO: design better plugin loaders +import { usePlugins } from './plugins/loader.ts'; +import { RecentProjectsPlugin } from './plugins/recent-projects-plugin.ts'; +const pluginManager = usePlugins(); +pluginManager.install(new RecentProjectsPlugin()) diff --git a/torii-client/src/views/RecentProjectsView.vue b/torii-client/src/plugins/RecentProjectsView.vue similarity index 100% rename from torii-client/src/views/RecentProjectsView.vue rename to torii-client/src/plugins/RecentProjectsView.vue diff --git a/torii-client/src/plugins/TAnchor.vue b/torii-client/src/plugins/TAnchor.vue new file mode 100644 index 0000000..14618e0 --- /dev/null +++ b/torii-client/src/plugins/TAnchor.vue @@ -0,0 +1,87 @@ + + + + + diff --git a/torii-client/src/plugins/core.ts b/torii-client/src/plugins/core.ts new file mode 100644 index 0000000..c03b137 --- /dev/null +++ b/torii-client/src/plugins/core.ts @@ -0,0 +1,34 @@ +import type { Component } from 'vue'; + +/** + * @brief Torii plugin initialization settings + */ +export type ToriiPluginConfig = { + id: string; + version: string; +}; + +/** + * @brief A Torii plugin + */ +export default class ToriiPlugin { + public readonly id: string; + public readonly version: string; + + constructor(config: ToriiPluginConfig) { + this.id = config.id; + this.version = config.version; + } + + /** + * @brief This function is invoked by the internal `` element and renders + * content at specific anchor points. Plugins can append custom content to these + * predefined anchor points. + * + * @param anchorId The name of the anchor id. + */ + public renderAnchor(anchorId: string): Promise | Component | undefined { + void anchorId; // mark anchorId as used + return undefined; + } +} diff --git a/torii-client/src/plugins/loader.ts b/torii-client/src/plugins/loader.ts new file mode 100644 index 0000000..d1d1111 --- /dev/null +++ b/torii-client/src/plugins/loader.ts @@ -0,0 +1,51 @@ +import { readonly, ref } from 'vue'; +import ToriiPlugin from './core'; + +/** + * @brief Singleton instance of the Torii plugin manager. + */ +let singleton: ToriiPluginManager | undefined; + +/** + * @brief The Torii plugin manager. + */ +class ToriiPluginManager { + #plugins: ToriiPlugin[] = []; + #pluginNames = ref([]); + + /** + * @brief Gets the reactive reference of installed plugins. This is immutable outside + * of the Torii plugin manager. + */ + public plugins() { + return readonly(this.#pluginNames); + } + + public install(p: ToriiPlugin) { + this.#plugins.push(p); + this.#pluginNames.value.push(p.id); + } + + public uninstall(pluginId: string) { + this.#plugins = this.#plugins.filter((p) => p.id !== pluginId); + this.#pluginNames.value = this.#pluginNames.value.filter( + (pid) => pid !== pluginId + ); + } + + public getPlugin(pluginId: string): ToriiPlugin | undefined { + return this.#plugins.find((p) => p.id === pluginId); + } +} + +/** + * @returns The singleton instance of the Torii plugin manager, lazily + * initializing it if is not yet set. + */ +export function usePlugins() { + if (!singleton) { + singleton = new ToriiPluginManager(); + } + + return singleton; +} diff --git a/torii-client/src/plugins/recent-projects-plugin.ts b/torii-client/src/plugins/recent-projects-plugin.ts new file mode 100644 index 0000000..4fb7b10 --- /dev/null +++ b/torii-client/src/plugins/recent-projects-plugin.ts @@ -0,0 +1,19 @@ +import ToriiPlugin from './core'; + +export class RecentProjectsPlugin extends ToriiPlugin { + constructor() { + super({ + id: 'core:recent-projects', + version: '0.1.0', + }); + } + + public override renderAnchor(anchorId: string) { + switch(anchorId) { + case 'welcome:sidebar:top': + return import('./RecentProjectsView.vue'); + default: + return; + } + } +} diff --git a/torii-client/src/views/HomeView.vue b/torii-client/src/views/HomeView.vue index 1b0fa57..335d99e 100644 --- a/torii-client/src/views/HomeView.vue +++ b/torii-client/src/views/HomeView.vue @@ -1,7 +1,7 @@ diff --git a/torii-client/src/views/HomeView.vue b/torii-client/src/views/HomeView.vue index 335d99e..3d6867b 100644 --- a/torii-client/src/views/HomeView.vue +++ b/torii-client/src/views/HomeView.vue @@ -1,7 +1,9 @@