forked from Mirrors/gomuks
web/rightpanel: add button to track user devices
This commit is contained in:
parent
0fb9805c85
commit
6f3619f632
8 changed files with 47 additions and 2 deletions
|
@ -90,6 +90,14 @@ func (h *HiClient) handleJSONCommand(ctx context.Context, req *JSONCommand) (any
|
|||
return unmarshalAndCall(req.Data, func(params *getProfileParams) ([]id.RoomID, error) {
|
||||
return h.GetMutualRooms(ctx, params.UserID)
|
||||
})
|
||||
case "track_user_devices":
|
||||
return unmarshalAndCall(req.Data, func(params *getProfileParams) (*ProfileEncryptionInfo, error) {
|
||||
err := h.TrackUserDevices(ctx, params.UserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return h.GetProfileEncryptionInfo(ctx, params.UserID)
|
||||
})
|
||||
case "get_profile_encryption_info":
|
||||
return unmarshalAndCall(req.Data, func(params *getProfileParams) (*ProfileEncryptionInfo, error) {
|
||||
return h.GetProfileEncryptionInfo(ctx, params.UserID)
|
||||
|
|
|
@ -91,3 +91,8 @@ func (h *HiClient) GetProfileEncryptionInfo(ctx context.Context, userID id.UserI
|
|||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (h *HiClient) TrackUserDevices(ctx context.Context, userID id.UserID) error {
|
||||
_, err := h.Crypto.FetchKeys(ctx, []id.UserID{userID}, true)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -186,6 +186,10 @@ export default abstract class RPCClient {
|
|||
return this.request("get_profile_encryption_info", { user_id })
|
||||
}
|
||||
|
||||
trackUserDevices(user_id: UserID): Promise<ProfileEncryptionInfo> {
|
||||
return this.request("track_user_devices", { user_id })
|
||||
}
|
||||
|
||||
ensureGroupSessionShared(room_id: RoomID): Promise<boolean> {
|
||||
return this.request("ensure_group_session_shared", { room_id })
|
||||
}
|
||||
|
|
1
web/src/icons/devices-off.svg
Normal file
1
web/src/icons/devices-off.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><path d="m354-720-80-80h566v80H354Zm526 520-80-80v-280H640v126l-80-80v-86q0-17 11.5-28.5T600-640h240q17 0 28.5 11.5T880-600v400ZM792-56 688-160h-88q-17 0-28.5-11.5T560-200v-88L240-608v328h240v120H80v-120h80v-408L56-792l56-56 736 736-56 56Zm-72-301Z"/></svg>
|
After Width: | Height: | Size: 365 B |
1
web/src/icons/devices.svg
Normal file
1
web/src/icons/devices.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><path d="M80-160v-120h80v-440q0-33 23.5-56.5T240-800h600v80H240v440h240v120H80Zm520 0q-17 0-28.5-11.5T560-200v-400q0-17 11.5-28.5T600-640h240q17 0 28.5 11.5T880-600v400q0 17-11.5 28.5T840-160H600Zm40-120h160v-280H640v280Zm0 0h160-160Z"/></svg>
|
After Width: | Height: | Size: 351 B |
|
@ -135,6 +135,13 @@ div.right-panel-content.user {
|
|||
display: inline-block;
|
||||
}
|
||||
|
||||
button.action {
|
||||
padding: .5rem 1rem;
|
||||
width: 100%;
|
||||
gap: .25rem;
|
||||
justify-content: left;
|
||||
}
|
||||
|
||||
div.devices > details > ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
|
|
|
@ -73,7 +73,10 @@ const UserInfo = ({ userID }: UserInfoProps) => {
|
|||
</>}
|
||||
<DeviceList client={client} room={roomCtx?.store} userID={userID}/>
|
||||
<hr/>
|
||||
<UserInfoError errors={errors}/>
|
||||
{errors?.length ? <>
|
||||
<UserInfoError errors={errors}/>
|
||||
<hr/>
|
||||
</> : null}
|
||||
</>
|
||||
}
|
||||
|
||||
|
|
|
@ -13,12 +13,13 @@
|
|||
//
|
||||
// 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 { useEffect, useState } from "react"
|
||||
import { useCallback, useEffect, useState, useTransition } from "react"
|
||||
import { ScaleLoader } from "react-spinners"
|
||||
import Client from "@/api/client.ts"
|
||||
import { RoomStateStore } from "@/api/statestore"
|
||||
import { ProfileDevice, ProfileEncryptionInfo, TrustState, UserID } from "@/api/types"
|
||||
import UserInfoError from "./UserInfoError.tsx"
|
||||
import DevicesIcon from "@/icons/devices.svg?react"
|
||||
import EncryptedOffIcon from "@/icons/encrypted-off.svg?react"
|
||||
import EncryptedQuestionIcon from "@/icons/encrypted-question.svg?react"
|
||||
import EncryptedIcon from "@/icons/encrypted.svg?react"
|
||||
|
@ -32,6 +33,18 @@ interface DeviceListProps {
|
|||
const DeviceList = ({ client, room, userID }: DeviceListProps) => {
|
||||
const [view, setEncryptionInfo] = useState<ProfileEncryptionInfo | null>(null)
|
||||
const [errors, setErrors] = useState<string[] | null>(null)
|
||||
const [trackChangePending, startTransition] = useTransition()
|
||||
const doTrackDeviceList = useCallback(() => {
|
||||
startTransition(async () => {
|
||||
try {
|
||||
const resp = await client.rpc.trackUserDevices(userID)
|
||||
setEncryptionInfo(resp)
|
||||
setErrors(resp.errors)
|
||||
} catch (err) {
|
||||
setErrors([`${err}`])
|
||||
}
|
||||
})
|
||||
}, [client, userID])
|
||||
useEffect(() => {
|
||||
setEncryptionInfo(null)
|
||||
setErrors(null)
|
||||
|
@ -60,6 +73,9 @@ const DeviceList = ({ client, room, userID }: DeviceListProps) => {
|
|||
<h4>Security</h4>
|
||||
<p>{encryptionMessage}</p>
|
||||
<p>This user's device list is not being tracked.</p>
|
||||
<button className="action" onClick={doTrackDeviceList} disabled={trackChangePending}>
|
||||
<DevicesIcon /> Start tracking device list
|
||||
</button>
|
||||
<UserInfoError errors={errors}/>
|
||||
</div>
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue