From 1322b12cf6f7a05d927e71dfe0b9435dd74edd82 Mon Sep 17 00:00:00 2001 From: MTRNord Date: Fri, 10 Nov 2017 17:31:46 +0000 Subject: [PATCH 1/4] Add Twitch Widget --- config/integrations/twitch_widget.yaml | 7 ++ web/app/app.module.ts | 3 + .../twitch/twitch-config.component.html | 65 +++++++++++++++++ .../twitch/twitch-config.component.scss | 4 ++ .../widget/twitch/twitch-config.component.ts | 70 +++++++++++++++++++ web/app/riot/riot.component.ts | 5 +- web/app/shared/integration.service.ts | 3 + web/app/shared/models/widget.ts | 3 + 8 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 config/integrations/twitch_widget.yaml create mode 100644 web/app/configs/widget/twitch/twitch-config.component.html create mode 100644 web/app/configs/widget/twitch/twitch-config.component.scss create mode 100644 web/app/configs/widget/twitch/twitch-config.component.ts 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 @@ +
+ +
+ +

Configure Twitch Livestream widgets

+
+
+
+
+

Loading widgets...

+
+
+
+
+
+
+
+
+ + + + +
+
+
+ {{ widget.name || widget.url }} (added by {{ widget.ownerId }}) + + +
+ + + + +
+
+
+
+
+
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; From 89c22b31ca7359048a3225f162c49d15709f5579 Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 10 Nov 2017 18:42:39 +0100 Subject: [PATCH 2/4] Add twitch.png avatar --- web/public/img/avatars/twitch.png | Bin 0 -> 15623 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 web/public/img/avatars/twitch.png diff --git a/web/public/img/avatars/twitch.png b/web/public/img/avatars/twitch.png new file mode 100644 index 0000000000000000000000000000000000000000..88ea80348687104edb52ef79569ca748812dd50e GIT binary patch literal 15623 zcmeI3Yj6`)6vuB%DWwk|qe5HMu0ci=lifVqE=g!@D6N`O+A2|Yi7m{qqZkx1J zno&U%A64-&K4yIIuH!h$OdXLaz7W(A#TiE!7)4QshcJxNf)?uCBu#G9l#332yP39o za_;|}bN6@8z1=VSNOjemoXq@8066>E0#KwA>*|$y=iMwXd32mhY7}%qj}NK=u+9qlIDVO+P>n*f=(TB1ZST`iqRXaP zV0JQ2UzyM%R&@A<+K#F^zGE3*?9$A#XIg_SOyCg|jtY9*UYQNrG~v7~v{g5)p~4bn znN3rw7NqK()l`|}7bvsNqUH5Q165e8)0>M8MW)*+1EaUljEUA4YxPDJ{+Jjl`q9`k zp=I^En%Ejgd9)n-X4AANijSq~Kp>zC7};pES%gXFFh#-nIX{21& z?i1)5L6%zmyfC{B-pbTucdv*|@x>XDNgWw;?m|!;BTOBMgoRrnvO-pPuWXrL;1tPU zCrNI5q|2&@5mIGkYFC+cW@@^V<3+DZ_EsyM7#3gict*j&DS}p6eIk zX~(${jXL{(TOvuCQKc$G8TM#9(z~#O!{=G8uzaLoM#IGax`2`VNch+_0xg2~VjC)wDy$kii7YiK z0nRU!Hp8B{)cqdGJTf$~gq2qR3%JFRixKgTT%+Nx9lfSj^>AZhKft+h;dRhk=~2FT z<%qssT~~K&SYK#h;D^?$f1{!3aAN4fi-)4aiJ|ex`Cd`68=}<`+(?vq0!NO9TKKRa z*ezzW(QKs?-H8#^Vo-3`J4CpLWwkR6W=k|EaU^Nv!Z9O}k!WOOv5kimp#p*nrGd2xE-WHc zKyaZnur|SkMT80nE|dn=Cb+POPyxY((!kmT7ZwpJAh=K(SexL&B0>cO7fJ(b6I@tC zsDR)?X<%)F3yTO95L_q?tW9uX5upNt3#Eaz2`(%mR6uZ{G_W?og++u42riTc)+V^H zh)@B+h0?&<1Q!+&Dj>K}8d&?HxH97}0SaFD=3fB5;@7rd?Hc%cAjMbII05LG20-XR z0L~4;>rnt&832wo0KmQgz+~y^C7+f9kXBpiD6I<~IC02XRmLR%S_5uaZCSRUdqQ2mm2Cf2^%SfInba?*fe}1v@e81k3|3}p;Q{;WyeG{1MNlOPB&#yXN z_Bq%#aBSYSS6shue1rRgHQ#M||J&7%rL?$hj~<$3Tqvh&7$y?@}Rg7w)Y!cxtBeT&*Y z>ehorrxx(^RDifI727fEKIcMi5 zM}qGAgC|_D)_rZy@mtxWsu>wO_|u`_UrRsSa>p*PEpU9^+3yQ>PY%64{q-Hk`wME) ze?0eVPM&O9^y+0H#zug?w@UMSfI-n6~6 zcEhvcEfe#`{aD*YEeDqEGpeqBC;ipMr?<@Nwtx@-sUQPTs1fybuj<|R_?qLL+kfvn z+y8TESLez9dpXPR+%qjV=awB=PhJ^7Cj_V1)oEXv0bDl>J^#i=5IUU&a{ESI<~Rn6 z{+Xtb#Ncec>ZvI_D8*$c{iQ}%*r(I^BncE z^X%hGkgrkiC127Xnmax{5pY5ejP44YCnI!MSkk>m0sssRjRRBntb6*))ZJ Date: Fri, 10 Nov 2017 17:49:59 +0000 Subject: [PATCH 3/4] Add missing space --- web/app/shared/models/widget.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/app/shared/models/widget.ts b/web/app/shared/models/widget.ts index 7ef4719..2186add 100644 --- a/web/app/shared/models/widget.ts +++ b/web/app/shared/models/widget.ts @@ -7,7 +7,7 @@ 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 +// 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 From a2316cd2c94e29913f31f0612dd14452407a4e07 Mon Sep 17 00:00:00 2001 From: MTRNord Date: Fri, 10 Nov 2017 17:55:17 +0000 Subject: [PATCH 4/4] fix typo s/Youtube/Twitch/ --- config/integrations/twitch_widget.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/integrations/twitch_widget.yaml b/config/integrations/twitch_widget.yaml index 3a870e6..46ce899 100644 --- a/config/integrations/twitch_widget.yaml +++ b/config/integrations/twitch_widget.yaml @@ -1,4 +1,4 @@ -# All this configuration does is make "Youtube Widget" available in the UI +# All this configuration does is make "Twitch Widget" available in the UI type: "widget" integrationType: "twitch" enabled: true