diff --git a/.env b/.env deleted file mode 100644 index 0b6ef10..0000000 --- a/.env +++ /dev/null @@ -1,6 +0,0 @@ -REACT_APP_VERSION=$npm_package_version -REACT_APP_NAME=$npm_package_name -REACT_APP_DESCRIPTION=$npm_package_description -REACT_APP_URL=$npm_package_url -BROWSER=none -SERVER_PORT=5002 \ No newline at end of file diff --git a/.env.development b/.env.development deleted file mode 100644 index afc4ceb..0000000 --- a/.env.development +++ /dev/null @@ -1 +0,0 @@ -REACT_APP_SERVER="http://localhost:5002" \ No newline at end of file diff --git a/.env.production b/.env.production deleted file mode 100644 index 1f68da5..0000000 --- a/.env.production +++ /dev/null @@ -1 +0,0 @@ -REACT_APP_SERVER="" \ No newline at end of file diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml deleted file mode 100644 index f4817e8..0000000 --- a/.github/workflows/build-linux.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Linux:Build/release - -on: push - -jobs: - release: - runs-on: ${{ matrix.os }} - - strategy: - matrix: - os: [ubuntu-latest] - - steps: - - name: Check out Git repository - uses: actions/checkout@v1 - - - name: Install Node.js, NPM and Yarn - uses: actions/setup-node@v1 - with: - node-version: 14 - - - name: Build/release Electron app - uses: samuelmeuli/action-electron-builder@v1 - with: - args: -c.snap.publish=github - # GitHub token, automatically provided to the action - # (No need to define this secret in the repo settings) - github_token: ${{ secrets.github_token }} - - # If the commit is tagged with a version (e.g. "v1.0.0"), - # release the app after building - release: ${{ startsWith(github.ref, 'refs/tags/v') }} \ No newline at end of file diff --git a/.github/workflows/build-mac.yml b/.github/workflows/build-mac.yml deleted file mode 100644 index 93d5165..0000000 --- a/.github/workflows/build-mac.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Mac:Build/release - -on: push - -jobs: - release: - runs-on: ${{ matrix.os }} - - strategy: - matrix: - os: [macos-latest] - - steps: - - name: Check out Git repository - uses: actions/checkout@v1 - - - name: Install Node.js, NPM and Yarn - uses: actions/setup-node@v1 - with: - node-version: 14 - - name: Install libmpeg - run : brew install libtool - - name: Install autoMake pour Libsodium - run : brew install automake - - - name: Build/release Electron app - uses: samuelmeuli/action-electron-builder@v1 - with: - args: -c.snap.publish=github - # GitHub token, automatically provided to the action - # (No need to define this secret in the repo settings) - github_token: ${{ secrets.github_token }} - - # If the commit is tagged with a version (e.g. "v1.0.0"), - # release the app after building - release: ${{ startsWith(github.ref, 'refs/tags/v') }} \ No newline at end of file diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml deleted file mode 100644 index eff9932..0000000 --- a/.github/workflows/build-windows.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Win:Build/release - -on: push - -jobs: - release: - runs-on: ${{ matrix.os }} - - strategy: - matrix: - os: [windows-latest] - - steps: - - name: Check out Git repository - uses: actions/checkout@v1 - - - name: Install Node.js, NPM and Yarn - uses: actions/setup-node@v1 - with: - node-version: 14 - - name : set vs version - run : npm config set msvs_version 2015 - - name : install dépendances (A MORT WINDOWS) - run : npm install --global windows-build-tools@4.0.0 --vs2015 - - - name: Build/release Electron app - uses: samuelmeuli/action-electron-builder@v1 - with: - args: -c.snap.publish=github - # GitHub token, automatically provided to the action - # (No need to define this secret in the repo settings) - github_token: ${{ secrets.github_token }} - - # If the commit is tagged with a version (e.g. "v1.0.0"), - # release the app after building - release: ${{ startsWith(github.ref, 'refs/tags/v') }} \ No newline at end of file diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml new file mode 100644 index 0000000..e98d41e --- /dev/null +++ b/.github/workflows/documentation.yml @@ -0,0 +1,53 @@ +name: documentation + +on: + pull_request: + branches: [doc] + push: + branches: [doc] + +jobs: + checks: + if: github.event_name != 'push' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-node@v1 + with: + node-version: '12.x' + - name: Test Build + run: | + if [ -e yarn.lock ]; then + yarn install --frozen-lockfile + elif [ -e package-lock.json ]; then + npm ci + else + npm i + fi + npm run build + gh-release: + if: github.event_name != 'pull_request' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-node@v1 + with: + node-version: '12.x' + - uses: webfactory/ssh-agent@v0.5.1 + with: + ssh-private-key: ${{ secrets.GH_PAGES_DEPLOY }} + - name: Release to GitHub Pages + env: + USE_SSH: true + GIT_USER: git + run: | + git config --global user.email "actions@github.com" + git config --global user.name "gh-actions" + if [ -e yarn.lock ]; then + yarn install --frozen-lockfile + elif [ -e package-lock.json ]; then + npm ci + else + npm i + fi + npm run deploy \ No newline at end of file diff --git a/.gitignore b/.gitignore index c64d317..b2d6de3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,18 +1,14 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies +# Dependencies /node_modules -/.pnp -.pnp.js - -# testing -/coverage -# production +# Production /build -/BuildServer -# misc +# Generated files +.docusaurus +.cache-loader + +# Misc .DS_Store .env.local .env.development.local @@ -22,9 +18,3 @@ npm-debug.log* yarn-debug.log* yarn-error.log* - -.eslintcache - -dist/ - -.yarn/ diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index a8df1a5..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "cSpell.words": [ - "APPDATA", - "Discordjs", - "Spotify", - "bodyparser", - "browserslist", - "bufferutil", - "cacheable", - "compat", - "craco", - "deezer", - "opusscript", - "precaching", - "preelectron", - "preload", - "varchar" - ] -} \ No newline at end of file diff --git a/Annalyse/V1.puml b/Annalyse/V1.puml deleted file mode 100644 index a1eeab7..0000000 --- a/Annalyse/V1.puml +++ /dev/null @@ -1,246 +0,0 @@ -@startuml -package "Client React/Redux"{ - class Bot{ - img : any - user : any - link : string - Pending: Boolean - Serveur : Array_any - ActiveServeur : String - ActiveBot : number - ServeurChan: Array_any - canPlay : Array_any - BotGetter() - CanPlay() - BotServerGetter() - BotServerChanGetter() - reset() - } - class Event{ - ReloadBot: Boolean - Ready:Boolean - Pending:Boolean - Voice_Change : Boolean - Voice_Queue : Boolean - Voice_Error: Boolean - Voice_Playing: Boolean - Voice_Join: Boolean - Voice_Leave: Boolean - EventInit() - SetUpdateBot() - SetResetBot() - SetVoiceChange() - SetVoiceError() - SetVoicePlaying() - SetVoiceLeave() - } - - class Voice{ - Pending:Boolean - Playing:Boolean - Volume:number - ChanId:String - GuildId:String - Status:Boolean - Asap:Boolean - Paused:Boolean - Queue : Any - - SetChanId() - SetAsap() - JoinChan() - LeaveChan() - StopVoice() - SkipVoice() - StartVoice - SetVolume() - GetStatus() - GetVoice() - GetPause() - GetVolume() - SetChanIdAction() - } - - interface Token{ - id: number - label: string - token : string - } - - class TokenState{ - {field}allToken : Array(Token) - ActiveTokenId : number - Pending : Boolean - - TokenGetter() - TokenCreate() - TokenDelete() - TokenActivate() - TokenDeactivate() - } - - class showModal{ - TokenForm: Boolean - CreateTab: Boolean - CreateButton: Boolean - Burger: Boolean - BoardParam: Boolean - queueSlide: Boolean - importExport: Boolean - - ShowTokenForm() - HideTokenForm() - ShowCreateTab() - HideCreateTab() - showCreateButton() - HideCreateButton() - SetBurger() - SetBoardParam() - SetQueueSlide() - SetImportExport() - } - - class sBoard{ - Pending: Boolean - Board: Array_any - ActiveBoard: number - ActiveLayout : Array_any - Sound: String - Url: String - Button: String - Type: enumSongType - BoardAsChanged: Boolean - Editing: Boolean - Id: number - SetActiveBoard() - SetSound() - SetHandlerLayout() - Lock() - Unlock() - AddButton() - EditButton() - LoadButton() - RemoveButton() - ResetCreateButtonModal() - SetUrl() - SetButton() - SetType() - UpdateBoard() - GetBoardd() - DeleteBoard() - UpdateBoard() - CreateBoard() - } -} - -package "Serveur"{ - interface song{ - title: string - url: string - type: SongType - } - interface SongQueue{ - voiceChannel: VoiceChannel - connection : VoiceConnection - Volume: number - playing: Boolean - canPlay: Boolean - queue: Array__song - } - class VoiceHandler{ - SongQueue : SongQueue - - GetQueue() - GetVolume() - GetServer() - GetChannel() - GetIsPaused() - GetStatus() - GetVoiceStatus() - Leave() - Join() - Pause() - Resume() - Stop() - Skip() - DeleteSong() - Play() - Player() - SetVolume() - } - class Store{ - nconf : nconf - static soundBoard :any - CreateFolderIfNotExist() - AddFileConfig() - GetNConf() - GetConf() - SetConf() - GetVar() - SaveConf() - } - class Server{ - app : KoaServeur - io : SocketIoServeur - Server : NodeHttp - Port : number - - GetApp() - GetSocket() - GetServer() - AddRouter() - ListenServer() - AddToAppContext() - MountStatic() - AddListener() - } - class Discord{ - Client : DiscordJsClient - Ready : Boolean - BotId : number - VoiceHandler : VoiceHandler - - LoginClient() - DisconnectClient() - DefaultFire() - FireWhenDebug() - FireWhenWarn() - FireWhenError() - FireWhenReady() - FireWhenDisconnect() - FireWhenGuildJoin() - - GetBotId() - GetClient() - GetUser() - GetVoice() - GetAllServer() - GetOneServer() - GetAllChan() - GetOneChan() - SetPresenceFromPresenceData() - SetPresence() - getVoice() - VoiceJoin() - VoiceLeave() - } - class DataBase{ - db : sqliteDatabase - Table : any - - CreateTokenTable() - CreateTabTable() - FormatString() - InsertToken() - GetAllToken() - GetToken() - DeleteToken() - EditToken() - GetAllTab() - DeleteTab() - InsertTab() - EditTabLabel() - EditTabContent() - } -} -@enduml \ No newline at end of file diff --git a/Annalyse/V2.puml b/Annalyse/V2.puml deleted file mode 100644 index f7e3504..0000000 --- a/Annalyse/V2.puml +++ /dev/null @@ -1,234 +0,0 @@ -@startuml v2 -package "Client React/Redux"{ - class Bot{ - img : any - user : any - link : string - Serveur : Array_any - ActiveServeur : String - ActiveBot : number - ServeurChan: Array_any - canPlay : Array_any - BotGetter() - CanPlay() - BotServerGetter() - BotServerChanGetter() - reset() - } - class Event{ - botConnected : Boolean - voiceUpdate : Boolean - boardUpdate : Boolean - - eventInit() - setBotConnected() - setVoiceUpdate() - setBoardUpdate() - } - - class Voice{ - Playing:Boolean - Volume:number - ChanId:String - GuildId:String - Status:Boolean - Asap:Boolean - Paused:Boolean - Queue : Any - - SetChanId() - SetAsap() - JoinChan() - LeaveChan() - StopVoice() - SkipVoice() - StartVoice - SetVolume() - GetStatus() - GetVoice() - GetPause() - GetVolume() - SetChanIdAction() - } - - interface Token{ - id: number - label: string - token : string - } - - class TokenState{ - {field}allToken : Array(Token) - ActiveTokenId : number - - TokenGetter() - TokenCreate() - TokenDelete() - TokenActivate() - TokenDeactivate() - } - - class showModal{ - TokenForm: Boolean - CreateTab: Boolean - CreateButton: Boolean - Burger: Boolean - BoardParam: Boolean - queueSlide: Boolean - importExport: Boolean - - ShowTokenForm() - HideTokenForm() - ShowCreateTab() - HideCreateTab() - showCreateButton() - HideCreateButton() - SetBurger() - SetBoardParam() - SetQueueSlide() - SetImportExport() - } - - class sBoard{ - Board: Array_any - ActiveBoard: number - ActiveLayout : Array_any - Sound: String - Url: String - Button: String - Type: enumSongType - BoardAsChanged: Boolean - Editing: Boolean - Id: number - SetActiveBoard() - SetSound() - SetHandlerLayout() - Lock() - Unlock() - AddButton() - EditButton() - LoadButton() - RemoveButton() - ResetCreateButtonModal() - SetUrl() - SetButton() - SetType() - UpdateBoard() - GetBoardd() - DeleteBoard() - UpdateBoard() - CreateBoard() - } -} - -package "Serveur"{ - interface song{ - title: string - url: string - type: SongType - } - interface SongQueue{ - voiceChannel: VoiceChannel - connection : VoiceConnection - Volume: number - playing: Boolean - canPlay: Boolean - queue: Array__song - } - class VoiceHandler{ - SongQueue : SongQueue - - GetQueue() - GetVolume() - GetServer() - GetChannel() - GetIsPaused() - GetStatus() - GetVoiceStatus() - Leave() - Join() - Pause() - Resume() - Stop() - Skip() - DeleteSong() - Play() - Player() - SetVolume() - } - class Store{ - nconf : nconf - static soundBoard :any - CreateFolderIfNotExist() - AddFileConfig() - GetNConf() - GetConf() - SetConf() - GetVar() - SaveConf() - } - class Server{ - app : KoaServeur - io : SocketIoServeur - Server : NodeHttp - Port : number - - GetApp() - GetSocket() - GetServer() - AddRouter() - ListenServer() - AddToAppContext() - MountStatic() - AddListener() - } - class Discord{ - Client : DiscordJsClient - Ready : Boolean - BotId : number - VoiceHandler : VoiceHandler - - LoginClient() - DisconnectClient() - DefaultFire() - FireWhenDebug() - FireWhenWarn() - FireWhenError() - FireWhenReady() - FireWhenDisconnect() - FireWhenGuildJoin() - - GetBotId() - GetClient() - GetUser() - GetVoice() - GetAllServer() - GetOneServer() - GetAllChan() - GetOneChan() - SetPresenceFromPresenceData() - SetPresence() - getVoice() - VoiceJoin() - VoiceLeave() - } - class DataBase{ - db : sqliteDatabase - Table : any - - CreateTokenTable() - CreateTabTable() - FormatString() - InsertToken() - GetAllToken() - GetToken() - DeleteToken() - EditToken() - GetAllTab() - DeleteTab() - InsertTab() - EditTabLabel() - EditTabContent() - } -} -@enduml \ No newline at end of file diff --git a/Annalyse/v1_infra.puml b/Annalyse/v1_infra.puml deleted file mode 100644 index 8c0b9ac..0000000 --- a/Annalyse/v1_infra.puml +++ /dev/null @@ -1,34 +0,0 @@ -@startuml v1 infra -node client{ - component Redux - component React - component Socket_io_client -} - -node serveur{ - component socket_io_serveur - component koa - component DiscordJs - component Koa_Static_client - component Store - component Db -} - -React <--> Redux -Socket_io_client <--> Redux - -koa <--> socket_io_serveur -koa <--> DiscordJs -koa <--> Store -koa <--> Db -koa <--> Koa_Static_client -Db <--> Store -Db <--> DiscordJs -socket_io_serveur <--> DiscordJs -socket_io_serveur <--> Store -socket_io_serveur <--> Db - -client --> serveur : Axios -serveur --> client : Socket.io - -@enduml \ No newline at end of file diff --git a/Annalyse/v2_infra.puml b/Annalyse/v2_infra.puml deleted file mode 100644 index d300078..0000000 --- a/Annalyse/v2_infra.puml +++ /dev/null @@ -1,50 +0,0 @@ -@startuml v2 infra -node node[ - Vert = dispatch + state - Rouge = - Black = Is part of -] - -node client{ - component Redux - component React - component Socket_io_client -} - -node serveur{ - component ReduxServeur as rs - component socket_io_serveur - component Store - component koa - agent koa_Api - component DiscordJs - agent DiscordBot - component DiscordJsVoiceHandler as dsv - component Koa_Static_client - component Db -} - -rs <-[#Green]-> Db -rs <-[#Green]-> Store -rs <-[#Green]-> koa -rs <-[#Green]-> DiscordBot -rs <-[#Green]-> DiscordJs -koa -[#Black]-> Koa_Static_client : Affiche l'interface -Koa_Static_client --> client -koa <-[#Black]-> koa_Api -rs <-[#Green]-> dsv -DiscordJs <-[#Black]-> DiscordBot -DiscordJs <-[#Black]-> dsv -rs --> socket_io_serveur : Emit des event - -React <--> Redux -Socket_io_client <--> Redux -Redux--> koa_Api : Appelle via Axios - - -socket_io_serveur --> Socket_io_client - -client --> serveur : Axios -serveur --> client : Socket.io - -@enduml \ No newline at end of file diff --git a/Icon/pause.svg b/Icon/pause.svg deleted file mode 100644 index 0ccad17..0000000 --- a/Icon/pause.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/Icon/pen.svg b/Icon/pen.svg deleted file mode 100644 index 05afc3b..0000000 --- a/Icon/pen.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/Icon/play.svg b/Icon/play.svg deleted file mode 100644 index 2249720..0000000 --- a/Icon/play.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/Icon/trash.svg b/Icon/trash.svg deleted file mode 100644 index e459f98..0000000 --- a/Icon/trash.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/Icon/youtube.svg b/Icon/youtube.svg deleted file mode 100644 index d699726..0000000 --- a/Icon/youtube.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/README.md b/README.md index 540dfdf..8960fa2 100644 --- a/README.md +++ b/README.md @@ -1,171 +1,33 @@ -# Bot Discord ? (OLD SOUNDBOARD) +# Website -[![Linux:Build/release](https://github.com/batleforc/UnlabeledProject/actions/workflows/build-linux.yml/badge.svg)](https://github.com/batleforc/UnlabeledProject/actions/workflows/build-linux.yml) -[![Win:Build/release](https://github.com/batleforc/UnlabeledProject/actions/workflows/build-windows.yml/badge.svg)](https://github.com/batleforc/UnlabeledProject/actions/workflows/build-windows.yml) -[![Mac:Build/release](https://github.com/batleforc/UnlabeledProject/actions/workflows/build-mac.yml/badge.svg)](https://github.com/batleforc/UnlabeledProject/actions/workflows/build-mac.yml) -[![CodeFactor](https://www.codefactor.io/repository/github/batleforc/unlabeledproject/badge)](https://www.codefactor.io/repository/github/batleforc/unlabeledproject) -![GitHub commit activity](https://img.shields.io/github/commit-activity/m/batleforc/UnlabeledProject) - - -Projet d'une soundboard vers une toolbox afin de me familiariser avec certain package : - -## L'objectif - -Ce bot est et devient une "simple" boite a outils Discord avec une interface web. - -Les objectif sont : - - -> Mettre en place une SoundBoard qui émet du son pour le moment via discord - => Contrôle de la soundboard via CMD discord - => Contrôle de la soundboard via interface WEB - -> Mise en place de plugin commande/Endpoint - -> Mise en place de configuration +This website is built using [Docusaurus 2](https://v2.docusaurus.io/), a modern static website generator. ## Installation -Deux choix s'offre a vous : - -- Build les source via - -```shell - $ yarn - Install les dépendance - $ yarn build - Permet de build le serveur et le client - $ yarn dist - Permet de build les source dans un exécutable +```console +yarn install ``` -- Télécharger une release - -=> [Github](https://github.com/batleforc/UnlabeledProject/releases) - -### Linux - -Pour installer la version snap : - - ```shell - - $ snap install ${filename} --dangerous --classic - Install the snap application - - ``` - -Le param dangerous permet d'installer le fichier snap qui n'est pas encore signer. -Le param classic permet d'installer le fichier snap en lui laissant l'accès aux fichier du pc (cella permet entre autre d'installer les fichier ffmpeg) - -Pour installer la version AppImage - ```shell - $ chmod a+x ${filename}.appImage - Permet d'indiquer que le fichier est exécutable - $ ./${filename}.appImage - ``` - -### Win - -Installer le fichier .exe - -### Mac - -Alors la.... - -## SoundBoard ? - -Une sound board c'est quoi ? Une Sound board est une table non pas de mixage mais d'effet sonore. - -L'objectif est simple : - - -> Afficher une liste d'effet sonore - -> Modificateur de voix ? V2 webRTC - -> Déclencher ces effet sois via une page web sur l'ordinateur sois sur son smartphone - -> Avoir un serveur local qui contiendrais la solution et qui jouerais les son sur le poste en utilisant le micro - => L'intérêt est de pouvoir appliquer les effet sonore sur discord - -> Ajouter des effet sonore - -> Avoir un lien avec Spotify - -> Dans une V2 un lien avec Deezer/SoundCloud - -> Un système de plugin audio (permet l'ajout de fonctionnalité en fonctionnement et une gestion de l'activation ou non) - => Pour les plugin : - => Contrôle via discord - => Contrôle via des raccourci clavier +## Local Development -=> recense des son - -=> a approfondir - -## Mise en oeuvre - -L'objectif serais d'émettre des sons sur un input audio que discord ou un autre peux capturer. - -### Mappage - -- / => Le client de l'app (react) - - /api => Api avec le framework Koa - - /io => Socket .io permet le temps réel - -## Configuration - -### UI - -- Axios : Fortement conseiller, je n'ai encore jamais eu le courage de passer le cap -- React : Package que j'aime beaucoup et que je souhaite approfondir -- Redux : Comme pour React -- Typescript : Version d'un js typer qui me fait TRES ENVIE -- Socket .io : Pas utiliser depuis un moment -- Tailwind - -### BackEnd - -- Koa : Alternative a Express dont on ne ma dis que du bien - - - Koa router - - Koa Body - - Koa Static - - Koa Mount - -- Typescript -- Socket.io : Pas utiliser depuis un moment - -### Général - -- Yarn - -### Build/Watch - - - Server - - Watch (S:DevWatch) - => S:Build : Cli type script + -w (Watch) + --projet Configuration spécifique aux build du serveur) - => S:Watch : nodemon + -w (surveille un dossier précis) + Fichier a exécuter - - Build (S:ProdBuild) - => cli type script avec configuration sans -w - - Client - - Watch (start) - => craco start (fichier de configuration spécifique a craco) - - Build (build) - => craco build (fichier de configuration spécifique a craco) - - Général - - watch (watch) - => concurrently + --names (les alias de chaque commande) + -c (les couleur attribuer aux log de chaque commande) + les commande - - build - => Pas encore définis - -### Useful Link - - - - +```console +yarn start +``` - +This command starts a local development server and open up a browser window. Most changes are reflected live without having to restart the server. - +## Build - +```console +yarn build +``` - Voice : +This command generates static content into the `build` directory and can be served using any static contents hosting service. - +## Deployment - +```console +GIT_USER= USE_SSH=true yarn deploy +``` - +If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. diff --git a/Server/Actions/Board.ts b/Server/Actions/Board.ts deleted file mode 100644 index d07bd83..0000000 --- a/Server/Actions/Board.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; -import { Db } from "../index"; -import { SocketEmit, BoardEvent } from "./Event"; - -export interface iBoard { - id: number; - label: string; - content: string; -} -export interface iBoardState { - Board: [iBoard] | [any] | any | []; - Ready: Boolean; -} - -export const BoardGetter = createAsyncThunk( - "Board/get", - async ( - { force }: { force?: boolean | undefined }, - { dispatch, getState } - ) => { - dispatch(setReady(Db.db !== undefined)); - return Db.GetAllTab(); - } -); - -export const BoardCreate = createAsyncThunk( - "Board/Create", - async ({ label }: { label: string }, { dispatch, getState }) => { - await Db.InsertTab(label); - await dispatch(BoardGetter({ force: false })).then(() => - dispatch(SocketEmit(BoardEvent.BoardCreate)) - ); - } -); - -export const BoardDelete = createAsyncThunk( - "Board/Create", - async ({ TabId }: { TabId: number }, { dispatch, getState }) => { - await Db.DeleteTab(TabId); - await dispatch(BoardGetter({ force: false })).then(() => - dispatch(SocketEmit(BoardEvent.BoardDelete)) - ); - } -); - -export const BoardUpdate = createAsyncThunk( - "Board/Update", - async ( - { - TabId, - label, - content, - }: { TabId: number; label?: string; content?: object }, - { dispatch } - ) => { - if (label !== undefined) { - await Db.EditTabLabel(TabId, label); - } - if (content !== undefined) { - await Db.EditTabContent(TabId, JSON.stringify(content)); - } - await dispatch(BoardGetter({ force: false })).then(() => - dispatch(SocketEmit(BoardEvent.BoardUpdate)) - ); - } -); - -const initialState = { - Board: [], - Ready: false, -} as iBoardState; -const Board = createSlice({ - name: "Board", - initialState, - reducers: { - setReady: (state, { payload }) => { - state.Ready = payload; - }, - }, - extraReducers: (builder) => - builder.addCase(BoardGetter.fulfilled, (state, { payload }) => { - state.Board = payload; - }), -}); -export const { setReady } = Board.actions; -export default Board.reducer; diff --git a/Server/Actions/Bot.ts b/Server/Actions/Bot.ts deleted file mode 100644 index e813098..0000000 --- a/Server/Actions/Bot.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; -import { ActivityType, PresenceStatusData } from "discord.js"; -import { DiscordClient, Db } from "../index"; -import { Leave } from "./VoiceHandler"; -import { SocketEmit, BotEvent } from "./Event"; - -export const BotGet = createAsyncThunk("Bot/Get", async () => - DiscordClient.GetUser() -); - -export const BotLogin = createAsyncThunk( - "Bot/Login", - async ({ id }: { id: string }) => { - return Db.GetToken(id).then((value) => { - DiscordClient.LoginClient(value.token, Number(id)); - return Number(id); - }); - } -); -export const BotDisconnect = createAsyncThunk( - "Bot/disconnect", - async (_, { dispatch }) => { - DiscordClient.DisconnectClient({ - whenReady: () => { - dispatch(BotGetActivity()); - dispatch(setReady(true)); - dispatch(SocketEmit(BotEvent.BotReady)); - }, - onLeave: () => { - dispatch(Leave()); - dispatch(SocketEmit(BotEvent.BotDisconnect)); - }, - BotUpdate: () => { - dispatch(SocketEmit(BotEvent.BotUpdate)); - }, - GuildUpdate: () => { - dispatch(SocketEmit(BotEvent.GuildUpdate)); - }, - }); - } -); - -export const BotGetAllParsedServeur = createAsyncThunk( - "Bot/GetAllServeur", - async () => - DiscordClient.GetAllServer().map((value: any) => { - return { - id: value.id, - ServeurName: value.name, - ServeurAcronyme: value.nameAcronym, - Icon: value.iconURL(), - nbrMembre: value.memberCount, - ownerID: value.ownerID, - }; - }) -); - -export const BotGetAllChan = createAsyncThunk( - "Bot/GetAllChan", - async ({ params }: { params: string }) => - DiscordClient.GetAllChan(params)?.filter((value) => - ["text", "voice"].includes(value.type) - ) -); - -export const BotSetActivity = createAsyncThunk( - "Bot/SetActivity", - async ( - { - online, - name, - type, - }: { online: PresenceStatusData; name: string; type: ActivityType }, - { dispatch } - ) => { - DiscordClient.SetPresence(online, name, type); - dispatch(BotGetActivity()); - } -); - -export const BotGetActivity = createAsyncThunk("Bot/GetActivity", async () => ({ - status: DiscordClient.GetPresence()?.status || "", - name: DiscordClient.GetPresence()?.activities[0].name || "", - type: DiscordClient.GetPresence()?.activities[0].type || "", -})); - -export interface iBot { - Ready: Boolean; - BotId: number; - Presence: { - Status: string; - name: string; - type: string; - }; -} -const initialState = { - Ready: false, - BotId: -1, - Presence: { - Status: "", - name: "", - type: "", - }, -} as iBot; - -const Bot = createSlice({ - name: "Bot", - initialState, - reducers: { - setReady: (state, { payload }) => { - state.Ready = payload; - }, - }, - extraReducers: (builder) => - builder - .addCase(BotLogin.fulfilled, (state, { payload }) => { - state.BotId = payload; - }) - .addCase(BotGetActivity.fulfilled, (state, { payload }) => { - state.Presence.Status = payload.status; - state.Presence.name = payload.name; - state.Presence.type = payload.type; - }) - .addCase(BotDisconnect.fulfilled, (state) => { - state.Ready = false; - state.BotId = -1; - state.Presence = initialState.Presence; - }), -}); - -export const { setReady } = Bot.actions; -export default Bot.reducer; diff --git a/Server/Actions/Event.ts b/Server/Actions/Event.ts deleted file mode 100644 index 9593c8c..0000000 --- a/Server/Actions/Event.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; -import { Serveur } from "../index"; - -export enum BoardEvent { - BoardUpdate = "BoardUpdate", - BoardCreate = "BoardCreate", - BoardDelete = "BoardDelete", -} - -export enum VoiceEvent { - VoiceJoin = "VoiceJoin", - VoiceChange = "VoiceChanChange", - VoiceLeave = "VoiceLeave", - VoiceUpdate = "VoiceUpdate", - VoiceQueue = "VoiceQueueUpdate", - VoiceError = "VoiceError", - VoiceVolume = "VoiceVolume", -} - -export enum BotEvent { - BotReady = "BotReady", - BotDisconnect = "BotDisconnect", - BotUpdate = "BotUpdate", - GuildUpdate = "guildUpdate", -} - -export enum TokenEvent { - TokenCreate = "TokenCreate", - TokenDelete = "TokenDelete", - TokenUpdate = "TokenUpdate", -} - -export enum AppEvent { - ServeurStart = "AppStart", - ServeurStop = "AppStop", - ConfUpdate = "ConfigUpdate", - ClientRestart = "ClientRestart", -} - -interface event {} -const initialState = {} as event; -const Event = createSlice({ - name: "Event", - initialState, - reducers: { - SocketEmit: (state, { payload }) => { - Serveur.GetSocket().emit(payload); - }, - }, -}); - -export default Event.reducer; -export const { SocketEmit } = Event.actions; diff --git a/Server/Actions/Token.ts b/Server/Actions/Token.ts deleted file mode 100644 index 59df44b..0000000 --- a/Server/Actions/Token.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; -import { Db } from "../index"; -import { SocketEmit, TokenEvent } from "./Event"; - -export interface Token { - id: number; - label: string; - token: string; -} - -export interface iTokenState { - Token: [Token] | [any] | any | []; - Ready: Boolean; -} - -export const TokenGetter = createAsyncThunk( - "Token/Get", - async (undefin, { dispatch }) => { - dispatch(setReady(Db.db !== undefined)); - return Db.GetAllToken(); - } -); - -export const TokenCreate = createAsyncThunk( - "Token/Create", - async ({ label, token }: { label: string; token: string }, { dispatch }) => { - await Db.InsertToken(label, token); - await dispatch(TokenGetter()).then(() => - dispatch(SocketEmit(TokenEvent.TokenCreate)) - ); - } -); - -export const TokenDelete = createAsyncThunk( - "Token/Delete", - async ({ TokenId }: { TokenId: number }, { dispatch }) => { - await Db.DeleteToken(TokenId); - await dispatch(TokenGetter()).then(() => - dispatch(SocketEmit(TokenEvent.TokenDelete)) - ); - } -); - -export const TokenUpdate = createAsyncThunk( - "Token/Update", - async ({ id, label, token }: Token, { dispatch }) => { - await Db.EditToken(id, label, token); - await dispatch(TokenGetter()).then(() => - dispatch(SocketEmit(TokenEvent.TokenUpdate)) - ); - } -); - -const initialState = { - Token: [], - Ready: false, -} as iTokenState; -const Token = createSlice({ - name: "Token", - initialState, - reducers: { - setReady: (state, { payload }) => { - state.Ready = payload; - }, - }, - extraReducers: (builder) => - builder.addCase(TokenGetter.fulfilled, (state, { payload }) => { - state.Token = payload; - }), -}); - -export const { setReady } = Token.actions; -export default Token.reducer; diff --git a/Server/Actions/VoiceHandler.ts b/Server/Actions/VoiceHandler.ts deleted file mode 100644 index 80f3486..0000000 --- a/Server/Actions/VoiceHandler.ts +++ /dev/null @@ -1,234 +0,0 @@ -import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; -import { VoiceChannel, VoiceConnection } from "discord.js"; -import { DiscordClient } from "../index"; -import { canJoin } from "../Utils/Permissions"; -import { SocketEmit, VoiceEvent } from "./Event"; -import ytdl from "ytdl-core"; -import FFmpeg from "prism-media"; - -export enum SongType { - link = 1, - YouTube = 2, - Spotify = 3, -} - -export interface Song { - title: string; - url: string; - type: SongType; -} - -export interface SongQueue { - voiceChannel: VoiceChannel | null; - connection: VoiceConnection | null; -} -const SongGState = { - voiceChannel: null, - connection: null, -} as SongQueue; - -export interface VoiceState { - Volume: number; - playing: boolean; - canPlay: boolean; - queue: Array; -} -export const initialState = { - Volume: 5, - playing: false, - queue: [], - canPlay: false, -} as VoiceState; - -export const getIsPaused = () => SongGState.connection?.dispatcher?.paused; -export const getStatus = () => SongGState.connection?.status; - -export const GetVoiceStatus = createAsyncThunk( - "Voice/GetState", - async (nothing, { getState }) => { - var { Voice } = getState() as { Voice: VoiceState }; - - return { - Queue: Voice.queue, - Volume: Voice.Volume, - Server: SongGState.voiceChannel?.guild, - Chan: SongGState.voiceChannel, - Paused: SongGState.connection?.dispatcher?.paused || false, - Status: SongGState.connection?.status, - }; - } -); - -export const Leave = createAsyncThunk("Voice/Leave", async (_,{dispatch}) => { - SongGState.connection?.disconnect(); - SongGState.voiceChannel = null; - dispatch(SocketEmit(VoiceEvent.VoiceLeave)) - return; -}); -export const Join = createAsyncThunk( - "Voice/join", - async ( - { guildId, channelId }: { guildId: string; channelId: string }, - { dispatch } - ) => { - var voiceChan = DiscordClient.GetOneChan( - guildId, - channelId - ) as VoiceChannel; - if (canJoin(voiceChan)) { - return voiceChan.join().then((value) => { - SongGState.voiceChannel = voiceChan; - SongGState.connection = value; - dispatch(SocketEmit(VoiceEvent.VoiceJoin)) - return true; - }); - } - return false; - } -); -export const Pause = createAsyncThunk("Voice/Pause", async (_, { dispatch }) => { - SongGState.connection?.dispatcher?.pause(); - dispatch(SocketEmit(VoiceEvent.VoiceUpdate)) -}); -export const Resume = createAsyncThunk("Voice/Resume", async (_, { dispatch }) => { - SongGState.connection?.dispatcher?.resume(); - dispatch(SocketEmit(VoiceEvent.VoiceUpdate)) -}); - -export const Stop = createAsyncThunk( - "Voice/Stop", - async (nothing, { dispatch }) => { - dispatch(Voice.actions.Stop()); - SongGState.connection?.dispatcher?.end(); - dispatch(SocketEmit(VoiceEvent.VoiceUpdate)) - } -); - -export const Skip = createAsyncThunk("Voice/Skip", async (_, { dispatch }) => { - SongGState.connection?.dispatcher?.end(); - dispatch(SocketEmit(VoiceEvent.VoiceUpdate)) -}); - -export const Play = createAsyncThunk( - "Voice/Play", - async ( - { song, now }: { song?: Song; now?: boolean }, - { dispatch, getState } - ) => { - var { Voice: voice } = getState() as { Voice: VoiceState }; - if (!voice.canPlay || !song) return; - if (song.type === 2) - song.title = (await ytdl.getInfo(song.url)).videoDetails.title; - if (now) { - dispatch(Voice.actions.AddSongNow({ song: song })); - } else dispatch(Voice.actions.AddSong({ song: song })); - if (voice.queue.length <= 1) { - dispatch(Player()); - } - dispatch(SocketEmit(VoiceEvent.VoiceUpdate)) - } -); -const Player = createAsyncThunk( - "Voice/Player", - async ({}, { getState, dispatch }) => { - var { Voice: voice } = getState() as { Voice: VoiceState }; - if (voice.queue.length === 0) { - dispatch(SocketEmit(VoiceEvent.VoiceUpdate)) - return; - } - if (voice.canPlay) { - var dispatcher = SongGState.connection - ?.play( - voice.queue[0].type === SongType.link - ? voice.queue[0].url - : voice.queue[0].type === SongType.YouTube - ? ytdl(voice.queue[0].url, { filter: "audioonly" }) - : voice.queue[0].url - ) - .on("finish", () => { - dispatch(Voice.actions.ShiftSong()); - dispatch(Player()); - dispatch(SocketEmit(VoiceEvent.VoiceUpdate)) - }) - .on("error", (error) => { - dispatch(Voice.actions.setPlaying(false)); - }); - dispatch(Voice.actions.setPlaying(true)); - dispatcher?.setVolumeLogarithmic(voice.Volume / 5); - } else { - dispatch(Voice.actions.setPlaying(false)); - } - } -); - -export const canPlay = createAsyncThunk("Voice/canPlay", async () => { - try { - FFmpeg.FFmpeg.getInfo(); - return { canPlay: true }; - } catch (error) { - return { canPlay: false, msg: error }; - } -}); - -export const setVolume = createAsyncThunk( - "Voice/SetVolume", - async (volume: Number, { dispatch }) => { - dispatch(Voice.actions.setVolume(volume)) - dispatch(SocketEmit(VoiceEvent.VoiceVolume)) - } -); - -export const DeleteSong = createAsyncThunk( - "Voice/DeleteSong", - async (id: number, { dispatch }) => { - dispatch(Voice.actions.DeleteSong(id)) - dispatch(SocketEmit(VoiceEvent.VoiceUpdate)) - } -) - -const Voice = createSlice({ - name: "Voice", - initialState, - reducers: { - setCanPlay: (state, { payload }) => { - state.canPlay = payload; - }, - setVolume: (state, { payload }) => { - state.Volume = payload; - SongGState.connection?.dispatcher?.setVolumeLogarithmic(payload / 5); - }, - setPlaying: (state, { payload }) => { - state.playing = payload; - }, - DeleteSong: (state, { payload: { id } }) => { - state.queue.splice(id, 1); - }, - Stop: (state) => { - state.queue = []; - }, - AddSongNow: (state, { payload: { song } }) => { - state.queue.splice(1, 0, song); - }, - AddSong: (state, { payload: { song } }) => { - state.queue.push(song); - }, - ShiftSong: (state) => { - state.queue.shift(); - }, - }, - extraReducers: (builder) => - builder - .addCase(Leave.fulfilled, (state) => { - state.canPlay = false; - state.queue = []; - state.playing = false; - }) - .addCase(Join.fulfilled, (state, { payload }) => { - state.canPlay = payload; - }) - .addCase(canPlay.fulfilled, (state, { payload }) => { - state.canPlay = payload.canPlay; - }), -}); - -export default Voice.reducer; diff --git a/Server/Actions/index.ts b/Server/Actions/index.ts deleted file mode 100644 index 45e0f2e..0000000 --- a/Server/Actions/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { configureStore, getDefaultMiddleware } from "@reduxjs/toolkit"; -import Board from "./Board"; -import Event from "./Event"; -import Token from "./Token"; -import Bot from "./Bot"; -import Voice from "./VoiceHandler"; - -const store = configureStore({ - reducer: { - Board, - Event, - Token, - Voice, - Bot, - }, - middleware: (getDefaultMiddleware) => getDefaultMiddleware(), - devTools: true, -}); - -export default store; diff --git a/Server/Router/Api.ts b/Server/Router/Api.ts deleted file mode 100644 index b1de469..0000000 --- a/Server/Router/Api.ts +++ /dev/null @@ -1,64 +0,0 @@ -import Router from '@koa/router' -import Token from './Api/Token' -import Bot from './Api/Bot' -import Voice from './Api/Voice' -import sBoard from './Api/sboard' -import FFmpeg from 'prism-media' -import os from 'os' -var router = new Router({ - prefix: '/Api' -}); -router - .get("/",async (ctx : any,next : any)=>{ - ctx.body = "Hello World" - await next() - }) - .post("/", async (ctx : any,next : any)=>{ - ctx.body=ctx.request.body - await next() - }) - .get("/canPlay", async (ctx : any, next:any)=>{ - ctx.body={ - canPlay:false, - os : process.env.npm_config_platform || os.platform(), - ffmpeg:"https://www.ffmpeg.org/download.html", - link:{ - win:"#build-windows", - linux:"#build-linux", - mac:"#build-mac" - }, - where:ctx.store.GetConf("ffmpeg") - } - try{ - FFmpeg.FFmpeg.getInfo() - ctx.body.canPlay = true - } catch(error){ - ctx.body.canPlay = false - ctx.body.message=error - } - await next() - }) - .get("/me",async (ctx:any,next:any)=>{ - if(ctx.discord.Ready) - ctx.body={ - img:ctx.discord.GetUser()?ctx.discord.GetUser().displayAvatarURL():"https://cdn.discordapp.com/embed/avatars/0.png", - user:ctx.discord.GetUser(), - link:`https://discord.com/oauth2/authorize?client_id=${ctx.discord.GetUser().id}&scope=bot&permissions=343273214`, - botId:ctx.discord.GetBotId() - } - else - ctx.body={ - img:"https://cdn.discordapp.com/embed/avatars/0.png", - message:"Bot not started yet or not ready", - link:"", - botId: -1 - } - await next() - }) - -router.use('/token', Token.routes(), Token.allowedMethods()); -router.use('/bot', Bot.routes(), Bot.allowedMethods()); -router.use('/voice',Voice.routes(),Voice.allowedMethods()); -router.use('/sboard',sBoard.routes(),sBoard.allowedMethods()); - -export default router \ No newline at end of file diff --git a/Server/Router/Api/Bot.ts b/Server/Router/Api/Bot.ts deleted file mode 100644 index 0caee9f..0000000 --- a/Server/Router/Api/Bot.ts +++ /dev/null @@ -1,64 +0,0 @@ -import Router from "@koa/router"; -import DataBase from "../../Utils/Db"; -import Discord from "../../Utils/Discord"; -import Store from "../../Actions/index"; -import { - BotDisconnect, - BotGetAllChan, - BotGetAllParsedServeur, - BotLogin, - BotSetActivity, -} from "../../Actions/Bot"; -import store from "../../Actions/index"; -import { Token } from "../../Actions/Token"; -var Bot = new Router(); - -Bot.get("/serveur", async (ctx: any, next: any) => { - if (ctx.discord.Ready) - ctx.body = (await Store.dispatch(BotGetAllParsedServeur())).payload; - else - ctx.body = { - message: "Bot not started yet or not ready", - }; - await next(); -}) - .get("/chan/:id", async (ctx: any, next: any) => { - var params = ctx.params.id; - if (ctx.discord.Ready) { - ctx.body = await (await (Store.dispatch(BotGetAllChan({ params: params })))).payload; - } else ctx.body = []; - await next(); - }) - .post("/start", async (ctx: any, next: any) => { - var { id } = ctx.request.body; - if (id === undefined) { - ctx.body = { message: "id manquant" }; - await next(); - } else { - if (ctx.discord.Ready) await Store.dispatch(BotDisconnect()); - await Store.dispatch( - BotLogin({ - id: id, - }) - ); - ctx.body = { message: "all Is Green" }; - } - await next(); - }) - .post("/stop", async (ctx: any, next: any) => { - Store.dispatch(BotDisconnect()) - ctx.body = { message: "all Is Green" }; - await next(); - }) - .get("/presence", async (ctx: any, next: any) => { - ctx.body = Store.getState().Bot.Presence - await next(); - }) - .post("/presence", async (ctx: any, next: any) => { - var { online, name, type } = ctx.request.body; - await Store.dispatch(BotSetActivity({ online: online, name: name, type: type })) - ctx.body = Store.getState().Bot.Presence - await next(); - }); - -export default Bot; diff --git a/Server/Router/Api/Token.ts b/Server/Router/Api/Token.ts deleted file mode 100644 index 5e6fbf7..0000000 --- a/Server/Router/Api/Token.ts +++ /dev/null @@ -1,52 +0,0 @@ -import Router from "@koa/router"; -import Store from "../../Actions/index"; -import { TokenCreate, TokenDelete, TokenUpdate } from "../../Actions/Token"; -var Token = new Router(); - -Token.get("/", async (ctx: any, next: any) => { - ctx.body = Store.getState().Token.Token; - await next(); -}) - .post("/", async (ctx: any, next: any) => { - var body = ctx.request.body; - if (body.label === undefined || body.token === undefined) { - ctx.status = 400; - ctx.body = { message: "Error one argument missing" }; - } else { - await Store.dispatch( - TokenCreate({ label: body.label, token: body.token }) - ); - ctx.body = Store.getState().Token.Token; - } - await next(); - }) - .delete("/:id", async (ctx: any, next: any) => { - var params = ctx.params.id; - if (params === undefined) { - ctx.status = 400; - ctx.body = { message: "Error one argument missing" }; - } else { - await Store.dispatch(TokenDelete({ TokenId: Number(params) })); - } - ctx.body = Store.getState().Token.Token; - await next(); - }) - .put("/:id", async (ctx: any, next: any) => { - var body = ctx.request.body; - if ( - ctx.params.id === undefined || - body.label === undefined || - body.token === undefined - ) { - ctx.status = 400; - ctx.body = { message: "Error one argument missing" }; - } else { - await Store.dispatch( - TokenUpdate({ id: ctx.params.id, label: body.label, token: body.token }) - ); - } - ctx.body = Store.getState().Token.Token; - await next(); - }); - -export default Token; diff --git a/Server/Router/Api/Voice.ts b/Server/Router/Api/Voice.ts deleted file mode 100644 index 7f1414a..0000000 --- a/Server/Router/Api/Voice.ts +++ /dev/null @@ -1,116 +0,0 @@ -import Router from "@koa/router"; -import Discord from "../../Utils/Discord"; -import { - Song, - getIsPaused, - getStatus, - GetVoiceStatus, - Join, - DeleteSong, - Leave, - setVolume, - Play, - Pause, - Resume, - Stop, - Skip -} from "../../Actions/VoiceHandler"; -import Store from "../../Actions/index"; -var Voice = new Router(); - -Voice.get("/volume", async (ctx: any, next: any) => { - ctx.body = Store.getState().Voice.Volume; - await next(); -}) - .get("/pause", async (ctx: any, next: any) => { - ctx.body = getIsPaused(); - await next(); - }) - .get("/status", async (ctx: any, next: any) => { - ctx.body = getStatus(); - await next(); - }) - .get("/", async (ctx: any, next: any) => { - await Store.dispatch(GetVoiceStatus()).then(({payload}) => { - ctx.body = payload; - }); - await next(); - }) - .post("/join", async (ctx: any, next: any) => { - var { guildId, chanId } = ctx.request.body; - if (guildId === undefined || chanId === undefined) { - ctx.body = { - message: "Param manquant", - guildId: guildId === undefined, - chanId: chanId === undefined, - }; - } else { - Store.dispatch(Join({ guildId: guildId, channelId: chanId })); - ctx.body = { - launched: true, - }; - } - await next(); - }) - .post("/skipAt", async (ctx: any, next: any) => { - var { id } = ctx.request.body; - if (id === undefined) { - ctx.body = { - message: "Param manquant", - SongId: id === undefined, - }; - } else { - Store.dispatch(DeleteSong(id)); - ctx.body = { - launched: true, - }; - } - await next(); - }) - .post("/leave", async (ctx: any, next: any) => { - Store.dispatch(Leave()); - ctx.body = { launched: true }; - await next(); - }) - .post("/volume", async (ctx: any, next: any) => { - var { vol } = ctx.request.body; - if (vol === undefined) { - ctx.body = { message: "Param manquant", vol: vol === undefined }; - } else { - Store.dispatch(setVolume(vol)); - ctx.body = { launched: true }; - } - await next(); - }) - .post("/play", async (ctx: any, next: any) => { - var { toPlay, now } = ctx.request.body; - if (toPlay === undefined) { - ctx.body = { message: "Param manquant ", toPlay: toPlay === undefined }; - } else { - Store.dispatch(Play({ song: (toPlay as Song), now: now })); - ctx.body = { launched: true }; - } - await next(); - }) - .post("/pause", async (ctx: any, next: any) => { - Store.dispatch(Pause()) - ctx.body = { launched: true }; - await next(); - }) - .post("/resume", async (ctx: any, next: any) => { - Store.dispatch(Resume()) - ctx.body = { launched: true }; - await next(); - }) - .post("/stop", async (ctx: any, next: any) => { - Store.dispatch(Stop()) - ctx.body = { launched: true }; - await next(); - }) - .post("/skip", async (ctx: any, next: any) => { - Store.dispatch(Skip()) - ctx.body = { launched: true }; - await next(); - }); - -export default Voice; diff --git a/Server/Router/Api/sboard.ts b/Server/Router/Api/sboard.ts deleted file mode 100644 index b6685c0..0000000 --- a/Server/Router/Api/sboard.ts +++ /dev/null @@ -1,66 +0,0 @@ -import Router from "@koa/router"; -import { Log } from "../../Utils/Log"; -import Store from "../../Actions/index"; -import { BoardCreate, BoardDelete, BoardUpdate } from "../../Actions/Board"; - -var sBoard = new Router(); - -sBoard - .get("/", async (ctx: any, next: any) => { - ctx.body = Store.getState().Board.Board; - await next(); - }) - .post("/", async (ctx: any, next: any) => { - var { label } = ctx.request.body; - if (label === undefined) { - ctx.status = 400; - ctx.body = { message: "Error one argument missing" }; - } else { - await Store.dispatch(BoardCreate({ label: label })); - Log("Board", `[${ctx.request.ip}] ajout d'un board nommer ${label}`); - ctx.body = Store.getState().Board.Board; - } - await next(); - }) - .delete("/:TabId", async (ctx: any, next: any) => { - if (ctx.params.TabId === undefined) { - ctx.status = 400; - ctx.body = { message: "Error one argument missing" }; - } else { - await Store.dispatch(BoardDelete({ TabId: ctx.params.TabId })); - Log( - "Board", - `[${ctx.request.ip}] suppression d'un board a l'id ${ctx.params.TabId}` - ); - ctx.body = Store.getState().Board.Board; - } - await next(); - }) - .put("/:TabId", async (ctx: any, next: any) => { - var { label, content } = ctx.request.body; - var { TabId } = ctx.params; - if (TabId === undefined) { - ctx.status = 400; - ctx.body = { message: "Error one argument missing" }; - } else { - await Store.dispatch( - BoardUpdate({ - TabId: TabId, - label: label, - content: content, - }) - ); - Log( - "Board", - `[${ - ctx.request.ip - }] modification du board ${TabId} => {content:${JSON.stringify( - content - )},label:${label}}` - ); - ctx.body = Store.getState().Board.Board; - } - await next(); - }); - -export default sBoard; diff --git a/Server/Router/Client.ts b/Server/Router/Client.ts deleted file mode 100644 index 8a14df6..0000000 --- a/Server/Router/Client.ts +++ /dev/null @@ -1,9 +0,0 @@ -import serve from 'koa-static' -import koa from 'koa' -import path from 'path' - -var Client = new koa(); -console.log(path.resolve(__dirname,"..",'..',"build")) -Client.use(serve(path.resolve(__dirname,"..",'..',"build"))) - -export default Client; diff --git a/Server/Utils/Db.ts b/Server/Utils/Db.ts deleted file mode 100644 index 72c7932..0000000 --- a/Server/Utils/Db.ts +++ /dev/null @@ -1,86 +0,0 @@ -import sq from "sqlite3"; -import sqlite, { open } from "sqlite"; -import Store from "./Store"; -import { ModuleLog } from "../Utils/Log"; -class DataBase { - db?: sqlite.Database; - Table: any; - constructor(conf: Store, onceReady?: Function) { - open({ - filename: conf.GetConf("db"), - driver: sq.cached.Database, - }).then((db) => { - this.db = db; - this.Table = conf.GetConf("table"); - this.CreateTokenTable(conf.GetConf("table").token); - this.CreateTabTable(conf.GetConf("table").tab); - if (onceReady !== undefined) onceReady(); - ModuleLog("DataBase", undefined, true); - }); - } - CreateTokenTable = (TokenTableName: string) => - this.db?.run( - `CREATE TABLE IF NOT EXISTS ${TokenTableName} ( - id integer PRIMARY KEY, - label varchar(55) NOT NULL, - token varchar(255) NOT NULL - )` - ); - CreateTabTable = (TabTableName: string) => - this.db?.run( - `CREATE TABLE IF NOT EXISTS ${TabTableName} ( - id integer PRIMARY KEY, - label varchar(55) NOT NULL, - content TEXT - )` - ); - - FormatString = (stringContent: string) => { - return stringContent.split("'").join("''"); - }; - - InsertToken = (label: string, token: string) => - this.db?.run(`INSERT INTO ${this.Table.token} (label,token) VALUES (?,?)`, [ - this.FormatString(label), - token, - ]); - GetAllToken = async () => this.db?.all(`select * from ${this.Table.token} `); - GetToken = async (id: string) => - this.db?.get(`Select * from ${this.Table.token} where id = ?`, id); - DeleteToken = (idToken: number) => - this.db?.exec(`Delete from ${this.Table.token} where id=${idToken}`); - EditToken = (idToken: number, label: string, token: string) => - this.db?.run( - `Update ${this.Table.token} set label = '${this.FormatString( - label - )}', token = '${token}' where id=${idToken}` - ); - - GetAllTab = async () => this.db?.all(`select * from ${this.Table.tab}`); - DeleteTab = (TabId: number) => { - this.db?.exec(`Delete from ${this.Table.tab} where id=${TabId}`); - }; - InsertTab = (label: string) => - this.db?.run(`INSERT INTO ${this.Table.tab} (label,content) VALUES (?,?)`, [ - this.FormatString(label), - "[]", - ]); - EditTabLabel = (TabId: number, label: string) => - this.db?.run( - `Update ${this.Table.tab} set label = '${this.FormatString( - label - )}' where id=${TabId}` - ); - EditTabContent = (TabId: number, content: string) => - this.db?.run( - `Update ${this.Table.tab} set content = '${this.FormatString( - content - )}' where id=${TabId}` - ); - InsertOrUpdateTab = (TabId: number, label: string, content: string) => - this.db?.run( - `REPLACE INTO ${this.Table.tab} (label,content) VALUES ('${label}','${content}')` - ); -} - -export default DataBase; diff --git a/Server/Utils/Discord.ts b/Server/Utils/Discord.ts deleted file mode 100644 index 96c5b8a..0000000 --- a/Server/Utils/Discord.ts +++ /dev/null @@ -1,108 +0,0 @@ -import Discordjs, { - ActivityType, - PresenceData, - PresenceStatusData, -} from "discord.js"; -import { Log, ModuleLog } from "../Utils/Log"; -class Discord { - client: Discordjs.Client; - Ready: Boolean; - BotId: number; - constructor() { - this.BotId = -1; - this.client = new Discordjs.Client(); - this.Ready = false; - ModuleLog("Discord", undefined, true); - } - - //#region Auth - LoginClient = (token: string, botId: number) => { - this.client.login(token); - this.BotId = botId; - }; - DisconnectClient = ( - { onLeave, whenReady,GuildUpdate,BotUpdate }: { onLeave?: Function; whenReady?: Function,GuildUpdate?:Function,BotUpdate?:Function } - ) => { - this.client = new Discordjs.Client(); - this.DefaultFire(BotUpdate,GuildUpdate,whenReady); - this.BotId = -1; - this.Ready = false; - if (onLeave) onLeave(); - if (BotUpdate) BotUpdate(); - }; - //#endregion - - //#region FireEvent - DefaultFire = (BotUpdate?:Function,GuildUpdate?:Function, WhenReady?: Function) => { - this.FireWhenReady(BotUpdate, () => { - if (WhenReady) WhenReady(); - }); - this.FireWhenDisconnect(BotUpdate, () => {}); - this.FireWhenGuildJoin(GuildUpdate, () => {}); - if (process.env.NODE_ENV == "development") { - this.FireWhenDebug(); - this.FireWhenWarn(); - this.FireWhenError(); - } - ModuleLog("Discord", "Event initialiser"); - }; - FireWhenDebug = () => - this.client.on("debug", (message: string) => Log("Discord", message)); - FireWhenWarn = () => - this.client.on("warn", (message: string) => Log("Discord", message)); - FireWhenError = () => - this.client.on("error", (message: Error) => - Log("Discord", message.message) - ); - FireWhenReady = (BotUpdate?: Function, toDo?: Function) => - this.client.on("ready", () => { - this.Ready = true; - Log("Discord", "Bot Started"); - Log("Socket", "Tout les client sont actualiser"); - if (BotUpdate)BotUpdate(); - if(toDo)toDo(); - }); - FireWhenDisconnect = (BotUpdate?: Function, toDo?: Function) => - this.client.on("disconnect", () => { - this.Ready = false; - if (BotUpdate)BotUpdate(); - if(toDo)toDo(); - Log("Discord", "Bot Off"); - }); - FireWhenGuildJoin = (GuildUpdate?: Function, toDo?: Function) => - this.client.on("guildCreate", (guild) => { - if (GuildUpdate) GuildUpdate(); - if(toDo) toDo(); - Log("Discord", "Bot join guild " + guild.name); - Log("Socket", "Tout les client sont actualiser"); - }); - //#endregion - - //#region Getter - GetBotId = () => this.BotId; - GetClient = () => this.client; - GetUser = () => this.client.user; - GetPresence = () => this.GetUser()?.presence; - GetAllServer = () => this.client.guilds.cache; - GetOneServer = (guildId: string) => - this.client.guilds.cache.find((value, index) => index === guildId); - GetAllChan = (guildId: string) => this.GetOneServer(guildId)?.channels.cache; - GetOneChan = (guildId: string, ChanId: string) => - this.GetAllChan(guildId)?.find((value, index) => index === ChanId); - //#endregion - - //#region PresenceHandler - SetPresenceFromPresenceData = (presence: PresenceData) => - this.client.user?.setPresence(presence); - SetPresence = (online: PresenceStatusData, name: string, type: ActivityType) => - this.SetPresenceFromPresenceData({ - status: online, - activity: { - name: name, - type: type, - }, - }); - //#endregion -} - -export default Discord; diff --git a/Server/Utils/Log.ts b/Server/Utils/Log.ts deleted file mode 100644 index bdc0643..0000000 --- a/Server/Utils/Log.ts +++ /dev/null @@ -1,84 +0,0 @@ -const chalk = require("chalk"); -const { createLogger, format, transports } = require("winston"); -const { consoleFormat } = require("winston-console-format"); -const Path = require("path"); -require("winston-daily-rotate-file"); - -const transport = new transports.DailyRotateFile({ - filename: "unlabeled-%DATE%.log", - datePattern: "YYYY-MM-DD-HH", - zippedArchive: true, - dirname: Path.join( - String(process.env.APPDATA || process.env.HOME), - "SoundBoard", - "log" - ), - maxSize: "20m", - maxFiles: "7d", -}); -const logger = createLogger({ - level: "silly", - format: format.combine( - format.timestamp(), - format.ms(), - format.errors({ stack: true }), - format.splat(), - format.json() - ), - defaultMeta : {service:"UnlabeledProject"}, - transports: [ - transport, - ], -}); - -if (process.env.NODE_ENV !== "production") { - logger.add(new transports.Console({ - format: format.combine( - format.colorize({ all: true }), - format.padLevels(), - consoleFormat({ - showMeta: true, - metaStrip: ["timestamp", "service"], - inspectOptions: { - depth: Infinity, - colors: true, - maxArrayLength: Infinity, - breakLength: 120, - compact:Infinity - } - }) - ) - })); -} - -/** - * * Permet de console.log - * @param tag Qui envoie le message - * @param message Message envoyer par l'utilisateur - */ -export const Log = async (tag: string, message: string) => { - logger.info(`[${tag}]=> ${new Date().toISOString()} : ${message}`); -}; - -export const LogObject = async (tag: string, message: object) => { - logger.info(message); -}; - -/** - * * Permet de log une erreur - * @param tag Qui envoie le message - * @param message Message envoyer par l'utilisateur - */ -export const ErrorLog = async (tag: string, message: string) => { - logger.error(`${tag}]=> ${new Date().toISOString()} : ${message}`) -}; - -export const ModuleLog = async ( - who: string, - file: string = "", - init: Boolean = false -) => { - logger.verbose(`[${who}]=> ${new Date().toISOString()} : ${ - init ? file.substring(0, file.length - 3) : file - } ${init ? "est initialiser" : ""}`); -}; diff --git a/Server/Utils/Permissions.ts b/Server/Utils/Permissions.ts deleted file mode 100644 index 4aa7e2e..0000000 --- a/Server/Utils/Permissions.ts +++ /dev/null @@ -1,7 +0,0 @@ -import {Client, VoiceChannel} from 'discord.js' - -export const getPermission = (voiceChan : VoiceChannel) => - voiceChan.guild.me&&voiceChan.permissionsFor(voiceChan.guild.me) - -export const canJoin = ( voiceChan : VoiceChannel) => - getPermission(voiceChan)?.has("CONNECT")&&getPermission(voiceChan)?.has("SPEAK") || false \ No newline at end of file diff --git a/Server/Utils/Server.ts b/Server/Utils/Server.ts deleted file mode 100644 index c71012e..0000000 --- a/Server/Utils/Server.ts +++ /dev/null @@ -1,66 +0,0 @@ -import Router from "koa-router" -import cors from "@koa/cors" -import {Server,Socket} from 'socket.io' -import {ModuleLog} from '../Utils/Log' -import serve from "koa-static" -import path from 'path' -import fs from "fs" - -var Koa = require('koa') -var KoaBody = require('koa-body') -var mount = require('koa-mount') -class WebServer{ - app : any - io : any - server : any - Port : number - constructor(Port : number){ - this.Port =Port - this.app= new Koa(); - this.server = require('http').createServer(this.app.callback()) - this.io = new Server(this.server,{ - cors:{ - origin:"*" - } - }) - var static_pages = new Koa(); - static_pages.use(serve(path.resolve(__dirname,"..",'..',"build"))) - this.app.use(mount("/",static_pages)) - this.app.use(cors()) - this.app.use(KoaBody()) - this.io.emit("botReset"); - this.io.on('connection',(Socket : Socket)=>{ - this.io.emit("botUpdate") - }) - ModuleLog("WebServer",undefined,true) - } - - GetApp = () => this.app - GetSocket = () => this.io - GetServer = () => this.server - - // KOA - AddRouter = ( router : Router ) => this.app.use(router.routes()).use(router.allowedMethods()) - - ListenServer = ( callback : Function ) => { - this.app.use(async (ctx : any,next:any)=>{ - if(ctx.body===undefined){ - ctx.type='html' - ctx.body=fs.readFileSync(path.resolve(__dirname,"..","..",'build/index.html')) - } - await next() - }) - this.server.listen(this.Port,callback) - } - - AddToAppContext = ( key : string , ContextObject : object ) => this.app.context[key] = ContextObject - - MountStatic = ( path : string , koaMiddleware : any ) => this.app.use(mount(path,koaMiddleware)) - - // SOCKET.IO - AddListener = ( event : string , whatToDo : Function ) => this.io.on('connection', (Socket : Socket) => { - Socket.on(event,(param : any)=>whatToDo(Socket,param)) - }) -} - -export default WebServer; \ No newline at end of file diff --git a/Server/Utils/Store.ts b/Server/Utils/Store.ts deleted file mode 100644 index 4b70d23..0000000 --- a/Server/Utils/Store.ts +++ /dev/null @@ -1,43 +0,0 @@ -import path from 'path' -import fs from 'fs' -import {ModuleLog} from '../Utils/Log' -class Store{ - nconf - static soundBoardRoot : any - constructor(){ - this.nconf = require('nconf') - Store.soundBoardRoot = path.join(String(process.env.APPDATA||process.env.HOME),"SoundBoard") - this.nconf - .argv() - .env() - this.CreateFolderIfNotExist(Store.soundBoardRoot) - this.CreateFolderIfNotExist(path.join(Store.soundBoardRoot,"Store")) - this.CreateFolderIfNotExist(path.join(Store.soundBoardRoot,"log")) - this.AddFileConfig(path.join(Store.soundBoardRoot,"Store","config.json")) - this.CreateFolderIfNotExist(path.join(Store.soundBoardRoot,"ffmpeg")) - this.CreateFolderIfNotExist(path.join(Store.soundBoardRoot,"command")) - process.env.FFMPEG_BIN=path.join(Store.soundBoardRoot,"ffmpeg","ffmpeg") - this.nconf.defaults({ - "db": path.join(Store.soundBoardRoot,"soundboard.db"), - "ffmpeg": path.join(Store.soundBoardRoot,"ffmpeg"), - "tokenTable":"TokenTable", - "table":{ - "token":"TokenTable", - "test":"TestTable", - "tab":"TabTable", - "tabItem":"TabItemTable" - } - }) - ModuleLog("Store",undefined,true) - } - CreateFolderIfNotExist = (pathDir:string)=>!fs.existsSync(pathDir)?fs.mkdirSync(pathDir):true - AddFileConfig = (pathDir:string) => this.nconf.file({file:pathDir}) - GetNConf = () => this.nconf - GetConf = (label : string) => this.nconf.get(label) - setConf = (label : string,value : object) => this.nconf.set(label,value) - GetVar = (store:string,variable:string) => this.nconf.get(`${store}:${variable}`) - SaveConf = (callback?:Function)=> this.nconf.save(callback) - -} - -export default Store; \ No newline at end of file diff --git a/Server/index.ts b/Server/index.ts deleted file mode 100644 index a586a83..0000000 --- a/Server/index.ts +++ /dev/null @@ -1,67 +0,0 @@ -require("dotenv-flow").config(); -import { Log, ModuleLog, LogObject } from "./Utils/Log"; -ModuleLog("Serveur", "Starting"); -import ReduxStore from "./Actions"; -import WebServer from "./Utils/Server"; -import Store from "./Utils/Store"; -import DataBase from "./Utils/Db"; -import Discord from "./Utils/Discord"; -import Api from "./Router/Api"; -import { BoardGetter } from "./Actions/Board"; -import { TokenGetter } from "./Actions/Token"; -import { BotDisconnect } from "./Actions/Bot"; -import { SocketEmit, AppEvent } from "./Actions/Event"; -import { Leave } from "./Actions/VoiceHandler"; - -export var store = new Store(); -export var DiscordClient = new Discord(); -export var Serveur = new WebServer(Number(process.env.SERVER_PORT) || 5000); -export var Db = new DataBase(store, () => { - ReduxStore.dispatch(BotDisconnect()); - ReduxStore.dispatch(BoardGetter({ force: false })); - ReduxStore.dispatch(TokenGetter()); - ReduxStore.dispatch(SocketEmit(AppEvent.ServeurStart)); -}); - -ReduxStore.subscribe(() => LogObject("Redux", ReduxStore.getState())); - -Serveur.AddToAppContext("Db", Db); -Serveur.AddToAppContext("discord", DiscordClient); -Serveur.AddToAppContext("store", store); -Serveur.AddToAppContext("io", Serveur.GetSocket()); -Serveur.AddToAppContext("Redux", ReduxStore); -Serveur.AddRouter(Api); - -Serveur.GetSocket().on("connection", (socket: any) => { - Log("Socket", "Un utilisateur est connecter"); -}); -Serveur.AddListener("message", (socket: any, param: any) => { - socket.emit("test", param); -}); - -process.stdin.resume(); - -function exitHandler() { - ReduxStore.dispatch(SocketEmit(AppEvent.ServeurStop)); - ReduxStore.dispatch(Leave()); - ReduxStore.dispatch(BotDisconnect()); - process.exit(); -} - -process.on("exit", exitHandler); - -process.on("SIGINT", exitHandler); - -process.on("SIGUSR1", exitHandler); -process.on("SIGUSR2", exitHandler); - -process.on("uncaughtException", exitHandler); - -Serveur.ListenServer(() => { - ModuleLog( - "Serveur", - `Le serveur est en écoute sur le port ${String( - process.env.SERVER_PORT - )} et fonctionne en ${String(process.env.NODE_ENV)}` - ); -}); diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 0000000..e00595d --- /dev/null +++ b/babel.config.js @@ -0,0 +1,3 @@ +module.exports = { + presets: [require.resolve('@docusaurus/core/lib/babel/preset')], +}; diff --git a/blog/2019-05-30-welcome.mdx b/blog/2019-05-30-welcome.mdx new file mode 100644 index 0000000..c1f1fae --- /dev/null +++ b/blog/2019-05-30-welcome.mdx @@ -0,0 +1,11 @@ +--- +slug: Bienvenue +title: Bienvenue +author: Maxime Leriche +author_title: Étudiant développeur +author_url: https://github.com/batleforc +author_image_url: /UnlabeledProject/img/toolbox.png +tags: [hello, docusaurus, UnlabeledProject] +--- + + diff --git a/craco.config.js b/craco.config.js deleted file mode 100644 index 414adba..0000000 --- a/craco.config.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = { - style: { - postcss: { - plugins: [ - require('tailwindcss'), - require('autoprefixer'), - ], - }, - }, -} \ No newline at end of file diff --git a/docs/GetStarted/creerBot.md b/docs/GetStarted/creerBot.md new file mode 100644 index 0000000..46d8051 --- /dev/null +++ b/docs/GetStarted/creerBot.md @@ -0,0 +1,66 @@ +--- +title: Créer/Choisir un bot +--- + +Vous venez de lancer le client "unlabeled" sauf qu'il vous indique que vous n'avez pas de token ! Que faire ?? + +Pas de panique les étapes sont assez rapides! + +### 1. Créer une application discord + +Afin de créer une application discord qui ensuite deviendra un "bot rendez vous" sur discord . + +Une fois sur cette page et que vous vous êtes authentifié avec un compte discord vous avez deux choix: + +- Vous avez déjà une application et souhaitez l'utiliser avec notre client ? Si oui vous pouvez directement passer à l'étape 2 après avoir cliqué sur l'application que vous aurez choisi. +- Vous n'avez pas d'application? Alors continuez de lire 😄 + +#### Vous êtes toujours là ? Si oui, vous souhaitez créer une application discord ! + +![newApp](/img/newApp.png) +En haut à droite de votre page se trouve un bouton "New Application", cliquez dessus. + +Il vous sera demandé d'entrer un nom. Attention celui-ci sera le nom de votre bot. + +Une fois fait vous serez redirigé sur une page vous permettant de changer l'image de votre application/bot ainsi que son nom et sa description. + +### 2. Créer un bot dans discord et récupérer son token + +Vous apercevrez dans le menu de gauche un onglet "Bot", veuillez vous y rendre. + +![BuildABot](/img/buildABot.png) + +Il est temps futur docteur Frankenstein ! Donnez la vie à votre oeuvre ! Votre premier bot discord ! + +Vous trouverez un bouton "Add Bot" qui liera un bot à votre application discord. + +![IlEstVivant](/img/itsALIVE.png) + +N'est il pas beau ce premier bot ? Ici vous aurez la possibilité de changer le nom de votre bot ainsi que son image. Mais le plus important reste à venir. Il est temps de cliquer sur copy, ce qui vous donnera accès à toute la magie de discord. Le TOKEN cette clef illisible est l'identité de votre bot, ne le partager surtout pas ! (sauf avec le client bien sur). + +### 3. Créer le bot dans le client + +Impatient ? Il est temps de retourner dans le client et de cliquer en haut à droite sur "No Bot Ready" + +Une fois fais vous obtiendrez un bouton Add Token, après avoir cliquer dessus il vous sera demandé d'entrer un label pour votre bot (celui ci vous permettras de le reconnaître à l'avenir) ainsi que le fameux TOKEN. + +Cliquer sur Send et votre bot sera sauvegardé + +![saveBot](/img/saveBot.png) + +:::info + +Vous venez de créer un bot dans votre client, afin de l'utiliser vous n'avez qu'à cliquer sur le bouton "play" : celui situé sous le label que vous avez attribué lors de la création du bot dans le client. Le bouton play est celui du milieu. + +Une fois fait vous avez connecté votre bot à discord, GG. + +Cette action est à effectuer à chaque Démarrage du client. + +::: + +Pourquoi avoir choisi ce processus de création/utilisation du bot : + +- Premièrement il n'est pas possible de créer un bot à partir de l'api discord (du moins pas avec la partie public de l'api) +- J'ai choisi un processus où l'utilisateur a accès aux information afin de le sensibiliser. +- Tout spam ou action contrevenant aux règles de discord lui sera imputés, le bot/l'application lui appartient. +- Je n'ai pas développé UnlabeledProject afin qu'un utilisateur contrevienne aux règles de discord. diff --git a/docs/GetStarted/getStarted.md b/docs/GetStarted/getStarted.md new file mode 100644 index 0000000..b04ae9f --- /dev/null +++ b/docs/GetStarted/getStarted.md @@ -0,0 +1,59 @@ +--- +title: Getting Started +slug: / +--- + +[![Linux :Build/release](https://github.com/batleforc/UnlabeledProject/actions/workflows/build-linux.yml/badge.svg)](https://github.com/batleforc/UnlabeledProject/actions/workflows/build-linux.yml) +[![Win:Build/release](https://github.com/batleforc/UnlabeledProject/actions/workflows/build-windows.yml/badge.svg)](https://github.com/batleforc/UnlabeledProject/actions/workflows/build-windows.yml) +[![Mac :Build/release](https://github.com/batleforc/UnlabeledProject/actions/workflows/build-mac.yml/badge.svg)](https://github.com/batleforc/UnlabeledProject/actions/workflows/build-mac.yml) +[![CodeFactor](https://www.codefactor.io/repository/github/batleforc/unlabeledproject/badge)](https://www.codefactor.io/repository/github/batleforc/unlabeledproject) +![GitHub commit activity](https://img.shields.io/github/commit-activity/m/batleforc/UnlabeledProject) + +## Bienvenue + +Si vous êtes ici, cela ne peux être que pour trois raisons : + +- Vous souhaitez utiliser la solution sans titre. +- Vous êtes un de mes profs. +- Vous êtes curieux. + +Dans tout les cas, je vous souhaite la bienvenue sur ce projet. + +## Objectif + +Ce projet possède deux objectifs : + +- Un à court terme qui consiste à créer une SoundBoard. +- Un à plus long terme qui vise à faire de ce projet une solution boite à outils beaucoup plus complète. + +## Contexte + +Pourquoi ce projet ? + +Il y a quelque temps trois événements sont arrivés : + +- Un ami à demandé le nom d'un software de SoundBoard facile à utiliser et gratuit +- J'ai eu cruellement besoin et envie de maîtriser de nouvelle tech/Framework +- Il nous a été demandé de mener un projet tutoré + +À la suite de ces trois événements une liste de compétences a été dressée : + +- Approfondissement et découverte de nouveaux frameworks et outils. + - [Découverte d'électron](/docs/electron) + - [Mise en place de l'environnement d'origine](/docs/setup) +- Passage d'un client Web à un client "Tout en un" + - [Mise en place d'un environnement electron](/docs/electron) +- Mise en place d'un pipeline Cross-Plateforme (Linux, Windows, Mac) + - [Mise en place d'une pipeline](/docs/pipeline) +- Mise en place d'un processus de version applicative + - [Mise en place d'une release](/docs/pipeline) + + +Je vais donc tenter de vous expliquer le processus que j'ai utilisé pour acquérir ces compétences aux cours de cette doc. + +### Ensuite ? + +Tout dépend de pourquoi vous êtes là : + +- Pour l'installation de la solution => [Installation de la solution en local et processus d'utilisation](/docs/install) +- Pour la consultation de détail de la stack technique => [Stack technique](/docs/stacktechnique) diff --git a/docs/GetStarted/install.mdx b/docs/GetStarted/install.mdx new file mode 100644 index 0000000..7942220 --- /dev/null +++ b/docs/GetStarted/install.mdx @@ -0,0 +1,291 @@ +--- +title: Installation +slug : /install +--- + +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + +Afin d'entrer dans le vif du sujet je vous invite à faire un choix. + +Utiliser le code source ou le code PréCompilé : + + + + +### Vous avez choisi d'utiliser le code source de l'application + +

Un choix honorable mais risqué.

+ Avant de continuer veillez à remplir ces prérequis : +
    +
  • Avoir git sur son ordinateur
  • +
  • Avoir une installation de node v14 ou plus
  • +
  • Avoir Yarn ou Npm (de préférence Yarn)
  • +
+

Prêt à commencer ?

+ +#### 1. Récupération du code source + + ```shell + git clone https://github.com/batleforc/UnlabeledProject.git + cd UnlabeledProject + ``` + +:::info + +Première étape, vous venez de récupérer le code source de cette solution sans titre et de vous déplacer dans le dossier les contenants. + +::: + +#### 2. Installation des dépendances + + + + + ```shell + yarn + ``` + + + + + ```shell + npm install + ``` + + + + +:::info + +Seconde étape, un peu plus longue cette fois ci, vous venez d'installer les "outils" nécessaires à l'utilisation de la solution. + +::: + +#### 3. Compilation du code + + + + + ```shell + yarn build + ``` + + + + + ```shell + npm run build + ``` + + + + +:::info + +Troisième étape, vous venez de préparer le code à exécuter. + +::: + +#### 4. Et si on lançais le code ? + + + + + ```shell + yarn S:DevWatch + ``` + + + + + ```shell + npm run S:DevWatch + ``` + + + + +:::info + +Le code fonctionne quand vous vous rendez sur ? Alors vous pouvez passer à l'étape suivante ! + +::: + +#### 5. Création des exécutables + + + + + ```shell + yarn dist + ``` + + + + + ```shell + npm run dist + ``` + + + + +:::info + +Une fois cette commande finie, vous retrouverez les exécutables/installers dans le dossier *dist*. Pour la suite de la marche à suivre je vous invite à retourner tout en haut et cliquer sur PréCompiler + +::: + +
+ + +### Vous avez choisis d'utiliser les sources pré-compilées + +:::info + +Vous retrouverez les fichiers compilés dans l'onglet [Release](/release) + +::: + + + + Deux types de fichiers sont disponibles + + + +```shell + snap install {Le fichier en .snap} --dangerous --classic +``` + + Le param dangerous permet d'installer le fichier snap qui n'est pas encore signé. Le param classic permet d'installer le fichier snap en lui laissant l'accès aux fichiers du pc (cela permet entre autre d'installer les fichiers ffmpeg). + + + +```shell + chmod a+x {Le fichier en .appImage} + + ./{Le fichier en .appImage} +``` + + La première commande indique que le fichier est exécutable, la seconde permet de l'exécuter. + + + + + Deux types de fichiers sont disponibles + + + Le fichier que vous souhaitez est un installable. +

Afin de l'utiliser veuillez double cliquer sur celui ci.

+ Une fois l'installation finie, il ne vous reste plus qu'à lancer l'exécutable présent sur votre bureau. +
+ + Le fichier que vous avez choisi contient la version portable de l'application +

Afin d'utiliser cette version il suffit uniquement de la lancer.

+
+
+
+ + Malheureusement pour vous, Mac n'est pas encore complètement supporté, celui-ci nécessite la possession d'un mac pour compiler l'application. +

Heureusement pour vous (et moi), vous pouvez toujours utiliser ce projet à partir des sources !!

+
+
+
+
+ +### Possible erreur + +#### FFMPEG unavailable + +![Ffmpeg](/img/ffmpeg.png) + +Le message que vous venez de voir est commun aux démarages et contient une bonne partie des informations nécessaires à sa résolution. + +Pas de panique, je suis là pour vous aider dans sa résolution. + +Peut importe votre système d'exploitation le processus est le même: + +1. Allez sur (vous pouvez aussi cliquer directement sur le lien dans la modal, celuic-i vous dirigera vers la page de téléchargements) +2. Télécharger l'archive contenant le build correspondant à votre système. +3. Ensuite veuillez placer le fichier ffmpeg contenue dans l'archive dans le dossier indiquer en derniére ligne de la modal +4. Cliquer sur try again, si la modal disparais vous être prêt à passer à l'étape suivante + +Si vous rencontrez un probléme veuillez me contacter par mail ou ouvrez une issue sur github. + +### Que c'est t'il passer ? + +Pourquoi avoir choisi un client sous cette forme ? + +Deux choses sont à savoir : + +- Le client est utilisable via votre navigateur ou le client, certaines fonctionnalités telle que la persistance du client en tant que service d'arrière plan (que je sais possible) est une fonctionalité à venir. L'utilisateur n'aura à terme qu'à lancer son navigateur ou a simplement double cliquer sur l'icone dans le volet de notification, ou encore à relancer l'executable. +- A terme une version serveur sera disponible. + +Pourquoi avoir fait le choix de ne pas télécharger de manière procédural ffmpeg ? + +Le probléme avec un téléchargement procédural est le risque que celui-ci écrase une version qui serais fournis pas l'utilisateur. + +J'ai (suite aux expliquation d'un de mes professeurs) commencé à utiliser ffmpeg dans d'autre script pour l'uniformisation des audios fournis aux bot. L'assurance que ffmpeg soit dans ce dossier et y reste me permetra à l'avenir d'avancer sur une fonctionnalité de cache des audios. diff --git a/docs/GetStarted/joinYou.md b/docs/GetStarted/joinYou.md new file mode 100644 index 0000000..a23213e --- /dev/null +++ b/docs/GetStarted/joinYou.md @@ -0,0 +1,40 @@ +--- +title: Convoquer le bot dans un channel +--- + +Hello you 😜 + +Si vous êtes là c'est que vous venez de connecter votre bot via le client. Si ce n'est pas le cas je vous invite à rejoindre la catégorie "Créer/Choisir un bot". + +## Invitation du bot dans une Guild + +![defaultConnect](/img/defaultConnect.png) + +A l'heure actuelle votre écran doit globalement ressembler à celui-ci. + +:::info + +Si la guild que vous souhaitez ne ce situe pas dans la liste déroulante "Select a serveur" je vous invite à cliquer sur "lien d'invitation" situé sous le nom de votre bot. + +Cela vous redirigera vers une page vous permettant d'inviter votre bot dans un serveur où vous avez les droits pour le faire. +Dans le cas où vous n'avez pas ces droits veuillez demander à un administrateur du dit serveur. + +::: + +## Rejoindre un channel Vocal + +Un channel Vocal est un endroit où vous et vos amis(ou ennemi/neutre) pouvez vous connecter. + +Afin d'invoquer votre bot dans le un channel vocal, veuillez cliquer sur Voice dans la barre supérieur. + +![voice](/img/voice.png) + +Ensuite sélectionnez la guild contenant le channel vocal via "Select a serveur" puis dans "select a voice channel" le channel où vous souhaitez aller. + +:::caution + +Attention, si votre bot n'a pas de droits suffisants pour rejoindre un channel vocal, il vous faudra demander à un administrateur pour lui donner. + +::: + +Il ne vous reste plus qu'à cliquer sur join et votre bot vous aura rejoint. diff --git a/docs/SoundBoard/createBoard.md b/docs/SoundBoard/createBoard.md new file mode 100644 index 0000000..2142d75 --- /dev/null +++ b/docs/SoundBoard/createBoard.md @@ -0,0 +1,5 @@ +--- +title: Créer un Board +--- + +WIP \ No newline at end of file diff --git a/docs/SoundBoard/createButton.md b/docs/SoundBoard/createButton.md new file mode 100644 index 0000000..a48c595 --- /dev/null +++ b/docs/SoundBoard/createButton.md @@ -0,0 +1,5 @@ +--- +title: Créer un Bouton +--- + +WIP \ No newline at end of file diff --git a/docs/StackTech/Setup.md b/docs/StackTech/Setup.md new file mode 100644 index 0000000..d192170 --- /dev/null +++ b/docs/StackTech/Setup.md @@ -0,0 +1,185 @@ +--- +title: Mise en place de l'environnement +slug : /setup +--- + +Prêt à mettre en place l'environnement Create React App (Appeler CRA dans la suite) TypeScript (Appeler Ts dans la suite) + Serveur TypeScript ? + +:::info + Vous souhaitez retrouver la stack que je vous fait installer ici ? [elle est disponible dans la page StackTech](/docs/stacktechnique) +::: + +### 1. Mise en place du client + +#### 1.1. Mise en place de CRA + +```shell + yarn create react-app ${Le nom de votre projet} --template typescript +``` + +Cette commande vous permettra d'initialiser votre projet Create-React-App. + +#### 1.2. Mise en place des Packages + +```shell + yarn add @reduxjs/toolkit axios react-redux redux react-router-dom + yarn add @types/redux @types/react-redux @types/react-router-dom -d +``` + +Ici vous avez ajouté les packages nécessaires à la création de l'application: + +- redux : Vous permet de gérer l'état global de l'application. +- axios : Vous permet de faire des requêtes web. +- react-router-dom : Permet de gérer un système de chemin. + +D'autres packages sont utilisés : + +- react-grid-layout : Permet la gestion de tableau dynamique (Utiliser dans l'interface de la soundboard) +- socket.io-client : Permet d'écouter et lancer des events en temps réel. +- D'autres packages, dont l'installation est plus compliquée, sont expliqués plus bas. + +### 2. Mise en place serveur (Koa + Socket.io) + +#### 2.1. Package + +```shell + yarn add @koa/cors @koa/router koa koa-body koa-mount koa-static socket.io typescript nodemon concurrently cross-env dotenv-flow + yarn add @types/koa @types/koa-bodyparser @types/koa-cors @types/koa-json @types/koa-router @types/koa-static @types/node @types/socket.io -d +``` + +Les packages nécessaires aux développement sont ajoutés ainsi que leur type. + +#### 2.2 Configuration + +Afin de créer une configuration compléte il est nécessaire de créer quelques fichiers et dossiers. + +Commencer par créer à la racine un dossier Server puis place à la configuration Ts. + +```json title="/serveur.tsconfig.json" + { + "compilerOptions": { + "module": "commonjs", + "esModuleInterop": true, + "outDir": "BuildServer", // Fichier de destination du code compilé. + "target": "es6", // La version de JavaScript visée. + "strict": true, // Activation de toutes les verifications strictes liées aux Ts. + "allowJs":true, + "skipLibCheck":true // Permet de résoudre les cas où deux Lib ont le même type. + }, + "include": [ + "Server/**/*" // Le dossier contenant le code source du serveur. + ] +} +``` + +Ce fichier est la configuration typescript appliquée à votre serveur. + +```json +{ + ...Votre Package.json + "scripts":{ + "S:Build":"tsc -w --projet ./serveur.tsconfig.json", + "S:ProdBuild":"cross-env NODE_ENV=production tsc --project ./serveur.tsconfig.json", + "S:Watch": "nodemon -q -w BuildServer BuildServer/index.js", + "S:DevWatch": "cross-env NODE_ENV=development concurrently --names \"S:Build,S:Watch\" -c \"grey.bold,blue.bold\" \"yarn:S:Build\" \"yarn:S:Watch\" --node-env=development", + } +} +``` + +=> S:Build : Intérprétation du code en TypeScript vers JavaScript en temps réel (Le code interprété à nouveau à chaques sauvegardes). + +=> S:ProdBuild : Interprétation du code pour la production. + +=> S:Watch : Exécution du code du dossier BuildServer. + +=> S:DevWatch : Exécution en parallèle du build server ainsi que de l'exécuteur serveur. + +#### 2.3 Les autres paquets + +D'autres packets sont utilisés pour la partie serveur tel que : + +- Discordjs : Interface avec discord. Facilite fortement le développement de bot. +- sqlite && sqlite3 : Framework permettant l'utilisation d'une base de donnée. +- nconf : Permet l'utilisation de configuration .json, les chemins vers les bases de donnée ou autre sont sauvegardée de cette manière. +- chalk : Permet la coloration du terminal. + +Certains paquets sont utilisés pour la partie vocal de DiscordJs: + +- Sodium +- utf-8-validate +- opusscript +- ffmpeg-static +- bufferutil + +Tous ces paquets sont utilisés afin de fluidifier les flux audios ainsi que permettre leur lecture. + +Un autre paquet est utilisé pour la lecture de vidéo youtube : ytdl-code + +### 3. Mise en place de Craco et TailwindCSS + +Create React App Configuration Override (Craco) est un package qui permet de modifier le package react-script. + +```shell + yarn add @craco/craco +``` + +Puis créer un fichier correspondant à la configuration de craco: + +```js title="/craco.config.js" +module.exports = { + style: { + postcss: { + plugins: [ + require('tailwindcss'), + require('autoprefixer'), + ], + }, + }, +} +``` + +Pour appliquer la configuration de craco : penser à modifier votre package.json et remplacer les "react-scripts" par craco. + +La prochaine étape consiste à générer puis modifier la configuration de Tailwind, Tailwind est un framework Css complet (et non pas une bibliothèque de composant). + +```shell + npx tailwindcss init +``` + +Cette commande vous permettra d'installer tailwindcss. Il ne vous reste plus qu'à modifier la configuration pour lui indiquer où se situe le code source, puis d'ajouter les mots clefs pour intégrer le css dans un de vos fichiers .css : + +```js title="/tailwind.config.js" +module.exports ={ + purge: ['./src/**/*.{js,jsx,ts,tsx}', './public/index.html'], +} +``` + +```css title="Votre fichier en .css" +@tailwind base; +@tailwind components; +@tailwind utilities; + +... Vos style css +``` + +### Pourquoi ? + +#### Tailwind + +J'ai choisis Tailwind en raison des différences entre les librairies que j'utilisais avant (et je ne retournerais plus en arrière). Par le passée j'utilisais [Material-ui](https://material-ui.com/), qui en plus d'être lourd possède un grand nombre de fonctionnalité cachées. Oui j'ai choisis de réinventer la roue pour pas mal de fonctionnalités mais connaître les tenants et les aboutissants de celle-ci m'a été extrêmement bénéfique. + +#### Koa + +Ancien utilisateur d'Express, je souhaitais apprendre à utiliser de nouveaux frameworks/packets pour la gestion web. + +Koa est plus long à mettre en place mais me parais plus robuste sur le long terme. + +#### Socket.io + +Avec un système comme Discordjs qui est utilisé beaucoup d'event et d'action asynchrone sont effectuées. Une mise à jour de l'interface en temps réel est donc devenue obligatoire et un fonctionnement ou socket.io ainsi que Redux sont en harmonie et devenue très agréable à utiliser. + +#### TypeScript + +TypeScript, ni plus ni moins qu'un javascript typer, de la rigueur dans le respect des types, des interfaces. Je n'ai pas été jusqu'au bout de ce qu'est capable de m'offrir le typescript. Cependant cette premiére expérience me rend confiant, malgré la mauvaise image que les untilisateurs ont du Js, celle-ci peut très bien dépasser cette dernière. + +Un point important et qui m'a beaucoup fait rire (car oui, passer 3h à faire du bug fix et réaliser que le type utilisé pour une variable n'est pas la bonne m'est arrivé.) est qu'il est nécessaire d'installer les packest en "@types" mais il faut faire attention, certains packets fournissent ces types directement. diff --git a/docs/StackTech/StackTech.md b/docs/StackTech/StackTech.md new file mode 100644 index 0000000..47c3f55 --- /dev/null +++ b/docs/StackTech/StackTech.md @@ -0,0 +1,91 @@ +--- +title: Stach technique +slug : /stacktechnique +--- + +Lors de la conception de ce projet le point le plus important est et reste la découverte de nouveaux Framework/Techno . + +Voici les technos en apprentissage : + +- TypeScript ( Un JavaScript avec du style et du type ) +- Axios ( Framework pour les requêtes html ) +- Tailwind ( Framework CSS ) +- Koa ( Framework de serveur http ) +- Yarn ( Gestionnaire de packages ) +- Electron ( Framework de packages d'application sous un format natif ) +- Better-sqlite3 devenue sqlite + sqlite3 (Framework de Base de donnée locale) + +Les technos en approfondissement : + +- React ( Framework d'Interface ) +- Redux ( Framework de gestion d'état ) +- Socket.io ( Framework d'event en temps réel ) +- NodeJs ( Plateforme libre JavaScript orientée application ) + +A l'origine le projet était sous le format : + +```plantuml A l'origine des temps +card Yarn{ + node Client [ + Client + ---- + TypeScript + React + Redux + TailWind + Axios + Socket.io + ] + node BackEnd [ + BackEnd + ---- + Typescript + NodeJs + Koa + Socket.io + BetterSqlite3 + ] +} +BackEnd <-r- Client : Axios +BackEnd --> Client : Socket.io +``` + +Puis un jour Electron Arriva : + +```plantuml A l'origine des temps +card Yarn{ + node Electron{ + node Client [ + Client + ---- + TypeScript + React + Redux + TailWind + Axios + Socket.io + ] + node BackEnd [ + BackEnd + ---- + Typescript + NodeJs + Koa + Socket.io + sqlite3 + ] + } +} +BackEnd <-r- Client : Axios +BackEnd --> Client : Socket.io +``` + +Un tout petit changement de stack me direz vous ? Et bien non, un énorme en réalité. + +Prêt pour la suite ? + +=> [Mise en place Electron](/docs/electron) + +=> [Mise en place de l'environnement de base](/docs/setup) + +=> [Mise en place d'une pipeline](/docs/pipeline) diff --git a/docs/StackTech/electron.md b/docs/StackTech/electron.md new file mode 100644 index 0000000..990472c --- /dev/null +++ b/docs/StackTech/electron.md @@ -0,0 +1,179 @@ +--- +title: Electron +slug : /electron +--- + +KEZAKO ? + +Cette partie d'atome est un framework permettant de développer des applications desktop multi-plateformes à partir de JavaScript/Html/CSS. + +Le processus de développement est "Simple". + +## Mise en place d'un environnement de dev + +:::info + +Pour la suite de cette page je pars du principe qu'on ajoute la stack electron sur un projet déjà existant, dans une autre doc j'explique la mise en place de mon environnement post electron. + +L'environnement [pré-electron est disponible ici](/docs/setup) + +::: + +### 1. Installation des packages + +```shell + yarn add electron electron-builder wait-on concurrently electron-is-dev +``` + +Electron permet de lancer la solution sans construire (build) la solution complète. + +Electron-Builder permet de compiler la solution. + +"Wait-On" permet d'attendre une réponse d'une url spécifique pour ici continuer le processus. + +"Concurrently" permet de lancer plusieures commandes aux même moment. + +### 2. Un peu de configuration + +```json title="package.json" +{ + ... le reste de votre package.json + "main": "./build/electron.js", + "build": { + "productName": "unlabeledProject", + "appId": "com.example.unlabeledProject", + "icon": "build/toolbox.png", + "asar": true, + "files": [ + "package.json", + "build/**/*", + "node_modules/**/*", + "BuildServer/**/*" + ] + }, +} +``` + +Toutes ces lignes sont-elles vraiment nécessaires ? + +Dans notre cas oui, mais je suis là pour vous les expliquer: + +- main : L'emplacement de votre fichier electron.js, celui-ci est le point d'entrée de votre application (imaginez cliquer sur ce fichier quand vous lancer la solution finale ou uniquement en dev) +- build: + - productName : Le nom de votre produit (sera utilisé pour la compilation de votre exécutable) + - appId : Id Linux/Apple, cette id permet de reconnaître le package. + - icon : L'icon utiliser pour vos exécutables (penser à bien importer le dossier où il est dans les fichiers) + - asar : Si vous utilisez le format asar pour vos fichiers compressés. Théoriquement il accélère les requires. + - files: Tous les fichiers/dossiers incluent dans le package finale, penser à include le node_modules, vos ou votre dossier(s) de source ainsi que votre icon (ici, build contient le client ainsi que l'icon) + + +### 3. Ajout des scripts + +```json title="package.json" +{ + ... le reste de votre package.json + "scripts":{ + "start":"VOTRE SCRIPT DE STARTUP", + "build":"VOTRE SCRIPT DE BUILD", + "postinstall": "electron-builder install-app-deps", + "electronDev": "concurrently \"yarn start\" \"wait-on http://localhost:3000 && electron .\"", + "electronAlone":"electron .", + "ebuild": "yarn run build && node_modules/.bin/build", + "electron-pack": "build --em.main=build/electron.js", + "pack": "electron-builder --dir", + "dist": "electron-builder", + "distStartup":"yarn build && yarn dist" + } +} +``` + +Pour le bon fonctionnement de la solution TOUS ces scripts sont nécessaires: + +- postinstall : Est exécuté après l'installation d'un package, il permet de reconstruire les extensions dans un format propice à l'utilisation electron. +- electronDev : Permet de lancer votre environnement de dev via start puis d'attendre que celui-ci soit lancé pour lancer le client electron. +- electronAlone : Dans beaucoup de cas j'ai eu à modifier uniquement la partie electron, afin d'accélérer les starts/restarts je lançais une fois unique start puis relançais uniquement la partie electron. +- pack : Permet d'obtenir uniquement le dossier contenant la solution compilée. +- dist : Permet via la configuration de l'étape 2 de compiler vos fichiers (par défault .snap pour linux, .exe pour windows et .appImage pour mac) +- distStartup : Permet en une commande de build les composants ainsi que le client electron. + +### 4. electron.js + +Je vous fournis une version simplifiée de mon fichier electronJs les commentaires sont intégrés dans le code fournis, si vous souhaitez mettre en place un système plus complet avec un icon tray, veuillez vous en référer à mon code. + +Le code electron.js est placé dans mon dossier public afin d'éviter que celui ci sois modifié, ne comptez pas sur du TypeScript pour celui ci. + +```js title="/public/electron.js" + const electron = require("electron"); + const { app, BrowserWindow } = electron; + const isDev = require("electron-is-dev"); + const Server = require('../BuildServer/index') // permet de lancer le serveur aux démarrage + const path = require("path"); + let mainWindow; + const BaseFolder = path.join(__dirname); + const icon = path.join(BaseFolder,"toolbox.png"); + + const createWindow = ({showOnLoad = true}={}) => { + if(mainWindow){ + mainWindow.focus(); + return; + } + mainWindow = new BrowserWindow({ + width: 1280, // Permet de définir la taille de la fenêtre + height: 720, + autoHideMenuBar : true, // Permet de cacher la barre de menu intégrer a electron + icon : icon // L'icon de la fenêtre électron + }); + mainWindow.loadURL( + isDev ? + "http://localhost:3000" : // Le serveur de dev local + "http://localhost:5000" // Le serveur de production + ) + mainWindow.once("ready-to-show",()=>{ + if(showOnLoad) mainWindow.show(); //si on veux montrer la fenêtre aux démarrage + }) + mainWindow.once("closed", () => (mainWindow = null)); // si la fenêtre est fermer on vide mainWindow + } + + const init = () => { + app.on("window-all-closed", (e) => e.preventDefault()); // evite que toute la solution sois fermer si toute les fenêtre sont fermer. + }; + app.requestSingleInstanceLock() ? init() : app.quit(); // Evite d'avoir deux fois le serveur démarrer + app.on("second-instance", () => mainWindow.show()); // montre la fenêtre si la solution est démarrer deux fois + + app.on("ready",()=>{ + if (mainWindow === null) { + createWindow(); // si aucune fenêtre en créer une. + } + }) + + app.on("activate", () => { + if (mainWindow === null) { + createWindow(); // si aucune fenêtre en créer une. + } + }); +``` + +### How It Work + +```plantuml + actor user + node Electron { + node Serveur + node Client + } + user -u-> Electron : 1.Lance la solution + Serveur -[#black]-> Client : Expose le contenue static + Serveur -[#black]-> Serveur : Expose l'Api + Electron --> Serveur : 2.Lance le serveur + Serveur -[#black]-> Electron : Expose le contenue web + Electron --> user : 3.Ouvre une fenêtre "Native" affichant le client +``` + +Lors du démarrage de notre solution notre electron va démarrer notre serveur web, celui ci intègre une partie statique qui n'est autre que notre client ainsi qu'une partie Api. + +#### Pourquoi Electron et pas React-Native + +React native et Electron n'ont pas le même objectif. + +React native vise les appareille Android et Ios contrairement a Electron qui vise les Ordinateur. + diff --git a/docs/StackTech/pipeline.mdx b/docs/StackTech/pipeline.mdx new file mode 100644 index 0000000..1de7717 --- /dev/null +++ b/docs/StackTech/pipeline.mdx @@ -0,0 +1,245 @@ +--- +title: Pipeline +slug : /pipeline +--- + +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + +Deux pipelines ont été mises en place pour répondre à trois objectifs : + +- La pipeline principale : + - S'assurer que la solution sois capable de compiler en cas de push. + - Compiler la solution sur plusieurs plateforme en cas de Tag. +- La pipeline secondaire : + - Déployer la documentation. + +A terme une troisième Pipeline seras mise en place. Celle-ci aura pour but de déployer en cas de tag une nouvelle version du serveur en production. + +Chaque Pipeline est mise en place via le système Github Action. + +### Pipeline Principale => Release + +```plantuml pipelinePrincipal + actor You + node GithubAction + node Github + You--> Github : Effectue un commit + Github --> GithubAction : Demande l'exécution de la pipeline + GithubAction --> GithubAction : Compile la solution pour Linux, Windows et peu être mac (si les Action ne sont pas en surcharge) + GithubAction --> Github : Retourne les résultats de compilation en cas de Tag et créer un brouillon de release +``` + + + + +```yaml +name: Win:Build/release + +on: push + +jobs: + release: + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: [windows-latest] + + steps: + - name: Check out Git repository + uses: actions/checkout@v1 + + - name: Install Node.js, NPM and Yarn + uses: actions/setup-node@v1 + with: + node-version: 14 + - name : set vs version + run : npm config set msvs_version 2015 + # Choix de la version 2015 pour être compatible avec le package sodium + - name : install dépendances + run : npm install --global windows-build-tools@4.0.0 --vs2015 + # Installation des package nécessaires a la compilation + + - name: Build/release Electron app + uses: samuelmeuli/action-electron-builder@v1 + with: + args: -c.snap.publish=github + # GitHub token, automatically provided to the action + # (No need to define this secret in the repo settings) + github_token: ${{ secrets.github_token }} + + # If the commit is tagged with a version (e.g. "v1.0.0"), + # release the app after building + release: ${{ startsWith(github.ref, 'refs/tags/v') }} +``` + + + + +```yaml +name: Linux:Build/release + +on: push + +jobs: + release: + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: [ubuntu-latest] + + steps: + - name: Check out Git repository + uses: actions/checkout@v1 + + - name: Install Node.js, NPM and Yarn + uses: actions/setup-node@v1 + with: + node-version: 14 + + - name: Build/release Electron app + uses: samuelmeuli/action-electron-builder@v1 + with: + args: -c.snap.publish=github + # GitHub token, automatically provided to the action + # (No need to define this secret in the repo settings) + github_token: ${{ secrets.github_token }} + + # If the commit is tagged with a version (e.g. "v1.0.0"), + # release the app after building + release: ${{ startsWith(github.ref, 'refs/tags/v') }} +``` + + + + +```yaml +name: Mac:Build/release + +on: push + +jobs: + release: + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: [macos-latest] + + steps: + - name: Check out Git repository + uses: actions/checkout@v1 + + - name: Install Node.js, NPM and Yarn + uses: actions/setup-node@v1 + with: + node-version: 14 + - name: Install libmpeg + run : brew install libtool + # Installation de la librarie libtool nécessaires a l'uttilisation de ffmpeg (SoundBoard) + - name: Install autoMake pour Libsodium + run : brew install automake + # Installation de la librarie automake, nécessaire a la compilation des package electron + - name: Build/release Electron app + uses: samuelmeuli/action-electron-builder@v1 + with: + args: -c.snap.publish=github + # GitHub token, automatically provided to the action + # (No need to define this secret in the repo settings) + github_token: ${{ secrets.github_token }} + + # If the commit is tagged with a version (e.g. "v1.0.0"), + # release the app after building + release: ${{ startsWith(github.ref, 'refs/tags/v') }} +``` + + + + +L'action Github *samuelmeuli/action-electron-builder@v1*, permet de compiler une solution electron. + +### Pipeline Secondaire => Documentation + +```plantuml doc + actor You + node GithubAction + node Github + You--> Github : Effectue un commit sur la branch doc + Github --> GithubAction : Demande l'exécution de la pipeline + GithubAction --> GithubAction : Build de la solution docusaurus + GithubAction --> Github : Push du build sur la branch gh-pages +``` + + + + ```yaml +name: documentation + +on: + pull_request: + branches: [doc] + push: + branches: [doc] + +jobs: + checks: + if: github.event_name != 'push' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-node@v1 + with: + node-version: '12.x' + - name: Test Build + run: | + if [ -e yarn.lock ]; then + yarn install --frozen-lockfile + elif [ -e package-lock.json ]; then + npm ci + else + npm i + fi + npm run build + gh-release: + if: github.event_name != 'pull_request' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-node@v1 + with: + node-version: '12.x' + - uses: webfactory/ssh-agent@v0.5.1 + with: + ssh-private-key: ${{ secrets.GH_PAGES_DEPLOY }} + - name: Release to GitHub Pages + env: + USE_SSH: true + GIT_USER: git + run: | + git config --global user.email "actions@github.com" + git config --global user.name "gh-actions" + if [ -e yarn.lock ]; then + yarn install --frozen-lockfile + elif [ -e package-lock.json ]; then + npm ci + else + npm i + fi + npm run deploy + ``` + + + + +Cette pipeline permet la compilation de la doc docusaurus et son déploiement automatique sur github Pages (Ceux sur quoi vous êtes actuellement). diff --git a/docs/StackTech/tech.md b/docs/StackTech/tech.md new file mode 100644 index 0000000..2c3b2ce --- /dev/null +++ b/docs/StackTech/tech.md @@ -0,0 +1,102 @@ +--- +title: Tech +slug : /tech +--- + +### L'ancienne version + +Chaque composant sont interconnecter. Le passage d'une techno a une autre est rendu plus compliquer. + +```plantuml V1 +node client{ + component Redux + component React + component Socket_io_client +} + +node serveur{ + component socket_io_serveur + component koa + component DiscordJs + component Koa_Static_client + component Store + component Db +} + +React <--> Redux +Socket_io_client <--> Redux + +koa <--> socket_io_serveur +koa <--> DiscordJs +koa <--> Store +koa <--> Db +koa <--> Koa_Static_client +Db <--> Store +Db <--> DiscordJs +socket_io_serveur <--> DiscordJs +socket_io_serveur <--> Store +socket_io_serveur <--> Db + +client --> serveur : Axios +serveur --> client : Socket.io +``` + +### Futur version + +Redux devient le centre du projet, certes le remplacement de redux devient impossible mais celle des autre composant deviendrait assez facile. + +L'activation/désactivation de fonctionnalité deviens aussi facile. Une condition et cella est effectuer. + +Les état globaux permette aussi l'activation d'désactivation des fonctionnalité. + +Les ligne verte sont des connection via fonction dispatch et récupération des états globaux. Le dispatch ainsi que le getState sont fournis par l'api Redux. + +Les ligne noir représente des composant (DiscordJsHandler dépend de DiscordJs, etc). + +```plantuml V2 +node node[ + Vert = dispatch + state + Rouge = Emission d'event + Black = Is part of +] + +node client{ + component Redux + component React + component Socket_io_client +} + +node serveur{ + component ReduxServeur as rs + component socket_io_serveur + component Store + component koa + agent koa_Api + component DiscordJs + agent DiscordBot + component DiscordJsVoiceHandler as dsv + component Koa_Static_client + component Db +} + +rs <-[#Green]-> Db +rs <-[#Green]-> Store +rs <-[#Green]-> koa +rs <-[#Green]-> DiscordBot +rs <-[#Green]-> DiscordJs +koa -[#Black]-> Koa_Static_client : Affiche l'interface +Koa_Static_client --> client +koa <-[#Black]-> koa_Api +rs <-[#Green]-> dsv +DiscordJs <-[#Black]-> DiscordBot +DiscordJs <-[#Black]-> dsv +rs -[#Red]-> socket_io_serveur : Emit des event + +React <--> Redux +Socket_io_client <--> Redux +Redux--> koa_Api : Appelle via Axios + + +socket_io_serveur -[#Red]-> Socket_io_client + +``` diff --git a/docusaurus.config.js b/docusaurus.config.js new file mode 100644 index 0000000..eb6bf72 --- /dev/null +++ b/docusaurus.config.js @@ -0,0 +1,101 @@ +/** @type {import('@docusaurus/types').DocusaurusConfig} */ +const simplePlantUml = require("@akebifiky/remark-simple-plantuml"); +module.exports = { + title: "UnlabeledDoc", + tagline: "Une documentation sans titre, pour un projet sans Titre", + url: "https://batleforc.github.io", + baseUrl: "/UnlabeledProject/", + onBrokenLinks: "throw", + onBrokenMarkdownLinks: "warn", + favicon: "img/favicon.ico", + organizationName: "batleforc", // Usually your GitHub org/user name. + projectName: "UnlabeledProject", // Usually your repo name. + themeConfig: { + colorMode: { + defaultMode: "dark", + }, + navbar: { + title: "UnlabeledProject", + logo: { + alt: "toolbox", + src: "img/toolbox.png", + }, + items: [ + { + to: "docs/", + activeBasePath: "docs", + label: "Docs", + position: "left", + }, + { to: "blog", label: "Blog", position: "left" }, + { to: "release", label: "Release", position: "right" }, + { + href: "https://github.com/batleforc/UnlabeledProject", + label: "GitHub", + position: "right", + }, + ], + }, + footer: { + style: "dark", + links: [ + { + title: "Docs", + items: [ + { + label: "Getting Started", + to: "docs/", + }, + { + label: "Kanban", + href: "https://github.com/batleforc/UnlabeledProject/projects/1", + }, + { + label: "Miro", + href: "https://miro.com/app/board/o9J_lM04aYE=/", + }, + ], + }, + { + title: "More", + items: [ + { + label: "Blog", + to: "blog", + }, + { + label: "WebSite", + href: "https://maxleriche.tech", + }, + { + label: "GitHub", + href: "https://github.com/batleforc/UnlabeledProject", + }, + ], + }, + ], + copyright: `Copyright © ${new Date().getFullYear()} UnlabeledProject, Inc. Built with Docusaurus.`, + }, + }, + presets: [ + [ + "@docusaurus/preset-classic", + { + docs: { + sidebarPath: require.resolve("./sidebars.js"), + // Please change this to your repo. + editUrl: "https://github.com/batleforc/UnlabeledProject/edit/doc/", + remarkPlugins: [simplePlantUml], + }, + blog: { + showReadingTime: true, + // Please change this to your repo. + editUrl: "https://github.com/batleforc/UnlabeledProject/edit/doc/", + }, + theme: { + customCss: require.resolve("./src/css/custom.css"), + }, + }, + ], + ], +}; diff --git a/package.json b/package.json index a0a4147..c4370d9 100644 --- a/package.json +++ b/package.json @@ -1,148 +1,31 @@ { - "name": "unlabeledProject", - "version": "2.1.1", + "name": "unlabeleddoc", + "version": "0.0.0", "private": true, - "description": "Projet de soundboard afin de me familiariser avec certain package", - "url": "https://github.com/batleforc/SoundBoard", - "repository": { - "type": "git", - "url": "git+https://github.com/batleforc/SoundBoard.git" - }, - "author": "Batleforc", - "license": "ISC", - "homepage": "./", - "main": "./build/electron.js", - "build": { - "productName": "unlabeledProject", - "appId": "com.example.unlabeledProject", - "icon": "build/toolbox.png", - "asar": true, - "files": [ - "package.json", - "build/**/*", - "node_modules/**/*", - "BuildServer/**/*" - ], - "win": { - "target": [ - { - "target": "portable" - }, - { - "target": "nsis" - }, - { - "target": "zip" - } - ] - }, - "snap": { - "confinement": "classic" - }, - "directories": { - "buildResources": "assets" - } - }, - "bugs": { - "url": "https://github.com/batleforc/SoundBoard/issues" + "scripts": { + "docusaurus": "docusaurus", + "start": "docusaurus start", + "build": "docusaurus build", + "swizzle": "docusaurus swizzle", + "deploy": "docusaurus deploy", + "clear": "docusaurus clear", + "serve": "docusaurus serve", + "write-translations": "docusaurus write-translations", + "write-heading-ids": "docusaurus write-heading-ids" }, "dependencies": { - "@craco/craco": "^6.1.0", - "@discordjs/opus": "^0.4.0", - "@koa/cors": "^3.1.0", - "@koa/router": "^10.0.0", - "@reduxjs/toolkit": "^1.5.0", - "@tailwindcss/postcss7-compat": "npm:@tailwindcss/postcss7-compat", - "@testing-library/jest-dom": "^5.11.4", - "@testing-library/react": "^11.1.0", - "@testing-library/user-event": "^12.1.10", - "autoprefixer": "9", + "@akebifiky/remark-simple-plantuml": "^1.0.2", + "@docusaurus/core": "2.0.0-alpha.72", + "@docusaurus/preset-classic": "2.0.0-alpha.72", + "@mdx-js/react": "^1.6.21", "axios": "^0.21.1", - "bufferutil": "^4.0.3", - "chalk": "^4.1.0", - "concurrently": "^5.3.0", - "cross-env": "^7.0.3", - "discord.js": "^12.5.1", - "dotenv-flow": "^3.2.0", - "electron-is-dev": "^2.0.0", - "electron-log": "^4.3.2", - "ffmpeg-static": "^4.2.7", - "icomoon-react": "^2.0.19", - "koa": "^2.13.1", - "koa-body": "^4.2.0", - "koa-mount": "^4.0.0", - "koa-static": "^5.0.0", - "nconf": "^0.11.2", - "node-abi": "^2.21.0", - "nodemon": "^2.0.7", - "open": "^8.0.5", - "opusscript": "^0.0.8", - "postcss": "7", + "clsx": "^1.1.1", "react": "^17.0.1", - "react-burger-menu": "^3.0.6", - "react-dom": "^17.0.1", - "react-grid-layout": "^1.2.3", - "react-redux": "^7.2.2", - "react-router-dom": "^5.2.0", - "react-scripts": "4.0.1", - "redux": "^4.0.5", - "socket.io": "^3.1.0", - "socket.io-client": "^3.1.2", - "sodium": "^3.0.2", - "sqlite": "^4.0.19", - "sqlite3": "^5.0.2", - "tailwindcss": "npm:@tailwindcss/postcss7-compat", - "typescript": "^4.0.3", - "underscore": "^1.12.1", - "utf-8-validate": "^5.0.4", - "web-vitals": "^0.2.4", - "winston": "^3.3.3", - "winston-console-format": "^1.0.8", - "winston-daily-rotate-file": "^4.5.2", - "workbox-background-sync": "^5.1.3", - "workbox-broadcast-update": "^5.1.3", - "workbox-cacheable-response": "^5.1.3", - "workbox-core": "^5.1.3", - "workbox-expiration": "^5.1.3", - "workbox-google-analytics": "^5.1.3", - "workbox-navigation-preload": "^5.1.3", - "workbox-precaching": "^5.1.3", - "workbox-range-requests": "^5.1.3", - "workbox-routing": "^5.1.3", - "workbox-strategies": "^5.1.3", - "workbox-streams": "^5.1.3", - "ytdl-core": "^4.5.0" - }, - "scripts": { - "start": "cross-env NODE_ENV=development craco start", - "c:build": "cross-env NODE_ENV=production craco build", - "build": "yarn c:build && yarn S:ProdBuild", - "test": "craco test", - "eject": "craco eject", - "S:Build": "tsc -w --project ./serveur.tsconfig.json", - "S:ProdBuild": "cross-env NODE_ENV=production tsc --project ./serveur.tsconfig.json", - "S:Watch": "nodemon -q -w BuildServer BuildServer/index.js", - "S:DevWatch": "cross-env NODE_ENV=development concurrently --names \"S:Build,S:Watch\" -c \"grey.bold,blue.bold\" \"yarn:S:Build\" \"yarn:S:Watch\" --node-env=development", - "watch": "cross-env NODE_ENV=development concurrently --names \"S:Build,S:Watch,C:Watch\" -c \"grey.bold,blue.bold,white.bold\" \"yarn:S:Build\" \"yarn:S:Watch\" \"yarn:start\"", - "ebuild": "yarn run build && node_modules/.bin/build", - "electronDev": "concurrently \"yarn start\" \"wait-on http://localhost:3000 && electron .\"", - "electronAlone": "electron .", - "allInDev": "concurrently \"yarn start\" \"wait-on http://localhost:3000 && electron .\" \"yarn S:DevWatch\"", - "preelectron-pack": "yarn c:build && yarn S:ProdBuild", - "postinstall": "electron-builder install-app-deps", - "electron-pack": "build --em.main=build/electron.js", - "pack": "electron-builder --dir", - "dist": "electron-builder" - }, - "eslintConfig": { - "extends": [ - "react-app", - "react-app/jest" - ] + "react-dom": "^17.0.1" }, "browserslist": { "production": [ - ">0.2%", + ">0.5%", "not dead", "not op_mini all" ], @@ -151,34 +34,5 @@ "last 1 firefox version", "last 1 safari version" ] - }, - "devDependencies": { - "@types/chalk": "^2.2.0", - "@types/jest": "^26.0.22", - "@types/koa": "^2.11.7", - "@types/koa-bodyparser": "^4.3.0", - "@types/koa-cors": "^0.0.0", - "@types/koa-json": "^2.0.18", - "@types/koa-mount": "^4.0.0", - "@types/koa-router": "^7.4.1", - "@types/koa-static": "^4.0.1", - "@types/koa__cors": "^3.0.2", - "@types/koa__router": "^8.0.4", - "@types/nconf": "^0.10.0", - "@types/node": "^14.14.22", - "@types/react": "^16.9.53", - "@types/react-burger-menu": "^2.6.2", - "@types/react-dom": "^16.9.8", - "@types/react-grid-layout": "^1.1.1", - "@types/react-redux": "^7.1.16", - "@types/react-router-dom": "^5.1.7", - "@types/redux": "^3.6.0", - "@types/socket.io": "^2.1.13", - "@types/socket.io-client": "^1.4.35", - "@types/sqlite3": "^3.1.7", - "@types/underscore": "^1.10.24", - "electron": "11.4.0", - "electron-builder": "^22.10.5", - "wait-on": "^5.3.0" } } diff --git a/public/component.css b/public/component.css deleted file mode 100644 index 3d84173..0000000 --- a/public/component.css +++ /dev/null @@ -1,180 +0,0 @@ -.react-resizable { - position: relative; -} -.react-resizable-handle { - position: absolute; - width: 20px; - height: 20px; - background-repeat: no-repeat; - background-origin: content-box; - box-sizing: border-box; - background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2IDYiIHN0eWxlPSJiYWNrZ3JvdW5kLWNvbG9yOiNmZmZmZmYwMCIgeD0iMHB4IiB5PSIwcHgiIHdpZHRoPSI2cHgiIGhlaWdodD0iNnB4Ij48ZyBvcGFjaXR5PSIwLjMwMiI+PHBhdGggZD0iTSA2IDYgTCAwIDYgTCAwIDQuMiBMIDQgNC4yIEwgNC4yIDQuMiBMIDQuMiAwIEwgNiAwIEwgNiA2IEwgNiA2IFoiIGZpbGw9IiMwMDAwMDAiLz48L2c+PC9zdmc+'); - background-position: bottom right; - padding: 0 3px 3px 0; -} -.react-resizable-handle-sw { - bottom: 0; - left: 0; - cursor: sw-resize; - transform: rotate(90deg); -} -.react-resizable-handle-se { - bottom: 0; - right: 0; - cursor: se-resize; -} -.react-resizable-handle-nw { - top: 0; - left: 0; - cursor: nw-resize; - transform: rotate(180deg); -} -.react-resizable-handle-ne { - top: 0; - right: 0; - cursor: ne-resize; - transform: rotate(270deg); -} -.react-resizable-handle-w, -.react-resizable-handle-e { - top: 50%; - margin-top: -10px; - cursor: ew-resize; -} -.react-resizable-handle-w { - left: 0; - transform: rotate(135deg); -} -.react-resizable-handle-e { - right: 0; - transform: rotate(315deg); -} -.react-resizable-handle-n, -.react-resizable-handle-s { - left: 50%; - margin-left: -10px; - cursor: ns-resize; -} -.react-resizable-handle-n { - top: 0; - transform: rotate(225deg); -} -.react-resizable-handle-s { - bottom: 0; - transform: rotate(45deg); -} - -.react-grid-layout { - position: relative; - transition: height 200ms ease; -} -.react-grid-item { - transition: all 200ms ease; - transition-property: left, top; -} -.react-grid-item img { - pointer-events: none; - user-select: none; -} -.react-grid-item.cssTransforms { - transition-property: transform; -} -.react-grid-item.resizing { - z-index: 1; - will-change: width, height; -} - -.react-grid-item.react-draggable-dragging { - transition: none; - z-index: 3; - will-change: transform; -} - -.react-grid-item.dropping { - visibility: hidden; -} - -.react-grid-item.react-grid-placeholder { - background: red; - opacity: 0.2; - transition-duration: 100ms; - z-index: 2; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - -o-user-select: none; - user-select: none; -} - -.react-grid-item > .react-resizable-handle { - position: absolute; - width: 20px; - height: 20px; -} - -.react-grid-item > .react-resizable-handle::after { - content: ""; - position: absolute; - right: 3px; - bottom: 3px; - width: 5px; - height: 5px; - border-right: 2px solid rgba(0, 0, 0, 0.4); - border-bottom: 2px solid rgba(0, 0, 0, 0.4); -} - -.react-resizable-hide > .react-resizable-handle { - display: none; -} - -.react-grid-item > .react-resizable-handle.react-resizable-handle-sw { - bottom: 0; - left: 0; - cursor: sw-resize; - transform: rotate(90deg); -} -.react-grid-item > .react-resizable-handle.react-resizable-handle-se { - bottom: 0; - right: 0; - cursor: se-resize; -} -.react-grid-item > .react-resizable-handle.react-resizable-handle-nw { - top: 0; - left: 0; - cursor: nw-resize; - transform: rotate(180deg); -} -.react-grid-item > .react-resizable-handle.react-resizable-handle-ne { - top: 0; - right: 0; - cursor: ne-resize; - transform: rotate(270deg); -} -.react-grid-item > .react-resizable-handle.react-resizable-handle-w, -.react-grid-item > .react-resizable-handle.react-resizable-handle-e { - top: 50%; - margin-top: -10px; - cursor: ew-resize; -} -.react-grid-item > .react-resizable-handle.react-resizable-handle-w { - left: 0; - transform: rotate(135deg); -} -.react-grid-item > .react-resizable-handle.react-resizable-handle-e { - right: 0; - transform: rotate(315deg); -} -.react-grid-item > .react-resizable-handle.react-resizable-handle-n, -.react-grid-item > .react-resizable-handle.react-resizable-handle-s { - left: 50%; - margin-left: -10px; - cursor: ns-resize; -} -.react-grid-item > .react-resizable-handle.react-resizable-handle-n { - top: 0; - transform: rotate(225deg); -} -.react-grid-item > .react-resizable-handle.react-resizable-handle-s { - bottom: 0; - transform: rotate(45deg); -} diff --git a/public/elec/server.js b/public/elec/server.js deleted file mode 100644 index 46002d8..0000000 --- a/public/elec/server.js +++ /dev/null @@ -1,44 +0,0 @@ -const { fork } = require("child_process"); -const path = require("path"); - -let server = null; - -const serverPath = path.join(__dirname, "..", "..", "BuildServer"); -const serverJs = path.join(serverPath, "index.js"); - -function bufferToString(buffer) { - return (Buffer.isBuffer(buffer) ? buffer.toString() : buffer).trim(); -} - -function output(buffer) { - console.log(bufferToString(buffer)); -} - -function startServeur() { - if (server) return server; - server = fork(serverJs, { stdio: ["pipe", "pipe", "pipe", "ipc"] }); - server.stdout.on("data", output); - server.stderr.on("data", output); - - server.on("close", (code) => { - output(`Server stoped with code ${code}`); - }); -} - -function stopServeur() { - if (!server) return; - server.stdin.pause(); - server.kill(); - server = null; -} - -function restartServeur() { - if (!server) stopServeur(); - startServeur(); -} - -module.exports = { - startServeur, - stopServeur, - restartServeur, -}; diff --git a/public/elec/tray.js b/public/elec/tray.js deleted file mode 100644 index 48cf3eb..0000000 --- a/public/elec/tray.js +++ /dev/null @@ -1,50 +0,0 @@ -const open = require("open"); -const pack = require("../../package.json"); -const isDev = require("electron-is-dev"); -const { Tray, Menu } = require("electron"); -const path = require("path"); -const { restartServeur } = require("./server"); - -let tray = null; - -async function openInBrowser() { - open(`http://localhost:${isDev ? "3000" : "5000"}`); -} - -function createMenu(quit, openInClient) { - return new Menu.buildFromTemplate([ - { - label: `${pack.name} ${pack.version}`, - enabled: false, - }, - { type: "separator" }, - { - label: "Open in browser", - click: () => openInBrowser(), - }, - { - label: "Open in client", - click: openInClient, - }, - { type: "separator" }, - { - label: "Restart serveur", - click: () => restartServeur(), - }, - { type: "separator" }, - { label: "Exit", click: () => quit() }, - ]); -} - -async function createTray(icon, mainWindow, openInClient, quit) { - tray = new Tray(icon); - tray.setToolTip(`${pack.name} ${pack.version}`); - tray.setContextMenu(createMenu(quit, async () => await mainWindow())); - tray.setIgnoreDoubleClickEvents(true); - tray.on("click", async () => await mainWindow()); - - return tray; -} - -module.exports = (icon, MainWindow, openInClient, quit) => - tray || createTray(icon, MainWindow, openInClient, quit); diff --git a/public/electron.js b/public/electron.js deleted file mode 100644 index d70609b..0000000 --- a/public/electron.js +++ /dev/null @@ -1,67 +0,0 @@ -const electron = require("electron"); -const { app, BrowserWindow } = require("electron"); -const isDev = require("electron-is-dev"); -const path = require("path"); -const { startServeur, stopServeur } = require("./elec/server"); - -let mainWindow; -const BaseFolder = path.join(__dirname); -const icon = path.join(BaseFolder, "toolbox.png"); - -const createWindow = ({ showOnLoad = true } = {}) => { - if (mainWindow) { - mainWindow.focus(); - return; - } - mainWindow = new BrowserWindow({ - width: 1280, - height: 720, - autoHideMenuBar: true, - icon: icon, - }); - mainWindow.loadURL( - isDev ? "http://localhost:3000" : "http://localhost:5000/" - ); - mainWindow.once("ready-to-show", () => { - if (showOnLoad) mainWindow.show(); - }); - mainWindow.once("closed", () => (mainWindow = null)); - mainWindow.removeMenu(); -}; - -const init = () => { - app.on("window-all-closed", (e) => e.preventDefault()); -}; - -const onQuit = () => { - stopServeur(); - app.quit(); -}; - -app.requestSingleInstanceLock() ? init() : app.quit(); -app.on("second-instance", () => mainWindow.show()); - -app.on("ready", () => { - const tray = require("./elec/tray"); - startServeur(); - createWindow(); - tray( - icon, - createWindow, - () => { - console.log("test"); - }, - onQuit - ); -}); - -app.on("window-all-closed", () => {}); - -app.on("activate", () => { - if (mainWindow === null) { - createWindow(); - } -}); - -process.on("SIGINT", onQuit); -process.on("SIGTERM", onQuit); diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index a11777c..0000000 Binary files a/public/favicon.ico and /dev/null differ diff --git a/public/index.html b/public/index.html deleted file mode 100644 index 2a53fea..0000000 --- a/public/index.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - UnlabeledProject - - - -
- - diff --git a/public/logo192.png b/public/logo192.png deleted file mode 100644 index fc44b0a..0000000 Binary files a/public/logo192.png and /dev/null differ diff --git a/public/logo512.png b/public/logo512.png deleted file mode 100644 index a4e47a6..0000000 Binary files a/public/logo512.png and /dev/null differ diff --git a/public/manifest.json b/public/manifest.json deleted file mode 100644 index 080d6c7..0000000 --- a/public/manifest.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "short_name": "React App", - "name": "Create React App Sample", - "icons": [ - { - "src": "favicon.ico", - "sizes": "64x64 32x32 24x24 16x16", - "type": "image/x-icon" - }, - { - "src": "logo192.png", - "type": "image/png", - "sizes": "192x192" - }, - { - "src": "logo512.png", - "type": "image/png", - "sizes": "512x512" - } - ], - "start_url": ".", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff" -} diff --git a/public/robots.txt b/public/robots.txt deleted file mode 100644 index e9e57dc..0000000 --- a/public/robots.txt +++ /dev/null @@ -1,3 +0,0 @@ -# https://www.robotstxt.org/robotstxt.html -User-agent: * -Disallow: diff --git a/serveur.tsconfig.json b/serveur.tsconfig.json deleted file mode 100644 index 0d0f05a..0000000 --- a/serveur.tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "compilerOptions": { - "module": "commonjs", - "lib": [ - "es6" - ], - "esModuleInterop": true, - "outDir": "BuildServer", - "target": "es5", - "strict": true, - "allowJs":true, - "skipLibCheck":true - }, - "include": [ - "Server/**/*" - ] -} \ No newline at end of file diff --git a/sidebars.js b/sidebars.js new file mode 100644 index 0000000..6c0e453 --- /dev/null +++ b/sidebars.js @@ -0,0 +1,31 @@ +module.exports = { + docs: [ + { + type: "category", + label: "Get Started", + items: [ + "GetStarted/getStarted", + "GetStarted/install", + "GetStarted/creerBot", + "GetStarted/joinYou", + "StackTech/StackTech", + ], + }, + { + type: "category", + label: "SoundBoard", + items: ["SoundBoard/createBoard", "SoundBoard/createButton"], + }, + { + type: "category", + label: "Stack Technique", + items: [ + "StackTech/StackTech", + "StackTech/electron", + "StackTech/Setup", + "StackTech/pipeline", + "StackTech/tech", + ], + }, + ], +}; diff --git a/src/Action/Bot.tsx b/src/Action/Bot.tsx deleted file mode 100644 index 2e3ef56..0000000 --- a/src/Action/Bot.tsx +++ /dev/null @@ -1,189 +0,0 @@ -import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; -import { getVoice } from "./Voice"; -import axios from "axios"; -var ApiBot = process.env.REACT_APP_SERVER + "/api/bot/"; -interface User { - img: any; - user: any; - link: string; - Pending: Boolean; - Serveur: [any] | []; - ActiveServeur: String; - ActiveBot: number; - ServeurChan: [any] | []; - canPlay: any; - Presence: { - Status: string; - name: string; - type: string; - }; -} - -export const BotGetter = createAsyncThunk( - "Bot/get", - async ({ force }: { force?: boolean }, { dispatch }) => { - return axios - .get(process.env.REACT_APP_SERVER + "/api/me") - .then((value) => value.data); - }, - { - condition: ({ force }: { force?: boolean }, { getState }): boolean => { - var test = getState(); - if ((test as any).Bot.user !== null && force !== true) return false; - return true; - }, - } -); - -export const CanPlay = createAsyncThunk( - "Bot/CanPlay", - async (nothing, { dispatch }) => { - return axios - .get(process.env.REACT_APP_SERVER + "/api/canplay") - .then((value) => value.data); - } -); - -export const BotServerGetter = createAsyncThunk( - "Bot/serveur/get", - async (value, { dispatch }) => { - return axios.get(ApiBot + "serveur").then((value2) => value2.data); - }, - { - condition: (force: boolean | void, { getState }): boolean => { - var test = getState(); - if ((test as any).Bot.user === null) return false; - return true; - }, - } -); - -export const BotServeurChanGetter = createAsyncThunk( - "Bot/Serveur/chan/get", - async (value: string, { dispatch }) => { - return axios - .get(`${ApiBot}chan/${value}`) - .then((res) => ({ id: value, res: res.data })); - } -); -export const BotPresenceGetter = createAsyncThunk( - "Bot/presence/getter", - async () => { - return axios.get(`${ApiBot}presence`).then((value2) => value2.data); - } -); -export const BotPresenceSetter = createAsyncThunk( - "Bot/presence/Setter", - async ({ - online, - name, - type, - }: { - online: string; - name: string; - type: string; - }) => { - return axios - .post(`${ApiBot}presence`, { - online, - name, - type, - }) - .then((value2) => value2.data); - } -); - -const initialState = { - img: null, - user: null, - Pending: false, - link: "", - Serveur: [], - ActiveServeur: "-1", - ActiveBot: -1, - ServeurChan: [], - canPlay: { - canPlay: true, - }, - Presence: { - Status: "", - name: "", - type: "", - }, -} as User; - -const BotSlicer = createSlice({ - name: "Bot", - initialState, - reducers: { - reset: (state) => { - state = initialState; - }, - setStatus: (state, { payload }) => { - state.Presence.Status = payload; - }, - setName: (state, { payload }) => { - state.Presence.name = payload; - }, - setType: (state, { payload }) => { - state.Presence.type = payload; - }, - }, - extraReducers: (builder) => { - builder - .addCase(BotGetter.fulfilled, (state, { payload }) => { - state.Pending = false; - state.img = payload.img; - state.user = payload.user; - state.link = payload.link; - state.ActiveBot = payload.botId; - }) - .addCase(BotGetter.rejected, (state, action) => { - state.Pending = false; - }) - .addCase(BotGetter.pending, (state, Action) => { - state.Pending = true; - }) - .addCase(BotServerGetter.pending, (state) => { - state.Pending = true; - }) - .addCase(BotServerGetter.rejected, (state) => { - state.Pending = false; - }) - .addCase(BotServerGetter.fulfilled, (state, { payload }) => { - state.Pending = false; - state.Serveur = payload; - }) - .addCase(BotServeurChanGetter.pending, (state) => { - state.Pending = true; - }) - .addCase(BotServeurChanGetter.rejected, (state) => { - state.Pending = false; - }) - .addCase(BotServeurChanGetter.fulfilled, (state, { payload }) => { - state.Pending = false; - state.ActiveServeur = payload.id; - state.ServeurChan = payload.res; - }) - .addCase(CanPlay.pending, (state) => { - state.Pending = true; - }) - .addCase(CanPlay.rejected, (state) => { - state.Pending = false; - }) - .addCase(CanPlay.fulfilled, (state, { payload }) => { - state.Pending = false; - state.canPlay = payload; - }) - .addCase(getVoice.fulfilled, (state, { payload }) => { - if (payload.Server) state.ActiveServeur = payload.Server.id; - }) - .addCase(BotPresenceGetter.fulfilled, (state, { payload }) => { - console.log(payload); - state.Presence = payload; - }); - }, -}); - -export const { reset, setStatus, setName, setType } = BotSlicer.actions; -export default BotSlicer.reducer; diff --git a/src/Action/Event.tsx b/src/Action/Event.tsx deleted file mode 100644 index 16ce6b3..0000000 --- a/src/Action/Event.tsx +++ /dev/null @@ -1,92 +0,0 @@ -import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; -import { BotGetter, BotPresenceGetter, BotServerGetter } from "./Bot"; -import { getStatus, getVoice } from "./Voice"; - -export enum BoardEvent { - BoardUpdate = "BoardUpdate", - BoardCreate = "BoardCreate", - BoardDelete = "BoardDelete", -} - -export enum VoiceEvent { - VoiceJoin = "VoiceJoin", - VoiceChange = "VoiceChanChange", - VoiceLeave = "VoiceLeave", - VoiceUpdate = "VoiceUpdate", - VoiceError = "VoiceError", - VoiceVolume = "VoiceVolume", -} - -export enum BotEvent { - BotReady = "BotReady", - BotDisconnect = "BotDisconnect", - BotUpdate = "BotUpdate", - GuildUpdate = "guildUpdate", -} - -export enum TokenEvent { - TokenCreate = "TokenCreate", - TokenDelete = "TokenDelete", - TokenUpdate = "TokenUpdate", -} - -export enum AppEvent { - ServeurStart = "AppStart", - ServeurStop = "AppStop", - ConfUpdate = "ConfigUpdate", - ClientRestart = "ClientRestart", -} - -interface Event { - Ready: boolean; - Pending: boolean; -} -const initialState = { - Ready: false, - Pending: false, -} as Event; - -export const EventInit = createAsyncThunk( - "Event/init", - async ({ socket }: any, { dispatch }) => { - socket.on(BotEvent.BotUpdate, () => { - dispatch(BotGetter({ force: true })); - dispatch(BotServerGetter()); - dispatch(BotPresenceGetter()) - }); - socket.on(VoiceEvent.VoiceUpdate, () => { - dispatch(getVoice()); - }); - socket.on(VoiceEvent.VoiceJoin, () => { - dispatch(getStatus()); - }); - }, - { - condition: (force: boolean | void, { getState }): boolean => { - var test = getState(); - if ((test as any).Event.Ready) return false; - return true; - }, - } -); - -const EventSlicer = createSlice({ - name: "Event", - initialState, - reducers: {}, - extraReducers: (builder) => { - builder - .addCase(EventInit.pending, (state) => { - state.Pending = true; - }) - .addCase(EventInit.rejected, (state) => { - state.Pending = false; - }) - .addCase(EventInit.fulfilled, (state) => { - state.Pending = false; - state.Ready = true; - }); - }, -}); - -export default EventSlicer.reducer; diff --git a/src/Action/Token.tsx b/src/Action/Token.tsx deleted file mode 100644 index 57ce3ca..0000000 --- a/src/Action/Token.tsx +++ /dev/null @@ -1,175 +0,0 @@ -import { createSlice, createAsyncThunk, PayloadAction } from "@reduxjs/toolkit"; -import axios from "axios"; - -var Api = process.env.REACT_APP_SERVER + "/api/"; -interface Token { - id: number; - label: string; - token: string; -} -interface TokenState { - AllToken: [Token] | []; - ActiveTokenId: number | null; - Pending: Boolean; -} - -export const TokenGetter = createAsyncThunk( - "token/get", - async (value, { dispatch }) => { - return axios.get(Api + "token").then((value) => { - return value.data; - }); - }, - { - condition: (force: boolean | void, { getState }): boolean => { - var test = getState(); - if ((test as any).Token.AllToken.length !== 0) return false; - return true; - }, - } -); -export const TokenCreate = createAsyncThunk( - "token/post", - async ({ label, token }: any, { dispatch }) => { - return axios - .post(Api + "token", { - label: label, - token: token, - }) - .then((res) => { - return res.data; - }); - }, - { - condition: (force: boolean | void, { getState }): boolean => { - var { Token }: any = getState(); - if ((Token as TokenState).Pending === true) { - return false; - } - return true; - }, - } -); -export const TokenDelete = createAsyncThunk( - "token/Delete", - async (id: any, { dispatch }) => { - return axios.delete(`${Api}token/${id}`).then((res) => { - return res.data; - }); - }, - { - condition: (force: boolean | void, { getState }): boolean => { - var { Token }: any = getState(); - if ((Token as TokenState).Pending === true) { - return false; - } - return true; - }, - } -); - -export const TokenActivate = createAsyncThunk( - "token/Activate", - async (id: any, { dispatch }) => { - return axios - .post(`${Api}bot/start`, { - id: id, - }) - .then((res) => { - dispatch(TokenGetter()); - return res.data; - }); - }, - { - condition: (force: boolean | void, { getState }): boolean => { - var { Token }: any = getState(); - if ((Token as TokenState).Pending === true) { - return false; - } - return true; - }, - } -); -export const TokenDeactivate = createAsyncThunk( - "token/Deactivate", - async (id: any, { dispatch }) => { - return axios.post(`${Api}bot/stop`).then((res) => { - dispatch(TokenGetter()); - return res.data; - }); - }, - { - condition: (force: boolean | void, { getState }): boolean => { - var { Token }: any = getState(); - if ((Token as TokenState).Pending === true) { - return false; - } - return true; - }, - } -); - -const initialState = { - AllToken: [], - ActiveTokenId: null, - Pending: false, -} as TokenState; - -const TokenSlicer = createSlice({ - name: "Token", - initialState, - reducers: { - setActiveTokenId: (state, action: PayloadAction) => { - state.ActiveTokenId = action.payload; - }, - }, - extraReducers: (builder) => { - builder - .addCase(TokenGetter.rejected, (state) => { - state.Pending = false; - }) - .addCase(TokenGetter.pending, (state) => { - state.Pending = true; - }) - .addCase(TokenGetter.fulfilled, (state, action) => { - state.Pending = false; - state.AllToken = action.payload; - }) - .addCase(TokenCreate.pending, (state) => { - state.Pending = true; - }) - .addCase(TokenCreate.rejected, (state) => { - state.Pending = false; - }) - .addCase(TokenCreate.fulfilled, (state, Action) => { - state.Pending = false; - state.AllToken= Action.payload - }) - .addCase(TokenDelete.fulfilled, (state, {payload}) => { - state.AllToken= payload - }) - .addCase(TokenActivate.pending, (state) => { - state.Pending = true; - }) - .addCase(TokenActivate.rejected, (state) => { - state.Pending = false; - }) - .addCase(TokenActivate.fulfilled, (state, Action) => { - state.Pending = false; - console.log(Action.payload); - }) - .addCase(TokenDeactivate.pending, (state) => { - state.Pending = true; - }) - .addCase(TokenDeactivate.rejected, (state) => { - state.Pending = false; - }) - .addCase(TokenDeactivate.fulfilled, (state, Action) => { - state.Pending = false; - console.log(Action.payload); - }); - }, -}); - -export const { setActiveTokenId } = TokenSlicer.actions; -export default TokenSlicer.reducer; diff --git a/src/Action/Voice.tsx b/src/Action/Voice.tsx deleted file mode 100644 index 36389f8..0000000 --- a/src/Action/Voice.tsx +++ /dev/null @@ -1,181 +0,0 @@ -import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; -import axios from "axios"; -var ApiVoice = process.env.REACT_APP_SERVER + "/api/voice/"; - -export const joinChan = createAsyncThunk( - "voice/Join", - async ({ guildId, ChanId }: any, { dispatch }) => { - return axios - .post(ApiVoice + "join", { - guildId: guildId, - chanId: ChanId, - }) - .then((value) => value.data); - } -); -export const leaveChan = createAsyncThunk( - "voice/leaveChan", - async (something: void, { dispatch }) => { - return axios.post(ApiVoice + "leave").then((value) => value.data); - } -); -export const stopVoice = createAsyncThunk( - "voice/stopVoice", - async (something: void, { dispatch }) => { - return axios.post(ApiVoice + "pause").then((value) => value.data); - } -); -export const skipVoice = createAsyncThunk( - "voice/stopVoice", - async (something: void, { dispatch }) => { - return axios.post(ApiVoice + "skip").then((value) => value.data); - } -); -export const startVoice = createAsyncThunk( - "voice/startVoice", - async ({ song, now }: { song: object; now: boolean }, { dispatch }) => { - return axios - .post(ApiVoice + "play", { - toPlay: song, - now: now, - }) - .then((value) => value.data); - } -); -export const resumeVoice = createAsyncThunk( - "voice/resumeVoice", - async (something: void, { dispatch }) => { - return axios.post(ApiVoice + "resume").then((value) => value.data); - } -); -export const setVolume = createAsyncThunk( - "voice/setVolume", - async (volume: number, { dispatch }) => { - return axios - .post(ApiVoice + "volume", { vol: volume }) - .then((value) => value.data); - } -); -export const getStatus = createAsyncThunk( - "voice/getStatus", - async (something: void, { dispatch }) => { - return axios.get(ApiVoice + "status").then((value) => value.data === 0); //if 0 = good sinon pas good - } -); - -export const getVoice = createAsyncThunk( - "voice/getVoice", - async (something: void, { dispatch }) => { - return axios.get(ApiVoice).then((value) => value.data); //if 0 = good sinon pas good - } -); - -export const getPause = createAsyncThunk( - "voice/getStatus", - async (something: void, { dispatch }) => { - return axios.get(ApiVoice + "pause").then((value) => value.data); - } -); -export const getVolume = createAsyncThunk( - "voice/getVolume", - async (something: void, { dispatch }) => { - return axios.get(ApiVoice + "volume").then((value) => value.data); - } -); - -export const setChanIdAction = createAsyncThunk( - "Voice/setChanIdAction", - async (id: string, { dispatch, getState }) => { - var { Bot }: any = getState(); - if(id==="-2"){ - dispatch(leaveChan()) - id="-1" - } - if (Number(id) > -1) - dispatch( - joinChan({ - guildId: Bot.ActiveServeur, - ChanId: id, - }) - ); - dispatch(setChanId(id)); - } -); - -interface Voice { - Pending: boolean; - Playing: boolean; - Volume: number; - ChanId: string; - GuildId: string; - Status: Boolean; - Asap: Boolean; - Paused: Boolean; - Queue: any; -} -const initialState = { - Pending: false, - Playing: false, - Volume: 0, - ChanId: "-1", - GuildId: "", - Status: false, - Asap: true, - Paused: false, - Queue: [], -} as Voice; - -const VoiceSlicer = createSlice({ - name: "Voice", - initialState, - reducers: { - setChanId: (state, { payload }) => { - state.ChanId = payload; - }, - setAsap: (state, { payload }) => { - state.Asap = payload; - }, - }, - extraReducers: (builder) => { - builder - .addCase(getStatus.pending, (state, payload) => { - state.Pending = true; - }) - .addCase(getStatus.rejected, (state, payload) => { - state.Pending = false; - }) - .addCase(getStatus.fulfilled, (state, { payload }) => { - state.Pending = false; - state.Status = payload; - }) - .addCase(getVolume.pending, (state, payload) => { - state.Pending = true; - }) - .addCase(getVolume.rejected, (state, payload) => { - state.Pending = false; - }) - .addCase(getVolume.fulfilled, (state, { payload }) => { - state.Pending = false; - state.Volume = payload; - }) - .addCase(getVoice.pending, (state, payload) => { - state.Pending = true; - }) - .addCase(getVoice.rejected, (state, payload) => { - state.Pending = false; - }) - .addCase(getVoice.fulfilled, (state, { payload }) => { - state.Pending = false; - state.Volume = payload.Volume; - state.ChanId = payload.Chan !== null ? payload.Chan.id : "-1"; - state.GuildId = payload.Server?.id; - state.Status = payload.Status === 0; - state.Paused = payload.Paused || false; - state.Queue = payload.Queue; - console.log(payload); - }); - }, -}); - -export const { setChanId, setAsap } = VoiceSlicer.actions; -export default VoiceSlicer.reducer; diff --git a/src/Action/index.tsx b/src/Action/index.tsx deleted file mode 100644 index 061146a..0000000 --- a/src/Action/index.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { configureStore } from "@reduxjs/toolkit"; -import Token from "./Token"; -import ShowModal from "./showModal"; -import Bot from "./Bot"; -import Event from "./Event"; -import Voice from "./Voice"; -import sBoard from "./sBoard"; - -export default configureStore({ - reducer: { - Token, - Bot, - ShowModal, - Event, - Voice, - sBoard, - }, - middleware: (getDefaultMiddleware) => getDefaultMiddleware(), - devTools: true, -}); diff --git a/src/Action/sBoard.tsx b/src/Action/sBoard.tsx deleted file mode 100644 index a71f275..0000000 --- a/src/Action/sBoard.tsx +++ /dev/null @@ -1,227 +0,0 @@ -import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; -import axios from "axios"; -var ApiSBoard = process.env.REACT_APP_SERVER + "/api/sboard/"; - -export enum SongType { - link = 1, - YouTube = 2, - Spotify = 3, -} - -export const GetBoard = createAsyncThunk( - "sBoard/get", - async (nothing, { dispatch }) => { - return axios.get(ApiSBoard).then((value) => value.data); - } -); -export const DeleteBoard = createAsyncThunk( - "sBoard/Delete", - async ({ tabId }: any, { dispatch }) => { - return axios.delete(ApiSBoard + `${tabId}`).then((value) => value.data); - } -); -export const UpdateBoard = createAsyncThunk( - "sBoard/updateLabel", - async ({ tabId, label, content }: any, { dispatch }) => { - return axios - .put(ApiSBoard + `${tabId}`, { - label: label, - content: content, - }) - .then((value) => value.data); - } -); - -export const CreateBoard = createAsyncThunk( - "sBoard/CreateBoard", - async ({ tabId, label }: any, { dispatch }) => { - return axios - .post(ApiSBoard, { - label: label, - }) - .then((value) => value.data); - } -); - -interface Board { - Pending: Boolean; - Board: [any] | [] | any; - ActiveBoard: Number; - ActiveLayout: [any] | [] | any; - sound: String; - url: String; - button: String; - type: SongType; - BoardAsChanged: boolean; - editing: boolean; - id: number; -} -const initialState = { - Pending: false, - Board: [], - ActiveBoard: -1, - ActiveLayout: [], - sound: "", - url: "", - button: "", - type: SongType.link, - BoardAsChanged: false, - editing: false, - id: -1, -} as Board; -const parse = (state: any, { payload }: any) => { - state.Pending = false; - state.Board = payload; - state.ActiveLayout = - state.Board[Number(state.ActiveBoard)] !== undefined - ? JSON.parse(state.Board[Number(state.ActiveBoard)].content) - : []; -}; -const SBoardSlicer = createSlice({ - name: "sBoard", - initialState, - reducers: { - setActiveBoard: (state, { payload }) => { - state.ActiveBoard = state.ActiveBoard === payload ? -1 : payload; - state.ActiveLayout = - state.Board[Number(state.ActiveBoard)] !== undefined - ? JSON.parse(state.Board[payload].content) - : []; - }, - setSound: (state, { payload }) => ({ ...state, sound: payload }), - setHandlerLayout: (state, { payload }) => { - state.ActiveLayout = payload.map((value: any, index: any) => ({ - ...state.ActiveLayout[index], - ...value, - })); - state.BoardAsChanged = true; - }, - lock: (state) => { - state.ActiveLayout = state.ActiveLayout.map((value: any) => ({ - ...value, - static: true, - })); - }, - unLock: (state) => { - state.ActiveLayout = state.ActiveLayout.map((value: any) => ({ - ...value, - static: false, - })); - }, - addButton: (state) => { - state.ActiveLayout = state.ActiveLayout.concat([ - { - i: - state.ActiveLayout.length > 0 - ? String( - Number(state.ActiveLayout[state.ActiveLayout.length - 1].i) + - 1 - ) - : "0", - x: 0, - y: 0, - w: 1, - h: 2, - text: state.button, - url: state.url, - type: state.type, - static: state.ActiveLayout[0]?.static || false, - }, - ]); - state.url = ""; - state.button = ""; - state.BoardAsChanged = true; - state.type = 0; - state.editing = false; - state.id = -1; - }, - editButton: (state) => { - state.ActiveLayout[state.id].url = state.url; - state.ActiveLayout[state.id].text = state.button; - state.ActiveLayout[state.id].type = state.type; - state.url = ""; - state.button = ""; - state.BoardAsChanged = true; - state.type = 0; - state.editing = false; - state.id = -1; - }, - loadButton: (state, { payload }) => { - state.url = state.ActiveLayout[payload].url; - state.button = state.ActiveLayout[payload].text; - state.type = state.ActiveLayout[payload].type; - state.editing = true; - state.id = payload; - }, - removeButton: (state, { payload }) => { - state.ActiveLayout.splice(payload, 1); - state.BoardAsChanged = true; - }, - resetCreateButtonModal: (state) => { - state.url = ""; - state.button = ""; - state.BoardAsChanged = true; - state.type = 0; - state.editing = false; - state.id = -1; - }, - setUrl: (state, { payload }) => ({ ...state, url: payload }), - setButton: (state, { payload }) => ({ ...state, button: payload }), - setType: (state, { payload }) => ({ ...state, type: Number(payload) }), - updateBoard: (state, { payload }) => { - state.ActiveLayout = JSON.parse(payload); - }, - }, - extraReducers: (builder) => { - builder - .addCase(GetBoard.pending, (state) => { - state.Pending = true; - }) - .addCase(GetBoard.rejected, (state) => { - state.Pending = false; - }) - .addCase(GetBoard.fulfilled, parse) - .addCase(DeleteBoard.pending, (state) => { - state.Pending = true; - }) - .addCase(DeleteBoard.rejected, (state) => { - state.Pending = false; - }) - .addCase(DeleteBoard.fulfilled, parse) - .addCase(UpdateBoard.pending, (state) => { - state.Pending = true; - }) - .addCase(UpdateBoard.rejected, (state) => { - state.Pending = false; - }) - .addCase(UpdateBoard.fulfilled, (state, action) => { - state.BoardAsChanged = false; - parse(state, action); - }) - .addCase(CreateBoard.pending, (state) => { - state.Pending = true; - }) - .addCase(CreateBoard.rejected, (state) => { - state.Pending = false; - }) - .addCase(CreateBoard.fulfilled, parse); - }, -}); - -export const { - setActiveBoard, - setSound, - setHandlerLayout, - lock, - unLock, - addButton, - setUrl, - setButton, - removeButton, - editButton, - loadButton, - setType, - resetCreateButtonModal, - updateBoard, -} = SBoardSlicer.actions; -export default SBoardSlicer.reducer; diff --git a/src/Action/showModal.tsx b/src/Action/showModal.tsx deleted file mode 100644 index 3648fd5..0000000 --- a/src/Action/showModal.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import { createSlice } from "@reduxjs/toolkit"; - -interface Modal { - TokenForm: Boolean; - CreateTab: Boolean; - CreateButton: Boolean; - Burger: Boolean; - boardParam: Boolean; - queueSlide: Boolean; - importExport: Boolean; -} - -const initialState = { - TokenForm: false, - CreateTab: false, - CreateButton: false, - Burger: false, - boardParam: false, - queueSlide: false, - importExport: false, -} as Modal; - -const ShowModalSlicer = createSlice({ - name: "showModal", - initialState, - reducers: { - showTokenForm: (state) => { - state.TokenForm = true; - }, - hideTokenForm: (state) => { - state.TokenForm = false; - }, - showCreateTab: (state) => { - state.CreateTab = true; - }, - hideCreateTab: (state) => { - state.CreateTab = false; - }, - showCreateButton: (state) => { - state.CreateButton = true; - }, - hideCreateButton: (state) => { - state.CreateButton = false; - }, - setBurger: (state, { payload }) => { - state.Burger = payload; - }, - setBoardParam: (state, { payload }) => { - state.boardParam = payload; - if (payload === true) state.queueSlide = false; - }, - setQueueSlide: (state, { payload }) => { - state.queueSlide = payload; - if (payload === true) state.boardParam = false; - }, - setImportExport: (state, { payload }) => { - state.importExport = payload; - }, - }, -}); - -export const { - showTokenForm, - hideTokenForm, - showCreateTab, - hideCreateTab, - showCreateButton, - hideCreateButton, - setBurger, - setBoardParam, - setQueueSlide, - setImportExport, -} = ShowModalSlicer.actions; -export default ShowModalSlicer.reducer; diff --git a/src/Component/App.tsx b/src/Component/App.tsx deleted file mode 100644 index 10de2bd..0000000 --- a/src/Component/App.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import React, { useEffect } from "react"; -import { connect } from "react-redux"; -import { TokenGetter } from "../Action/Token"; -import { - BotGetter, - BotServerGetter, - CanPlay, - BotServeurChanGetter, - BotPresenceGetter, -} from "../Action/Bot"; -import { Route } from "react-router-dom"; -import TokenComponent from "./Token"; -import NavBar from "./navbar"; -import BotCanPlay from "./Bot/modal"; -import io from "socket.io-client"; -import { EventInit } from "../Action/Event"; -import { getVoice } from "../Action/Voice"; -import Voice from "./Voice"; -var socket = io(process.env.REACT_APP_SERVER as string, {}); -export const App = ({ dispatch, Token, Event, Bot }: any) => { - useEffect(() => { - dispatch(TokenGetter()); - dispatch(CanPlay()); - dispatch(BotGetter({})).then(() => dispatch(BotServerGetter())); - dispatch(BotPresenceGetter()) - dispatch(getVoice()).then(({ payload }: any) => { - if (payload.Chan && payload.Server) { - dispatch(BotServeurChanGetter(payload.Server.id)); - } - }); - dispatch(EventInit({ socket })); - if (process.env.REACT_APP_NAME !== undefined) - document.title = process.env.REACT_APP_NAME; - // eslint-disable-next-line - }, []); - - return ( -
- - - - -
- ); -}; - -export default connect((state) => state)(App); diff --git a/src/Component/Bot/modal.tsx b/src/Component/Bot/modal.tsx deleted file mode 100644 index 7edc609..0000000 --- a/src/Component/Bot/modal.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import React from "react"; -import { connect } from "react-redux"; -import Modal from "../Modal"; - -import { CanPlay } from "../../Action/Bot"; - -const BotCanPlay = ({ Bot, dispatch }: any) => { - return ( - { - dispatch(CanPlay()); - }} - activateText="TryAgain" - Content={() => ( -
- {Bot.canPlay.canPlay !== true && ( -
-

Les binaries ffmpeg ne sont pas disponible

-

- Afin de pouvoir utiliser le bot veuillez télécharger l'archive - contenant les exécutable nécessaire : -

- - {" "} - =>Ffmpeg.org - -

- Une fois l'archive télécharger veuillez placer sont contenue - dans : -

- {Bot.canPlay.where}\
- - La documentation - -
- )} -
- )} - /> - ); -}; - -export default connect((state) => state)(BotCanPlay); diff --git a/src/Component/Modal/index.tsx b/src/Component/Modal/index.tsx deleted file mode 100644 index 7f88499..0000000 --- a/src/Component/Modal/index.tsx +++ /dev/null @@ -1,110 +0,0 @@ -import React, { useEffect, useRef } from "react"; - -export const Modal = ({ - on, - warn, - exitOnEscape = true, - title = process.env.REACT_APP_NAME, - Content, - message, - activateText, - activate, - deactivateText, - deactivate, -}: any) => { - const modalRef = useRef(null); - const onEscape = ({ key }: any) => { - if (key === "Escape"&&on===true) { - activate(); - window.removeEventListener("keydown", onEscape); - } - }; - const onOutside = (event: any) => { - if (!modalRef.current?.contains(event.target)&&on===true) { - activate(); - window.removeEventListener("keydown", onOutside); - } - }; - useEffect(() => { - if (exitOnEscape) { - window.addEventListener("keydown", onEscape); - window.addEventListener("mousedown", onOutside); - return () => { - window.removeEventListener("keydown", onEscape); - window.removeEventListener("mousedown", onOutside); - }; - } - // eslint-disable-next-line - }, []); - return ( -
-
- -
-
-
- {warn && ( -
- -
- )} -
- -
{Content ? : message}
-
- {activate && ( - - )} - {deactivate && ( - - )} -
-
-
-
-
-
-
- ); -}; - -export default Modal; diff --git a/src/Component/Modal/info/credit.tsx b/src/Component/Modal/info/credit.tsx deleted file mode 100644 index 6e4f48e..0000000 --- a/src/Component/Modal/info/credit.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react'; - -const Credit = () => { - return ( -
-

R2-D2 by P Thanga Vignesh from the Noun Project

-
- ) -} \ No newline at end of file diff --git a/src/Component/Token/TokenForm.tsx b/src/Component/Token/TokenForm.tsx deleted file mode 100644 index b74be27..0000000 --- a/src/Component/Token/TokenForm.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import React, { useState } from "react"; -import { connect } from "react-redux"; -import { TokenCreate } from "../../Action/Token"; - -export const TokenForm = ({ dispatch, Token, ...props }: any) => { - var [label, setLabel] = useState(""); - var [token, setToken] = useState(""); - var send = () => { - if (label.length >= 2 && token.length >= 2) { - dispatch(TokenCreate({ label, token })); - setLabel(""); - setToken(""); - } - }; - return ( -
-
- - - - {">"}comment créer un bot ?{"<"} -
-
- ); -}; - -export default connect((state) => state)(TokenForm); diff --git a/src/Component/Token/TokenItem.tsx b/src/Component/Token/TokenItem.tsx deleted file mode 100644 index ee2ed1b..0000000 --- a/src/Component/Token/TokenItem.tsx +++ /dev/null @@ -1,102 +0,0 @@ -import React from "react"; -import { connect } from "react-redux"; -import { - TokenDelete, - TokenActivate, - TokenDeactivate, -} from "../../Action/Token"; - -export const TokenItem = ({ - Token, - dispatch, - value = { label: "Unlabeled Bot" }, - load = false, - Bot, - ...props -}: any) => { - var del = () => { - if (value.id) dispatch(TokenDelete(value.id)); - }; - var play = () => { - if (value.id) dispatch(TokenActivate(value.id)); - }; - var stop = () => { - if (value.id) dispatch(TokenDeactivate(value.id)); - }; - return ( -
-

{value.label}

-

- {value.token ? value.token.substring(0, 4) : "To...Ken"} - {value.token ? "..." : ""} - {value.token ? value.token.substring(value.token.length - 4) : ""} -

-
- - - - {value.id !== Bot.ActiveBot && ( - - - - - )} - {value.id === Bot.ActiveBot && ( - - - - )} -
-
- ); -}; - -export default connect((state) => state)(TokenItem); diff --git a/src/Component/Token/TokenModalForm.tsx b/src/Component/Token/TokenModalForm.tsx deleted file mode 100644 index bad18df..0000000 --- a/src/Component/Token/TokenModalForm.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import React from "react"; -import { connect } from "react-redux"; -import Modal from "../Modal"; -import TokenForm from "./TokenForm"; -import { hideTokenForm } from "../../Action/showModal"; - -const TokenModalForm = ({ ShowModal, dispatch }: any) => { - return ( - { - dispatch(hideTokenForm()); - }} - activateText="Exit" - Content={TokenForm} - /> - ); -}; - -export default connect((state) => state)(TokenModalForm); diff --git a/src/Component/Token/index.tsx b/src/Component/Token/index.tsx deleted file mode 100644 index 156cb48..0000000 --- a/src/Component/Token/index.tsx +++ /dev/null @@ -1,144 +0,0 @@ -import React from "react"; -import { connect } from "react-redux"; -import TokenItem from "./TokenItem"; -import { showTokenForm } from "../../Action/showModal"; -import { Link } from "react-router-dom"; -import TokenModalForm from "./TokenModalForm"; -import { - BotPresenceGetter, - BotPresenceSetter, - setName, - setStatus, - setType, -} from "../../Action/Bot"; - -export const index = ({ Token, dispatch, Bot, ...props }: any) => { - return ( -
- {Token.Pending &&
} -

Liste des Bot:

-
- {!Token.Pending && Token.AllToken.length === 0 && ( -
-

Aucun Bot disponible

-

Veuillez en créer un

- -
- )} - {Token.AllToken.map((value: any) => ( - - ))} -
- dispatch(showTokenForm())} - /> - {Bot.ActiveBot !== -1 && ( -
-

Bot actif :

-
- Icon du bot -
-

Username : {Bot.user.username}

-

Tag : {Bot.user.tag}

-
-
- - - - - -
-
-

Guild disponible:

- {Array.isArray(Bot.Serveur) && - Bot.Serveur.map((value: any) => ( -
=>{value.ServeurName}
- ))} -
-
- - Vers la SoundBoard - -
- )} - -
- ); -}; - -export default connect((state) => state)(index); diff --git a/src/Component/Voice/AddButtonModal.tsx b/src/Component/Voice/AddButtonModal.tsx deleted file mode 100644 index 2ac849e..0000000 --- a/src/Component/Voice/AddButtonModal.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import React from 'react' -import { connect } from 'react-redux' -import Modal from '../Modal' -import {hideCreateButton} from '../../Action/showModal' -import ButtonForm from './ButtonForm' -import { resetCreateButtonModal } from '../../Action/sBoard' - -const TokenModalForm = ({ShowModal,dispatch}:any) =>{ - return( - { - dispatch(hideCreateButton()) - dispatch(resetCreateButtonModal()) - }} - activateText="Exit" - Content={ButtonForm} /> - ) -} - -export default connect(state=>state)(TokenModalForm) \ No newline at end of file diff --git a/src/Component/Voice/AddTabModal.tsx b/src/Component/Voice/AddTabModal.tsx deleted file mode 100644 index 6f25638..0000000 --- a/src/Component/Voice/AddTabModal.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import React from 'react' -import { connect } from 'react-redux' -import Modal from '../Modal' -import {hideCreateTab} from '../../Action/showModal' -import TabForm from './TabForm' -const TokenModalForm = ({ShowModal,dispatch}:any) =>{ - return( - dispatch(hideCreateTab())} - activateText="Exit" - Content={TabForm} /> - ) -} - -export default connect(state=>state)(TokenModalForm) \ No newline at end of file diff --git a/src/Component/Voice/BoardLayout.tsx b/src/Component/Voice/BoardLayout.tsx deleted file mode 100644 index 3991236..0000000 --- a/src/Component/Voice/BoardLayout.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import React from "react"; -import { connect } from "react-redux"; -import GridLayout from "react-grid-layout"; -import { removeButton, setHandlerLayout, loadButton } from "../../Action/sBoard"; -import { startVoice } from "../../Action/Voice"; -import { showCreateButton } from "../../Action/showModal"; - -const BoardLayout = ({ sBoard, dispatch, Voice }: any) => { - // eslint-disable-next-line - var enumMedia = { 1: "mp3", 2: "YouTube", 3: "spotify" }; - return ( - - dispatch(setHandlerLayout(Layout)) - } - className="layout overflow-auto h-full w-full" - layout={sBoard.ActiveLayout} - cols={11} - rowHeight={30} - width={1200} - > - {sBoard.ActiveLayout.map((value: any, index: number) => ( -
{ - if (value.static) - dispatch( - startVoice({ - song: { - title: value.text, - url: value.url, - type: value.type, - }, - now: Voice.Asap, - }) - ); - }} - > - {value.text} - {!value.static && ( -
- dispatch(removeButton(index))} - className="bg-gray-400 rounded-md hover:bg-gray-200 mx-0.5" - style={{ width: "24px", height: "24px" }} - xmlns="http://www.w3.org/2000/svg" - fill="none" - viewBox="0 0 24 24" - stroke="currentColor" - > - - - { - dispatch(loadButton(index)) - dispatch(showCreateButton()) - }} - className="bg-gray-400 rounded-md hover:bg-gray-200 mx-0.5" - style={{ width: "24px", height: "24px" }} - fill="none" - viewBox="0 0 24 24" - stroke="currentColor" - > - - -
- )} -
- ))} -
- ); -}; - -export default connect((state) => state)(BoardLayout); diff --git a/src/Component/Voice/BoardParam.tsx b/src/Component/Voice/BoardParam.tsx deleted file mode 100644 index 24c34fa..0000000 --- a/src/Component/Voice/BoardParam.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import React from "react"; -import { connect } from "react-redux"; -import { DeleteBoard, lock, unLock, UpdateBoard } from "../../Action/sBoard"; -import { setImportExport, showCreateButton, showCreateTab } from "../../Action/showModal"; - -const BoardParam = ({ dispatch, sBoard }: any) => { - return ( -
-
- - - - - - - -
-
- ); -}; - -export default connect((state) => state)(BoardParam); diff --git a/src/Component/Voice/ButtonForm.tsx b/src/Component/Voice/ButtonForm.tsx deleted file mode 100644 index 634a0f5..0000000 --- a/src/Component/Voice/ButtonForm.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import React from "react"; -import { connect } from "react-redux"; -import { - setButton, - setUrl, - addButton, - setType, - editButton, -} from "../../Action/sBoard"; -import { startVoice } from "../../Action/Voice"; - -export const ButtonForm = ({ dispatch, Voice, sBoard, ...props }: any) => { - var send = () => { - if (sBoard.button.length >= 2 && sBoard.url.length >= 2) { - dispatch((sBoard.editing ? editButton : addButton)()); - } - }; - return ( -
-
- - - - - -
-
- ); -}; - -export default connect((state) => state)(ButtonForm); diff --git a/src/Component/Voice/TabForm.tsx b/src/Component/Voice/TabForm.tsx deleted file mode 100644 index d8d270b..0000000 --- a/src/Component/Voice/TabForm.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React,{useState} from 'react'; -import { connect } from 'react-redux' -import { CreateBoard } from '../../Action/sBoard'; - -export const TabForm =({dispatch,Voice,...props}:any)=>{ - var [label,setLabel] = useState(""); - var send = () => { - if(label.length>=2){ - dispatch(CreateBoard({label:label})) - setLabel("") - } - } - return( -
-
- - -
-
- ) -} - -export default connect(state=>state)(TabForm) \ No newline at end of file diff --git a/src/Component/Voice/VoicePlayer.tsx b/src/Component/Voice/VoicePlayer.tsx deleted file mode 100644 index a930351..0000000 --- a/src/Component/Voice/VoicePlayer.tsx +++ /dev/null @@ -1,87 +0,0 @@ -import React from "react"; -import { connect } from "react-redux"; -import { resumeVoice, stopVoice, setVolume, setAsap, skipVoice } from "../../Action/Voice"; -const VoicePlayer = ({ dispatch, Voice, ...props }: any) => { - return ( -
- - dispatch(setAsap(e.target.checked))} - checked={Voice.Asap} - className="place-self-center" - /> - dispatch(resumeVoice())} - className="bg-gray-400 rounded-md hover:bg-gray-200 mx-0.5" - style={{ width: "24px", height: "24px" }} - fill="none" - viewBox="0 0 24 24" - stroke="currentColor" - > - - - - dispatch(stopVoice())} - className="bg-gray-400 rounded-md hover:bg-gray-200 mx-0.5" - style={{ width: "24px", height: "24px" }} - fill="none" - viewBox="0 0 24 24" - stroke="currentColor" - > - - - dispatch(skipVoice())} - > - - -
- - dispatch(setVolume(Number(event.target.value)))} - value={Voice.Volume} - /> -
-
- ); -}; - -export default connect((state) => state)(VoicePlayer); diff --git a/src/Component/Voice/impExport.tsx b/src/Component/Voice/impExport.tsx deleted file mode 100644 index a397121..0000000 --- a/src/Component/Voice/impExport.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import React from 'react'; -import { connect } from 'react-redux' -import { setImportExport } from '../../Action/showModal'; -import Modal from '../Modal' -import ImportExportForm from './imprExportForm' - -const ImportExportModal = ({ ShowModal, dispatch }: any) => { - return ( - { - dispatch(setImportExport(false)) - }} - activateText="Exit" - Content={ImportExportForm} - /> - ) -} - -export default connect(state=>state)(ImportExportModal) \ No newline at end of file diff --git a/src/Component/Voice/imprExportForm.tsx b/src/Component/Voice/imprExportForm.tsx deleted file mode 100644 index e9e4e1c..0000000 --- a/src/Component/Voice/imprExportForm.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import React from "react"; -import { connect } from "react-redux"; -import { updateBoard } from "../../Action/sBoard"; - -const ImportExportForm = ({ ShowModal, sBoard, dispatch }: any) => { - var [code, setCode] = React.useState(""); - React.useEffect(() => { - setCode(JSON.stringify(sBoard.ActiveLayout)); - // eslint-disable-next-line - }, [sBoard.ActiveLayout]); - return ( -
-