From: Andrew Gundersen Date: Tue, 18 Jan 2022 22:58:56 +0000 (-0600) Subject: polish X-Git-Url: https://andrewgundersen.net/repos?a=commitdiff_plain;h=5d74c6764828c394e93d2db82e82f438d897f071;p=mime-chat polish --- diff --git a/src/audio.js b/src/audio.js index 3736ee9..a42043b 100644 --- a/src/audio.js +++ b/src/audio.js @@ -67,7 +67,7 @@ function stopRecording() setRecordingStatus(false); sendMessage({ - category: "audio/L16", + category: "audio", text: null, blob: encode(nodeAudio.utils.mergeChunks(chunks).buffer) }); diff --git a/src/io.js b/src/io.js index a269d49..435377e 100644 --- a/src/io.js +++ b/src/io.js @@ -56,25 +56,3 @@ ipcMain.on("message", (_e, message) => sendMessage(message)); exports.connectToPlatform = connectToPlatform; exports.sendMessage = sendMessage; exports.disconnectFromPlatform = disconnectFromPlatform; - - - -/* ------------- Test Messages------------- */ - - - -setTimeout(() => { - - // sendMessage({ - // category: "text/plain", - // text: "show contacts", - // blob: null - // }) - - sendMessage({ - category: "text/plain", - text: "add contact John Smith, john.smith97@gmail.com", - blob: null - }) - -}, 2000); diff --git a/src/main.js b/src/main.js index 841579e..f4b803a 100644 --- a/src/main.js +++ b/src/main.js @@ -8,6 +8,8 @@ const { createWin } = require("./window"); const { initAccount } = require("./account"); const { terminateAudio } = require("./audio"); +app.commandLine.appendSwitch("enable-transparent-visuals"); + // Assert a light theme nativeTheme.themeSource = "light"; @@ -20,7 +22,7 @@ app.on("ready", () => initAccount(); }); -// app.on("will-quit", terminateAudio); +app.on("will-quit", terminateAudio); // When user clicks app icon (re-open) app.on("activate", createWin); diff --git a/src/render/assets/connectLogo.svg b/src/render/assets/connectLogo.svg index 7a390a4..7adceea 100644 --- a/src/render/assets/connectLogo.svg +++ b/src/render/assets/connectLogo.svg @@ -1,14 +1,12 @@ - - - - - - - - - - + diff --git a/src/render/components/app.js b/src/render/components/app.js index 08909a6..ffc34f7 100644 --- a/src/render/components/app.js +++ b/src/render/components/app.js @@ -1,6 +1,7 @@ +import Login from "./login.js"; import Splash from "./splash.js"; +import Header from "./header.js"; import Messenger from "./messenger.js"; -import Login from "./login.js"; const account = Vue.ref(null); @@ -8,6 +9,7 @@ const App = { components: { Splash, + Header, Messenger, Login }, @@ -20,7 +22,7 @@ const App = template: `
- +
@@ -31,7 +33,6 @@ const App = } window.mainApi.on("set-account", (account_) => { - console.log("setting-account"); account.value = account_; }); diff --git a/src/render/components/bubble.js b/src/render/components/bubble.js index 16f7983..59e0417 100644 --- a/src/render/components/bubble.js +++ b/src/render/components/bubble.js @@ -1,6 +1,6 @@ const Bubble = { - props: ["category", "text", "blob", "modifier", "child"], + props: ["category", "text", "html", "blob", "modifier", "child"], setup(props) { @@ -9,7 +9,7 @@ const Bubble = } Vue.onMounted(() => { - document.getElementById("messenger").dispatchEvent(new CustomEvent('adjust-scroll')); + document.dispatchEvent(new CustomEvent("scroll")); }); return { getUrl }; @@ -18,13 +18,13 @@ const Bubble = template: `
-

{{ text }}

+

{{ text }}

-

{{ text }}

+

{{ text }}

-
+
- + {{ text }} diff --git a/src/render/components/context.js b/src/render/components/context.js index b6879ae..0c9e89c 100644 --- a/src/render/components/context.js +++ b/src/render/components/context.js @@ -20,15 +20,10 @@ const Context = template: ` -
- - - -
+ :src="'data:image/png;base64,' + avatar" + /> {{ context }} diff --git a/src/render/components/control/scroll.js b/src/render/components/control/scroll.js index 4666ea1..db0dd3b 100644 --- a/src/render/components/control/scroll.js +++ b/src/render/components/control/scroll.js @@ -7,13 +7,11 @@ const initScroll = (elementId) => { } const isBottom = () => { - if (el) { - return el.scrollHeight - el.clientHeight <= el.scrollTop + 1; - } + return el.scrollHeight - el.clientHeight <= el.scrollTop + 1; } const adjustScroll = () => { - if (el) { + if (isBottom()) { el.scrollTo({ top: el.scrollHeight - el.clientHeight, behavior: 'smooth' diff --git a/src/render/components/control/text.js b/src/render/components/control/text.js index 626746f..cc8fafd 100644 --- a/src/render/components/control/text.js +++ b/src/render/components/control/text.js @@ -35,7 +35,7 @@ function useText(elementId, left, typing) window.addEventListener("keydown", (e) => { - if (!show.value && !metaKeys.includes(e.key)) + if (!show.value && !metaKeys.includes(e.key) && !e.ctrlKey) { show.value = true; } @@ -47,7 +47,7 @@ function useText(elementId, left, typing) if (e.key === "Enter" && el.value) { window.mainApi.send("message", { - category: "text/plain", + category: "text", text: el.value, blob: null }); diff --git a/src/render/components/drop.js b/src/render/components/drop.js new file mode 100644 index 0000000..e677555 --- /dev/null +++ b/src/render/components/drop.js @@ -0,0 +1,19 @@ +const onDrop = async (e) => { + const file = e.dataTransfer.items[0].getAsFile(); + + const buffer = await file.arrayBuffer(); + const b64String = await window.mainApi.invoke("encode", buffer); + + let category = "file"; + if (file.type.startsWith("image/")) { + category = "image" + } + + window.mainApi.send("message", { + category: category, + text: file.name, + blob: b64String + }); +} + +export default onDrop; \ No newline at end of file diff --git a/src/render/components/message.js b/src/render/components/message.js index fd1b41c..23e28df 100644 --- a/src/render/components/message.js +++ b/src/render/components/message.js @@ -22,6 +22,7 @@ const Message = v-for="(c, index) in content" :category="c.category" :text="c.text" + :html="c.html" :blob="c.blob" :modifier="modifier" :child="calcChild(index, content.length)" diff --git a/src/render/components/messenger.js b/src/render/components/messenger.js index 668b505..3384d6d 100644 --- a/src/render/components/messenger.js +++ b/src/render/components/messenger.js @@ -1,4 +1,5 @@ -import initScroll from "./control/scroll.js"; +import onDrop from "./control/drop.js"; +import adjustScroll from "./control/scroll.js"; import WS from "./ws.js"; import Input from "./input.js"; @@ -17,62 +18,32 @@ const Messenger = { setup() { const person = Vue.ref(""); - const messages = Vue.ref([{ - modifier: "ai", - content: [{ - category: "text/html", - text: `
-

About HTML Parser

-

Return the text of the most recently opened start tag. This should not normally be needed for structured processing, but may be useful in dealing with HTML “as deployed” or for re-generating input with minimal changes (whitespace between attributes can be preserved, etc.).

-
`, - blob: null - }], - context: "Email from David Spade", - avatar: null, - id: 0 - }]); - - const onDrop = async (e) => { - const file = e.dataTransfer.items[0].getAsFile(); - - const buffer = await file.arrayBuffer(); - const b64String = await window.mainApi.invoke("encode", buffer); - - window.mainApi.send("message", { - category: file.type, - text: file.name, - blob: b64String - }); - } + const messages = Vue.ref([]); Vue.onMounted(() => { - window.mainApi.on("message", (message) => { - if (message.person) + window.mainApi.on("update", (update) => { + + if (update.name) { - person.value = message.person; - messages.value = message.messages; + person.value = update; } - else if (message.name) + else if (typeof update == Array) { - person.value = message; + messages.value.push(...update); } else if (message.content) { - messages.value.push(message); + messages.value.push(update); } - else + else if (update.new) { - messages.value[messages.value.length - 1].content.push(message); + messages.value.at(-1)[update.new] = update.val; } - }); - initScroll("messenger"); - window.mainApi.send("messenger"); - }); + }); - Vue.onUnmounted(() => { - messages.value = []; + window.mainApi.send("message", "win"); }); return { person, messages, onDrop }; diff --git a/src/render/components/settings.js b/src/render/components/settings.js index 68d69f2..8e4a0fc 100644 --- a/src/render/components/settings.js +++ b/src/render/components/settings.js @@ -4,15 +4,23 @@ const Settings = setup() { const active = Vue.ref(false); - window.addEventListener("keydown", (e) => { - console.log("toggle settings"); - }) + function hideSettings(e) { + if (e.key == "Escape") { + active.value = false; + window.removeEventListener("keydown", hideSettings); + } + } + + function showSettings() { + active.value = true; + window.addEventListener("keydown", hideSettings); + } const logout = async () => { await window.mainApi.send("logout"); } - return { active, logout }; + return { showSettings, active, logout }; }, template: ` @@ -22,7 +30,11 @@ const Settings = Logout -
` + + + ` } export default Settings; \ No newline at end of file diff --git a/src/render/main.css b/src/render/main.css index f25adda..57429e3 100644 --- a/src/render/main.css +++ b/src/render/main.css @@ -1,6 +1,7 @@ html, body { margin: 0; padding: 0; + background-color: rgba(235, 235, 235, 0.75); } /* The first word of the class is the component that it modifys. */ @@ -46,6 +47,7 @@ html, body { } .contacts img { + height: 30px; border-radius: 50%; } @@ -60,26 +62,10 @@ html, body { .contacts .email { font-family: SF Compact Display; - font-weight: bold; font-size: 12px; color: #898989; } -.mail { - padding: 12px; - margin: 0px; - background-color: #D6F2FF; - border-radius: inherit; -} - -.mail h4 { - margin-top: 0px; -} - -.mail p { - margin-bottom: 0px; -} - #header-menu { position: fixed; margin-left: 20px; @@ -251,6 +237,7 @@ html, body { content: ''; display: inline-block; position: absolute; + box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.15); } .ws-dot::before { @@ -493,13 +480,13 @@ html, body { } .bubble a { + display:inline-block; + text-decoration: none; border-radius: inherit; - font-family: "SF Compact Rounded"; background-color: #D9D9D9; font-weight: bold; - padding: 12px; + padding: 10px; color: #727272; - margin: 0px; } .context { @@ -522,18 +509,9 @@ html, body { } .context-avatar { - display: flex; - justify-content: center; - align-items: center; - width: 30px; - height: 30px; - background-color: white; - border-radius: 15px; margin-right: 5px; -} - -.context-avatar img { border-radius: 50%; + height: 30px; } /* ---------- shared between components ---------- */ diff --git a/src/render/preload.js b/src/render/preload.js index 9b50adf..e3c66f9 100644 --- a/src/render/preload.js +++ b/src/render/preload.js @@ -4,7 +4,7 @@ const { contextBridge, ipcRenderer } = require("electron"); const validFromMainChannels = [ "set-account", - "message", + "update", "ws-status", "record", "playback" @@ -16,7 +16,8 @@ const validToMain = [ "login", "logout", "encode", - "decode" + "decode", + "nav-bar" ] ipcRenderer.setMaxListeners(250); diff --git a/src/session.js b/src/session.js index 08ece17..b4433a4 100644 --- a/src/session.js +++ b/src/session.js @@ -5,21 +5,13 @@ const { backgroundMitt, ipcEmit } = require("./utils/emitter"); const { connectToPlatform, disconnectFromPlatform } = require("./io"); const { initAudio, terminateAudio, playback, streamState } = require("./audio"); -let ui; /* wait to receive ui from the platform */ - const messageQueue = []; let processContentId; -/* Possible messages: - * - New UI (set ui) - * - New message (add message to ui.messages) - * - New content (add content to existing message) - * - Update person - */ backgroundMitt.on("message", (message) => messageQueue.push(message)); -function handleMessageQueue() +function handleUpdateQueue() { if (!streamState.pb && !streamState.rec) { @@ -27,71 +19,32 @@ function handleMessageQueue() if (update) { - console.log("Handling UI Update:", update); - - if (update.person) - { - ui = update; - } - else if (update.name) - { - ui.person = update; - } - else if (update.content) + if (update.title) { - ui.messages.push(update); + new Notification(update).show(); } - else + else if (update.audio) { - ui.messages[ui.messages.length - 1].content.push(update); + playback(update); } - - ipcEmit("message", update); - - // notify(); + else { ipcEmit("update", update); } } } } - -function notify() -{ - const message = ui.messages[ui.messages.length - 1]; - - const content = message.content[message.content.length -1]; - - new Notification( - { - title: message.context, - body: content.text - } - ).show(); - - if (content.category == "audio/L16") playback(content.blob, message.id); -} - function launchSession(account) { connectToPlatform(account); - // initAudio(); + initAudio(); processContentId = setInterval(handleMessageQueue, 100); } function endSession() { clearInterval(processContentId); - // terminateAudio(); + terminateAudio(); disconnectFromPlatform(); - ui = null; } -ipcMain.on("messenger", () => { - if (ui) { - ipcEmit("message", ui); - } -}); - exports.launchSession = launchSession; exports.endSession = endSession; - -// ui.messages[ui.messages.findIndex(m => m.id === message.id)].content.push(message); diff --git a/src/window.js b/src/window.js index 77db4ea..45a45da 100644 --- a/src/window.js +++ b/src/window.js @@ -21,28 +21,11 @@ function updateWindowPosition() } -function createPreviewWin(_e, content) +function onNavBar(_e, cmd) { - console.log("Creating preview window"); - - const preview = new BrowserWindow({ - width: 500, - height: 300, - x: null, - y: null, - resizable: true, - frame: false, - webPreferences: { preload: path.join(__dirname, "/render/preload.js") } - }); - - preview.loadFile(path.join(__dirname, "preview.html")); - - preview.webContents.on("did-finish-load", () => { - preview.webContents.send("preview-init", content); - }); + cmd === "close" ? win.close() : win.minimize(); } - function createWin() { if (win) return; @@ -56,7 +39,6 @@ function createWin() x: pos.x, y: pos.y, resizable: true, - backgroundColor: "#EBEBEB", frame: false, minWidth: 350, minHeight: 500, @@ -92,6 +74,6 @@ function createWin() }); } -ipcMain.on("preview", createPreviewWin); +ipcMain.on("nav-bar", onNavBar); exports.createWin = createWin;