diff --git a/.gitignore b/.gitignore index 1279394..656b796 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1 @@ -build/bin/ -node_modules -frontend/dist -frontend/wailsjs - -.prettierignore - -config.json \ No newline at end of file +.prettierignore \ No newline at end of file diff --git a/app.go b/app.go deleted file mode 100644 index 5cd7ae8..0000000 --- a/app.go +++ /dev/null @@ -1,563 +0,0 @@ -package main - -import ( - "context" - "errors" - "fmt" - "log" - "os" - "path/filepath" - "sync" - "time" - - "github.com/tylertravisty/rum-goggles/internal/api" - "github.com/tylertravisty/rum-goggles/internal/chatbot" - "github.com/tylertravisty/rum-goggles/internal/config" - rumblelivestreamlib "github.com/tylertravisty/rumble-livestream-lib-go" - "github.com/wailsapp/wails/v2/pkg/runtime" -) - -type chat struct { - username string - password string - url string -} - -// App struct -type App struct { - ctx context.Context - cfg *config.App - cfgMu sync.Mutex - api *api.Api - apiMu sync.Mutex - cb *chatbot.ChatBot - cbMu sync.Mutex - logError *log.Logger - logInfo *log.Logger -} - -// NewApp creates a new App application struct -func NewApp() *App { - app := &App{} - err := app.initLog() - if err != nil { - log.Fatal("error initializing log:", err) - } - - app.api = api.NewApi(app.logError, app.logInfo) - - return app -} - -// startup is called when the app starts. The context is saved -// so we can call the runtime methods -func (a *App) startup(ctx context.Context) { - a.ctx = ctx - a.api.Startup(ctx) - - err := a.loadConfig() - if err != nil { - a.logError.Fatal("error loading config: ", err) - } -} - -func (a *App) initLog() error { - f, err := config.LogFile() - if err != nil { - return fmt.Errorf("error opening log file: %v", err) - } - - a.logInfo = log.New(f, "[info]", log.LstdFlags|log.Lshortfile) - a.logError = log.New(f, "[error]", log.LstdFlags|log.Lshortfile) - return nil -} - -func (a *App) loadConfig() error { - cfg, err := config.Load() - if err != nil { - if !errors.Is(err, os.ErrNotExist) { - return fmt.Errorf("error loading config: %v", err) - } - - return a.newConfig() - } - - a.cfg = cfg - return nil -} - -func (a *App) newConfig() error { - cfg := &config.App{Channels: map[string]config.Channel{}} - err := cfg.Save() - if err != nil { - return fmt.Errorf("error saving new config: %v", err) - } - - a.cfg = cfg - return nil -} - -func (a *App) Config() *config.App { - return a.cfg -} - -func (a *App) AddChannel(url string) (*config.App, error) { - client := rumblelivestreamlib.Client{StreamKey: url} - resp, err := client.Request() - if err != nil { - a.logError.Println("error executing api request:", err) - return nil, fmt.Errorf("Error querying API. Verify key and try again.") - } - - name := resp.Username - if resp.ChannelName != "" { - name = resp.ChannelName - } - - a.cfgMu.Lock() - defer a.cfgMu.Unlock() - _, err = a.cfg.NewChannel(url, name) - if err != nil { - a.logError.Println("error creating new channel:", err) - return nil, fmt.Errorf("Error creating new channel. Try again.") - } - - err = a.cfg.Save() - if err != nil { - a.logError.Println("error saving config:", err) - return nil, fmt.Errorf("Error saving channel information. Try again.") - } - - return a.cfg, nil -} - -func (a *App) ChatBotMessages(cid string) (map[string]config.ChatMessage, error) { - a.cfgMu.Lock() - defer a.cfgMu.Unlock() - channel, exists := a.cfg.Channels[cid] - if !exists { - a.logError.Println("channel does not exist:", cid) - return nil, fmt.Errorf("Cannot find channel. Try reloading.") - } - - return channel.ChatBot.Messages, nil -} - -func (a *App) AddChatMessage(cid string, cm config.ChatMessage) (map[string]config.ChatMessage, error) { - var err error - a.cfgMu.Lock() - defer a.cfgMu.Unlock() - _, err = a.cfg.NewChatMessage(cid, cm) - if err != nil { - a.logError.Println("error creating new chat:", err) - return nil, fmt.Errorf("Error creating new chat message. Try again.") - } - - err = a.cfg.Save() - if err != nil { - a.logError.Println("error saving config:", err) - return nil, fmt.Errorf("Error saving chat message information. Try again.") - } - - a.updateChatBotConfig(a.cfg.Channels[cid].ChatBot) - - return a.cfg.Channels[cid].ChatBot.Messages, nil -} - -func (a *App) DeleteChatMessage(cid string, cm config.ChatMessage) (map[string]config.ChatMessage, error) { - a.cbMu.Lock() - if a.cb != nil { - err := a.cb.StopMessage(cm.ID) - if err != nil { - a.logError.Println("error stopping chat bot message:", err) - return nil, fmt.Errorf("Error stopping message. Try Again.") - } - } - a.cbMu.Unlock() - - a.cfgMu.Lock() - defer a.cfgMu.Unlock() - err := a.cfg.DeleteChatMessage(cid, cm) - if err != nil { - a.logError.Println("error deleting chat message:", err) - return nil, fmt.Errorf("Error deleting chat message. Try again.") - } - - err = a.cfg.Save() - if err != nil { - a.logError.Println("error saving config:", err) - return nil, fmt.Errorf("Error saving chat message information. Try again.") - } - - a.updateChatBotConfig(a.cfg.Channels[cid].ChatBot) - - return a.cfg.Channels[cid].ChatBot.Messages, nil -} - -func (a *App) UpdateChatMessage(cid string, cm config.ChatMessage) (map[string]config.ChatMessage, error) { - var err error - a.cfgMu.Lock() - defer a.cfgMu.Unlock() - _, err = a.cfg.UpdateChatMessage(cid, cm) - if err != nil { - a.logError.Println("error updating chat message:", err) - return nil, fmt.Errorf("Error updating chat message. Try again.") - } - - err = a.cfg.Save() - if err != nil { - a.logError.Println("error saving config:", err) - return nil, fmt.Errorf("Error saving chat message information. Try again.") - } - - a.updateChatBotConfig(a.cfg.Channels[cid].ChatBot) - - return a.cfg.Channels[cid].ChatBot.Messages, nil -} - -type NewChatBotResponse struct { - LoggedIn bool `json:"logged_in"` - StreamUrl string `json:"stream_url"` - Username string `json:"username"` -} - -func (a *App) GetChatBot(cid string) (NewChatBotResponse, error) { - if a.cb == nil { - return NewChatBotResponse{}, fmt.Errorf("Chat bot not initalized.") - } - - loggedIn, err := a.cb.LoggedIn() - if err != nil { - a.logError.Println("error checking if chat bot is logged in:", err) - return NewChatBotResponse{}, fmt.Errorf("Error checking if chat bot is logged in. Try again.") - } - - return NewChatBotResponse{loggedIn, a.cb.Cfg.Session.Client.StreamUrl, a.cb.Cfg.Session.Username}, nil -} - -func (a *App) NewChatBot(cid string) (NewChatBotResponse, error) { - a.cbMu.Lock() - defer a.cbMu.Unlock() - - if a.cb != nil { - err := a.resetChatBot() - if err != nil { - a.logError.Println("error resetting chat bot:", err) - return NewChatBotResponse{}, fmt.Errorf("Error creating chat bot. Try Again.") - } - } - channel, exists := a.cfg.Channels[cid] - if !exists { - a.logError.Println("channel does not exist:", cid) - return NewChatBotResponse{}, fmt.Errorf("Channel does not exist.") - } - - if channel.ChatBot.Session.Client.StreamUrl == "" { - return NewChatBotResponse{}, nil - } - - var err error - a.cb, err = chatbot.NewChatBot(a.ctx, channel.ChatBot, a.logError) - if err != nil { - a.logError.Println("error creating new chat bot:", err) - return NewChatBotResponse{}, fmt.Errorf("Error creating new chat bot. Try again.") - } - - loggedIn, err := a.cb.LoggedIn() - if err != nil { - a.logError.Println("error checking if chat bot is logged in:", err) - return NewChatBotResponse{}, fmt.Errorf("Error checking if chat bot is logged in. Try again.") - } - - if loggedIn { - err = a.cb.StartChatStream() - if err != nil { - a.logError.Println("error starting chat stream:", err) - return NewChatBotResponse{}, fmt.Errorf("Error connecting to chat. Try again.") - } - } - - return NewChatBotResponse{loggedIn, channel.ChatBot.Session.Client.StreamUrl, channel.ChatBot.Session.Username}, nil -} - -func (a *App) LoginChatBot(cid string, username string, password string, streamUrl string) error { - a.cbMu.Lock() - defer a.cbMu.Unlock() - a.cfgMu.Lock() - defer a.cfgMu.Unlock() - - if a.cb != nil { - err := a.resetChatBot() - if err != nil { - a.logError.Println("error resetting chat bot:", err) - return fmt.Errorf("Error creating chat bot. Try Again.") - } - } - channel, exists := a.cfg.Channels[cid] - if !exists { - a.logError.Println("channel does not exist:", cid) - return fmt.Errorf("Channel does not exist.") - } - channel.ChatBot.Session.Client.StreamUrl = streamUrl - - var err error - a.cb, err = chatbot.NewChatBot(a.ctx, channel.ChatBot, a.logError) - if err != nil { - a.logError.Println("error creating new chat bot:", err) - return fmt.Errorf("Error creating new chat bot. Try again.") - } - - cookies, err := a.cb.Login(username, password) - if err != nil { - a.logError.Println("error logging into chat bot:", err) - return fmt.Errorf("Error logging in. Try again.") - } - - channel.ChatBot.Session = config.ChatBotSession{ - Client: rumblelivestreamlib.NewClientOptions{ - Cookies: cookies, - StreamUrl: streamUrl, - }, - Username: username, - } - a.cfg.Channels[cid] = channel - err = a.cfg.Save() - if err != nil { - a.logError.Println("error saving config:", err) - return fmt.Errorf("Error saving session information. Try again.") - } - - a.cb.Cfg.Session = channel.ChatBot.Session - - err = a.cb.StartChatStream() - if err != nil { - a.logError.Println("error starting chat stream:", err) - return fmt.Errorf("Error connecting to chat. Try again.") - } - - return nil -} - -func (a *App) StopAllChatBot(cid string) error { - if a.cb == nil { - return fmt.Errorf("Chat bot not initialized.") - } - - err := a.cb.StopAllMessages() - if err != nil { - a.logError.Println("error stopping all chat bot messages:", err) - return fmt.Errorf("Error stopping messages.") - } - - return nil -} - -func (a *App) StartAllChatBot(cid string) error { - if a.cb == nil { - return fmt.Errorf("Chat bot not initialized.") - } - - err := a.cb.StartAllMessages() - if err != nil { - a.logError.Println("error starting all chat bot messages:", err) - return fmt.Errorf("Error starting messages.") - } - - return nil -} - -func (a *App) UpdateChatBotUrl(cid string, streamUrl string) error { - a.cbMu.Lock() - defer a.cbMu.Unlock() - a.cfgMu.Lock() - defer a.cfgMu.Unlock() - - if a.cb == nil { - return fmt.Errorf("Chat bot not initialized.") - } - - err := a.resetChatBot() - if err != nil { - a.logError.Println("error resetting chat bot:", err) - return fmt.Errorf("Error creating chat bot. Try Again.") - } - - channel, exists := a.cfg.Channels[cid] - if !exists { - a.logError.Println("channel does not exist:", cid) - return fmt.Errorf("Channel does not exist.") - } - channel.ChatBot.Session.Client.StreamUrl = streamUrl - - a.cb, err = chatbot.NewChatBot(a.ctx, channel.ChatBot, a.logError) - if err != nil { - a.logError.Println("error creating new chat bot:", err) - return fmt.Errorf("Error creating new chat bot. Try again.") - } - - a.cfg.Channels[cid] = channel - err = a.cfg.Save() - if err != nil { - a.logError.Println("error saving config:", err) - return fmt.Errorf("Error saving session information. Try again.") - } - - a.cb.Cfg.Session.Client.StreamUrl = streamUrl - - err = a.cb.StartChatStream() - if err != nil { - a.logError.Println("error starting chat stream:", err) - return fmt.Errorf("Error connecting to chat. Try again.") - } - - return nil -} - -func (a *App) ResetChatBot(cid string, logout bool) error { - a.cbMu.Lock() - defer a.cbMu.Unlock() - a.cfgMu.Lock() - defer a.cfgMu.Unlock() - - if a.cb == nil { - return nil - } - - err := a.cb.StopAllMessages() - if err != nil { - return fmt.Errorf("error stopping all chat bot messages: %v", err) - } - - if logout { - err := a.cb.Logout() - if err != nil { - return fmt.Errorf("error logging out of chat bot: %v", err) - } - - //TODO: reset session in config - channel, exists := a.cfg.Channels[cid] - if !exists { - a.logError.Println("channel does not exist:", cid) - return fmt.Errorf("Channel does not exist.") - } - - channel.ChatBot.Session = config.ChatBotSession{} - a.cfg.Channels[cid] = channel - err = a.cfg.Save() - if err != nil { - a.logError.Println("error saving config:", err) - return fmt.Errorf("Error saving session information. Try again.") - } - } - - err = a.resetChatBot() - if err != nil { - a.logError.Println("error resetting chat bot:", err) - return fmt.Errorf("Error resetting chat bot. Try Again.") - } - - return nil -} - -func (a *App) resetChatBot() error { - if a.cb == nil { - // return fmt.Errorf("chat bot is nil") - return nil - } - - err := a.cb.StopAllMessages() - if err != nil { - return fmt.Errorf("error stopping all chat bot messages: %v", err) - } - - err = a.cb.StopChatStream() - if err != nil { - return fmt.Errorf("error stopping chat stream: %v", err) - } - - a.cb = nil - - return nil -} - -func (a *App) StartChatBotMessage(mid string) error { - a.cbMu.Lock() - defer a.cbMu.Unlock() - - if a.cb == nil { - return fmt.Errorf("Chat bot not initialized.") - } - - err := a.cb.StartMessage(mid) - if err != nil { - a.logError.Println("error starting chat bot message:", err) - return fmt.Errorf("Error starting message. Try Again.") - } - - return nil -} - -func (a *App) StopChatBotMessage(mid string) error { - a.cbMu.Lock() - defer a.cbMu.Unlock() - - // If chat bot not initialized, then stop does nothing - if a.cb == nil { - return nil - } - - err := a.cb.StopMessage(mid) - if err != nil { - a.logError.Println("error stopping chat bot message:", err) - return fmt.Errorf("Error stopping message. Try Again.") - } - - return nil -} - -func (a *App) StartApi(cid string) error { - channel, found := a.cfg.Channels[cid] - if !found { - a.logError.Println("could not find channel CID:", cid) - return fmt.Errorf("channel CID not found") - } - - err := a.api.Start(channel.ApiUrl, channel.Interval*time.Second) - if err != nil { - a.logError.Println("error starting api:", err) - return fmt.Errorf("error starting API") - } - - return nil -} - -func (a *App) StopApi() { - a.api.Stop() -} - -func (a *App) updateChatBotConfig(cfg config.ChatBot) { - a.cbMu.Lock() - defer a.cbMu.Unlock() - if a.cb != nil { - a.cb.Cfg = cfg - } -} - -func (a *App) OpenFileDialog() (string, error) { - home, err := os.UserHomeDir() - if err != nil { - a.logError.Println("error getting home directory:", err) - return "", fmt.Errorf("Error opening file explorer. Try again.") - } - filepath, err := runtime.OpenFileDialog(a.ctx, runtime.OpenDialogOptions{DefaultDirectory: home}) - if err != nil { - a.logError.Println("error opening file dialog:", err) - return "", fmt.Errorf("Error opening file explorer. Try again.") - } - - return filepath, err -} - -func (a *App) FilepathBase(path string) string { - return filepath.Base(path) -} diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx deleted file mode 100644 index 987b323..0000000 --- a/frontend/src/App.jsx +++ /dev/null @@ -1,21 +0,0 @@ -import { useEffect, useState } from 'react'; -import { MemoryRouter as Router, Route, Routes, Link } from 'react-router-dom'; - -import './App.css'; - -import { NavSignIn, NavDashboard } from './screens/Navigation'; -import Dashboard from './screens/Dashboard'; -import SignIn from './screens/SignIn'; - -function App() { - return ( - - - }> - }> - - - ); -} - -export default App; diff --git a/frontend/src/assets/icons/eye-slash.png b/frontend/src/assets/icons/eye-slash.png deleted file mode 100644 index fe97fa0..0000000 Binary files a/frontend/src/assets/icons/eye-slash.png and /dev/null differ diff --git a/frontend/src/assets/icons/eye.png b/frontend/src/assets/icons/eye.png deleted file mode 100644 index 5ca94ec..0000000 Binary files a/frontend/src/assets/icons/eye.png and /dev/null differ diff --git a/frontend/src/assets/icons/gear-fill.png b/frontend/src/assets/icons/gear-fill.png deleted file mode 100644 index e0bf42b..0000000 Binary files a/frontend/src/assets/icons/gear-fill.png and /dev/null differ diff --git a/frontend/src/assets/icons/gear.png b/frontend/src/assets/icons/gear.png deleted file mode 100644 index c192495..0000000 Binary files a/frontend/src/assets/icons/gear.png and /dev/null differ diff --git a/frontend/src/assets/icons/hand-thumbs-down.png b/frontend/src/assets/icons/hand-thumbs-down.png deleted file mode 100644 index 27eace7..0000000 Binary files a/frontend/src/assets/icons/hand-thumbs-down.png and /dev/null differ diff --git a/frontend/src/assets/icons/hand-thumbs-up.png b/frontend/src/assets/icons/hand-thumbs-up.png deleted file mode 100644 index 75eddf3..0000000 Binary files a/frontend/src/assets/icons/hand-thumbs-up.png and /dev/null differ diff --git a/frontend/src/assets/icons/heart-fill.png b/frontend/src/assets/icons/heart-fill.png deleted file mode 100644 index 293d511..0000000 Binary files a/frontend/src/assets/icons/heart-fill.png and /dev/null differ diff --git a/frontend/src/assets/icons/house.png b/frontend/src/assets/icons/house.png deleted file mode 100644 index 982d5ea..0000000 Binary files a/frontend/src/assets/icons/house.png and /dev/null differ diff --git a/frontend/src/assets/icons/index.jsx b/frontend/src/assets/icons/index.jsx deleted file mode 100644 index b814454..0000000 --- a/frontend/src/assets/icons/index.jsx +++ /dev/null @@ -1,31 +0,0 @@ -import eye from './eye.png'; -import eye_slash from './eye-slash.png'; -import gear from './gear.png'; -import gear_fill from './gear-fill.png'; -import heart from './heart-fill.png'; -import house from './house.png'; -import pause from './pause-fill.png'; -import play from './play-fill.png'; -import play_green from './play-fill-green.png'; -import plus_circle from './plus-circle-fill.png'; -import star from './star-fill.png'; -import stop from './stop-fill.png'; -import thumbs_down from './hand-thumbs-down.png'; -import thumbs_up from './hand-thumbs-up.png'; -import x_lg from './x-lg.png'; - -export const Eye = eye; -export const EyeSlash = eye_slash; -export const Gear = gear; -export const GearFill = gear_fill; -export const Heart = heart; -export const House = house; -export const Pause = pause; -export const Play = play; -export const PlayGreen = play_green; -export const PlusCircle = plus_circle; -export const Star = star; -export const Stop = stop; -export const ThumbsDown = thumbs_down; -export const ThumbsUp = thumbs_up; -export const XLg = x_lg; diff --git a/frontend/src/assets/icons/pause-circle.png b/frontend/src/assets/icons/pause-circle.png deleted file mode 100644 index 686a73d..0000000 Binary files a/frontend/src/assets/icons/pause-circle.png and /dev/null differ diff --git a/frontend/src/assets/icons/pause-fill.png b/frontend/src/assets/icons/pause-fill.png deleted file mode 100644 index a54d600..0000000 Binary files a/frontend/src/assets/icons/pause-fill.png and /dev/null differ diff --git a/frontend/src/assets/icons/play-circle.png b/frontend/src/assets/icons/play-circle.png deleted file mode 100644 index def567b..0000000 Binary files a/frontend/src/assets/icons/play-circle.png and /dev/null differ diff --git a/frontend/src/assets/icons/play-fill-green.png b/frontend/src/assets/icons/play-fill-green.png deleted file mode 100644 index 6b7294a..0000000 Binary files a/frontend/src/assets/icons/play-fill-green.png and /dev/null differ diff --git a/frontend/src/assets/icons/play-fill.png b/frontend/src/assets/icons/play-fill.png deleted file mode 100644 index 2cbb56c..0000000 Binary files a/frontend/src/assets/icons/play-fill.png and /dev/null differ diff --git a/frontend/src/assets/icons/plus-circle-fill.png b/frontend/src/assets/icons/plus-circle-fill.png deleted file mode 100644 index 785e701..0000000 Binary files a/frontend/src/assets/icons/plus-circle-fill.png and /dev/null differ diff --git a/frontend/src/assets/icons/star-fill.png b/frontend/src/assets/icons/star-fill.png deleted file mode 100644 index 3478d59..0000000 Binary files a/frontend/src/assets/icons/star-fill.png and /dev/null differ diff --git a/frontend/src/assets/icons/stop-fill.png b/frontend/src/assets/icons/stop-fill.png deleted file mode 100644 index 6dccccf..0000000 Binary files a/frontend/src/assets/icons/stop-fill.png and /dev/null differ diff --git a/frontend/src/assets/icons/x-lg.png b/frontend/src/assets/icons/x-lg.png deleted file mode 100644 index 88a3d2b..0000000 Binary files a/frontend/src/assets/icons/x-lg.png and /dev/null differ diff --git a/frontend/src/components/ChannelList.css b/frontend/src/components/ChannelList.css deleted file mode 100644 index 7cbd1a9..0000000 --- a/frontend/src/components/ChannelList.css +++ /dev/null @@ -1,66 +0,0 @@ -.channel-list { - align-items: center; - display: flex; - flex-direction: column; - justify-content: center; - height: 100%; - width: 100%; -} - -.channel-list-title { - color: #85c742; - font-family: sans-serif; - font-size: 24px; - font-weight: bold; - padding: 5px; -} - -.channels { - background-color: white; - border: 1px solid #D6E0EA; - border-radius: 5px; - height: 100%; - overflow: auto; - width: 100%; -} - -.channel { - align-items: center; - /* border-top: 1px solid #D6E0EA; */ - display: flex; -} - -.channel-add { - background-color: #f3f5f8; - border: none; - padding: 10px; -} - -.channel-add:hover { - cursor: pointer; -} - -.channel-add-icon { - height: 36px; - width: 36px; -} - -.channel-button { - background-color: white; - border: none; - border-radius: 5px; - color: #061726; - font-family: sans-serif; - font-size: 24px; - font-weight: bold; - overflow: hidden; - padding: 10px 10px; - text-align: left; - white-space: nowrap; - width: 100%; -} - -.channel-button:hover { - background-color: #85c742; - cursor: pointer; -} \ No newline at end of file diff --git a/frontend/src/components/ChannelList.jsx b/frontend/src/components/ChannelList.jsx deleted file mode 100644 index 8a64348..0000000 --- a/frontend/src/components/ChannelList.jsx +++ /dev/null @@ -1,39 +0,0 @@ -import { PlusCircle } from '../assets/icons'; -import './ChannelList.css'; - -function ChannelList(props) { - const sortChannelsAlpha = () => { - let keys = Object.keys(props.channels); - // let sorted = [...props.channels].sort((a, b) => - // a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1 - // ); - - let sorted = [...keys].sort((a, b) => - props.channels[a].name.toLowerCase() > props.channels[b].name.toLowerCase() ? 1 : -1 - ); - return sorted; - }; - - return ( -
- Channels -
- {sortChannelsAlpha().map((channel, index) => ( -
- -
- ))} -
- {/* */} -
- ); -} - -export default ChannelList; diff --git a/frontend/src/components/ChatBot.css b/frontend/src/components/ChatBot.css deleted file mode 100644 index 6b879db..0000000 --- a/frontend/src/components/ChatBot.css +++ /dev/null @@ -1,64 +0,0 @@ -.chat-bot-error { - border: 1px solid red; - box-sizing: border-box; - color: red; - font-family: monospace; - font-size: 16px; - padding: 5px; - text-align: center; - width: 100%; -} - -.chat-bot-modal { - align-items: left; - display: flex; - flex-direction: column; - height: 100%; - justify-content: center; - width: 100%; -} - -.chat-bot-setting { - align-items: start; - display: flex; - flex-direction: column; - padding-top: 10px; - width: 100%; -} - -.chat-bot-setting-label { - color: white; - font-family: sans-serif; - font-size: 20px; - padding-bottom: 5px; - width: 100%; -} - -.chat-bot-setting-input { - border: none; - border-radius: 5px; - box-sizing: border-box; - font-family: monospace; - font-size: 16px; - outline: none; - padding: 10px; - resize: none; - width: 100%; -} - -.chat-bot-description { - align-items: center; - display: flex; - flex-direction: row; - justify-content: start; - padding-top: 10px; - width: 100%; -} - -.chat-bot-description-label { - color: white; - font-family: sans-serif; - font-size: 20px; - padding-bottom: 5px; - padding-right: 5px; -} \ No newline at end of file diff --git a/frontend/src/components/ChatBot.jsx b/frontend/src/components/ChatBot.jsx deleted file mode 100644 index 2296f3a..0000000 --- a/frontend/src/components/ChatBot.jsx +++ /dev/null @@ -1,174 +0,0 @@ -import { useEffect, useState } from 'react'; -import { Modal, SmallModal } from './Modal'; -import { LoginChatBot, UpdateChatBotUrl } from '../../wailsjs/go/main/App'; - -import './ChatBot.css'; - -export function ChatBotModal(props) { - const [error, setError] = useState(''); - const [loggedIn, setLoggedIn] = useState(props.loggedIn); - const [password, setPassword] = useState(''); - const [saving, setSaving] = useState(false); - const updatePassword = (event) => setPassword(event.target.value); - const [url, setUrl] = useState(props.streamUrl); - const updateUrl = (event) => setUrl(event.target.value); - const [username, setUsername] = useState(props.username); - const updateUsername = (event) => setUsername(event.target.value); - - useEffect(() => { - if (saving) { - // let user = username; - // let p = password; - // let u = url; - // props.onSubmit(user, p, u); - // NewChatBot(props.cid, username, password, url) - if (loggedIn) { - UpdateChatBotUrl(props.cid, url) - .then(() => { - reset(); - props.onUpdate(url); - }) - .catch((error) => { - setSaving(false); - setError(error); - console.log('Error updating chat bot:', error); - }); - } else { - LoginChatBot(props.cid, username, password, url) - .then(() => { - reset(); - props.onLogin(); - }) - .catch((error) => { - setSaving(false); - setError(error); - console.log('Error creating new chat bot:', error); - }); - } - } - }, [saving]); - - const reset = () => { - setError(''); - setLoggedIn(false); - setPassword(''); - setSaving(false); - setUrl(''); - setUsername(''); - }; - - const close = () => { - reset(); - props.onClose(); - }; - - const logout = () => { - reset(); - props.onLogout(); - }; - - const submit = () => { - if (username === '') { - setError('Add username'); - return; - } - - if (password === '' && !loggedIn) { - setError('Add password'); - return; - } - - if (url === '') { - setError('Add stream URL'); - return; - } - - setSaving(true); - // let user = username; - // let p = password; - // let u = url; - // reset(); - // props.onSubmit(user, p, u); - }; - - return ( - <> - { - console.log('Saving'); - } - : submit - } - title={'Chat Bot'} - > -
- {loggedIn ? ( -
- Logged in: - - {username} - -
- ) : ( -
- Username - -
- )} - {!loggedIn && ( -
- Password - -
- )} -
- Stream URL - -
-
-
- setError('')} - show={error !== ''} - style={{ minWidth: '300px', maxWidth: '300px', maxHeight: '100px' }} - title={'Error'} - message={error} - submitButton={'OK'} - onSubmit={() => setError('')} - /> - - ); -} - -export function StreamChatMessageItem() {} diff --git a/frontend/src/components/ChatMessage.css b/frontend/src/components/ChatMessage.css deleted file mode 100644 index 5e5a270..0000000 --- a/frontend/src/components/ChatMessage.css +++ /dev/null @@ -1,44 +0,0 @@ -.chat-message { - align-items: start; - background-color: rgba(6,23,38,1); - padding: 10px; - display: flex; - flex-direction: row; -} - -.chat-message-user-image { - border-radius: 50%; - height: 22px; - margin-right: 8px; - width: 22px; -} - -.chat-message-user-initial { - align-items: center; - background-color: #37c; - border: 1px solid #eee; - border-radius: 50%; - color: #eee; - display: flex; - font-family: sans-serif; - font-size: 12px; - font-weight: bold; - height: 22px; - justify-content: center; - margin-right: 8px; - width: 22px; -} - -.chat-message-username { - color: white; - font-family: sans-serif; - font-size: 14px; - font-weight: bold; - margin-right: 3px; -} - -.chat-message-text { - color: white; - font-family: sans-serif; - font-size: 14px; -} \ No newline at end of file diff --git a/frontend/src/components/ChatMessage.jsx b/frontend/src/components/ChatMessage.jsx deleted file mode 100644 index ca18b71..0000000 --- a/frontend/src/components/ChatMessage.jsx +++ /dev/null @@ -1,28 +0,0 @@ -import './ChatMessage.css'; - -function ChatMessage(props) { - const upperInitial = () => { - return props.message.username[0].toUpperCase(); - }; - - return ( -
- {props.message.image === '' || props.message.image === undefined ? ( - {upperInitial()} - ) : ( - - )} -
- - {props.message.username} - - {props.message.text} -
-
- ); -} - -export default ChatMessage; diff --git a/frontend/src/components/Highlight.css b/frontend/src/components/Highlight.css deleted file mode 100644 index 8a67f50..0000000 --- a/frontend/src/components/Highlight.css +++ /dev/null @@ -1,24 +0,0 @@ -.highlight { - align-items: start; - color: white; - display: flex; - background-color: #75a54b; - border-radius: 0.5rem; - flex-direction: column; - font-family: sans-serif; - font-weight: bold; - height: 40px; - justify-content: center; - min-width: 90px; - padding: 5px 10px; - width: 75px; -} - -.highlight-value { - font-family: monospace; - font-size: 20px; -} - -.highlight-description { - font-size: 12px; -} \ No newline at end of file diff --git a/frontend/src/components/Highlight.jsx b/frontend/src/components/Highlight.jsx deleted file mode 100644 index 3d00a63..0000000 --- a/frontend/src/components/Highlight.jsx +++ /dev/null @@ -1,72 +0,0 @@ -import './Highlight.css'; - -function Highlight(props) { - const countString = () => { - switch (true) { - case props.value <= 0: - return '-'; - case props.value < 1000: - return props.value; - case props.value < 1000000: - return (props.value / 1000).toFixed(3).slice(0, -2) + 'K'; - case props.value < 1000000000: - return (props.value / 1000000).toFixed(6).slice(0, -5) + 'M'; - default: - return 'Inf'; - } - }; - - const stopwatchString = () => { - if (isNaN(Date.parse(props.value))) { - return '--:--'; - } - let now = new Date(); - let date = new Date(props.value); - let diff = now - date; - - let msMinute = 1000 * 60; - let msHour = msMinute * 60; - let msDay = msHour * 24; - - let days = Math.floor(diff / msDay); - let hours = Math.floor((diff - days * msDay) / msHour); - let minutes = Math.floor((diff - days * msDay - hours * msHour) / msMinute); - - if (diff >= 100 * msDay) { - return days + 'd'; - } - if (diff >= msDay) { - return days + 'd ' + hours + 'h'; - } - - if (hours < 10) { - hours = '0' + hours; - } - - if (minutes < 10) { - minutes = '0' + minutes; - } - - return hours + ':' + minutes; - }; - - const valueString = () => { - switch (props.type) { - case 'count': - return countString(); - case 'stopwatch': - return stopwatchString(); - default: - return props.value; - } - }; - - return ( -
- {valueString()} - {props.description} -
- ); -} - -export default Highlight; diff --git a/frontend/src/components/Modal.css b/frontend/src/components/Modal.css deleted file mode 100644 index d4da5b4..0000000 --- a/frontend/src/components/Modal.css +++ /dev/null @@ -1,176 +0,0 @@ - -.modal-background { - align-items: center; - background-color: transparent; - display: flex; - height: 100vh; - justify-content: center; - left: 0; - position: absolute; - top: 0; - width: 100vw; -} - -.modal-body { - align-items: center; - display: flex; - height: 80%; - justify-content: center; - width: 100%; -} - -.modal-button { - background-color: #85c742; - border: none; - border-radius: 5px; - color: #061726; - cursor: pointer; - font-size: 18px; - font-weight: bold; - text-decoration: none; - /* width: 20%; */ - width: 70px; -} - -.modal-button-cancel { - background-color: transparent; - border: 1px solid #495a6a; - border-radius: 5px; - color: #495a6a; - cursor: pointer; - font-size: 18px; - font-weight: bold; - text-decoration: none; - /* width: 20%; */ - width: 70px; -} - -.modal-button-delete { - background-color: transparent; - border: 1px solid red; - border-radius: 5px; - color: red; - cursor: pointer; - font-size: 18px; - font-weight: bold; - text-decoration: none; - /* width: 20%; */ - width: 70px; -} - -.modal-close { - align-items: center; - background-color: transparent; - border: none; - display: flex; - flex-direction: center; - padding: 0px; -} - -.modal-close:hover { - cursor: pointer; -} - -.modal-close-icon { - height: 24px; - padding: 0px; - width: 24px; -} - -.modal-container { - align-items: center; - background-color: rgba(6,23,38,1); - border: 1px solid #495a6a; - border-radius: 15px; - color: black; - display: flex; - flex-direction: column; - height: 50%; - justify-content: space-between; - opacity: 1; - padding: 10px 20px; - width: 50%; -} - -.modal-footer { - align-items: center; - display: flex; - flex-direction: row; - justify-content: space-between; - height: 10%; - width: 100%; -} - -.modal-header { - align-items: center; - display: flex; - flex-direction: row; - justify-content: space-between; - height: 10%; - width: 100%; -} - -.modal-title { - color: white; - font-family: sans-serif; - font-size: 24px; -} - -.small-modal-button-delete { - background-color: red; - border: none; - border-radius: 5px; - color: white; - cursor: pointer; - font-size: 18px; - font-weight: bold; - text-decoration: none; - /* width: 20%; */ - width: 70px; -} - -.small-modal-container { - align-items: center; - /* background-color: rgba(6,23,38,1); */ - background-color: white; - border: 1px solid #495a6a; - /* border: 1px solid black; */ - border-radius: 15px; - color: black; - display: flex; - flex-direction: column; - height: 50%; - justify-content: space-between; - opacity: 1; - padding: 10px 20px; - width: 50%; -} - -.small-modal-header { - align-items: center; - display: flex; - flex-direction: row; - justify-content: space-between; - height: 10%; - width: 100%; -} - -.small-modal-footer { - align-items: center; - display: flex; - flex-direction: row; - justify-content: space-between; - height: 20%; - width: 100%; -} - -.small-modal-message { - font-family: sans-serif; - font-size: 18px; -} - -.small-modal-title { - color: black; - font-family: sans-serif; - font-size: 24px; -} \ No newline at end of file diff --git a/frontend/src/components/Modal.jsx b/frontend/src/components/Modal.jsx deleted file mode 100644 index 1be4fe8..0000000 --- a/frontend/src/components/Modal.jsx +++ /dev/null @@ -1,86 +0,0 @@ -import { XLg } from '../assets/icons'; -import './Modal.css'; - -export function Modal(props) { - return ( -
-
event.stopPropagation()} - style={props.style} - > -
- {props.title} - -
-
{props.children}
-
- {props.cancelButton && ( - - )} - {props.deleteButton && ( - - )} - {props.submitButton && ( - - )} -
-
-
- ); -} - -export function SmallModal(props) { - return ( -
-
event.stopPropagation()} - style={props.style} - > -
- {props.title} - -
-
- {props.message} -
-
- {props.cancelButton && ( - - )} - {props.deleteButton && ( - - )} - {props.submitButton && ( - - )} -
-
-
- ); -} diff --git a/frontend/src/components/StreamActivity.css b/frontend/src/components/StreamActivity.css deleted file mode 100644 index 7010da7..0000000 --- a/frontend/src/components/StreamActivity.css +++ /dev/null @@ -1,24 +0,0 @@ -.stream-activity { - width: 100%; - height: 100%; -} - -.stream-activity-header { - text-align: left; - background-color: rgba(6,23,38,1); - border-bottom: 1px solid #495a6a; - height: 19px; - padding: 10px 20px; -} - -.stream-activity-title { - color: white; - font-family: sans-serif; - font-size: 12px; - font-weight: bold; -} - -.stream-activity-list { - overflow-y: auto; - height: calc(100vh - 84px - 40px - 179px); -} \ No newline at end of file diff --git a/frontend/src/components/StreamActivity.jsx b/frontend/src/components/StreamActivity.jsx deleted file mode 100644 index 30f48f0..0000000 --- a/frontend/src/components/StreamActivity.jsx +++ /dev/null @@ -1,20 +0,0 @@ -import StreamEvent from './StreamEvent'; - -import './StreamActivity.css'; - -function StreamActivity(props) { - return ( -
-
- {props.title} -
-
- {props.events.map((event, index) => ( - - ))} -
-
- ); -} - -export default StreamActivity; diff --git a/frontend/src/components/StreamChat.css b/frontend/src/components/StreamChat.css deleted file mode 100644 index e75b20c..0000000 --- a/frontend/src/components/StreamChat.css +++ /dev/null @@ -1,28 +0,0 @@ -.stream-chat { - width: 100%; - height: 100%; -} - -.stream-chat-header { - align-items: center; - background-color: rgba(6,23,38,1); - border-bottom: 1px solid #495a6a; - display: flex; - flex-direction: row; - justify-content: space-between; - height: 19px; - padding: 10px 20px; - text-align: left; -} - -.stream-chat-list { - overflow-y: auto; - height: calc(100vh - 84px - 40px - 179px); -} - -.stream-chat-title { - color: white; - font-family: sans-serif; - font-size: 12px; - font-weight: bold; -} \ No newline at end of file diff --git a/frontend/src/components/StreamChat.jsx b/frontend/src/components/StreamChat.jsx deleted file mode 100644 index 3414bb7..0000000 --- a/frontend/src/components/StreamChat.jsx +++ /dev/null @@ -1,38 +0,0 @@ -import { useState } from 'react'; -import { EventsOn } from '../../wailsjs/runtime/runtime'; -import ChatMessage from './ChatMessage'; -import './StreamChat.css'; - -function StreamChat(props) { - const [messages, setMessages] = useState([ - { - color: '#ec131f', - image: 'https://ak2.rmbl.ws/z0/V/m/v/E/VmvEe.asF.4-18osof-s35kf7.jpeg', - username: 'tylertravisty', - text: 'Hello, world this is si s a a sdf asd f', - }, - { - username: 'tylertravisty', - text: 'Another chat message', - }, - ]); - - EventsOn('ChatMessage', (msg) => { - setMessages(...messages, msg); - }); - - return ( -
-
- {props.title} -
-
- {messages.map((message, index) => ( - - ))} -
-
- ); -} - -export default StreamChat; diff --git a/frontend/src/components/StreamChatBot.css b/frontend/src/components/StreamChatBot.css deleted file mode 100644 index 3526c82..0000000 --- a/frontend/src/components/StreamChatBot.css +++ /dev/null @@ -1,104 +0,0 @@ -.stream-chatbot { - width: 100%; - height: 100%; -} - -.stream-chatbot-button { - align-items: center; - border: none; - display: flex; - justify-content: center; - padding: 0px; -} - -.stream-chatbot-button:hover { - cursor: pointer; -} - -.stream-chatbot-button-title { - background-color: rgba(6,23,38,1); -} - -.stream-chatbot-button-chat { - align-items: center; - background-color: #000312; - display: flex; - justify-content: center; - width: 10%; -} - -.stream-chatbot-icon { - height: 24px; - width: 24px; -} - -.stream-chatbot-controls { - align-items: center; - display: flex; - flex-direction: row; - justify-content: space-between; - width: 55px; -} - -.stream-chatbot-header { - align-items: center; - background-color: rgba(6,23,38,1); - border-bottom: 1px solid #495a6a; - display: flex; - flex-direction: row; - justify-content: space-between; - height: 19px; - padding: 10px 20px; - text-align: left; -} - -.stream-chatbot-item { - border-bottom: 1px solid #82b1ff; - box-sizing: border-box; - color: white; - display: flex; - flex-direction: row; - font-family: sans-serif; - justify-content: space-between; - padding: 10px 20px; - width: 100%; -} - -.stream-chatbot-item-sender { - align-items: center; - box-sizing: border-box; - display: flex; - justify-content: left; - padding-left: 10px; - width: 20%; -} - -.stream-chatbot-item-interval { - align-items: center; - box-sizing: border-box; - display: flex; - justify-content: left; - padding-left: 10px; - width: 20%; -} - -.stream-chatbot-item-message { - align-items: center; - display: flex; - justify-content: left; - overflow: hidden; - white-space: nowrap; - width: 50%; -} - -.stream-chatbot-list { - overflow-y: auto; - height: calc(100vh - 84px - 40px - 179px); -} - -.stream-chatbot-title { - color: white; - font-family: sans-serif; - font-size: 12px; - font-weight: bold; -} \ No newline at end of file diff --git a/frontend/src/components/StreamChatBot.jsx b/frontend/src/components/StreamChatBot.jsx deleted file mode 100644 index 814b119..0000000 --- a/frontend/src/components/StreamChatBot.jsx +++ /dev/null @@ -1,237 +0,0 @@ -import { useEffect, useState } from 'react'; -import { FilepathBase, StartChatBotMessage, StopChatBotMessage } from '../../wailsjs/go/main/App'; -import { EventsOn } from '../../wailsjs/runtime/runtime'; -import { GearFill, Pause, Play, PlayGreen, PlusCircle, Stop } from '../assets/icons'; -import './StreamChatBot.css'; -import { SmallModal } from './Modal'; - -function StreamChatBot(props) { - const sortChatsAlpha = () => { - let keys = Object.keys(props.chats); - - let sorted = [...keys].sort((a, b) => - props.chats[a].text.toLowerCase() > props.chats[b].text.toLowerCase() ? 1 : -1 - ); - return sorted; - }; - - return ( -
-
- {props.title} -
- - -
-
- - -
-
-
- {sortChatsAlpha().map((chat, index) => ( - - ))} -
-
- ); -} - -export default StreamChatBot; - -function StreamChatItem(props) { - // const [active, setActive] = useState(props.isMessageActive(props.chat.id)); - const [active, setActive] = useState(false); - const [error, setError] = useState(''); - const [filename, setFilename] = useState(props.chat.text_file); - - useEffect(() => { - if (props.chat.text_file !== '') { - FilepathBase(props.chat.text_file).then((name) => { - setFilename(name); - }); - } - // setActive(props.isMessageActive(props.chat.id)); - }, [props]); - - const changeActive = (bool) => { - // console.log('ChangeActive:', bool); - // props.chat.active = bool; - // props.activateMessage(props.chat.id, bool); - setActive(bool); - }; - - useEffect(() => { - EventsOn('ChatBotCommandActive-' + props.chat.id, (mid) => { - console.log('ChatBotCommandActive', props.chat.id, mid); - if (mid === props.chat.id) { - changeActive(true); - } - }); - - EventsOn('ChatBotCommandError-' + props.chat.id, (mid) => { - console.log('ChatBotCommandError', props.chat.id, mid); - if (mid === props.chat.id) { - changeActive(false); - } - }); - - EventsOn('ChatBotMessageActive-' + props.chat.id, (mid) => { - console.log('ChatBotMessageActive', props.chat.id, mid); - if (mid === props.chat.id) { - changeActive(true); - } - }); - - EventsOn('ChatBotMessageError-' + props.chat.id, (mid) => { - console.log('ChatBotMessageError', props.chat.id, mid); - if (mid === props.chat.id) { - changeActive(false); - } - }); - }, []); - - const prependZero = (value) => { - if (value < 10) { - return '0' + value; - } - - return '' + value; - }; - - const printInterval = (interval) => { - let hours = Math.floor(interval / 3600); - let minutes = Math.floor(interval / 60 - hours * 60); - let seconds = Math.floor(interval - hours * 3600 - minutes * 60); - - // hours = prependZero(hours); - // minutes = prependZero(minutes); - // seconds = prependZero(seconds); - // return hours + ':' + minutes + ':' + seconds; - - return hours + 'h ' + minutes + 'm ' + seconds + 's'; - }; - - const intervalToTimer = (interval) => { - let hours = Math.floor(interval / 3600); - let minutes = Math.floor(interval / 60 - hours * 60); - let seconds = Math.floor(interval - hours * 3600 - minutes * 60); - - if (minutes !== 0) { - seconds = prependZero(seconds); - } - if (hours !== 0) { - minutes = prependZero(minutes); - } - if (hours === 0) { - hours = ''; - if (minutes === 0) { - minutes = ''; - if (seconds === 0) { - seconds = ''; - } - } - } - - return hours + minutes + seconds; - }; - - const openChat = () => { - props.onItemClick({ - id: props.chat.id, - as_channel: props.chat.as_channel, - command: props.chat.command, - interval: intervalToTimer(props.chat.interval), - on_command: props.chat.on_command, - on_command_follower: props.chat.on_command_follower, - on_command_rant_amount: props.chat.on_command_rant_amount, - on_command_subscriber: props.chat.on_command_subscriber, - text: props.chat.text, - text_file: props.chat.text_file, - }); - }; - - const startMessage = () => { - StartChatBotMessage(props.chat.id) - .then(() => { - changeActive(true); - }) - .catch((error) => { - setError(error); - }); - }; - - const stopMessage = () => { - StopChatBotMessage(props.chat.id).then(() => { - changeActive(false); - }); - }; - - return ( - <> - setError('')} - show={error !== ''} - style={{ minWidth: '300px', maxWidth: '200px', maxHeight: '200px' }} - title={'Error'} - message={error} - submitButton={'OK'} - onSubmit={() => setError('')} - /> -
openChat()}> - - {props.chat.text_file !== '' ? filename : props.chat.text} - - - {props.chat.on_command - ? props.chat.command - : printInterval(props.chat.interval)} - - - {props.chat.as_channel ? 'Channel' : 'User'} - - -
- - ); -} diff --git a/frontend/src/components/StreamChatMessage.css b/frontend/src/components/StreamChatMessage.css deleted file mode 100644 index edfcc30..0000000 --- a/frontend/src/components/StreamChatMessage.css +++ /dev/null @@ -1,358 +0,0 @@ -/* .modal-chat { - align-items: center; - background-color: red; - color: black; - display: flex; - height: 50%; - justify-content: center; - opacity: 1; - width: 50%; -} - -.modal-container { - align-items: center; - display: flex; - height: 100vh; - justify-content: center; - left: 0; - position: absolute; - top: 0; - width: 100vw; -} */ - -.chat-toggle { - align-items: center; - display: flex; - justify-content: space-between; - padding-top: 10px; - width: 100%; -} - -.chat-toggle-label { - color: white; - font-family: sans-serif; - padding-right: 10px; -} - -.chat-command { - align-items: center; - display: flex; - flex-direction: row; - justify-content: center; - padding-top: 10px; - width: 100%; -} - -.chat-command-input { - border: none; - border-radius: 34px; - box-sizing: border-box; - font-family: monospace; - font-size: 16px; - outline: none; - padding: 5px 10px 5px 10px; - text-align: center; - width: 100%; -} - -.chat-command-option { - align-items: center; - display: flex; - flex-direction: row; - justify-content: center; -} - -.chat-command-options { - align-items: center; - display: flex; - flex-direction: column; - justify-content: space-evenly; -} - -.chat-command-label { - color: white; - height: 29px; -} - -.chat-command-rant-amount { - border: none; - /* border-radius: 34px; */ - box-sizing: border-box; - font-family: monospace; - font-size: 16px; - outline: none; - /* padding: 5px 10px 5px 10px; */ - padding: 5px; - text-align: center; -} - -.chat-command-rant-amount-label { - color: white; - font-family: sans-serif; - padding-right: 10px; -} - -.chat-command-rant-amount-symbol { - color: white; - font-family: sans-serif; - font-size: 20px; - padding-right: 1px; -} - -.chat-interval { - align-items: center; - display: flex; - flex-direction: row; - justify-content: space-between; - padding-top: 10px; - width: 100%; -} - -.chat-interval-input { - border: none; - border-radius: 34px; - box-sizing: border-box; - font-family: monospace; - font-size: 16px; - outline: none; - padding: 5px 10px 5px 10px; - text-align: right; -} - -.chat-interval-input-zero::placeholder { - text-align: center; -} - -.chat-interval-input-value::placeholder { - color: black; - opacity: 1; - text-align: center; -} - -.chat-interval-label { - color: white; - font-family: sans-serif; - padding-right: 10px; -} - -.chat-options { - display: flex; - flex-direction: column; - width: 100%; -} - -.stream-chat-message { - align-items: center; - color: white; - display: flex; - flex-direction: column; - font-family: sans-serif; - justify-content: start; - width: 100%; -} - -.stream-chat-message-error { - border: 1px solid red; - box-sizing: border-box; - color: red; - font-family: monospace; - font-size: 16px; - padding: 5px; - text-align: center; - width: 100%; -} - -.stream-chat-message-label { - padding: 5px 0px; - /* width: 50%; */ -} - -.stream-chat-message-modal { - align-items: left; - display: flex; - flex-direction: column; - height: 100%; - justify-content: center; - width: 100%; -} - -.stream-chat-message-textarea { - border: none; - border-radius: 5px; - box-sizing: border-box; - font-family: monospace; - font-size: 16px; - outline: none; - padding: 10px; - resize: none; - width: 100%; -} - -.stream-chat-message-title { - align-items: center; - display: flex; - flex-direction: row; - justify-content: space-between; - width: 100%; -} - -.stream-chat-message-title-right { - align-items: center; - display: flex; - flex-direction: row; - justify-content: center; -} - -.chat-toggle-switch { - position: relative; - display: inline-block; - width: 50px; - height: 24px; -} - -.chat-toggle-switch input { - opacity: 0; - width: 0; - height: 0; -} - -.chat-toggle-slider { - position: absolute; - cursor: pointer; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: #495a6a; - -webkit-transition: .4s; - transition: .4s; -} - -.chat-toggle-slider:before { - position: absolute; - content: ""; - height: 16px; - width: 16px; - left: 4px; - bottom: 4px; - background-color: white; - -webkit-transition: .4s; - transition: .4s; -} - -input:checked + .chat-toggle-slider { - background-color: #85c742; -} - -input:checked + .chat-toggle-slider:before { - -webkit-transform: translateX(26px); - -ms-transform: translateX(26px); - transform: translateX(26px); -} -/* Rounded sliders */ -.chat-toggle-slider.round { - border-radius: 34px; -} - -.chat-toggle-slider.round:before { - border-radius: 50%; -} - -.chat-toggle-check-container { - display: block; - position: relative; - padding-left: 16px; - margin-bottom: 15px; - cursor: pointer; - font-size: 15px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.chat-toggle-check-container input { - position: absolute; - opacity: 0; - cursor: pointer; - height: 0; - width: 0; -} - -.chat-toggle-check { - border-radius: 3px; - position: absolute; - top: 0; - left: 0; - height: 15px; - width: 15px; - background-color: #495a6a; -} - -.chat-toggle-check-container:hover input ~ .chat-toggle-check { - background-color: #495a6a; -} - -.chat-toggle-check-container input:checked ~ .chat-toggle-check { - background-color: #85c742; -} - -.chat-toggle-check:after { - content: ""; - position: absolute; - display: none; -} - -.chat-toggle-check-container input:checked ~ .chat-toggle-check:after { - display: block; -} - -.chat-toggle-check-container .chat-toggle-check:after { - left: 4px; - top: 1px; - width: 4px; - height: 8px; - border: solid white; - border-width: 0 3px 3px 0; - -webkit-transform: rotate(45deg); - -ms-transform: rotate(45deg); - transform: rotate(45deg); -} - -.chat-toggle-check-label { - color: white; - font-family: sans-serif; - padding-right: 5px; -} - -.choose-file { - align-items: center; - display: flex; - flex-direction: row; - justify-content: space-between; - width: 100%; -} - -.choose-file-button-box { - min-width: 100px; - width: 100px; -} - -.choose-file-button { - background-color: #85c742; - border: none; - border-radius: 5px; - color: #061726; - cursor: pointer; - font-size: 16px; - text-decoration: none; - /* width: 200px; */ - width: 100%; -} - -.choose-file-path { - overflow: scroll; - margin-left: 5px; - white-space: nowrap; -} - diff --git a/frontend/src/components/StreamChatMessage.jsx b/frontend/src/components/StreamChatMessage.jsx deleted file mode 100644 index 774b0b6..0000000 --- a/frontend/src/components/StreamChatMessage.jsx +++ /dev/null @@ -1,404 +0,0 @@ -import { useEffect, useState } from 'react'; - -import { Modal, SmallModal } from './Modal'; - -import { OpenFileDialog } from '../../wailsjs/go/main/App'; - -import './StreamChatMessage.css'; - -export function StreamChatMessageModal(props) { - const [asChannel, setAsChannel] = useState(props.asChannel); - const [chatCommand, setChatCommand] = useState(props.chatCommand); - const [error, setError] = useState(''); - const [onCommand, setOnCommand] = useState(props.onCommand); - const [onCommandFollower, setOnCommandFollower] = useState(props.onCommandFollower); - const [onCommandRantAmount, setOnCommandRantAmount] = useState(props.onCommandRantAmount); - const [onCommandSubscriber, setOnCommandSubscriber] = useState(props.onCommandSubscriber); - const [openDelete, setOpenDelete] = useState(false); - const [readFromFile, setReadFromFile] = useState(false); - const [text, setText] = useState(props.text); - const [textFile, setTextFile] = useState(props.textFile); - const updateText = (event) => setText(event.target.value); - const [timer, setTimer] = useState(props.interval); - - useEffect(() => { - console.log('update chat'); - setAsChannel(props.asChannel); - setOnCommand(props.onCommand); - setOnCommandFollower(props.onCommandFollower); - setOnCommandSubscriber(props.onCommandSubscriber); - setOnCommandRantAmount(props.onCommandRantAmount); - setError(''); - setReadFromFile(props.textFile !== ''); - setText(props.text); - setTextFile(props.textFile); - setTimer(props.interval); - }, []); - - const reset = () => { - setAsChannel(false); - setChatCommand(false); - setError(''); - setReadFromFile(false); - setText(''); - setTextFile(''); - setOnCommand(false); - setOnCommandFollower(false); - setOnCommandSubscriber(false); - setOnCommandRantAmount(0); - setTimer(''); - }; - - const close = () => { - reset(); - props.onClose(); - }; - - const submit = () => { - if (!readFromFile && text === '') { - setError('Add message'); - return; - } - - if (readFromFile && textFile === '') { - setError('Select file containing messages'); - return; - } - - if (timer === '') { - setError('Set timer'); - return; - } - - if (onCommand && chatCommand === '') { - setError('Add command'); - return; - } - - let message = { - id: props.chatID, - as_channel: asChannel, - command: chatCommand, - interval: timerToInterval(), - on_command: onCommand, - on_command_follower: onCommandFollower, - on_command_rant_amount: onCommandRantAmount, - on_command_subscriber: onCommandSubscriber, - text: text, - text_file: textFile, - }; - - props.onSubmit(message); - }; - - const deleteMessage = () => { - if (props.chatID === '') { - close(); - return; - } - - setOpenDelete(true); - }; - - const confirmDelete = () => { - reset(); - setOpenDelete(false); - props.onDelete(props.chatID); - }; - - const updateChatCommand = (e) => { - let command = e.target.value; - - if (command.length === 1) { - if (command !== '!') { - command = '!' + command; - } - } - command = command.toLowerCase(); - let postfix = command.replace('!', ''); - - if (postfix !== '' && !/^[a-z0-9]+$/gi.test(postfix)) { - return; - } - - setChatCommand(command); - }; - - const updateTimerBackspace = (e) => { - if (timer.length === 0) { - return; - } - - if (e.keyCode === 8) { - setTimer(timer.substring(0, timer.length - 1)); - } - }; - - const updateTimer = (e) => { - let nums = '0123456789'; - let digit = e.target.value; - - if (!nums.includes(digit)) { - return; - } - - if (timer.length === 6) { - return; - } - - if (timer.length === 0 && digit === '0') { - return; - } - - setTimer(timer + digit); - }; - - const timerToInterval = () => { - let prefix = '0'.repeat(6 - timer.length); - let t = prefix + timer; - - let hours = parseInt(t.substring(0, 2)); - let minutes = parseInt(t.substring(2, 4)); - let seconds = parseInt(t.substring(4, 6)); - - return hours * 3600 + minutes * 60 + seconds; - }; - - const printTimer = () => { - if (timer === '') { - return '00:00:00'; - } - - let prefix = '0'.repeat(6 - timer.length); - let t = prefix + timer; - - return t.substring(0, 2) + ':' + t.substring(2, 4) + ':' + t.substring(4, 6); - }; - - const checkChannelToggle = (e) => { - setAsChannel(e.target.checked); - }; - - const checkCommandToggle = (e) => { - setOnCommand(e.target.checked); - }; - - const checkCommandFollower = (e) => { - setOnCommandFollower(e.target.checked); - }; - - const checkCommandSubscriber = (e) => { - setOnCommandSubscriber(e.target.checked); - }; - - const updateRantAmount = (e) => { - let amount = parseInt(e.target.value); - if (isNaN(amount)) { - amount = 0; - } - - setOnCommandRantAmount(amount); - }; - - const checkReadFromFile = (e) => { - setReadFromFile(e.target.checked); - if (!e.target.checked) { - setTextFile(''); - } - }; - - const chooseFile = () => { - OpenFileDialog() - .then((filepath) => { - if (filepath !== '') { - setTextFile(filepath); - } - }) - .catch((error) => setError(error)); - }; - - return ( - <> - -
-
- {/* {error && {error}} */} -
- Message -
- Read from file - -
-
- {readFromFile ? ( -
-
- -
- {textFile} -
- ) : ( -