diff --git a/.gitignore b/.gitignore index a3ae643..0c6e5cb 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ yarn-error.log* pnpm-debug.log* lerna-debug.log* +myenv + node_modules dist dist-ssr diff --git a/README.md b/README.md index 65e44d6..8fb353d 100644 --- a/README.md +++ b/README.md @@ -1,43 +1,56 @@ -# electron-vite-vue +# Podium Live -🥳 Really simple `Electron` + `Vue` + `Vite` boilerplate. +Twitch/YouTube ranking client intended to help streamers develop interesting apps for their viewers. -[![GitHub Build](https://github.com/electron-vite/electron-vite-vue/actions/workflows/build.yml/badge.svg)](https://github.com/electron-vite/electron-vite-vue/actions/workflows/build.yml) -[![GitHub Discord](https://img.shields.io/badge/chat-discord-blue?logo=discord)](https://discord.gg/sRqjYpEAUK) +[![GitHub Build](https://github.com/AQUASINE/podium/actions/workflows/build.yml/badge.svg)](https://github.com/electron-vite/electron-vite-vue/actions/workflows/build.yml) +[![Static Badge](https://img.shields.io/badge/Documentation-blue)](https://docs.podiumlive.dev/) ## Features -📦 Out of the box -🎯 Based on the official [template-vue-ts](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-vue-ts), less invasive -🌱 Extensible, really simple directory structure -💪 Support using Node.js API in Electron-Renderer -🔩 Support C/C++ native addons -🖥 It's easy to implement multiple windows +- Create ruleset pipelines that will rank your chatters based on their activity in chat. +- Find the best messages and best users based on whatever criteria you want. + +## TODO +- [ ] Add items to todo list + ## Quick Setup ```sh # clone the project -git clone https://github.com/electron-vite/electron-vite-vue.git +git clone https://github.com/AQUASINE/podium.git # enter the project directory -cd electron-vite-vue +cd podium -# install dependency +# install dependencies +pip install -r requirements.txt npm install +``` -# develop -npm run dev +Note that before running the project, you need to create a `config.json` file in the root directory with the following content: + +```json +{ + "TWITCH_OAUTH": "oauth:xxxxxxxxxxxxxxxxxx", + "BOT_USERNAME": "your_twitch_username", + "OPENAI_KEY": "sk-xxxxxxxxxxxxxxxxxxxxx" +} ``` -## Debug +Generate your Twitch OAuth token [here](https://twitchapps.com/tmi/), and use the account name you used to generate the token as `BOT_USERNAME`. -![electron-vite-react-debug.gif](https://github.com/electron-vite/electron-vite-react/blob/main/electron-vite-react-debug.gif?raw=true) +Get your OpenAI key [here](https://platform.openai.com/settings/profile?tab=api-keys). + +```sh +# develop +npm run dev +``` ## Directory @@ -74,6 +87,3 @@ export default { --> ## FAQ - -- [C/C++ addons, Node.js modules - Pre-Bundling](https://github.com/electron-vite/vite-plugin-electron-renderer#dependency-pre-bundling) -- [dependencies vs devDependencies](https://github.com/electron-vite/vite-plugin-electron-renderer#dependencies-vs-devdependencies) diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts new file mode 100644 index 0000000..e6694fd --- /dev/null +++ b/docs/.vitepress/config.ts @@ -0,0 +1,28 @@ +import { defineConfig } from 'vitepress' + +// https://vitepress.dev/reference/site-config +export default defineConfig({ + title: "Podium", + description: "Message/User ranking client for Twitch/YouTube Live", + themeConfig: { + // https://vitepress.dev/reference/default-theme-config + nav: [ + { text: 'Home', link: '/' }, + { text: 'Examples', link: '/markdown-examples' } + ], + + sidebar: [ + { + text: 'Examples', + items: [ + { text: 'Markdown Examples', link: '/markdown-examples' }, + { text: 'Runtime API Examples', link: '/api-examples' } + ] + } + ], + + socialLinks: [ + { icon: 'github', link: 'https://github.com/AQUASINE/podium' } + ] + } +}) diff --git a/docs/api-examples.md b/docs/api-examples.md new file mode 100644 index 0000000..6bd8bb5 --- /dev/null +++ b/docs/api-examples.md @@ -0,0 +1,49 @@ +--- +outline: deep +--- + +# Runtime API Examples + +This page demonstrates usage of some of the runtime APIs provided by VitePress. + +The main `useData()` API can be used to access site, theme, and page data for the current page. It works in both `.md` and `.vue` files: + +```md + + +## Results + +### Theme Data +
{{ theme }}
+ +### Page Data +
{{ page }}
+ +### Page Frontmatter +
{{ frontmatter }}
+``` + + + +## Results + +### Theme Data +
{{ theme }}
+ +### Page Data +
{{ page }}
+ +### Page Frontmatter +
{{ frontmatter }}
+ +## More + +Check out the documentation for the [full list of runtime APIs](https://vitepress.dev/reference/runtime-api#usedata). diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..ceb9075 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,25 @@ +--- +# https://vitepress.dev/reference/default-theme-home-page +layout: home + +hero: + name: "Podium" + text: "Ranking client for Twitch" + tagline: Give your chatters a way to compete for the top spot in your chat. + actions: + - theme: brand + text: Markdown Examples + link: /markdown-examples + - theme: alt + text: API Examples + link: /api-examples + +features: + - title: Feature A + details: Lorem ipsum dolor sit amet, consectetur adipiscing elit + - title: Feature B + details: Lorem ipsum dolor sit amet, consectetur adipiscing elit + - title: Feature C + details: Lorem ipsum dolor sit amet, consectetur adipiscing elit +--- + diff --git a/docs/markdown-examples.md b/docs/markdown-examples.md new file mode 100644 index 0000000..f9258a5 --- /dev/null +++ b/docs/markdown-examples.md @@ -0,0 +1,85 @@ +# Markdown Extension Examples + +This page demonstrates some of the built-in markdown extensions provided by VitePress. + +## Syntax Highlighting + +VitePress provides Syntax Highlighting powered by [Shiki](https://github.com/shikijs/shiki), with additional features like line-highlighting: + +**Input** + +````md +```js{4} +export default { + data () { + return { + msg: 'Highlighted!' + } + } +} +``` +```` + +**Output** + +```js{4} +export default { + data () { + return { + msg: 'Highlighted!' + } + } +} +``` + +## Custom Containers + +**Input** + +```md +::: info +This is an info box. +::: + +::: tip +This is a tip. +::: + +::: warning +This is a warning. +::: + +::: danger +This is a dangerous warning. +::: + +::: details +This is a details block. +::: +``` + +**Output** + +::: info +This is an info box. +::: + +::: tip +This is a tip. +::: + +::: warning +This is a warning. +::: + +::: danger +This is a dangerous warning. +::: + +::: details +This is a details block. +::: + +## More + +Check out the documentation for the [full list of markdown extensions](https://vitepress.dev/guide/markdown). diff --git a/electron-vite-vue.gif b/electron-vite-vue.gif deleted file mode 100644 index 66a14af..0000000 Binary files a/electron-vite-vue.gif and /dev/null differ diff --git a/index.html b/index.html index 59f2fd3..e6bd4e4 100644 --- a/index.html +++ b/index.html @@ -8,6 +8,12 @@ + + + + + + Podium diff --git a/package.json b/package.json index 819e70a..3bc35c5 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,11 @@ "scripts": { "dev": "vite", "build": "vue-tsc --noEmit && vite build && electron-builder", - "preview": "vite preview" + "preview": "vite preview", + "docs:dev": "vitepress dev docs", + "docs:build": "vitepress build docs", + "docs:preview": "vitepress preview docs", + "docs:deploy": "npm run docs:build && gh-pages -d docs/.vitepress/dist" }, "devDependencies": { "@mdi/font": "^7.4.47", @@ -38,6 +42,7 @@ "vite": "^5.0.10", "vite-plugin-electron": "^0.28.0", "vite-plugin-electron-renderer": "^0.14.5", + "vitepress": "^1.1.3", "vue": "^3.4.1", "vue-tsc": "^1.8.27" }, @@ -48,14 +53,19 @@ "chartjs": "^0.3.24", "codemirror": "^6.0.1", "electron-store": "^8.2.0", + "gh-pages": "^6.1.1", "highlight.js": "^11.9.0", "highlightjs": "^9.16.2", "three": "^0.163.0", + "uuid": "^9.0.1", "vue-codemirror": "^6.1.1", "vue-draggable": "^2.0.6", + "vue-draggable-next": "^2.2.1", "vue-draggable-resizable": "^3.0.0", "vue-resizable": "^2.1.7", + "vue-router": "^4.3.1", "vue-select": "^4.0.0-beta.6", + "vuedraggable": "^2.24.3", "vuetify": "^3.5.5", "vuex": "^4.1.0" } diff --git a/public/android-chrome-192x192.png b/public/android-chrome-192x192.png new file mode 100644 index 0000000..9a29e60 Binary files /dev/null and b/public/android-chrome-192x192.png differ diff --git a/public/android-chrome-512x512.png b/public/android-chrome-512x512.png new file mode 100644 index 0000000..b7e87e8 Binary files /dev/null and b/public/android-chrome-512x512.png differ diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png new file mode 100644 index 0000000..510e7b0 Binary files /dev/null and b/public/apple-touch-icon.png differ diff --git a/public/browserconfig.xml b/public/browserconfig.xml new file mode 100644 index 0000000..b3930d0 --- /dev/null +++ b/public/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #da532c + + + diff --git a/public/favicon-16x16.png b/public/favicon-16x16.png new file mode 100644 index 0000000..6f55c4d Binary files /dev/null and b/public/favicon-16x16.png differ diff --git a/public/favicon-32x32.png b/public/favicon-32x32.png new file mode 100644 index 0000000..9887d40 Binary files /dev/null and b/public/favicon-32x32.png differ diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..deecf37 Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/mstile-144x144.png b/public/mstile-144x144.png new file mode 100644 index 0000000..006d95f Binary files /dev/null and b/public/mstile-144x144.png differ diff --git a/public/mstile-150x150.png b/public/mstile-150x150.png new file mode 100644 index 0000000..1b2c52c Binary files /dev/null and b/public/mstile-150x150.png differ diff --git a/public/mstile-310x150.png b/public/mstile-310x150.png new file mode 100644 index 0000000..29802b5 Binary files /dev/null and b/public/mstile-310x150.png differ diff --git a/public/mstile-310x310.png b/public/mstile-310x310.png new file mode 100644 index 0000000..5e8a76d Binary files /dev/null and b/public/mstile-310x310.png differ diff --git a/public/mstile-70x70.png b/public/mstile-70x70.png new file mode 100644 index 0000000..28cb501 Binary files /dev/null and b/public/mstile-70x70.png differ diff --git a/public/site.webmanifest b/public/site.webmanifest new file mode 100644 index 0000000..b20abb7 --- /dev/null +++ b/public/site.webmanifest @@ -0,0 +1,19 @@ +{ + "name": "", + "short_name": "", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..4bbd0c6 Binary files /dev/null and b/requirements.txt differ diff --git a/src/App.vue b/src/App.vue index f16dacf..0381f74 100644 --- a/src/App.vue +++ b/src/App.vue @@ -22,7 +22,7 @@ import LeftSidebar from "./components/LeftSidebar.vue"; import UsersView from "./components/UsersView.vue"; import {mapState} from "vuex"; import AppTopbar from "./components/AppTopbar.vue"; -import CenterPanel from "./CenterPanel.vue"; +import CenterPanel from "./components/rule/CenterPanel.vue"; export default { name: 'App', diff --git a/src/components/AlwaysRuleContent.vue b/src/components/AlwaysRuleContent.vue deleted file mode 100644 index 668afb1..0000000 --- a/src/components/AlwaysRuleContent.vue +++ /dev/null @@ -1,12 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/components/AppTopbar.vue b/src/components/AppTopbar.vue index 47d4660..c6be3a5 100644 --- a/src/components/AppTopbar.vue +++ b/src/components/AppTopbar.vue @@ -11,18 +11,31 @@ Active Configuration
- +
- \ No newline at end of file diff --git a/src/components/PresentationModeCenterView.vue b/src/components/PresentationModeCenterView.vue index be7af25..963e21b 100644 --- a/src/components/PresentationModeCenterView.vue +++ b/src/components/PresentationModeCenterView.vue @@ -15,13 +15,19 @@ const worstChatter = computed(() => { if (users.value.length === 0) { return null; } - return users.value[0] - // return users.value[users.value.length - 1]; + // return users.value[0] + return users.value[users.value.length - 1]; +}); + +const worstChatterScore = computed(() => { + if (worstChatter.value) { + return worstChatter.value.user_score.toFixed(3); + } + return 0; }); onMounted(() => { const rect = threeContainerParent.value.getBoundingClientRect(); - console.log(rect.width, rect.height); const scene = new THREE.Scene(); const renderer = new THREE.WebGLRenderer(); // get size of the container @@ -55,7 +61,6 @@ onMounted(() => { cameraRotationStartY = camera.rotation.y; cameraRotationStartX = camera.rotation.x; scene.add(mrPodium); - console.log(gltf); // find all point lights and set their intensity to 0.5 mrPodium.traverse((child) => { @@ -113,7 +118,7 @@ onMounted(() => {
- Our best chatter is: + Our worst chatter is:
@@ -121,7 +126,7 @@ onMounted(() => { {{ worstChatter.user }}
- with a score of {{ worstChatter.user_score }} + with a score of {{ worstChatterScore }}
@@ -166,4 +171,9 @@ onMounted(() => { .container__message-box-wrapper { height: 0; } + +.container__presentation-mode { + width: 100%; + flex: 1; +} \ No newline at end of file diff --git a/src/components/PrimaryCenterView.vue b/src/components/PrimaryCenterView.vue index fa90c42..a028c1f 100644 --- a/src/components/PrimaryCenterView.vue +++ b/src/components/PrimaryCenterView.vue @@ -27,7 +27,6 @@
Rule Tuning
-
diff --git a/src/components/RegexRuleContent.vue b/src/components/RegexRuleContent.vue deleted file mode 100644 index 921b934..0000000 --- a/src/components/RegexRuleContent.vue +++ /dev/null @@ -1,82 +0,0 @@ - - - \ No newline at end of file diff --git a/src/components/RuleConfigCard.vue b/src/components/RuleConfigCard.vue index a53379e..7fac57b 100644 --- a/src/components/RuleConfigCard.vue +++ b/src/components/RuleConfigCard.vue @@ -13,17 +13,52 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/RuleSelectAutocomplete.vue b/src/components/RuleSelectAutocomplete.vue new file mode 100644 index 0000000..09c2dd5 --- /dev/null +++ b/src/components/RuleSelectAutocomplete.vue @@ -0,0 +1,29 @@ + + + \ No newline at end of file diff --git a/src/components/RuleTile.vue b/src/components/RuleTile.vue index ede19bf..acfa782 100644 --- a/src/components/RuleTile.vue +++ b/src/components/RuleTile.vue @@ -1,14 +1,20 @@ - \ No newline at end of file diff --git a/src/CenterPanel.vue b/src/components/rule/CenterPanel.vue similarity index 86% rename from src/CenterPanel.vue rename to src/components/rule/CenterPanel.vue index 10b783f..061c079 100644 --- a/src/CenterPanel.vue +++ b/src/components/rule/CenterPanel.vue @@ -13,10 +13,10 @@ + + + + \ No newline at end of file diff --git a/src/components/ContainsRuleContent.vue b/src/components/rule/ContainsRuleContent.vue similarity index 92% rename from src/components/ContainsRuleContent.vue rename to src/components/rule/ContainsRuleContent.vue index 384bdef..b2cc94c 100644 --- a/src/components/ContainsRuleContent.vue +++ b/src/components/rule/ContainsRuleContent.vue @@ -1,6 +1,6 @@ + + + + \ No newline at end of file diff --git a/src/components/ExactMatchRuleContent.vue b/src/components/rule/ExactMatchRuleContent.vue similarity index 92% rename from src/components/ExactMatchRuleContent.vue rename to src/components/rule/ExactMatchRuleContent.vue index c146b74..16154fd 100644 --- a/src/components/ExactMatchRuleContent.vue +++ b/src/components/rule/ExactMatchRuleContent.vue @@ -1,6 +1,6 @@ + + + + \ No newline at end of file diff --git a/src/components/rule/MessageLengthRuleContent.vue b/src/components/rule/MessageLengthRuleContent.vue new file mode 100644 index 0000000..e7039d6 --- /dev/null +++ b/src/components/rule/MessageLengthRuleContent.vue @@ -0,0 +1,84 @@ + + + + + \ No newline at end of file diff --git a/src/components/rule/MessageScoreRuleContent.vue b/src/components/rule/MessageScoreRuleContent.vue new file mode 100644 index 0000000..ce7a688 --- /dev/null +++ b/src/components/rule/MessageScoreRuleContent.vue @@ -0,0 +1,32 @@ + + + + + \ No newline at end of file diff --git a/src/components/rule/NothingRuleContent.vue b/src/components/rule/NothingRuleContent.vue new file mode 100644 index 0000000..6e9fe34 --- /dev/null +++ b/src/components/rule/NothingRuleContent.vue @@ -0,0 +1,13 @@ + + + + + \ No newline at end of file diff --git a/src/components/rule/RegexRuleContent.vue b/src/components/rule/RegexRuleContent.vue new file mode 100644 index 0000000..540b00c --- /dev/null +++ b/src/components/rule/RegexRuleContent.vue @@ -0,0 +1,99 @@ + + + \ No newline at end of file diff --git a/src/components/rule/ReplaceRuleContent.vue b/src/components/rule/ReplaceRuleContent.vue new file mode 100644 index 0000000..51b7ab2 --- /dev/null +++ b/src/components/rule/ReplaceRuleContent.vue @@ -0,0 +1,20 @@ + + + + + \ No newline at end of file diff --git a/src/components/rule/SeededChanceRuleContent.vue b/src/components/rule/SeededChanceRuleContent.vue new file mode 100644 index 0000000..285680d --- /dev/null +++ b/src/components/rule/SeededChanceRuleContent.vue @@ -0,0 +1,18 @@ + + + + + \ No newline at end of file diff --git a/src/components/rule/TimeBasedRuleContent.vue b/src/components/rule/TimeBasedRuleContent.vue new file mode 100644 index 0000000..9f40eeb --- /dev/null +++ b/src/components/rule/TimeBasedRuleContent.vue @@ -0,0 +1,16 @@ + + + + + \ No newline at end of file diff --git a/src/components/rule/UserBlacklistRuleContent.vue b/src/components/rule/UserBlacklistRuleContent.vue new file mode 100644 index 0000000..2eaddb6 --- /dev/null +++ b/src/components/rule/UserBlacklistRuleContent.vue @@ -0,0 +1,16 @@ + + + + + \ No newline at end of file diff --git a/src/components/rule/UserScoreRuleContent.vue b/src/components/rule/UserScoreRuleContent.vue new file mode 100644 index 0000000..65cdb33 --- /dev/null +++ b/src/components/rule/UserScoreRuleContent.vue @@ -0,0 +1,32 @@ + + + + + \ No newline at end of file diff --git a/src/components/rule/UserWhitelistRuleContent.vue b/src/components/rule/UserWhitelistRuleContent.vue new file mode 100644 index 0000000..bdd88ff --- /dev/null +++ b/src/components/rule/UserWhitelistRuleContent.vue @@ -0,0 +1,16 @@ + + + + + \ No newline at end of file diff --git a/src/rules.js b/src/rules.js index e114806..f4f81e6 100644 --- a/src/rules.js +++ b/src/rules.js @@ -31,7 +31,7 @@ export const conditionTypes = [ }, { id: 'score', - name: 'Current Message Score', + name: 'Message Score', description: "Match messages based on the message's current score.", }, { @@ -74,7 +74,7 @@ export const conditionTypes = [ export const actionTypes = [ { id: 'nothing', - name: 'Do Nothing', + name: 'Nothing', description: "Simply pass the message through without any modifications.", }, { @@ -99,7 +99,7 @@ export const actionTypes = [ }, { id: 'math', - name: 'Math', + name: 'Score Math', description: "Modify message or user score using math operations.", matchingKeywords: ['add', 'subtract', 'multiply', 'divide', 'modulo', 'power', 'root', 'function'] }, @@ -131,6 +131,46 @@ export const actionTypes = [ { id: 'sentimentAnalysis', name: 'Sentiment Analysis', - description: "Analyze the sentiment of a message.", + description: "Analyze the positive/negative sentiment of a message.", } -] \ No newline at end of file +] + +export const comparisonOperators = [ + { + id: '==', + name: 'Equal to', + }, + { + id: '!=', + name: 'Not equal to', + }, + { + id: '>', + name: 'Greater than', + }, + { + id: '>=', + name: 'Greater than or equal to', + }, + { + id: '<', + name: 'Less than', + }, + { + id: '<=', + name: 'Less than or equal to', + }, +] + +export const extendedComparisonOperators = [ + ...comparisonOperators, + { + id: 'dist >', + name: 'With distance greater than', + }, + { + id: 'dist <', + name: 'With distance less than', + }, +] + diff --git a/src/service/daemon.py b/src/service/daemon.py index 9b41879..9dbea2e 100644 --- a/src/service/daemon.py +++ b/src/service/daemon.py @@ -7,7 +7,7 @@ import threading as th import urllib.request from podium import * -from flask import Flask +from flask import Flask, request from gptclient import GPTClient from websockets.server import serve from websocket import create_connection @@ -22,14 +22,16 @@ 'brown' ]) -BOT_USERNAME = 'AQUASINE' YOUTUBE_FETCH_INTERVAL = 1 +BOT_USERNAME = 'AQUASINE' # try to read bot token from saved-credentials.json try: with open('saved-credentials.json', 'r') as f: credentials = json.load(f) BOT_TOKEN = credentials['TWITCH_OAUTH'] + if 'BOT_USERNAME' in credentials: + BOT_USERNAME = credentials['BOT_USERNAME'] except FileNotFoundError: print("saved-credentials.json not found. Using config.json") # read bot token from config.json. if it doesn't exist, tell the user to create it @@ -38,8 +40,9 @@ config = json.load(f) try: BOT_TOKEN = config['TWITCH_OAUTH'] + BOT_USERNAME = config['BOT_USERNAME'] except KeyError: - print("config.json is missing the TWITCH_OAUTH key. Please create a bot account and add the OAuth token to config.json") + print("config.json is missing the TWITCH_OAUTH or BOT_USERNAME key. Please create a bot account and add the OAuth token and bot username to config.json") exit(1) try: OPENAI_KEY = config['OPENAI_KEY'] @@ -313,13 +316,88 @@ async def reconnect(): def set_configuration(): global active_configuration data = request.json - # TODO: convert data to PodiumConfiguration + + rules = [] + for rule in data['rules']: + # convert rule to PodiumRule + action = None + if 'action' in rule: + actionInfo = rule['action'] + actionId = actionInfo['id'] + actionArgs = actionInfo['args'] + if actionId == 'nothing': + action = None + elif actionId == 'set': + score = actionArgs['score'] + action = [set_score, score] + elif actionId == 'math': + operator = actionArgs['operator'] + score = actionArgs['score'] + if operator == 'add': + action = [add_score, score] + elif operator == 'multiply': + action = [multiply_score, score] + elif operator == 'divide': + action = [divide_score, score] + elif operator == 'subtract': + action = [subtract_score, score] + elif actionId == 'add': + score = actionArgs['score'] + mode = actionArgs['mode'] + if mode == 'user': + action = [add_user_score, score] + if mode == 'message': + action = [add_message_score, score] + elif actionId == 'gpt': + prompt = actionArgs['prompt'] + gpt_client.set_prompt(prompt) + action = [gpt_score, gpt_client, prompt] + + condition = None + if 'condition' in rule: + conditionInfo = rule['condition'] + conditionId = conditionInfo['id'] + conditionArgs = conditionInfo['args'] + if conditionId == 'nothing': + condition = None + elif conditionId == 'contains': + text = conditionArgs['text'] + condition = [contains_text, text] + elif conditionId == 'regex': + regex = conditionArgs['regex'] + condition = [regex_match, regex] + elif conditionId == 'user': + user = conditionArgs['user'] + condition = [user_match, user] + elif conditionId == 'message': + message = conditionArgs['message'] + condition = [message_match, message] + elif conditionId == 'emote': + emote = conditionArgs['emote'] + condition = [emote_match, emote] + + podium_rule = PodiumRule(rule['name'], condition, action) + pass + + active_configuration = PodiumConfiguration(data['name'], data['twitch_channels'], data['youtube_channels'], rules) return 'ok' @app.route('/get_active_configuration') def get_active_configuration(): return active_configuration +@app.route('/set_twitch_channels', methods=['POST']) +async def set_twitch_channels(): + data = request.json + await bot.join_channels(data) + return 'ok' + +@app.route('/set_youtube_channels', methods=['POST']) +def set_youtube_channels(): + data = request.json + youtube.youtube_connect(data['channel_id'], data['channel_name']) + return 'ok' + @app.route('/get_configurations') def get_configurations(): return configurations @@ -328,8 +406,6 @@ def get_configurations(): def get_emotes(): return emote_sets - - processing_thread = None gpt_thread = None yt_thread = None diff --git a/src/service/gptclient.py b/src/service/gptclient.py index ad77493..c557a78 100644 --- a/src/service/gptclient.py +++ b/src/service/gptclient.py @@ -177,7 +177,7 @@ async def process_queue(self): gpt_client.enqueue_eval_async([ PodiumRuleResult("I am an epic gamer", 0, [], {}), PodiumRuleResult("Video games are for nerds", 0, [], {}), - PodiumRuleResult("KILL YOURSELF", 0, [], {}), + PodiumRuleResult("UNALIVE YOURSELF", 0, [], {}) ]) diff --git a/src/store/modules/configurations.js b/src/store/modules/configurations.js index eecf649..9ee3400 100644 --- a/src/store/modules/configurations.js +++ b/src/store/modules/configurations.js @@ -1,7 +1,7 @@ const configurations = { namespaced: true, state: { - active: 'abcdsdf', + activeId: 'abcdsdf', configurations: [ { id: "abcdsdf", @@ -44,13 +44,13 @@ const configurations = { ] }, getters: { - activeConfigurationObject(state) { - return state.configurations.find(c => c.id === state.active); + activeConfiguration(state) { + return state.configurations.find(c => c.id === state.activeId); } }, mutations: { - setActiveConfiguration(state, payload) { - state.active = payload; + setActiveId(state, payload) { + state.activeId = payload; }, setConfigurations(state, payload) { state.configurations = payload; @@ -64,4 +64,6 @@ const configurations = { state.configurations[index] = payload; } }, -} \ No newline at end of file +} + +export default configurations; \ No newline at end of file diff --git a/src/store/store.js b/src/store/store.js index 7d0e847..2900313 100644 --- a/src/store/store.js +++ b/src/store/store.js @@ -1,8 +1,11 @@ import {createStore} from "vuex"; +import configurations from "./modules/configurations.js"; const DEBUG_MESSAGES = false; const store = createStore({ - modules: {}, + modules: { + configurations + }, state: { isConnected: false, connectionString: "localhost:8765", diff --git a/src/style.css b/src/style.css index 3fdbfa8..118a62d 100644 --- a/src/style.css +++ b/src/style.css @@ -150,6 +150,30 @@ code { border-radius: 4px; } +input[type="number"] { + border-radius: 0.25rem; + font-size: 1em; + font-weight: 500; + font-family: inherit; + width: 50px; + height: 30px; + padding: 0.2em 0.75em; + background-color: var(--bg2); + border: 1px solid transparent; + transition: border-color 0.25s; +} + +input[type="text"].text-input { + border-radius: 0.25rem; + font-size: 1em; + font-weight: 500; + font-family: inherit; + height: 30px; + padding: 0.2em 0.75em; + background-color: var(--bg2); + border: 1px solid var(--bg4); + transition: border-color 0.25s; +} >>> { diff --git a/src/utils.js b/src/utils.js new file mode 100644 index 0000000..a88d11a --- /dev/null +++ b/src/utils.js @@ -0,0 +1,22 @@ +import { ref } from 'vue'; + +export function useMessageLengthValidator(initialValue) { + const value = ref(initialValue); + + const validate = () => { + value.value = Math.floor(value.value); + + if (value.value < 1) { + value.value = 1; + } + + if (value.value > 1000) { + value.value = 1000; + } + }; + + return { + value, + validate + }; +} \ No newline at end of file