Skip to content

Commit

Permalink
Add Administrator Please leave the room function
Browse files Browse the repository at this point in the history
  • Loading branch information
xdzqyyds committed Dec 12, 2024
1 parent 0faada1 commit a247b5e
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 5 deletions.
2 changes: 2 additions & 0 deletions server/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ func NewApi(rdb *redis.Client, secret string, live777Url string, live777Token st
r.Patch("/login/offline", handle.UpdateUserList)
r.Post("/login/invite", handle.Invite)
r.Patch("/login/invitee", handle.GetInvitation)
r.Post("/login/remove", handle.RemoveStream)
r.Patch("/login/makeremove", handle.MakeRemove)
r.Post("/room/", handle.CreateRoom)
r.Get("/room/{roomId}", handle.ShowRoom)
//r.Patch("/room/{roomId}", handle.UpdateRoom)
Expand Down
53 changes: 53 additions & 0 deletions server/api/v1/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ type UpdateUserStatusRequest struct {
Status string `json:"status"`
}

type RemoveStreamRequest struct {
StreamId string `json:"streamId"`
}

type MakeRemoveRequest struct {
StreamId string `json:"streamId"`
}

func (h *Handler) Login(w http.ResponseWriter, r *http.Request) {
var loginReq LoginRequest

Expand Down Expand Up @@ -234,3 +242,48 @@ func (h *Handler) Signup(w http.ResponseWriter, r *http.Request) {
log.Printf("New user registered successfully: %s\n", signupReq.UserId)
render.JSON(w, r, LoginResponse{Success: true, Message: "Registration successful! You can now login."})
}

func (h *Handler) RemoveStream(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var req RemoveStreamRequest

if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid request", http.StatusBadRequest)
return
}

if err := h.rdb.SAdd(ctx, model.StreamRemovalKey, req.StreamId).Err(); err != nil {
http.Error(w, "Failed to add stream to removal set", http.StatusInternalServerError)
return
}

w.WriteHeader(http.StatusOK)
}

func (h *Handler) MakeRemove(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var req MakeRemoveRequest

if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid request", http.StatusBadRequest)
return
}

isMember, err := h.rdb.SIsMember(ctx, model.StreamRemovalKey, req.StreamId).Result()
if err != nil {
http.Error(w, "Failed to check stream removal set", http.StatusInternalServerError)
return
}

value := 0
if isMember {
value = 1
if err := h.rdb.SRem(ctx, model.StreamRemovalKey, req.StreamId).Err(); err != nil {
http.Error(w, "Failed to remove stream from set", http.StatusInternalServerError)
return
}
}

w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]int{"value": value})
}
1 change: 1 addition & 0 deletions server/model/redis.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const (
UserStorageKey = "user_storage"
UserOnlineStatusKey = "user_online_status"
InvitationKey = "invitation"
StreamRemovalKey = "stream_removal"
)

func ClearRedis(rdb *redis.Client) {
Expand Down
4 changes: 4 additions & 0 deletions webapp/components/join.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useAtom } from 'jotai'
import {
locationAtom,
meetingIdAtom,
adminAtom
} from '../store/atom'
import { getStorage, setStorage, delStorage, setStorageStream, setStorageMeeting } from '../lib/storage'
import { newRoom, newUser, setApiToken, setRoomId } from '../lib/api'
Expand All @@ -22,13 +23,15 @@ export const getLoginStatus = async () => {
export default function Join() {
const [loc, setLoc] = useAtom(locationAtom)
const [__, setAtomMeetingId] = useAtom(meetingIdAtom)
const [_, setAdmin] = useAtom(adminAtom)
const [tmpId, setTmpId] = useState<string>('')

const newMeeting = async () => {
await getLoginStatus()
const meetingId = (await newRoom()).roomId
enterMeeting(meetingId)
setRoomId(meetingId)
setAdmin(true)
}

const joinMeeting = async () => {
Expand All @@ -39,6 +42,7 @@ export default function Join() {
//})
enterMeeting(meetingId)
setRoomId(meetingId)
setAdmin(false)
}

const enterMeeting = (meetingId: string) => {
Expand Down
7 changes: 6 additions & 1 deletion webapp/components/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
import copy from 'copy-to-clipboard'
import SvgDone from './svg/done'
import SvgEnd from './svg/end'
import { getRoom, delStream, Stream } from '../lib/api'
import { getRoom, delStream, Stream, makeRemove } from '../lib/api'
import { getStorageStream } from '../lib/storage'

export default function Layout(props: { meetingId: string }) {
Expand All @@ -38,6 +38,11 @@ export default function Layout(props: { meetingId: string }) {
return map
}, {} as { [_: string]: Stream })
setRemoteUserStatus(r)

const result = await makeRemove(localStreamId)
if (result.value === 1) {
await callEnd()
}
}

const callEnd = async () => {
Expand Down
24 changes: 24 additions & 0 deletions webapp/components/player/detail.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
import { UserStatus } from '../../store/atom'
import { removeStream } from '../../lib/api'
import { useState } from 'react'
import { useAtom } from 'jotai'
import { adminAtom } from '../../store/atom'

export default function Detail(props: { streamId: string, connStatus: string, userStatus: UserStatus, restart: () => void }) {
const { streamId, connStatus, userStatus, restart } = props
const [isButtonDisabled, setIsButtonDisabled] = useState(false)
const [isAdmin] = useAtom(adminAtom)

const handleDelete = () => {
if (!isButtonDisabled) {
removeStream(streamId)
setIsButtonDisabled(true)
setTimeout(() => {
setIsButtonDisabled(false)
}, 5000)
}
}

return (
<details className="text-white mx-2 text-sm font-border" style={{ position: 'absolute' }}>
<summary className="text-center rounded-lg px-xs" style={{ backgroundColor: connStatus === 'connected' ? 'rgba(16, 185, 129, 0.6)' : 'rgba(244, 63, 94, 0.6)' }}>{userStatus.name}</summary>
Expand All @@ -21,6 +38,13 @@ export default function Detail(props: { streamId: string, connStatus: string, us
<center className="text-white flex flex-row justify-around">
<p className="rounded-xl p-2 b-1 hover:border-orange-300">{userStatus.state}</p>
<button className="btn-primary" onClick={restart}>restart</button>
{isAdmin && (
<button
className={`btn-primary bg-rose-600 hover:bg-rose-700 ${isButtonDisabled ? 'opacity-50 cursor-not-allowed' : ''}`}
onClick={handleDelete}
disabled={isButtonDisabled}
>delete</button>
)}
</center>
</details>
)
Expand Down
24 changes: 24 additions & 0 deletions webapp/lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,28 @@ async function signup(userId: string, password: string): Promise<{ success: bool
return response.json()
}

async function removeStream(streamId: string): Promise<void> {
await fetch('/login/remove', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ streamId }),
})
}

async function makeRemove(localStreamId: string): Promise<{ value: number }> {
return (await fetch('/login/makeremove', {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ streamId: localStreamId }),
})).json()
}

export {
setRoomId,
setApiToken,
Expand All @@ -223,6 +245,8 @@ export {
newStream,
setStream,
delStream,
removeStream,
makeRemove,

login,
getUserOnlineStatus,
Expand Down
9 changes: 5 additions & 4 deletions webapp/store/atom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,20 +53,21 @@ userPasswordAtom.debugLabel = 'userPasswordAtom'
const isLoggedInAtom = atom<boolean>(false)
isLoggedInAtom.debugLabel = 'isLoggedInAtom'

const adminAtom = atom<boolean>(false)
adminAtom.debugLabel = 'adminAtom'

export {
locationAtom,
presentationStreamAtom,

meetingIdAtom,
meetingJoinedAtom,
presentationStreamAtom,
enabledPresentationAtom,
deviceSpeakerAtom,
speakerStatusAtom,

settingsEnabledScreenAtom,

userIdAtom,
userPasswordAtom,
adminAtom,
isLoggedInAtom,
}

Expand Down

0 comments on commit a247b5e

Please sign in to comment.