mirror of
https://github.com/tulir/gomuks.git
synced 2025-04-20 10:33:41 -05:00
Bring code up to date with the latest gomuks
This commit is contained in:
parent
13a45b7722
commit
0d8a6bce23
3 changed files with 105 additions and 65 deletions
|
@ -17,7 +17,7 @@ import { use, useCallback, useEffect, useState } from "react"
|
|||
import { PuffLoader } from "react-spinners"
|
||||
import { getAvatarURL } from "@/api/media.ts"
|
||||
import { useRoomMember } from "@/api/statestore"
|
||||
import { MemberEventContent, UserID, UserProfile, Presence } from "@/api/types"
|
||||
import { MemberEventContent, UserID, UserProfile } from "@/api/types"
|
||||
import { getLocalpart } from "@/util/validation.ts"
|
||||
import ClientContext from "../ClientContext.ts"
|
||||
import { LightboxContext } from "../modal"
|
||||
|
@ -26,7 +26,6 @@ import UserExtendedProfile from "./UserExtendedProfile.tsx"
|
|||
import DeviceList from "./UserInfoDeviceList.tsx"
|
||||
import UserInfoError from "./UserInfoError.tsx"
|
||||
import MutualRooms from "./UserInfoMutualRooms.tsx"
|
||||
import { ErrorResponse } from "@/api/rpc.ts"
|
||||
import { UserPresence } from "./UserPresence.tsx"
|
||||
|
||||
interface UserInfoProps {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// gomuks - A Matrix client written in Go.
|
||||
// Copyright (C) 2024 Tulir Asokan
|
||||
// Copyright (C) 2025 Nexus Nicholson
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
|
@ -13,10 +13,10 @@
|
|||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
import { MouseEvent, useEffect, useState } from "react"
|
||||
import { UserID, Presence, RPCEvent } from "@/api/types"
|
||||
import { ErrorResponse } from "@/api/rpc.ts"
|
||||
import { FormEvent, MouseEvent, useEffect, useState } from "react"
|
||||
import Client from "@/api/client"
|
||||
import { ErrorResponse } from "@/api/rpc.ts"
|
||||
import { Presence, RPCEvent, UserID } from "@/api/types"
|
||||
|
||||
interface UserPresenceProps {
|
||||
client: Client,
|
||||
|
@ -28,9 +28,18 @@ interface EditUserPresenceProps {
|
|||
setter: (presence: Presence) => void
|
||||
}
|
||||
const PresenceEmojis = {
|
||||
"online": <svg className="presence-indicator presence-online" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><circle cx="16" cy="16" r="50" /></svg>,
|
||||
"offline": <svg className="presence-indicator presence-offline" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><circle cx="16" cy="16" r="50" /></svg>,
|
||||
"unavailable": <svg className="presence-indicator presence-unavailable" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><circle cx="16" cy="16" r="50" /></svg>,
|
||||
"online": <svg
|
||||
className="presence-indicator presence-online"
|
||||
viewBox="0 0 16 16"
|
||||
xmlns="http://www.w3.org/2000/svg"><circle cx="16" cy="16" r="50" /></svg>,
|
||||
"offline": <svg
|
||||
className="presence-indicator presence-offline"
|
||||
viewBox="0 0 16 16"
|
||||
xmlns="http://www.w3.org/2000/svg"><circle cx="16" cy="16" r="50" /></svg>,
|
||||
"unavailable": <svg
|
||||
className="presence-indicator presence-unavailable"
|
||||
viewBox="0 0 16 16"
|
||||
xmlns="http://www.w3.org/2000/svg"><circle cx="16" cy="16" r="50" /></svg>,
|
||||
}
|
||||
|
||||
export const UserPresence = ({ client, userID }: UserPresenceProps) => {
|
||||
|
@ -41,7 +50,7 @@ export const UserPresence = ({ client, userID }: UserPresenceProps) => {
|
|||
if (event.command === "update_presence" && event.data.user_id === userID) {
|
||||
setPresence({
|
||||
"presence": event.data.presence,
|
||||
"status_msg": event.data.status_msg || null
|
||||
"status_msg": event.data.status_msg || null,
|
||||
})
|
||||
}
|
||||
})
|
||||
|
@ -54,13 +63,13 @@ export const UserPresence = ({ client, userID }: UserPresenceProps) => {
|
|||
if (err instanceof ErrorResponse && err.message.startsWith("M_NOT_FOUND")) {
|
||||
setPresence(null)
|
||||
} else {
|
||||
errors?.length ? setErrors([...errors, `${err}`]) : setErrors([`${err}`])
|
||||
}
|
||||
setErrors([...errors||[], `${err}`])
|
||||
}
|
||||
},
|
||||
)
|
||||
}, [client, userID])
|
||||
|
||||
if(!presence) return null;
|
||||
if(!presence) {return null}
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -73,13 +82,16 @@ export const UserPresence = ({ client, userID }: UserPresenceProps) => {
|
|||
}
|
||||
|
||||
export const DisplayUserPresence = ({ presence }: { presence: Presence | null }) => {
|
||||
if(!presence) return null
|
||||
if(!presence) {return null}
|
||||
return (
|
||||
<>
|
||||
<div className="presence" title={presence.presence}>{PresenceEmojis[presence.presence]} {presence.presence}</div>
|
||||
<div className="presence" title={presence.presence}>{PresenceEmojis[presence.presence]} {presence.presence}
|
||||
</div>
|
||||
{
|
||||
presence.status_msg && (
|
||||
<div className="statusmessage" title={"Status message"}><blockquote>{presence.status_msg}</blockquote></div>
|
||||
<div className="statusmessage" title={"Status message"}>
|
||||
<blockquote>{presence.status_msg}</blockquote>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</>
|
||||
|
@ -93,30 +105,59 @@ export const EditUserPresence = ({ client, presence, setter }: EditUserPresenceP
|
|||
err => console.error(err),
|
||||
)
|
||||
}
|
||||
const createPresence = (status: "online" | "unavailable" | "offline") => {
|
||||
return { ...(presence || {}), "presence": status }
|
||||
}
|
||||
const clearStatusMessage = (e: MouseEvent<HTMLButtonElement>) => {
|
||||
let p = presence || {"presence": "offline"}
|
||||
const p = presence || { "presence": "offline" }
|
||||
if(p.status_msg) {
|
||||
delete p.status_msg
|
||||
}
|
||||
const textInputElement = e.currentTarget.parentElement?.querySelector("input[type=text]") as HTMLInputElement
|
||||
client.rpc.setPresence(p).then(
|
||||
() => {setter(p); if(textInputElement) textInputElement.value = ""},
|
||||
() => {setter(p); if(textInputElement) {textInputElement.value = ""}},
|
||||
err => console.error(err),
|
||||
)
|
||||
}
|
||||
const onFormSubmit = (e: FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault()
|
||||
const textInputElement = e.currentTarget[0] as HTMLInputElement
|
||||
const newPresence = { ...(presence || {}), "status_msg": textInputElement.value }
|
||||
client.rpc.setPresence(newPresence).then(
|
||||
() => {setter(newPresence); textInputElement.value = ""},
|
||||
err => console.error(err),
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<h4>Set presence</h4>
|
||||
<div className="presencesetter">
|
||||
<button title="Set presence to online" onClick={() => sendNewPresence({...(presence || {}), "presence": "online"})} type="button">{PresenceEmojis["online"]} Online</button>
|
||||
<button title="Set presence to unavailable" onClick={() => sendNewPresence({...(presence || {}), "presence": "unavailable"})} type="button">{PresenceEmojis["unavailable"]} Unavailable</button>
|
||||
<button title="Set presence to offline" onClick={() => sendNewPresence({...(presence || {}), "presence": "offline"})} type="button">{PresenceEmojis["offline"]} Offline</button>
|
||||
<button
|
||||
title="Set presence to online"
|
||||
onClick={() => sendNewPresence(createPresence("online"))}
|
||||
type="button">
|
||||
{PresenceEmojis["online"]} Online
|
||||
</button>
|
||||
<button
|
||||
title="Set presence to unavailable"
|
||||
onClick={() => sendNewPresence(createPresence("unavailable"))}
|
||||
type="button">
|
||||
{PresenceEmojis["unavailable"]} Unavailable
|
||||
</button>
|
||||
<button
|
||||
title="Set presence to offline"
|
||||
onClick={() => sendNewPresence(createPresence("offline"))}
|
||||
type="button">
|
||||
{PresenceEmojis["offline"]} Offline
|
||||
</button>
|
||||
</div>
|
||||
<p></p>
|
||||
<div className="statussetter">
|
||||
<form className={presence?.status_msg ? "canclear" : "cannotclear"} onSubmit={(e) => {e.preventDefault(); sendNewPresence({...(presence || {}), "status_msg": (e.currentTarget[0] as HTMLInputElement).value})}}>
|
||||
<form className={presence?.status_msg ? "canclear" : "cannotclear"} onSubmit={onFormSubmit}>
|
||||
<input type="text" placeholder="Status message" defaultValue={presence?.status_msg || ""}/>
|
||||
{presence?.status_msg && <button title="Clear status" type="button" onClick={(e) => clearStatusMessage(e)}>Clear</button>}
|
||||
{presence?.status_msg &&
|
||||
<button title="Clear status" type="button" onClick={clearStatusMessage}>Clear</button>}
|
||||
<button title="Set status message" type="submit">Set</button>
|
||||
</form>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Reference in a new issue