/// TEMPORARY AI GENERATED FRONTEND \\\ /// NOT TO BE USED IN PRODUCTION \\\ import { Theme } from "theme.slint"; import { Screen, ServerItem, ChannelItem, MessageItem, MemberItem } from "types.slint"; import { LoginScreen } from "login.slint"; import { ServerRail } from "components/server-rail.slint"; import { ChannelList } from "components/channel-list.slint"; import { UserPanel } from "components/user-panel.slint"; import { ChatHeader } from "components/chat-header.slint"; import { MessageList } from "components/message-list.slint"; import { Composer } from "components/composer.slint"; import { MemberList } from "components/member-list.slint"; export { Screen, ServerItem, ChannelItem, MessageItem, MemberItem, ChannelKind, MessageKind, ReactionItem } from "types.slint"; export component MainWindow inherits Window { title: "Tofu"; min-width: 900px; min-height: 520px; preferred-width: 1280px; preferred-height: 800px; background: Theme.chat-bg; default-font-size: 15px; // ---- State pushed from Rust ------------------------------------------- in property screen: Screen.loading; in property login-error; in property login-busy; in-out property login-homeserver; in-out property login-username; in property me-name; in property me-id; in property me-initial; in property me-color: Theme.accent; in property <[ServerItem]> servers; in property home-unread; in property home-mentions; in property <[ChannelItem]> channels; in property <[MessageItem]> messages; in property <[MemberItem]> members; in property sidebar-title: "Direct Messages"; in property room-name; in property room-topic; in property room-is-dm; in property room-encrypted; in property room-open: false; in property room-nonce; in property loading-older; in property typing-text; in property toast; // ---- State owned by the UI -------------------------------------------- in-out property selected-server-id; // "" = Home in-out property selected-room-id; in-out property show-members: true; // Composer mode in-out property reply-to-id; in-out property reply-to-name; in-out property editing-id; in-out property composer-text; in-out property composer-text-nonce; in-out property composer-focus-nonce; // ---- Intents sent to Rust --------------------------------------------- callback login(string, string, string); callback logout(); callback select-server(string); callback select-room(string); callback send-message(string, string); // reply-to-id (may be ""), text callback edit-message(string, string); // event id, new text callback delete-message(string); callback toggle-reaction(string, string); callback load-older(); callback typing(); callback not-implemented(string); // feature name, for stubs if root.screen == Screen.loading: Rectangle { background: Theme.rail-bg; Text { text: "Tofu"; color: Theme.text-muted; font-size: 32px; font-weight: 700; horizontal-alignment: center; vertical-alignment: center; } } if root.screen == Screen.login: LoginScreen { error: root.login-error; busy: root.login-busy; homeserver <=> root.login-homeserver; username <=> root.login-username; submit(hs, user, pass) => { root.login(hs, user, pass); } } if root.screen == Screen.main: HorizontalLayout { // Left column: rail + channel list on top, "you" panel along the bottom. VerticalLayout { width: Theme.rail-width + Theme.sidebar-width; HorizontalLayout { ServerRail { servers: root.servers; selected-id: root.selected-server-id; home-unread: root.home-unread; home-mentions: root.home-mentions; select(id) => { root.selected-server-id = id; root.select-server(id); } add-server => { root.not-implemented("Create / join a space"); } } ChannelList { title: root.sidebar-title; is-home: root.selected-server-id == ""; channels: root.channels; selected-id: root.selected-room-id; select(id) => { root.selected-room-id = id; root.select-room(id); } open-server-menu => { root.not-implemented("Space settings"); } } } UserPanel { name: root.me-name; user-id: root.me-id; initial: root.me-initial; tint: root.me-color; logout => { root.logout(); } } } // Right: chat VerticalLayout { ChatHeader { room-name: root.room-name; topic: root.room-topic; is-dm: root.room-is-dm; encrypted: root.room-encrypted; show-members <=> root.show-members; open-threads => { root.not-implemented("Threads"); } open-pins => { root.not-implemented("Pinned messages"); } open-search => { root.not-implemented("Search"); } } HorizontalLayout { VerticalLayout { MessageList { messages: root.messages; room-name: root.room-name; loading-older: root.loading-older; room-nonce: root.room-nonce; reply(id, sender) => { root.editing-id = ""; root.reply-to-id = id; root.reply-to-name = sender; root.composer-focus-nonce += 1; } edit(id, body) => { root.reply-to-id = ""; root.editing-id = id; root.composer-text = body; root.composer-text-nonce += 1; } delete(id) => { root.delete-message(id); } react(id, key) => { root.toggle-reaction(id, key); } load-older => { root.load-older(); } } if root.room-open: Composer { text-to-set: root.composer-text; text-nonce: root.composer-text-nonce; focus-nonce: root.composer-focus-nonce; placeholder: root.room-is-dm ? "Message @\{root.room-name}" : "Message #\{root.room-name}"; banner: root.editing-id != "" ? "Editing message" : (root.reply-to-id != "" ? "Replying to \{root.reply-to-name}" : ""); editing: root.editing-id != ""; typing-text: root.typing-text; submit(text) => { if (root.editing-id != "") { root.edit-message(root.editing-id, text); } else { root.send-message(root.reply-to-id, text); } root.editing-id = ""; root.reply-to-id = ""; } cancel-banner => { root.editing-id = ""; root.reply-to-id = ""; root.composer-text = ""; root.composer-text-nonce += 1; } typing => { root.typing(); } attach => { root.not-implemented("File uploads"); } } } if root.show-members: MemberList { members: root.members; } } } } // Transient banner for errors and "coming soon" notices. if root.toast != "": Rectangle { width: min(480px, parent.width - 32px); height: 40px; x: (parent.width - self.width) / 2; y: parent.height - self.height - 96px; border-radius: 6px; background: Theme.popup-bg; border-width: 1px; border-color: Theme.divider; Text { x: 12px; width: parent.width - 24px; text: root.toast; color: Theme.text-normal; font-size: 14px; vertical-alignment: center; overflow: elide; } } }