Skip to content

Commit

Permalink
Improvements/misc (#494)
Browse files Browse the repository at this point in the history
* Action Selection Dialog: Hover Border

* Recipe Command Blocks: OBS Source Visibility

* Show UI Warning if Twitch Auth (soon) is invalid

* Recipe Command Blocks: OBS Source Mute

* update GH action to add the version to electron builds
  • Loading branch information
negue authored Sep 22, 2022
1 parent 57828a0 commit 9f3ce0a
Show file tree
Hide file tree
Showing 15 changed files with 336 additions and 26 deletions.
21 changes: 21 additions & 0 deletions .github/workflows/build_and_publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ jobs:
name: angular-dist
path: dist

- name: Modify package.json version for electron
uses: maxgfr/github-change-json@main
with:
key: 'version'
value: '${{ github.event.inputs.tag-name }}'
path: package.json

- run: npm run electron:build:only

- name: Create Release
Expand Down Expand Up @@ -184,6 +191,13 @@ jobs:
name: angular-dist
path: dist

- name: Modify package.json version for electron
uses: maxgfr/github-change-json@main
with:
key: 'version'
value: '${{ github.event.inputs.tag-name }}'
path: package.json

- run: npm run electron:build:only

- name: Upload Release Asset Windows Electron
Expand Down Expand Up @@ -234,6 +248,13 @@ jobs:
name: angular-dist
path: dist

- name: Modify package.json version for electron
uses: maxgfr/github-change-json@main
with:
key: 'version'
value: '${{ github.event.inputs.tag-name }}'
path: package.json

- run: npm run electron:build:only

- name: Upload Release Asset Mac Electron
Expand Down
19 changes: 12 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@

### Feature

* [x] Show Errors in the Dashboard - incl. a way to create a GitHub Issue from that
* [x] Twitch Auth: Improve custom scopes handling (if any were already configured, these will be always applied)
* [ ] Tell the Streamer with warnings / dialogs that the Token will expire in X Days
* [ ] Ability to re-authenticate even when you are not in the normal ports

* [ ] Recipe: more Obs Command Blocks: TBD
* [ ] if easy/fast todo: Support for new OBS-websocket(.js) v5
## 2022.1-beta-4

### Feature
* [x] Recipe: new OBS Command Block "Set Source Visibility"
* [x] Recipe: new OBS Command Block "Set Source Mute"
* [x] Tell the Streamer with warnings / dialogs that the Token will expire in X Days

## 2022.1-beta-3

### Feature
* [x] Show Errors in the Dashboard - incl. a way to create a GitHub Issue from that
* [x] Twitch Auth: Improve custom scopes handling (if any were already configured, these will be always applied)

## 2022.1-beta2
## 2022.1-beta-2

### Feature

Expand All @@ -32,7 +37,7 @@
* [x] Recipe new Command Block full entry is now a button
* [x] When you authenticate it'll be automatically saved

## 2022.1-beta1
## 2022.1-beta-1

### Breaking Changes

Expand Down
6 changes: 5 additions & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
This list might be changed in future, depending on the amount of work that needs to be done for these Features.

### 2022.2 and later
### 2022.2 and later (in no particular order)
* [ ] Twitch Extension
* [ ] Support for new OBS-websocket(.js) v5
* [ ] Labels on or around the Media, each with their own Position / Animation
* [ ] Changeable by Trigger Variables
* [ ] Can be placed like in the Arrange View
Expand All @@ -10,6 +12,8 @@ This list might be changed in future, depending on the amount of work that needs
* [ ] Replace all selected Trigger Action with an inline Recipes #439
* [ ] Recipe: more Twitch Command Blocks: Announce, Clear Chat, Start Commercial, Create Stream Marker, Slow Mode, Chat Settings
* [ ] Dependency: Twitch Scope System - for Scripts and Command Block Checks
* [ ] Recipe: Obs Command Block: Set Volume
* [ ] Dependency: Command Block Settings for Numbers with a Range Config

### Misc

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "memebox",
"version": "0.0.1",
"version": "v2202.1",
"description": "A meme-management tool",
"author": {
"name": ""
Expand Down
75 changes: 69 additions & 6 deletions projects/recipe-core/src/lib/command-blocks.obs.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import {RecipeCommandBlockRegistry, RecipeCommandConfigObsSetFilterStatePayload} from "./recipe.types";

/*
*
* Set Volume: SetVolume
*
* Mute Source: SetMute
*
*/

export function registerObsCommandBlocks (
registry: RecipeCommandBlockRegistry
): void {
const obsSwitchSceneType = "obs:switchScene";

registry[obsSwitchSceneType] = {
registry["obs:switchScene"] = {
pickerLabel: "Switch Scene",
commandGroup: "obs",
configArguments: [
Expand All @@ -27,6 +33,63 @@ export function registerObsCommandBlocks (
}
};


registry["obs:setSourceVisibility"] = {
pickerLabel: "Set Source Visibility",
commandGroup: "obs",
configArguments: [
{
name: "sourceName",
label: "Source to change the visibility",
type: "obs:source"
},
{
name: "visible",
label: "Visible",
type: "boolean"
}

],
toScriptCode: (step) => {
const scenePayload = step.payload.sourceName as string;

return `obs.setSourceVisibility('${scenePayload}', ${step.payload.visible});`;
},
commandEntryLabelAsync: (queries, payload) => {
const sourceName = payload.sourceName as string;

return Promise.resolve(`OBS: ${payload.visible ? 'show' : 'hide'} [${sourceName}] Source`);
}
};


registry["obs:setSourceMute"] = {
pickerLabel: "Set Source Mute",
commandGroup: "obs",
configArguments: [
{
name: "sourceName",
label: "Source to mute",
type: "obs:source"
},
{
name: "muted",
label: "Muted",
type: "boolean"
}
],
toScriptCode: (step) => {
const scenePayload = step.payload.sourceName as string;

return `obs.setSourceMute('${scenePayload}', ${step.payload.muted});`;
},
commandEntryLabelAsync: (queries, payload) => {
const sourceName = payload.sourceName as string;

return Promise.resolve(`OBS: ${payload.muted ? 'mute' : 'unmute'} [${sourceName}] Source`);
}
};

const obsSetFilterState = "obs:setFilterState";

registry[obsSetFilterState] = {
Expand All @@ -40,7 +103,7 @@ export function registerObsCommandBlocks (
},
{
name: "enabled",
label: "Set filter state",
label: "Enabled",
type: "boolean"
}
],
Expand All @@ -55,14 +118,14 @@ export function registerObsCommandBlocks (
const filterPayload = payload.filter as RecipeCommandConfigObsSetFilterStatePayload;
const enabled = payload.enabled as boolean;

return Promise.resolve(`OBS: setting Filter: ${filterPayload.filterName} to ${enabled}`);
return Promise.resolve(`OBS: ${enabled ? 'enable' : 'disable'} [${filterPayload.filterName}] Filter`);
}
};

const obsSendRaw = "obs:sendRaw";

registry[obsSendRaw] = {
pickerLabel: "Send Raw Request",
pickerLabel: "Send Raw Request (OBS WS v4)",
commandGroup: "obs",
configArguments: [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {RecipePipesModule} from "../pipes/recipe-pipes.module";
import {MatCardModule} from "@angular/material/card";
import {MatIconModule} from "@angular/material/icon";
import {MatTooltipModule} from "@angular/material/tooltip";
import {ObsSourceSelectionComponent} from "./obs-source-selection/obs-source-selection.component";

// todo extract this module to its own internal library ^

Expand All @@ -35,7 +36,8 @@ import {MatTooltipModule} from "@angular/material/tooltip";
ObsSceneSelectionComponent,
ObsFilterSelectionComponent,
ActionSelectionComponent,
ActionListSettingsComponent
ActionListSettingsComponent,
ObsSourceSelectionComponent
],
imports: [
CommonModule,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<div class="two-columns">
<div class="column">
<mat-form-field>
<mat-label>Select Source</mat-label>
<input
matInput
[formControl]="sourceFormControl"
[matAutocomplete]="sourceAutocomplete">
<mat-autocomplete #sourceAutocomplete="matAutocomplete"
(optionSelected)="payloadChanged.next($event.option.value)">
<mat-option *ngFor="let source of filteredSourceList$ | async"
[value]="source">
{{source}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.column {
margin: 0 0.5rem;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import {Component, Input, OnInit, Output} from '@angular/core';
import {combineLatest, from, Subject} from "rxjs";
import {FormControl} from "@angular/forms";
import {map, startWith} from "rxjs/operators";
import {ENDPOINTS, ObsSourceEntry} from "@memebox/contracts";
import {Scene} from "obs-websocket-js";
import {MemeboxApiService} from "@memebox/app-state";

@Component({
selector: 'app-obs-source-selection',
templateUrl: './obs-source-selection.component.html',
styleUrls: ['./obs-source-selection.component.scss']
})
export class ObsSourceSelectionComponent implements OnInit {
private _destroy$ = new Subject<void>();

public sourceFormControl = new FormControl();

@Output()
public readonly payloadChanged = new Subject<string>();

@Input()
public payload: string|null = null;

public allSourceListAsync = this.memeboxApi.get<ObsSourceEntry[]>(
`${ENDPOINTS.OBS_DATA.PREFIX}${ENDPOINTS.OBS_DATA.SOURCE_LIST}`
);

public allSceneListAsync = this.memeboxApi.get<Scene[]>(
`${ENDPOINTS.OBS_DATA.PREFIX}${ENDPOINTS.OBS_DATA.SCENE_LIST}`
);


public filteredSourceList$ = combineLatest([
this.sourceFormControl.valueChanges.pipe(
startWith(''),
),
from(this.allSourceListAsync),
from(this.allSceneListAsync)
]).pipe(
map(([enteredText, allSources, allScenes]) => {
const completeList = [
...(allSources?.map(s => s.name) ?? []),
...(allScenes?.map(s => s.name) ?? [])
];

if (!enteredText) {
return completeList;
}

enteredText = enteredText.toLowerCase();

return completeList?.filter(s => s.toLowerCase().includes(enteredText));
})
);

constructor(
private memeboxApi: MemeboxApiService,
) {
// Load State once

}

ngOnInit(): void {
if (this.payload) {
this.sourceFormControl.patchValue(this.payload);

setTimeout(() => {
if (this.payload) {
this.payloadChanged.next(this.payload);
}
});
}
}

ngOnDestroy(): void {
this._destroy$.next();
this._destroy$.complete();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ <h2 mat-dialog-title class="title-wrapper">
</ng-container>
<ng-container *ngSwitchCase="'boolean'">
<app-action-variable-input [variableType]="$any('boolean')"
label="Enabled"
[label]="config.label"
[value]="payload[config.name]"
(valueChanged)="payload[config.name] = $event">
</app-action-variable-input>
Expand Down Expand Up @@ -121,6 +121,10 @@ <h2 mat-dialog-title class="title-wrapper">
<app-obs-scene-selection [selectedScene]="payload[config.name]"
(sceneSelected)="payload[config.name] = $event"></app-obs-scene-selection>
</ng-container>
<ng-container *ngSwitchCase="'obs:source'">
<app-obs-source-selection [payload]="payload[config.name]"
(payloadChanged)="payload[config.name] = $event"></app-obs-source-selection>
</ng-container>
<ng-container *ngSwitchCase="'obs:filter'">
<app-obs-filter-selection [payload]="payload[config.name]"
(payloadChanged)="payload[config.name] = $event"></app-obs-filter-selection>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export class GetEntrySubBlockInfoArrayPipe implements PipeTransform {
{
name: 'entries',
labelId: RecipeRootCommandBlockId,
label: 'Recipe Commands',
label: 'Command Blocks',
entries: []
}
]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
.command-block-entry {
cursor: pointer;

mat-icon{
margin-right: 0.25rem;
}

&:hover {

background: #00000022;
Expand Down
Loading

0 comments on commit 9f3ce0a

Please sign in to comment.