(feat): add native notifications
(feat): add navbar profile popover (fix): chat input box click area to slim (qol): format
This commit is contained in:
parent
67b7926dab
commit
7ea3b32286
9 changed files with 131 additions and 59 deletions
|
|
@ -295,13 +295,15 @@ async function updateLocalParticipantAttributes(
|
|||
screenSharePreviewLength: attributes.screenSharePreview?.length ?? 0,
|
||||
});
|
||||
|
||||
await getRoom().localParticipant.setAttributes(attributes).catch((error) => {
|
||||
log(1, "call", "red", "Failed to update local participant attributes", {
|
||||
attributes: Object.keys(attributes),
|
||||
error,
|
||||
await getRoom()
|
||||
.localParticipant.setAttributes(attributes)
|
||||
.catch((error) => {
|
||||
log(1, "call", "red", "Failed to update local participant attributes", {
|
||||
attributes: Object.keys(attributes),
|
||||
error,
|
||||
});
|
||||
throw error;
|
||||
});
|
||||
throw error;
|
||||
});
|
||||
|
||||
log(2, "call", "purple", "Updated local participant attributes", {
|
||||
attributeKeys: Object.keys(attributes),
|
||||
|
|
@ -795,11 +797,13 @@ export async function connect(callId: string) {
|
|||
|
||||
syncAllRemoteTrackSubscriptions();
|
||||
|
||||
await getRoom().localParticipant.setMicrophoneEnabled(true).catch((error) => {
|
||||
log(1, "call", "red", "Failed to enable microphone", error);
|
||||
toast("error", "Failed to enable microphone.");
|
||||
throw error;
|
||||
});
|
||||
await getRoom()
|
||||
.localParticipant.setMicrophoneEnabled(true)
|
||||
.catch((error) => {
|
||||
log(1, "call", "red", "Failed to enable microphone", error);
|
||||
toast("error", "Failed to enable microphone.");
|
||||
throw error;
|
||||
});
|
||||
|
||||
syncParticipantState();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ export default function InputComponent({
|
|||
>
|
||||
<CardHeader className="relative p-0 flex flex-col">
|
||||
<Input
|
||||
className="w-full"
|
||||
paddingY="13px"
|
||||
paddingX="13px"
|
||||
placeholder="Send a message..."
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
"build": "tsc -p tsconfig.json --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tanstack/react-router": "^1.169.1",
|
||||
"@tauri-apps/api": "^2.11.0",
|
||||
"@tensamin/crypto": "workspace:*",
|
||||
"@tensamin/shared": "workspace:*",
|
||||
|
|
|
|||
|
|
@ -10,16 +10,17 @@ import { message as messageSchema } from "@tensamin/shared/data";
|
|||
import { Avatar, AvatarFallback, AvatarImage } from "@tensamin/ui";
|
||||
import { isTauri } from "@tauri-apps/api/core";
|
||||
import { useSession } from "@tensamin/storage/session";
|
||||
import { useNavigate } from "@tanstack/react-router";
|
||||
|
||||
export const context = createContext<contextType | undefined>(undefined);
|
||||
|
||||
function reduceDisplay(display: string) {
|
||||
const words = display.split(" ");
|
||||
if (words.length === 1) {
|
||||
return display.slice(0, 2).toUpperCase();
|
||||
} else {
|
||||
return words[0].charAt(0).toUpperCase() + words[1].charAt(0).toUpperCase();
|
||||
}
|
||||
async function requestNotificationPermission() {
|
||||
if (!("Notification" in window)) return false;
|
||||
|
||||
if (Notification.permission === "granted") return true;
|
||||
|
||||
const permission = await Notification.requestPermission();
|
||||
return permission === "granted";
|
||||
}
|
||||
|
||||
export default function Provider(props: { children: React.ReactNode }) {
|
||||
|
|
@ -29,6 +30,7 @@ export default function Provider(props: { children: React.ReactNode }) {
|
|||
const { decryptText, getSharedSecret } = useCrypto();
|
||||
const { addLiveMessage, userId } = useChat();
|
||||
const { moveUserIdToTop } = useSession();
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
return subscribePush(async (ttpMessage) => {
|
||||
|
|
@ -54,7 +56,7 @@ export default function Provider(props: { children: React.ReactNode }) {
|
|||
(await load("settings.read_confirmations")) &&
|
||||
userId === sender_id
|
||||
) {
|
||||
await send(
|
||||
void send(
|
||||
"message_state",
|
||||
{
|
||||
message_state: "read",
|
||||
|
|
@ -64,7 +66,7 @@ export default function Provider(props: { children: React.ReactNode }) {
|
|||
},
|
||||
);
|
||||
} else {
|
||||
await send(
|
||||
void send(
|
||||
"message_state",
|
||||
{
|
||||
message_state: "received",
|
||||
|
|
@ -92,18 +94,41 @@ export default function Provider(props: { children: React.ReactNode }) {
|
|||
if (isTauri()) {
|
||||
console.log("weewoo");
|
||||
} else {
|
||||
sonnerToast(user.display, {
|
||||
classNames: {
|
||||
content: "pl-4",
|
||||
},
|
||||
description: decryptedContent,
|
||||
icon: (
|
||||
<Avatar>
|
||||
<AvatarImage src={user.avatar} />
|
||||
<AvatarFallback>{reduceDisplay(user.display)}</AvatarFallback>
|
||||
</Avatar>
|
||||
),
|
||||
});
|
||||
const hasPermissions = await requestNotificationPermission();
|
||||
|
||||
if (hasPermissions) {
|
||||
const notification = new Notification(user.display, {
|
||||
body: decryptedContent,
|
||||
icon: user.avatar || user.display.slice(0, 2).toUpperCase(),
|
||||
badge: user.avatar || user.display.slice(0, 2).toUpperCase(),
|
||||
tag: `message-${user.user_id}`,
|
||||
silent: true,
|
||||
});
|
||||
|
||||
notification.onclick = () => {
|
||||
window.focus();
|
||||
navigate({
|
||||
to: `/chat?id=${user.user_id}`,
|
||||
});
|
||||
|
||||
notification.close();
|
||||
};
|
||||
} else {
|
||||
sonnerToast(user.display, {
|
||||
classNames: {
|
||||
content: "pl-4",
|
||||
},
|
||||
description: decryptedContent,
|
||||
icon: (
|
||||
<Avatar>
|
||||
<AvatarImage src={user.avatar} />
|
||||
<AvatarFallback>
|
||||
{user.display.slice(0, 2).toUpperCase()}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -117,6 +142,7 @@ export default function Provider(props: { children: React.ReactNode }) {
|
|||
userId,
|
||||
moveUserIdToTop,
|
||||
send,
|
||||
navigate,
|
||||
]);
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -257,7 +257,7 @@ export function Provider(props: {
|
|||
setErrorDescription(
|
||||
"You could try to restart your Iota, check for updates or check your network connection.",
|
||||
);
|
||||
})
|
||||
});
|
||||
}, [connected, subscribePush]);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue