state stuff in backend
This commit is contained in:
parent
728f2d67d0
commit
9350346b4c
|
|
@ -5,16 +5,11 @@
|
||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="8a64704d-5500-41a6-aa4c-e275933fc58c" name="Changes" comment="">
|
<list default="true" id="8a64704d-5500-41a6-aa4c-e275933fc58c" name="Changes" comment="">
|
||||||
<change afterPath="$PROJECT_DIR$/cmd/watchtogether/build.sh" afterDir="false" />
|
<change afterPath="$PROJECT_DIR$/internal/ws/state.go" afterDir="false" />
|
||||||
<change afterPath="$PROJECT_DIR$/../frontend/src/interfaces/SocketEvents.ts" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/cmd/watchtogether/main.go" beforeDir="false" afterPath="$PROJECT_DIR$/cmd/watchtogether/main.go" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/internal/ws/handlers.go" beforeDir="false" afterPath="$PROJECT_DIR$/internal/ws/handlers.go" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/internal/ws/handlers.go" beforeDir="false" afterPath="$PROJECT_DIR$/internal/ws/handlers.go" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/internal/ws/hub.go" beforeDir="false" afterPath="$PROJECT_DIR$/internal/ws/hub.go" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/internal/ws/hub.go" beforeDir="false" afterPath="$PROJECT_DIR$/internal/ws/hub.go" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/internal/ws/message.go" beforeDir="false" afterPath="$PROJECT_DIR$/internal/ws/message.go" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/../frontend/src/components/Container.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/src/components/Container.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/../frontend/src/components/Player.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/src/components/Player.tsx" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/../frontend/src/components/Player.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/src/components/Player.tsx" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/../frontend/src/interfaces/Identity.ts" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/src/interfaces/Identity.ts" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/../frontend/src/pages/player.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/src/pages/player.tsx" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/../frontend/src/pages/player.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/src/pages/player.tsx" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
|
|
|
||||||
|
|
@ -12,15 +12,19 @@ func handleIdentifyEvent(message *Message) {
|
||||||
if id, ok := d["clientID"]; ok {
|
if id, ok := d["clientID"]; ok {
|
||||||
log.Infof("Client %s has sent identify event", id.(string))
|
log.Infof("Client %s has sent identify event", id.(string))
|
||||||
}
|
}
|
||||||
|
user := d["user"].(map[string]interface{})
|
||||||
|
userId := user["id"].(string)
|
||||||
|
playhead := message.hub.State.playhead
|
||||||
|
|
||||||
m := Message{
|
m := Message{
|
||||||
MessageData: MessageData{
|
MessageData: MessageData{
|
||||||
Type: Identify,
|
Type: Identify,
|
||||||
Data: map[string]interface{}{
|
Data: map[string]interface{}{
|
||||||
"admin": true,
|
"admin": message.hub.State.IsAdmin(userId),
|
||||||
"playlist": "http://localhost:8081/BelleOpening.m3u8",
|
"playlist": "http://localhost:8081/BelleOpening.m3u8",
|
||||||
"controller": true,
|
"hasController": message.hub.State.IsController(userId),
|
||||||
"playhead": 0,
|
"playhead": playhead,
|
||||||
"user": d["user"],
|
"user": d["user"],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -54,6 +58,10 @@ func handleSetPlayhead(message *Message) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
log.Infof("Received SetPlayhead event. playhead is at %s", d["playhead"])
|
log.Infof("Received SetPlayhead event. playhead is at %s", d["playhead"])
|
||||||
|
err := message.hub.State.setPlayhead(d["playhead"].(float64))
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("unable to set playhead. %s", err)
|
||||||
|
}
|
||||||
for client := range message.Client.hub.Clients {
|
for client := range message.Client.hub.Clients {
|
||||||
if client == message.Client {
|
if client == message.Client {
|
||||||
continue
|
continue
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,9 @@ type Hub struct {
|
||||||
// Registered Clients
|
// Registered Clients
|
||||||
Clients map[*Client]bool
|
Clients map[*Client]bool
|
||||||
|
|
||||||
|
// State
|
||||||
|
State *State
|
||||||
|
|
||||||
// Inbound messages from the Clients
|
// Inbound messages from the Clients
|
||||||
broadcast chan RawMessage
|
broadcast chan RawMessage
|
||||||
|
|
||||||
|
|
@ -20,6 +23,7 @@ func NewHub() *Hub {
|
||||||
register: make(chan *Client),
|
register: make(chan *Client),
|
||||||
unregister: make(chan *Client),
|
unregister: make(chan *Client),
|
||||||
Clients: make(map[*Client]bool),
|
Clients: make(map[*Client]bool),
|
||||||
|
State: NewState(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
package ws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
type State struct {
|
||||||
|
sync.RWMutex
|
||||||
|
|
||||||
|
playhead float64
|
||||||
|
controllerUserId string
|
||||||
|
adminUserId string
|
||||||
|
paused bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewState() *State {
|
||||||
|
return &State{
|
||||||
|
playhead: 0,
|
||||||
|
controllerUserId: "218072060923084802",
|
||||||
|
adminUserId: "218072060923084802",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *State) setPlayhead(playhead float64) error {
|
||||||
|
if s == nil {
|
||||||
|
return errors.New("unable to find state")
|
||||||
|
}
|
||||||
|
s.Lock()
|
||||||
|
defer s.Lock()
|
||||||
|
s.playhead = playhead
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *State) IsController(userID string) bool {
|
||||||
|
if userID == s.controllerUserId {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
func (s *State) IsAdmin(userID string) bool {
|
||||||
|
if userID == s.adminUserId {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@ import { Box, css } from "@chakra-ui/react";
|
||||||
import React, { FC, useRef, useState } from "react";
|
import React, { FC, useRef, useState } from "react";
|
||||||
import ReactPlayer, { Config, ReactPlayerProps } from "react-player";
|
import ReactPlayer, { Config, ReactPlayerProps } from "react-player";
|
||||||
import { MessageTypes } from "../interfaces/IMessage";
|
import { MessageTypes } from "../interfaces/IMessage";
|
||||||
|
import SocketEvents from "../interfaces/SocketEvents";
|
||||||
import Message from "../util/Message";
|
import Message from "../util/Message";
|
||||||
import MessageUtil from "../util/MessageUtil";
|
import MessageUtil from "../util/MessageUtil";
|
||||||
import PlayerSocket from "../ws/websocket";
|
import PlayerSocket from "../ws/websocket";
|
||||||
|
|
@ -11,13 +12,6 @@ type PlayerProps = {
|
||||||
socket: PlayerSocket;
|
socket: PlayerSocket;
|
||||||
} & ReactPlayerProps;
|
} & ReactPlayerProps;
|
||||||
|
|
||||||
interface ProgressProps {
|
|
||||||
played: number;
|
|
||||||
playedSeconds: number;
|
|
||||||
loaded: number;
|
|
||||||
loadedSeconds: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Player: FC<PlayerProps> = (props) => {
|
const Player: FC<PlayerProps> = (props) => {
|
||||||
const playerRef = useRef<ReactPlayer>(null);
|
const playerRef = useRef<ReactPlayer>(null);
|
||||||
const [paused, setPaused] = useState<boolean>(false);
|
const [paused, setPaused] = useState<boolean>(false);
|
||||||
|
|
@ -27,21 +21,25 @@ const Player: FC<PlayerProps> = (props) => {
|
||||||
forceHLS: true,
|
forceHLS: true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const onProgress = (state: ProgressProps) => {
|
socket.emitter.on(SocketEvents.GetPlayhead, (e) => {
|
||||||
|
playerRef.current.seekTo(e.playhead);
|
||||||
|
});
|
||||||
|
const onSeek = (playedSeconds: number) => {
|
||||||
if (paused) {
|
if (paused) {
|
||||||
socket?.send(
|
socket?.send(
|
||||||
MessageUtil.encode(
|
MessageUtil.encode(
|
||||||
new Message(MessageTypes.SetPlayhead, {
|
new Message(MessageTypes.SetPlayhead, {
|
||||||
playhead: state.playedSeconds,
|
playhead: playedSeconds,
|
||||||
paused: true,
|
paused: true,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
socket?.send(
|
socket?.send(
|
||||||
MessageUtil.encode(
|
MessageUtil.encode(
|
||||||
new Message(MessageTypes.SetPlayhead, {
|
new Message(MessageTypes.SetPlayhead, {
|
||||||
playhead: state.playedSeconds,
|
playhead: playedSeconds,
|
||||||
paused: false,
|
paused: false,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
@ -79,7 +77,7 @@ const Player: FC<PlayerProps> = (props) => {
|
||||||
controls
|
controls
|
||||||
onPlay={onPlay}
|
onPlay={onPlay}
|
||||||
onPause={onPause}
|
onPause={onPause}
|
||||||
onProgress={onProgress}
|
onSeek={onSeek}
|
||||||
ref={playerRef}
|
ref={playerRef}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
enum SocketEvents {
|
enum SocketEvents {
|
||||||
Identify = "Identify",
|
Identify = "Identify",
|
||||||
|
GetPlayhead = "GetPlayhead",
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SocketEvents;
|
export default SocketEvents;
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,14 @@
|
||||||
import { Socket } from "dgram";
|
|
||||||
import { GetServerSideProps, NextPage } from "next";
|
import { GetServerSideProps, NextPage } from "next";
|
||||||
import { User } from "next-auth";
|
import { User } from "next-auth";
|
||||||
import { getSession } from "next-auth/react";
|
import { getSession } from "next-auth/react";
|
||||||
import dynamic from "next/dynamic";
|
import dynamic from "next/dynamic";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import React, { useRef, useState } from "react";
|
import React, { useState } from "react";
|
||||||
import ReactPlayer from "react-player";
|
|
||||||
import { BaseReactPlayerProps } from "react-player/base";
|
|
||||||
import { Container } from "../components/Container";
|
import { Container } from "../components/Container";
|
||||||
import useWS from "../hooks/useWS";
|
import useWS from "../hooks/useWS";
|
||||||
import IdentityData from "../interfaces/Identity";
|
import IdentityData from "../interfaces/Identity";
|
||||||
import { MessageTypes } from "../interfaces/IMessage";
|
|
||||||
import SocketEvents from "../interfaces/SocketEvents";
|
import SocketEvents from "../interfaces/SocketEvents";
|
||||||
import isBrowser from "../util/isBrowser";
|
import isBrowser from "../util/isBrowser";
|
||||||
import Message from "../util/Message";
|
|
||||||
import MessageUtil from "../util/MessageUtil";
|
|
||||||
|
|
||||||
const Player = dynamic(() => import("../components/Player"), { ssr: false });
|
const Player = dynamic(() => import("../components/Player"), { ssr: false });
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue