From 6e4c20dd4c97fc8579587504475362bfeda96a25 Mon Sep 17 00:00:00 2001 From: xiange Date: Thu, 11 Apr 2024 21:55:25 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=A6=84=20refactor:=20refactor=20Home?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chili-builder/src/additionalModule.ts | 10 +- packages/chili-builder/src/appBuilder.ts | 2 +- packages/chili-core/src/ui/window.ts | 3 +- packages/chili-ui/src/editor.ts | 9 +- packages/chili-ui/src/home/home.module.css | 8 +- packages/chili-ui/src/home/home.ts | 254 ++++++++++-------- packages/chili-ui/src/mainWindow.ts | 17 +- 7 files changed, 180 insertions(+), 123 deletions(-) diff --git a/packages/chili-builder/src/additionalModule.ts b/packages/chili-builder/src/additionalModule.ts index 1147497f..69851837 100644 --- a/packages/chili-builder/src/additionalModule.ts +++ b/packages/chili-builder/src/additionalModule.ts @@ -3,12 +3,12 @@ import { CommandKeys, I18nKeys, Locale } from "chili-core"; export interface AdditionalCommand { - tabName: I18nKeys, - groupName: I18nKeys, - command: CommandKeys + tabName: I18nKeys; + groupName: I18nKeys; + command: CommandKeys; } export interface IAdditionalModule { i18n(): Locale[]; - commands(): AdditionalCommand[] -} \ No newline at end of file + ribbonCommands(): AdditionalCommand[]; +} diff --git a/packages/chili-builder/src/appBuilder.ts b/packages/chili-builder/src/appBuilder.ts index 8c4d1729..f9a2adbf 100644 --- a/packages/chili-builder/src/appBuilder.ts +++ b/packages/chili-builder/src/appBuilder.ts @@ -105,7 +105,7 @@ export class AppBuilder { I18n.combineTranslation(local.code as any, local.translation); }); if (this._window) { - module.commands().forEach((command) => { + module.ribbonCommands().forEach((command) => { this._window!.registerRibbonCommand(command.tabName, command.groupName, command.command); }); } diff --git a/packages/chili-core/src/ui/window.ts b/packages/chili-core/src/ui/window.ts index 966fe283..834cf245 100644 --- a/packages/chili-core/src/ui/window.ts +++ b/packages/chili-core/src/ui/window.ts @@ -7,5 +7,6 @@ import { Button } from "./button"; export interface IWindow { init(app: IApplication): void; + registerHomeCommand(groupName: I18nKeys, command: CommandKeys | Button): void; registerRibbonCommand(tabName: I18nKeys, groupName: I18nKeys, command: CommandKeys | Button): void; -} \ No newline at end of file +} diff --git a/packages/chili-ui/src/editor.ts b/packages/chili-ui/src/editor.ts index f9b91ded..61c52412 100644 --- a/packages/chili-ui/src/editor.ts +++ b/packages/chili-ui/src/editor.ts @@ -36,16 +36,17 @@ export class Editor extends HTMLElement { viewport, ), new Statusbar().addClass(style.statusbar), - ) - ) + ), + ); + document.body.appendChild(this); } registerRibbonCommand(tabName: I18nKeys, groupName: I18nKeys, command: CommandKeys | Button) { - this.ribbonContent.ribbonTabs.find((p) => p.tabName === tabName) + this.ribbonContent.ribbonTabs + .find((p) => p.tabName === tabName) ?.groups.find((p) => p.groupName === groupName) ?.items.push(command); } - } customElements.define("chili-editor", Editor); diff --git a/packages/chili-ui/src/home/home.module.css b/packages/chili-ui/src/home/home.module.css index 10bd45b9..f3d882e4 100644 --- a/packages/chili-ui/src/home/home.module.css +++ b/packages/chili-ui/src/home/home.module.css @@ -22,9 +22,15 @@ display: flex; flex-direction: column; - & button { + .buttons { + display: flex; + flex-direction: column; + } + + .button { display: inline-block; height: 48px; + width: auto; font-size: 16px; margin: 8px 32px; padding: 0px 32px; diff --git a/packages/chili-ui/src/home/home.ts b/packages/chili-ui/src/home/home.ts index e658b8b5..3c30f874 100644 --- a/packages/chili-ui/src/home/home.ts +++ b/packages/chili-ui/src/home/home.ts @@ -1,123 +1,165 @@ // Copyright 2022-2023 the Chili authors. All rights reserved. AGPL-3.0 license. -import { Constants, I18n, IApplication, ObservableCollection, PubSub, RecentDocumentDTO } from "chili-core"; +import { + Constants, + I18n, + I18nKeys, + IApplication, + ObservableCollection, + PubSub, + RecentDocumentDTO, +} from "chili-core"; import { LanguageSelector } from "../components"; import { a, button, div, img, items, label, localize, span, svg } from "../controls"; import style from "./home.module.css"; -function hasOpen(app: IApplication, documentId: string) { - for (const document of app.documents) { - if (document.id === documentId) return true; - } - return false; +interface ApplicationCommand { + display: I18nKeys; + icon?: string; + onclick: () => void; } -export const Home = async (app: IApplication) => { - let documentArray: RecentDocumentDTO[] = await app.storage.page( - Constants.DBName, - Constants.RecentTable, - 0, - ); - let documents = new ObservableCollection(...documentArray); - return div( - { className: style.root }, - div( - { className: style.left }, +const applicationCommands = new ObservableCollection( + { + display: "command.document.new", + onclick: () => PubSub.default.pub("executeCommand", "doc.new"), + }, + { + display: "command.document.open", + onclick: () => PubSub.default.pub("executeCommand", "doc.open"), + }, +); + +export class Home extends HTMLElement { + constructor(readonly app: IApplication) { + super(); + this.className = style.root; + } + + private hasOpen(documentId: string) { + for (const document of this.app.documents) { + if (document.id === documentId) return true; + } + return false; + } + + private async getDocuments() { + let documentArray: RecentDocumentDTO[] = await this.app.storage.page( + Constants.DBName, + Constants.RecentTable, + 0, + ); + return new ObservableCollection(...documentArray); + } + + async render() { + let documents = await this.getDocuments(); + this.append( div( - { className: style.top }, + { className: style.left }, div( - { className: style.logo }, - svg({ icon: "icon-chili" }), - span({ - textContent: "CHILI3D", + { className: style.top }, + div( + { className: style.logo }, + svg({ icon: "icon-chili" }), + span({ + textContent: "CHILI3D", + }), + ), + items({ + className: style.buttons, + sources: applicationCommands, + template: (item) => + button({ + className: style.button, + textContent: localize(item.display), + onclick: item.onclick, + }), + }), + this.app.activeView?.document + ? button({ + className: `${style.button} ${style.back}`, + textContent: localize("common.back"), + onclick: () => { + PubSub.default.pub("displayHome", false); + }, + }) + : "", + ), + div( + { className: style.bottom }, + a({ + textContent: "Github", + href: "https://github.com/xiangechen/chili3d", + target: "_blank", }), ), - button({ - textContent: localize("command.document.new"), - onclick: () => PubSub.default.pub("executeCommand", "doc.new"), - }), - button({ - textContent: localize("command.document.open"), - onclick: () => PubSub.default.pub("executeCommand", "doc.open"), - }), - app.activeView?.document - ? button({ - className: style.back, - textContent: localize("common.back"), - onclick: () => { - PubSub.default.pub("displayHome", false); - }, - }) - : "", ), div( - { className: style.bottom }, - a({ - textContent: "Github", - href: "https://github.com/xiangechen/chili3d", - target: "_blank", - }), - ), - ), - div( - { className: style.right }, - label({ className: style.welcome, textContent: localize("home.welcome") }), - div({ className: style.recent, textContent: localize("home.recent") }), - items({ - className: style.documents, - sources: documents, - template: (item) => - div( - { - className: style.document, - onclick: () => { - if (hasOpen(app, item.id)) { - PubSub.default.pub("displayHome", false); - } else { - PubSub.default.pub( - "showPermanent", - async () => { - let document = await app.openDocument(item.id); - document?.application.activeView?.cameraController.fitContent(); - }, - "toast.excuting{0}", - I18n.translate("command.document.open"), - ); - } - }, - }, - img({ className: style.img, src: item.image }), + { className: style.right }, + label({ className: style.welcome, textContent: localize("home.welcome") }), + div({ className: style.recent, textContent: localize("home.recent") }), + items({ + className: style.documents, + sources: documents, + template: (item) => div( - { className: style.description }, - span({ className: style.title, textContent: item.name }), - span({ - className: style.date, - textContent: new Date(item.date).toLocaleDateString(), + { + className: style.document, + onclick: () => { + if (this.hasOpen(item.id)) { + PubSub.default.pub("displayHome", false); + } else { + PubSub.default.pub( + "showPermanent", + async () => { + let document = await this.app.openDocument(item.id); + document?.application.activeView?.cameraController.fitContent(); + }, + "toast.excuting{0}", + I18n.translate("command.document.open"), + ); + } + }, + }, + img({ className: style.img, src: item.image }), + div( + { className: style.description }, + span({ className: style.title, textContent: item.name }), + span({ + className: style.date, + textContent: new Date(item.date).toLocaleDateString(), + }), + ), + svg({ + className: style.delete, + icon: "icon-times", + onclick: async (e) => { + e.stopPropagation(); + if ( + window.confirm(I18n.translate("prompt.deleteDocument{0}", item.name)) + ) { + await this.app.storage.delete( + Constants.DBName, + Constants.DocumentTable, + item.id, + ); + await this.app.storage.delete( + Constants.DBName, + Constants.RecentTable, + item.id, + ); + documents.remove(item); + } + }, }), ), - svg({ - className: style.delete, - icon: "icon-times", - onclick: async (e) => { - e.stopPropagation(); - if (window.confirm(I18n.translate("prompt.deleteDocument{0}", item.name))) { - await app.storage.delete( - Constants.DBName, - Constants.DocumentTable, - item.id, - ); - await app.storage.delete( - Constants.DBName, - Constants.RecentTable, - item.id, - ); - documents.remove(item); - } - }, - }), - ), - }), - ), - LanguageSelector({ className: style.language }), - ); -}; + }), + ), + LanguageSelector({ className: style.language }), + ); + document.body.appendChild(this); + } +} + +customElements.define("chili-home", Home); diff --git a/packages/chili-ui/src/mainWindow.ts b/packages/chili-ui/src/mainWindow.ts index c16e2384..23256444 100644 --- a/packages/chili-ui/src/mainWindow.ts +++ b/packages/chili-ui/src/mainWindow.ts @@ -11,7 +11,7 @@ document.oncontextmenu = (e) => e.preventDefault(); export class MainWindow implements IWindow { private _inited: boolean = false; - private _home?: HTMLElement; + private _home?: Home; private _editor?: Editor; constructor() { @@ -25,6 +25,10 @@ export class MainWindow implements IWindow { this._inited = true; this._initHome(app); this._initEditor(app); + this._initSubs(app); + } + + private _initSubs(app: IApplication) { const displayHome = debounce(this.displayHome, 100); PubSub.default.sub("showToast", Toast.show); PubSub.default.sub("showDialog", Dialog.show); @@ -44,17 +48,20 @@ export class MainWindow implements IWindow { }; private async _initHome(app: IApplication) { - this._home = await Home(app); - document.body.append(this._home); + this._home = new Home(app); + await this._home.render(); } private async _initEditor(app: IApplication) { this._editor = new Editor(app); - document.body.append(this._editor); + } + + registerHomeCommand(groupName: I18nKeys, command: CommandKeys | Button): void { + throw new Error("Method not implemented."); } registerRibbonCommand(tabName: I18nKeys, groupName: I18nKeys, command: CommandKeys | Button) { - this._editor?.registerRibbonCommand(tabName, groupName, command) + this._editor?.registerRibbonCommand(tabName, groupName, command); } setTheme(theme: "light" | "dark") {