From 1eae7ee501d9428fbcb63b3f3095cac6e89ccebe Mon Sep 17 00:00:00 2001 From: alexa Date: Sat, 1 Jun 2024 16:35:22 +0200 Subject: [PATCH] work on ui, settings, sounds --- ui/actions.mjs | 12 ++++++++--- ui/api/Hooks.mjs | 9 +++++--- ui/api/LocalSetting.mjs | 16 ++++++++++++++ ui/base.css | 3 +++ ui/classes.css | 10 +++++++++ ui/components/channel.mjs | 1 + ui/components/common.mjs | 29 +++++++++++++++++-------- ui/components/layout.mjs | 1 + ui/components/pages/settings.mjs | 36 ++++++++++++++++++++++++------- ui/live/Notifier.mjs | 10 +++++++-- ui/sounds/bloom.mp3 | Bin 0 -> 49454 bytes ui/sounds/chord.mp3 | Bin 0 -> 49454 bytes ui/sounds/drop.mp3 | Bin 0 -> 49454 bytes ui/sounds/sky.mp3 | Bin 0 -> 49454 bytes 14 files changed, 102 insertions(+), 25 deletions(-) create mode 100644 ui/sounds/bloom.mp3 create mode 100644 ui/sounds/chord.mp3 create mode 100644 ui/sounds/drop.mp3 create mode 100644 ui/sounds/sky.mp3 diff --git a/ui/actions.mjs b/ui/actions.mjs index c7a00eb..6063520 100644 --- a/ui/actions.mjs +++ b/ui/actions.mjs @@ -18,20 +18,21 @@ export function toast(message, type = "info", timeout = 5) { }, timeout * 1000); } -export function notify(image, title, subtitle, message, timeout = 7) { +export function notify(image, title, subtitle, message, onclick = () => {}, timeout = 7) { const notification = create("div") .classes("card", "flex", "notification") .styles("animation-duration", `${timeout}s`) + .onclick(onclick) .children( create("img") .classes("notification-image") .src(image) .build(), create("div") - .classes("flex-v", "notification-content") + .classes("flex-v", "no-gap", "notification-content") .children( create("div") - .classes("notification-title") + .classes("notification-title", "bold") .text(title) .build(), create("div") @@ -111,4 +112,9 @@ export function toggleInstanceEnabled(instances, instance) { toast("Failed to toggle instance enabled", "negative"); } }); +} + +export function playSound(name) { + const audio = new Audio(`/sounds/${name}.mp3`); + audio.play(); } \ No newline at end of file diff --git a/ui/api/Hooks.mjs b/ui/api/Hooks.mjs index 271abd5..4cb5d8c 100644 --- a/ui/api/Hooks.mjs +++ b/ui/api/Hooks.mjs @@ -1,9 +1,9 @@ import {Api} from "./Api.mjs"; -import {toast} from "../actions.mjs"; +import {playSound, testImage, toast} from "../actions.mjs"; import {signal, store} from "https://fjs.targoninc.com/f.js"; import {Live} from "../live/Live.mjs"; import {Store} from "./Store.mjs"; -import {localNotificationsEnabled, systemNotificationsEnabled} from "./LocalSetting.mjs"; +import {currentSound, localNotificationsEnabled, soundEnabled, systemNotificationsEnabled} from "./LocalSetting.mjs"; import {Notifier} from "../live/Notifier.mjs"; export class Hooks { @@ -76,9 +76,12 @@ export function addMessage(channel, message) { if (systemNotificationsEnabled()) { new Notification(`New message from ${message.sender.displayname ?? message.sender.username}`, { body: message.text, - icon: message.sender.avatar, + icon: message.sender.avatar ?? testImage, }); } + if (soundEnabled()) { + playSound(currentSound()); + } } export function removeMessage(channel, messageId) { diff --git a/ui/api/LocalSetting.mjs b/ui/api/LocalSetting.mjs index d5a248a..fc8dee8 100644 --- a/ui/api/LocalSetting.mjs +++ b/ui/api/LocalSetting.mjs @@ -40,3 +40,19 @@ export function setSystemNotificationsEnabled(enabled) { } LocalSetting.set("systemNotifications", enabled); } + +export function soundEnabled() { + return LocalSetting.getBoolean("sound"); +} + +export function setSoundEnabled(enabled) { + LocalSetting.set("sound", enabled); +} + +export function currentSound() { + return LocalSetting.getString("currentSound"); +} + +export function setCurrentSound(sound) { + LocalSetting.set("currentSound", sound); +} diff --git a/ui/base.css b/ui/base.css index 252550e..5bdebda 100644 --- a/ui/base.css +++ b/ui/base.css @@ -10,6 +10,7 @@ --white: #efe9e7ff; --white-2: #e7ddda; --white-3: #ded2ce; + --white-4: #d6c9c5; --blue: #16bac5ff; --green: #6a994eff; --red: #bc4749ff; @@ -32,6 +33,7 @@ --bg: var(--white); --bg-2: var(--white-2); --bg-3: var(--white-3); + --bg-4: var(--white-4); --text: var(--black); --text-2: var(--black-2); --text-3: var(--black-3); @@ -51,6 +53,7 @@ --text: var(--white); --text-2: var(--white-2); --text-3: var(--white-3); + --text-4: var(--white-4); } } diff --git a/ui/classes.css b/ui/classes.css index 836a66c..481ca05 100644 --- a/ui/classes.css +++ b/ui/classes.css @@ -392,6 +392,12 @@ .notification { animation: fade-out var(--animation-time) forwards; + transition: transform var(--animation-time) ease; + cursor: pointer; +} + +.notification:hover { + transform: translateX(-3px); } @keyframes fade-out { @@ -419,4 +425,8 @@ .notification-title, .notification-subtitle, .notification-message { word-wrap: anywhere; +} + +.notification-message { + font-size: 0.8em; } \ No newline at end of file diff --git a/ui/components/channel.mjs b/ui/components/channel.mjs index c930bb3..87796a7 100644 --- a/ui/components/channel.mjs +++ b/ui/components/channel.mjs @@ -25,6 +25,7 @@ export class ChannelTemplates { .classes("flex-v", "no-gap") .children( create("span") + .classes("bold") .text(channel.name) .build(), create("span") diff --git a/ui/components/common.mjs b/ui/components/common.mjs index e4c9580..c0594f2 100644 --- a/ui/components/common.mjs +++ b/ui/components/common.mjs @@ -52,18 +52,29 @@ export class CommonTemplates { ).build(); } - static select(options, onchange) { + static select(label, options, value, onchange) { return create("div") - .classes("select") + .classes("flex", "align-center") .children( - create("select") - .onchange(onchange) + create("span") + .text(label) + .build(), + create("div") + .classes("select") .children( - ...options.map(option => { - return create("option") - .text(option) - .build(); - }) + create("select") + .onchange(onchange) + .children( + ...options.map(option => { + const selected = computedSignal(value, value => option.value === value); + + return create("option") + .text(option.text) + .value(option.value) + .selected(selected) + .build(); + }) + ).build() ).build() ).build(); } diff --git a/ui/components/layout.mjs b/ui/components/layout.mjs index 6e51a8b..befa09d 100644 --- a/ui/components/layout.mjs +++ b/ui/components/layout.mjs @@ -39,6 +39,7 @@ export class LayoutTemplates { .classes("flex-pane") .styles("min-width", minWidth) .styles("max-width", maxWidth) + .styles("width", maxWidth) .children(content) .id(id) .build(); diff --git a/ui/components/pages/settings.mjs b/ui/components/pages/settings.mjs index 8f76bb6..18bb36b 100644 --- a/ui/components/pages/settings.mjs +++ b/ui/components/pages/settings.mjs @@ -7,8 +7,9 @@ import {popup, removePopups, testImage, toast, toggleAllowlist, toggleInstanceEn import {PopupComponents} from "../popup.mjs"; import {Popups} from "../../api/Popups.mjs"; import { - localNotificationsEnabled, - setLocalNotificationsEnabled, setSystemNotificationsEnabled, + currentSound, + localNotificationsEnabled, setCurrentSound, + setLocalNotificationsEnabled, setSoundEnabled, setSystemNotificationsEnabled, soundEnabled, systemNotificationsEnabled } from "../../api/LocalSetting.mjs"; @@ -373,13 +374,27 @@ export class SettingsComponent { static settings() { const notifs_on = signal(localNotificationsEnabled()); + const notifs_color = computedSignal(notifs_on, on => on ? "var(--green)" : "var(--red)"); notifs_on.subscribe(v => { setLocalNotificationsEnabled(v ? "true" : "false"); }); const system_notifs_on = signal(systemNotificationsEnabled()); + const system_notifs_color = computedSignal(system_notifs_on, on => on ? "var(--green)" : "var(--red)"); system_notifs_on.subscribe(v => { setSystemNotificationsEnabled(v); }); + const notifText = computedSignal(notifs_on, on => on ? "Disable local notifications (in-window popups)" : "Enable local notifications (in-window popups)"); + const systemNotifText = computedSignal(system_notifs_on, on => on ? "Disable system notifications" : "Enable system notifications"); + const sound_on = signal(soundEnabled()); + sound_on.subscribe(v => { + setSoundEnabled(v); + }); + const sound_color = computedSignal(sound_on, on => on ? "var(--green)" : "var(--red)"); + const soundText = computedSignal(sound_on, on => on ? "Disable sound" : "Enable sound"); + const sound = signal(currentSound()); + sound.subscribe(v => { + setCurrentSound(v); + }); return create("div") .classes("flex-v", "card") @@ -390,12 +405,17 @@ export class SettingsComponent { create("div") .classes("flex-v") .children( - CommonTemplates.checkbox("notifications_check", "Enable local notifications (in-window popups)", notifs_on, (e) => { - notifs_on.value = e.target.checked; - }), - CommonTemplates.checkbox("system_notifications_check", "Enable system notifications (browser popups)", system_notifs_on, (e) => { - system_notifs_on.value = e.target.checked; - }), + CommonTemplates.circleToggle(notifText, notifs_color, () => { notifs_on.value = !notifs_on.value }), + CommonTemplates.circleToggle(systemNotifText, system_notifs_color, () => { system_notifs_on.value = !system_notifs_on.value }), + CommonTemplates.circleToggle(soundText, sound_color, () => { sound_on.value = !sound_on.value }), + CommonTemplates.select("New message sound", [ + { text: "Bloom", value: "bloom" }, + { text: "Chord", value: "chord" }, + { text: "Drop", value: "drop" }, + { text: "Sky", value: "sky" }, + ], sound, (e) => { + sound.value = e.target.value; + }) ).build(), ).build(); } diff --git a/ui/live/Notifier.mjs b/ui/live/Notifier.mjs index ffb2cc5..432943d 100644 --- a/ui/live/Notifier.mjs +++ b/ui/live/Notifier.mjs @@ -10,9 +10,15 @@ export class Notifier { return; } + const reference = channel.type === "dm" ? "DM" : channel.name; notify(message.sender.avatar ?? testImage, message.sender.displayname ?? message.sender.username, - "in " + channel.name, - truncate(message.text, 150)); + "in " + reference, + truncate(message.text, 150), + () => { + if (channelId !== Store.get('currentChannelId')) { + window.router.navigate(`/chat/${channelId}`); + } + }); } } \ No newline at end of file diff --git a/ui/sounds/bloom.mp3 b/ui/sounds/bloom.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..45e616edd7a033ac18ea2fa24fe39dcaaf5591f8 GIT binary patch literal 49454 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 GM&Lg#cP&c* literal 0 HcmV?d00001 diff --git a/ui/sounds/chord.mp3 b/ui/sounds/chord.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..dfe3dbb464d9963e62a268b549773e2ffcabfed0 GIT binary patch literal 49454 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 P823-H0wCLeB7y$}=F?ib literal 0 HcmV?d00001 diff --git a/ui/sounds/drop.mp3 b/ui/sounds/drop.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..ed0dea4b758dd58e7a124bc6f967b80c7761c24a GIT binary patch literal 49454 zcmeIz`%}$%9LMp`x6|dMgHAW!(l#fRazDgw5pxnbA)7Et*dnra&}J`)ak^+vN7P0( z8!4BSTT|n@yT+bFQ8rCWEX$7ElFMSJoh6L+%E zB?@5^*!_6G5{*s2@RWV~cZz92B@y2~GN_aD`@9!iV6!P9d7a3yk7&5#fBsy9%K4l} zx3sd>Eh=N!Ro`xoRn6=35_PAt@^mq^IeE*B^~U^_lb$yYv(z6R-6#u>>YBq*QF?Lv zNZomZxBh-$*^4}t^3sB45gC6msjg6;8LqHzK3{eyH*VCi13h&j#o#Pywny*oIMLHd zCxo5um_x@@sU=wGe3as#q!rq*F1Kt7W3(p6xsv9gR%>G^bJMoEx4Wd?9r9to+%axG zTD@|r{pXuBEf4RtYa&%&y)$rw!OgXJX0*I=P=@Z0nh)%qGd1Pj2c11l$>pWF27|?+ z$9$1drpYd_7vkAdr=9@{UAQbOlu}cws;}HjCBG|qeC^ZO*;(ynO89>9wAm&7-fu57 z3!Q&P_46e;W+8<1Z1Jm>(h!rEa%8XT@|>WqvfS^}ko=DaF9<#`KgjvA<5B(7ijJU2 z_k>vgg4p_!d6Uo9%qYwb+L~Nl+1Xjy8XuY-*m1>lBV~KLS$oK~T1at5Ay#B-oF&)L z6GEu%oDvFJ-1|pvu3VYVW)6Wml!Rl`;MsGb~a7r;qIJs zrztok$IfHbH^EDlzDbikr083!{wwr(UKRceGkbrsa-cXP4KOMvq>spYFd%u*(A}QV zTlA-Xu>O+&?#o)-0)uj#&y>|mb*j-jR&2XlC7C8BOn$h;A*8{ycV&aN^-UijNGEK1 zFHIGqM@!??Uk(Q63~^H=c28;^KXmEdqII>pg-0|CXA6x>p=<2r)p?a|EPMqO_XQ-vfzPQ42;j~xXjU&euP7^a^ z&6jJWh@ZVP*HxNBt|=VjrO4D~ce9OAGx_kMv58r}eeNz$4WHg!SMyZWOK6lY3_^Hs z9@6|IO}{Q8cHD9ER8cH3`Y@gTN-Mu#UU}`alF)1E35ynm`u+H(Z2$Mq zS&Q2(x^Hy9m@daRc=`^1HL_1Yt#|O)y1BM(^VZyZHobW3e}SN5bA;M8QHU;&Qc{!~ z0>?Xz8tpQ>Au96Mf|OXXc9ucd?=s2GZI>Oqv>AmPEHPDCURmDrke}U+2dB(qsd#Re>d#rx=5KGh{u_s`3%mCS7ce~6l+b>3_ir$t- z{m0Mo#4aPucBeEWE;`XotT$~+pg(CA8=GWfM8rgY`G)Jwup+-#4TdP#mu()+hlKM+xE1D}ds7J+Vd!pg2khcU}P$$LonTN&v-CLb&q^ zpg3MntWg3ejuOJ1R{+KFdSZxnf=0L4*4 zxbq62I9^YzQ35EA62hHV0LAfoVvQ0&ag-45yaFhW*Ar`$0E(l8aOV|3alD>bqXbYK zC4@V#0E*-F#2O`l;wT~9c?D1$uP4?h0Tf3G;m#|7;&?r=MhT!eN(gse0TjpUi8V?9 z#Zf}I^9rCiUQeu10w|6W!kt$D#qoM#jS@g{lo0N`0w|8x6Kj+Jilc;Z=M_M4yq;L2 z1W+6$ggdVQisSXf8YO_@C?VW=1yCHXC)Owd6h{f+&MSc8cs;R337|Mi2zOoq6vyj{ VHA(=*Q9`)$3ZOXBQ{crY@E4g&i>v?u literal 0 HcmV?d00001 diff --git a/ui/sounds/sky.mp3 b/ui/sounds/sky.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..c6f89fb3d6b72c29a967c0ff2308aec630dc6ed7 GIT binary patch literal 49454 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 literal 0 HcmV?d00001