Skip to content

Commit

Permalink
Merge pull request #134 from LordTocs/tocs
Browse files Browse the repository at this point in the history
0.1.9 Improvements
  • Loading branch information
LordTocs authored Apr 7, 2022
2 parents 3e3afcb + 752f98a commit 15fcdce
Show file tree
Hide file tree
Showing 16 changed files with 425 additions and 18 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "castmate",
"version": "0.1.8",
"version": "0.1.9",
"private": "true",
"description": "CastMate is a broadcaster tool that allows Twitch viewers to interact with a broadcasters stream components through Chat Commands, Channel Point rewards, and more.",
"author": "LordTocs & FitzBro",
Expand Down
Binary file added src/assets/automation.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/obsws_logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/triggers.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/twitchLogo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/websocket.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/websocketSettings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
143 changes: 143 additions & 0 deletions src/components/wizard/ObsSettings.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
<template>
<v-card>
<v-card-text>
<v-row>
<v-col>
<data-input
:schema="addRequired(this.plugins.obs.settings.hostname)"
label="Hostname"
v-model="hostname"
/>
</v-col>
<v-col>
<data-input
:schema="addRequired(this.plugins.obs.settings.port)"
label="Port"
v-model="port"
/>
</v-col>
</v-row>
<v-row>
<v-col>
<data-input
:schema="addRequired(this.plugins.obs.secrets.password)"
label="Password"
v-model="password"
secret
/>
</v-col>
</v-row>
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn :color="connected ? 'success' : 'primary'" :loading="trying" large @click="tryConnect"> {{ connected ? "Successfully Connected" : "Connect" }} </v-btn>
<v-spacer />
</v-card-actions>
</v-card>
</template>

<script>
import fs from "fs";
import YAML from "yaml";
import { mapGetters } from "vuex";
import DataInput from "../data/DataInput.vue";
import { mapIpcs } from "../../utils/ipcMap";
export default {
components: {
DataInput,
},
data() {
return {
hostname: "localhost",
port: 4444,
password: null,
connected: false,
trying: false,
};
},
computed: {
...mapGetters("ipc", ["plugins", "paths"]),
},
methods: {
...mapIpcs("obs", ["tryConnectSettings"]),
addRequired(schema) {
return { ...schema, required: true };
},
async save() {
const fullSettingsText = await fs.promises.readFile(
this.paths.settingsFilePath,
"utf-8"
);
const fullSettings = YAML.parse(fullSettingsText) || {};
if (!fullSettings.obs) {
fullSettings.obs = {};
}
fullSettings.obs.hostname = this.hostname;
fullSettings.obs.port = this.port;
await fs.promises.writeFile(
this.paths.settingsFilePath,
YAML.stringify(fullSettings)
);
const fullSecretsText = await fs.promises.readFile(
this.paths.secretsFilePath,
"utf-8"
);
const fullSecrets = YAML.parse(fullSecretsText) || {};
if (!fullSecrets.obs) {
fullSecrets.obs = {};
}
fullSecrets.obs.password = this.password;
await fs.promises.writeFile(
this.paths.secretsFilePath,
YAML.stringify(fullSecrets)
);
},
async load() {
const fullSettingsText = await fs.promises.readFile(
this.paths.settingsFilePath,
"utf-8"
);
const fullSettings = YAML.parse(fullSettingsText) || {};
this.hostname = fullSettings?.obs?.hostname || "localhost";
this.port = fullSettings?.obs?.port || 4444;
const fullSecretsText = await fs.promises.readFile(
this.paths.secretsFilePath,
"utf-8"
);
const fullSecrets = YAML.parse(fullSecretsText) || {};
this.password = fullSecrets?.obs?.password;
},
async tryConnect() {
this.trying = true;
const result = await this.tryConnectSettings(this.hostname, this.port, this.password);
this.trying = false;
if (result)
{
this.connected = true;
await this.save();
}
}
},
async mounted() {
await this.load();
},
};
</script>
<style>
</style>
195 changes: 195 additions & 0 deletions src/components/wizard/WelcomeDialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
<template>
<v-dialog persistent v-model="dialog" width="80%" @keydown.esc="cancel">
<v-card>
<p class="text-center text-h2" v-if="stage == 'welcome'">
Welcome to CastMate!
</p>
<v-card-title class="text-center" v-if="stage == 'twitch'">
<h1>
Sign Into <img src="../../assets/twitchLogo.png" class="twitchLogo" />
</h1>
</v-card-title>
<v-card-title class="text-center" v-if="stage == 'obs'">
<h1>
Configure OBS Websocket
<img src="../../assets/obsws_logo.png" class="obsWSLogo" />
</h1>
</v-card-title>
<v-card-title v-if="stage == 'done'">
<h1>You're ready to start creating with CastMate!</h1>
</v-card-title>
<v-card-text v-if="stage == 'welcome'">
<p class="text-h5 text-center">Thank you for downloading CastMate!</p>
<div class="d-flex flex-row justify-center my-4">
<img
src="../../assets/icons/icon.png"
style="width: 300px; height: auto; border-radius: 10px"
/>
</div>
<v-card-actions>
<v-spacer />
<v-btn x-large color="primary" @click="moveNext"> Get Started </v-btn>
<v-spacer />
</v-card-actions>
</v-card-text>
<v-card-text v-if="stage == 'twitch'">
<span class="text-h5"> CastMate needs you to sign into twitch. </span>
<br />
<span class="text-h6">
Sign into your channel account and optionally a chat bot account.
</span>
<twitch />
</v-card-text>
<v-card-text v-if="stage == 'obs'">
<span class="text-h5">You need to connect CastMate to OBS.</span>
<br />
<span class="text-h6">
CastMate connects through the OBS-Websocket plugin.
</span>
<br />
<span class="text-h6">
If you don't already have it installed you can download the installer
<a
href="https://github.com/obsproject/obs-websocket/releases/tag/4.9.1"
target="_"
>
here.
</a>
</span>
<hr class="my-4" />
<div class="my-3">
<span class="text-h6">
Once you've installed OBS-Websocket you can configure it in OBS.
</span>
</div>
<v-row>
<v-col class="d-flex flex-column justify-center text-center">
Go to the Tools -> WebSockets Server Settings
</v-col>
<v-col>
<img src="../../assets/websocketSettings.png" />
</v-col>
<v-col class="d-flex flex-column justify-center text-center">
Here you'll find the port and password CastMate needs. If you
haven't already you should set a password. It keeps your OBS secure.
</v-col>
<v-col>
<div></div>
<img src="../../assets/websocket.png" />
</v-col>
</v-row>
<hr class="my-4" />
<span class="text-h6"> Enter Your OBS Websocket Settings </span>
<br />
<span>
Match the port and password you set in OBS. Leave hostname as
"localhost" unless you know what you're doing!
</span>
<obs-settings />
</v-card-text>
<v-card-text v-if="stage == 'done'">
<span class="text-h5">
CastMate uses a profile system to set up "Triggers". Triggers let you
set what should happen when certain events occurs. Events such as a
chat command, a raid, someone follows, or someone subscribes.
</span>
<img src="../../assets/triggers.png" style="width: 98%; height: auto"/>
<hr class="my-2"/>
<span class="text-h5">
CastMate uses "Automations" to determine what should happen when a
trigger is activated. Automations are a sequence of actions. Actions
are things like playing a sound, toggling an OBS filter, changing your
lights color, or running text to speech.
</span>
<img
src="../../assets/automation.png"
style="width: 98%; height: auto"
/>
</v-card-text>
<v-card-actions v-if="stage != 'welcome' && stage != 'done'">
<v-btn small @click="moveNext"> Skip </v-btn>
<v-spacer />
<v-btn color="primary" :disabled="!ready" @click="moveNext">
Next
</v-btn>
</v-card-actions>
<v-card-actions v-if="stage == 'done'">
<v-spacer />
<v-btn x-large color="primary" @click="cancel"> Get Creating </v-btn>
<v-spacer />
</v-card-actions>
</v-card>
</v-dialog>
</template>

<script>
import { mapGetters } from "vuex";
import Twitch from "../plugins/twitch.vue";
import ObsSettings from "./ObsSettings.vue";
import { isFirstRun } from "../../utils/firstRun";
export default {
components: { Twitch, ObsSettings },
data() {
return {
dialog: false,
stage: "welcome",
};
},
computed: {
...mapGetters("ipc", ["stateLookup", "paths"]),
signedIn() {
return !!this.stateLookup.twitch.channelName;
},
obsConnected() {
return this.stateLookup.obs.connected;
},
ready() {
return (
this.stage == "welcome" ||
(this.stage == "twitch" && this.signedIn) ||
(this.stage == "obs" && this.obsConnected)
);
},
},
methods: {
open() {
this.dialog = true;
},
moveNext() {
if (this.stage == "welcome") {
this.stage = "twitch";
return;
}
if (this.stage == "twitch") {
this.stage = "obs";
return;
}
if (this.stage == "obs") {
this.stage = "done";
return;
}
},
cancel() {
this.dialog = false;
},
},
async mounted() {
if (await isFirstRun(this.paths.userFolder)) {
this.open();
}
},
};
</script>

<style scoped>
.twitchLogo {
height: 1em;
display: inline-block;
position: relative;
bottom: -0.275em;
}
.obsWSLogo {
height: 1em;
display: inline-block;
}
</style>
Loading

0 comments on commit 15fcdce

Please sign in to comment.