Add Twitch Widget

This commit is contained in:
MTRNord 2017-11-10 17:31:46 +00:00
parent 2d3c140b26
commit 1322b12cf6
8 changed files with 159 additions and 1 deletions

View file

@ -0,0 +1,7 @@
# All this configuration does is make "Youtube Widget" available in the UI
type: "widget"
integrationType: "twitch"
enabled: true
name: "Twitch Livestream"
about: "Embed a Twitch Livestream"
avatar: "img/avatars/twitch.png"

View file

@ -28,6 +28,7 @@ import { GenericWidgetWrapperComponent } from "./widget_wrappers/generic/generic
import { ToggleFullscreenDirective } from "./shared/toggle-fullscreen.directive";
import { FullscreenButtonComponent } from "./fullscreen-button/fullscreen-button.component";
import { YoutubeWidgetConfigComponent } from "./configs/widget/youtube/youtube-config.component";
import { TwitchWidgetConfigComponent } from "./configs/widget/twitch/twitch-config.component";
import { VideoWidgetWrapperComponent } from "./widget_wrappers/video/video.component";
@NgModule({
@ -58,6 +59,7 @@ import { VideoWidgetWrapperComponent } from "./widget_wrappers/video/video.compo
ToggleFullscreenDirective,
FullscreenButtonComponent,
YoutubeWidgetConfigComponent,
TwitchWidgetConfigComponent,
VideoWidgetWrapperComponent,
// Vendor
@ -78,6 +80,7 @@ import { VideoWidgetWrapperComponent } from "./widget_wrappers/video/video.compo
IrcConfigComponent,
CustomWidgetConfigComponent,
YoutubeWidgetConfigComponent,
TwitchWidgetConfigComponent
]
})
export class AppModule {

View file

@ -0,0 +1,65 @@
<div class="config-wrapper">
<img src="/img/close.svg" (click)="dialog.close()" class="close-icon">
<div class="config-header">
<img src="/img/avatars/twitch.png">
<h4>Configure Twitch Livestream widgets</h4>
</div>
<div class="config-content" *ngIf="isLoading">
<div class="row">
<div class="col-md-12">
<p><i class="fa fa-circle-notch fa-spin"></i> Loading widgets...</p>
</div>
</div>
</div>
<div class="config-content" *ngIf="!isLoading">
<form (submit)="validateAndAddWidget()" novalidate name="addForm">
<div class="row">
<div class="col-md-8" style="margin-bottom: 12px;">
<div class="input-group input-group-sm">
<input type="text" class="form-control"
placeholder="Twitch Channel Name"
[(ngModel)]="newWidgetUrl" name="newWidgetUrl"
[disabled]="isUpdating">
<span class="input-group-btn">
<button type="submit" class="btn btn-success" [disabled]="isUpdating">
<i class="fa fa-plus-circle"></i> Add Widget
</button>
</span>
</div>
</div>
<div class="col-md-12 removable widget-item" *ngFor="let widget of widgets trackById">
{{ widget.name || widget.url }} <span class="text-muted" *ngIf="widget.ownerId">(added by {{ widget.ownerId }})</span>
<button type="button" class="btn btn-outline-info btn-sm" (click)="editWidget(widget)"
style="margin-top: -5px;" [disabled]="isUpdating">
<i class="fa fa-pencil"></i> Edit Widget
</button>
<button type="button" class="btn btn-sm btn-outline-danger" (click)="removeWidget(widget)"
style="margin-top: -5px;" [disabled]="isUpdating">
<i class="fa fa-times"></i> Remove Widget
</button>
<div *ngIf="isWidgetToggled(widget)">
<label>
Widget Name
<input type="text" class="form-control"
placeholder="Twitch Widget"
[(ngModel)]="widget.newName" name="widget-name-{{widget.id}}"
[disabled]="isUpdating">
</label>
<label>
Channel Name
<input type="text" class="form-control"
placeholder="Twitch Channel Name"
[(ngModel)]="widget.data.newDimChannelName" name="widget-url-{{widget.id}}"
[disabled]="isUpdating">
</label>
<button type="button" class="btn btn-primary btn-sm" (click)="validateAndSaveWidget(widget)">Save
</button>
<button type="button" class="btn btn-outline btn-sm" (click)="toggleWidget(widget)">
Cancel
</button>
</div>
</div>
</div>
</form>
</div>
</div>

View file

@ -0,0 +1,4 @@
// component styles are encapsulated and only applied to their components
.widget-item {
margin-top: 3px;
}

View file

@ -0,0 +1,70 @@
import { Component } from "@angular/core";
import { ModalComponent, DialogRef } from "ngx-modialog";
import { WidgetComponent } from "../widget.component";
import { ScalarService } from "../../../shared/scalar.service";
import { ConfigModalContext } from "../../../integration/integration.component";
import { ToasterService } from "angular2-toaster";
import { Widget, WIDGET_DIM_TWITCH, WIDGET_SCALAR_TWITCH } from "../../../shared/models/widget";
@Component({
selector: "my-twitchwidget-config",
templateUrl: "twitch-config.component.html",
styleUrls: ["twitch-config.component.scss", "./../../config.component.scss"],
})
export class TwitchWidgetConfigComponent extends WidgetComponent implements ModalComponent<ConfigModalContext> {
constructor(public dialog: DialogRef<ConfigModalContext>,
toaster: ToasterService,
scalarService: ScalarService,
window: Window) {
super(
toaster,
scalarService,
dialog.context.roomId,
window,
WIDGET_DIM_TWITCH,
WIDGET_SCALAR_TWITCH,
dialog.context.integrationId,
"Twitch Widget",
"video", // wrapper
"twitch" // scalar wrapper
);
}
public validateAndAddWidget() {
// Replace channel name with path to embedable Twitch Player
const url = "https://player.twitch.tv/?channel="+this.newWidgetUrl;
// TODO Somehow Validate if it is a valid Username
if (!url) {
this.toaster.pop("warning", "Please enter a Twitch Livestream Channel Name");
return;
}
const originalUrl = this.newWidgetUrl;
this.newWidgetUrl = url;
this.addWidget({dimChannelName: originalUrl});
}
public validateAndSaveWidget(widget: Widget) {
const url = "https://player.twitch.tv/?channel="+widget.data.dimChannelName;
// TODO Somehow Validate if it is a valid Username
if (!url) {
this.toaster.pop("warning", "Please enter a Twitch Livestream Channel Name");
return;
}
if (!widget.data) widget.data = {};
widget.newUrl = url;
widget.data.dimChannelName = widget.data.newDimChannelName;
this.saveWidget(widget);
}
editWidget(widget: Widget) {
widget.data.newDimChannelName = widget.data.dimChannelName;
super.editWidget(widget);
}
}

View file

@ -6,7 +6,7 @@ import { ToasterService } from "angular2-toaster";
import { Integration } from "../shared/models/integration";
import { IntegrationService } from "../shared/integration.service";
import * as _ from "lodash";
import { WIDGET_DIM_CUSTOM, WIDGET_DIM_YOUTUBE } from "../shared/models/widget";
import { WIDGET_DIM_CUSTOM, WIDGET_DIM_YOUTUBE, WIDGET_DIM_TWITCH } from "../shared/models/widget";
import { IntegrationComponent } from "../integration/integration.component";
@Component({
@ -76,6 +76,9 @@ export class RiotComponent {
} else if (this.requestedScreen === "type_" + WIDGET_DIM_YOUTUBE) {
type = "widget";
integrationType = "youtube";
} else if (this.requestedScreen === "type_" + WIDGET_DIM_TWITCH) {
type = "widget";
integrationType = "twitch";
} else {
console.log("Unknown screen requested: " + this.requestedScreen);
}

View file

@ -6,6 +6,7 @@ import { IrcConfigComponent } from "../configs/irc/irc-config.component";
import { TravisCiConfigComponent } from "../configs/travisci/travisci-config.component";
import { CustomWidgetConfigComponent } from "../configs/widget/custom_widget/custom_widget-config.component";
import { YoutubeWidgetConfigComponent } from "../configs/widget/youtube/youtube-config.component";
import { TwitchWidgetConfigComponent } from "../configs/widget/twitch/twitch-config.component";
@Injectable()
export class IntegrationService {
@ -22,6 +23,7 @@ export class IntegrationService {
"widget": {
"customwidget": true,
"youtube": true,
"twitch": true,
},
};
@ -36,6 +38,7 @@ export class IntegrationService {
"widget": {
"customwidget": CustomWidgetConfigComponent,
"youtube": YoutubeWidgetConfigComponent,
"twitch": TwitchWidgetConfigComponent,
},
};

View file

@ -7,10 +7,13 @@ export const WIDGET_SCALAR_GOOGLEDOCS = "googledocs";
export const WIDGET_SCALAR_JITSI = "jitsi";
export const WIDGET_SCALAR_YOUTUBE = "youtube";
export const WIDGET_SCALAR_GRAFANA = "grafana";
//Placeholder until Scalar supports twitch
export const WIDGET_SCALAR_TWITCH = "";
// Dimension has its own set of types to ensure that we don't conflict with Scalar
export const WIDGET_DIM_CUSTOM = "dimension-customwidget";
export const WIDGET_DIM_YOUTUBE = "dimension-youtube";
export const WIDGET_DIM_TWITCH = "dimension-twitch";
export interface Widget {
id: string;