diff --git a/config/integrations/twitch_widget.yaml b/config/integrations/twitch_widget.yaml
new file mode 100644
index 0000000..3a870e6
--- /dev/null
+++ b/config/integrations/twitch_widget.yaml
@@ -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"
diff --git a/web/app/app.module.ts b/web/app/app.module.ts
index 74a6208..b62fe1e 100644
--- a/web/app/app.module.ts
+++ b/web/app/app.module.ts
@@ -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 {
diff --git a/web/app/configs/widget/twitch/twitch-config.component.html b/web/app/configs/widget/twitch/twitch-config.component.html
new file mode 100644
index 0000000..1a99d2d
--- /dev/null
+++ b/web/app/configs/widget/twitch/twitch-config.component.html
@@ -0,0 +1,65 @@
+
+
+
+
+
+
diff --git a/web/app/configs/widget/twitch/twitch-config.component.scss b/web/app/configs/widget/twitch/twitch-config.component.scss
new file mode 100644
index 0000000..92dce18
--- /dev/null
+++ b/web/app/configs/widget/twitch/twitch-config.component.scss
@@ -0,0 +1,4 @@
+// component styles are encapsulated and only applied to their components
+.widget-item {
+ margin-top: 3px;
+}
diff --git a/web/app/configs/widget/twitch/twitch-config.component.ts b/web/app/configs/widget/twitch/twitch-config.component.ts
new file mode 100644
index 0000000..066babc
--- /dev/null
+++ b/web/app/configs/widget/twitch/twitch-config.component.ts
@@ -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 {
+
+ constructor(public dialog: DialogRef,
+ 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);
+ }
+
+}
diff --git a/web/app/riot/riot.component.ts b/web/app/riot/riot.component.ts
index d41dec6..83fd31f 100644
--- a/web/app/riot/riot.component.ts
+++ b/web/app/riot/riot.component.ts
@@ -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);
}
diff --git a/web/app/shared/integration.service.ts b/web/app/shared/integration.service.ts
index a6e65a6..46f2229 100644
--- a/web/app/shared/integration.service.ts
+++ b/web/app/shared/integration.service.ts
@@ -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,
},
};
diff --git a/web/app/shared/models/widget.ts b/web/app/shared/models/widget.ts
index e1017f4..7ef4719 100644
--- a/web/app/shared/models/widget.ts
+++ b/web/app/shared/models/widget.ts
@@ -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;