Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
79f6f7f32c
|
@ -109,8 +109,9 @@ func (cr *ChatRoom) Join(conn *chatConnection, data common.JoinData) (*Client, e
|
|||
} else {
|
||||
client.Send(playingCommand)
|
||||
}
|
||||
cr.AddEventMsg(common.EvJoin, data.Name, data.Color)
|
||||
|
||||
if !settings.LetThemLurk {
|
||||
cr.AddEventMsg(common.EvJoin, data.Name, data.Color)
|
||||
}
|
||||
sendHiddenMessage(common.CdJoin, nil)
|
||||
sendHiddenMessage(common.CdEmote, common.Emotes)
|
||||
|
||||
|
@ -135,7 +136,9 @@ func (cr *ChatRoom) Leave(name, color string) {
|
|||
client.conn.Close()
|
||||
cr.delClient(id)
|
||||
|
||||
cr.AddEventMsg(common.EvLeave, name, color)
|
||||
if !settings.LetThemLurk {
|
||||
cr.AddEventMsg(common.EvLeave, name, color)
|
||||
}
|
||||
common.LogChatf("[leave] %s %s\n", host, name)
|
||||
}
|
||||
|
||||
|
|
135
common/colors.go
135
common/colors.go
|
@ -18,32 +18,115 @@ func init() {
|
|||
// the values in colors must be lowercase so it matches with the color input
|
||||
// this saves from having to call strings.ToLower(color) every time to check
|
||||
var Colors = []string{
|
||||
"aliceblue", "antiquewhite", "aqua", "aquamarine", "azure",
|
||||
"beige", "bisque", "blanchedalmond", "blueviolet", "brown",
|
||||
"burlywood", "cadetblue", "chartreuse", "chocolate", "coral",
|
||||
"cornflowerblue", "cornsilk", "crimson", "cyan", "darkcyan",
|
||||
"darkgoldenrod", "darkgray", "darkkhaki", "darkmagenta", "darkolivegreen",
|
||||
"darkorange", "darkorchid", "darksalmon", "darkseagreen", "darkslateblue",
|
||||
"darkslategray", "darkturquoise", "darkviolet", "deeppink", "deepskyblue",
|
||||
"dimgray", "dodgerblue", "firebrick", "floralwhite", "forestgreen",
|
||||
"fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod",
|
||||
"gray", "greenyellow", "honeydew", "hotpink", "indigo",
|
||||
"ivory", "khaki", "lavender", "lavenderblush", "lawngreen",
|
||||
"lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow",
|
||||
"lightgrey", "lightgreen", "lightpink", "lightsalmon", "lightseagreen",
|
||||
"lightskyblue", "lightslategray", "lightsteelblue", "lightyellow", "lime",
|
||||
"limegreen", "linen", "magenta", "mediumaquamarine", "mediumorchid",
|
||||
"mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
|
||||
"mediumvioletred", "mintcream", "mistyrose", "moccasin", "navajowhite",
|
||||
"oldlace", "olive", "olivedrab", "orange", "orangered",
|
||||
"orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred",
|
||||
"papayawhip", "peachpuff", "peru", "pink", "plum",
|
||||
"powderblue", "purple", "rebeccapurple", "red", "rosybrown",
|
||||
"royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen",
|
||||
"seashell", "sienna", "silver", "skyblue", "slateblue",
|
||||
"slategray", "snow", "springgreen", "steelblue", "tan",
|
||||
"teal", "thistle", "tomato", "turquoise", "violet",
|
||||
"wheat", "white", "whitesmoke", "yellow", "yellowgreen",
|
||||
"aliceblue",
|
||||
"antiquewhite",
|
||||
"aqua",
|
||||
"aquamarine",
|
||||
"azure",
|
||||
"beige",
|
||||
"bisque",
|
||||
"blanchedalmond",
|
||||
"burlywood",
|
||||
"cadetblue",
|
||||
"chartreuse",
|
||||
"chocolate",
|
||||
"coral",
|
||||
"cornflowerblue",
|
||||
"cornsilk",
|
||||
"cyan",
|
||||
"darkcyan",
|
||||
"darkgoldenrod",
|
||||
"darkgray",
|
||||
"darkkhaki",
|
||||
"darkorange",
|
||||
"darksalmon",
|
||||
"darkseagreen",
|
||||
"darkturquoise",
|
||||
"deeppink",
|
||||
"deepskyblue",
|
||||
"dodgerblue",
|
||||
"floralwhite",
|
||||
"fuchsia",
|
||||
"gainsboro",
|
||||
"ghostwhite",
|
||||
"gold",
|
||||
"goldenrod",
|
||||
"gray",
|
||||
"greenyellow",
|
||||
"honeydew",
|
||||
"hotpink",
|
||||
"ivory",
|
||||
"khaki",
|
||||
"lavender",
|
||||
"lavenderblush",
|
||||
"lawngreen",
|
||||
"lemonchiffon",
|
||||
"lightblue",
|
||||
"lightcoral",
|
||||
"lightcyan",
|
||||
"lightgoldenrodyellow",
|
||||
"lightgreen",
|
||||
"lightgrey",
|
||||
"lightpink",
|
||||
"lightsalmon",
|
||||
"lightseagreen",
|
||||
"lightskyblue",
|
||||
"lightslategray",
|
||||
"lightsteelblue",
|
||||
"lightyellow",
|
||||
"lime",
|
||||
"limegreen",
|
||||
"linen",
|
||||
"magenta",
|
||||
"mediumaquamarine",
|
||||
"mediumorchid",
|
||||
"mediumpurple",
|
||||
"mediumseagreen",
|
||||
"mediumslateblue",
|
||||
"mediumspringgreen",
|
||||
"mediumturquoise",
|
||||
"mintcream",
|
||||
"mistyrose",
|
||||
"moccasin",
|
||||
"navajowhite",
|
||||
"oldlace",
|
||||
"olive",
|
||||
"olivedrab",
|
||||
"orange",
|
||||
"orangered",
|
||||
"orchid",
|
||||
"palegoldenrod",
|
||||
"palegreen",
|
||||
"paleturquoise",
|
||||
"palevioletred",
|
||||
"papayawhip",
|
||||
"peachpuff",
|
||||
"peru",
|
||||
"pink",
|
||||
"plum",
|
||||
"powderblue",
|
||||
"red",
|
||||
"rosybrown",
|
||||
"salmon",
|
||||
"sandybrown",
|
||||
"seagreen",
|
||||
"seashell",
|
||||
"silver",
|
||||
"skyblue",
|
||||
"slategray",
|
||||
"snow",
|
||||
"springgreen",
|
||||
"steelblue",
|
||||
"tan",
|
||||
"thistle",
|
||||
"tomato",
|
||||
"turquoise",
|
||||
"violet",
|
||||
"wheat",
|
||||
"white",
|
||||
"whitesmoke",
|
||||
"yellow",
|
||||
"yellowgreen",
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
|
@ -168,6 +168,7 @@ func getUserIDs(names []string) []TwitchUser {
|
|||
log.Fatalln("Error generating new request:", err)
|
||||
}
|
||||
request.Header.Set("Client-ID", settings.TwitchClientID)
|
||||
request.Header.Set("Authorization", fmt.Sprintf("Bearer %s", settings.TwitchClientSecret))
|
||||
|
||||
client := http.Client{}
|
||||
resp, err := client.Do(request)
|
||||
|
|
|
@ -328,7 +328,7 @@ func handleIndexTemplate(w http.ResponseWriter, r *http.Request) {
|
|||
Video: true,
|
||||
Chat: true,
|
||||
MessageHistoryCount: settings.MaxMessageCount,
|
||||
Title: "Movie Night!",
|
||||
Title: settings.PageTitle,
|
||||
}
|
||||
|
||||
path := strings.Split(strings.TrimLeft(r.URL.Path, "/"), "/")
|
||||
|
|
127
readme.md
127
readme.md
|
@ -1,3 +1,19 @@
|
|||
<!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-refresh-toc -->
|
||||
**Table of Contents**
|
||||
|
||||
- [MovieNight stream server](#movienight-stream-server)
|
||||
- [Build requirements](#build-requirements)
|
||||
- [Older Go Versions](#older-go-versions)
|
||||
- [Compile and install](#compile-and-install)
|
||||
- [Docker build](#docker-build)
|
||||
- [Building the Container](#building-the-container)
|
||||
- [Running the Container](#running-the-container)
|
||||
- [docker-compose](#docker-compose)
|
||||
- [Notes for Running Using docker-compose](#notes-for-running-using-docker-compose)
|
||||
- [Usage](#usage)
|
||||
- [Configuration](#configuration)
|
||||
|
||||
<!-- markdown-toc end -->
|
||||
# MovieNight stream server
|
||||
|
||||
[![Build status](https://api.travis-ci.org/zorchenhimer/MovieNight.svg?branch=master)](https://travis-ci.org/zorchenhimer/MovieNight)
|
||||
|
@ -20,7 +36,7 @@ Once you have that setup add an enviromnent variable named `GO_VERSION` and
|
|||
set it to the version you installed (eg, `1.14.1`). The Makefile will now use
|
||||
the newer version.
|
||||
|
||||
## Install
|
||||
### Compile and install
|
||||
|
||||
To just download and run:
|
||||
|
||||
|
@ -31,6 +47,43 @@ $ make
|
|||
$ ./MovieNight
|
||||
```
|
||||
|
||||
### Docker build
|
||||
MovieNight provides a Dockerfile and a docker-compose file to run MovieNight using Docker.
|
||||
|
||||
#### Building the Container
|
||||
Install Docker, clone the repository and build:
|
||||
|
||||
```shell
|
||||
docker build -t movienight .
|
||||
```
|
||||
|
||||
#### Running the Container
|
||||
Run the image once it's built:
|
||||
|
||||
```shell
|
||||
docker run -d -p 8089:8089 -p 1935:1935 [-v ./settings.json:/config/settings.json] movienight
|
||||
```
|
||||
|
||||
Explanation:
|
||||
- **-d** runs the container in the background.
|
||||
- **-p 8089:8089** maps the MovieNight web interface to port 8089 on the server.
|
||||
- **-p 1935:1935** maps the RTMP port for OBS to port 1935 (default RTMP port) on the server.
|
||||
- **-v ./settings.json:/config/settings.json** maps the file *settings.json* into the container. [OPTIONAL]
|
||||
|
||||
#### docker-compose
|
||||
docker-compose will automatically build the image, no need to build it manually.
|
||||
|
||||
Install Docker and docker-compose, clone the repository and change into the directory *./docker*. Then run:
|
||||
|
||||
```shell
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
This docker-compose file will create a volume called *movienight-config* and automatically add the standard *settings.json* file to it. It also maps port 8089 and 1935 to the same ports of the host.
|
||||
|
||||
#### Notes for Running Using docker-compose
|
||||
The container needs to be restarted to apply any changes you make to *settings.json*.
|
||||
|
||||
## Usage
|
||||
|
||||
Now you can use OBS to push a stream to the server. Set the stream URL to
|
||||
|
@ -70,40 +123,42 @@ Usage of .\MovieNight.exe:
|
|||
host:port of the MovieNight (default ":8089")
|
||||
```
|
||||
|
||||
## Docker
|
||||
MovieNight provides a Dockerfile and a docker-compose file to run MovieNight using Docker.
|
||||
## Configuration
|
||||
|
||||
### Dockerfile
|
||||
#### Building the Container
|
||||
Install Docker, clone the repository and build:
|
||||
MovieNight’s configuration is controlled by `settings.json`:
|
||||
|
||||
```shell
|
||||
docker build -t movienight .
|
||||
```
|
||||
|
||||
#### Running the Container
|
||||
Run the image once it's built:
|
||||
|
||||
```shell
|
||||
docker run -d -p 8089:8089 -p 1935:1935 [-v ./settings.json:/config/settings.json] movienight
|
||||
```
|
||||
|
||||
Explanation:
|
||||
- **-d** runs the container in the background.
|
||||
- **-p 8089:8089** maps the MovieNight web interface to port 8089 on the server.
|
||||
- **-p 1935:1935** maps the RTMP port for OBS to port 1935 (default RTMP port) on the server.
|
||||
- **-v ./settings.json:/config/settings.json** maps the file *settings.json* into the container. [OPTIONAL]
|
||||
|
||||
### docker-compose
|
||||
docker-compose will automatically build the image, no need to build it manually.
|
||||
|
||||
Install Docker and docker-compose, clone the repository and change into the directory *./docker*. Then run:
|
||||
|
||||
```shell
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
This docker-compose file will create a volume called *movienight-config* and automatically add the standard *settings.json* file to it. It also maps port 8089 and 1935 to the same ports of the host.
|
||||
|
||||
#### Notes for Running Using docker-compose
|
||||
The container needs to be restarted to apply any changes you make to *settings.json*.
|
||||
- `AdminPassword`: users can enter `/auth <value>` into chat to grant themselves
|
||||
admin privileges. This value is automatically regenerated unless
|
||||
`RegenAdminPass` is false.
|
||||
- `ApprovedEmotes`: list of Twitch users whose emotes can be imported into
|
||||
MovieNight. Using `/addemotes <username>` in chat will add to this list.
|
||||
- `Bans`: list of banned users.
|
||||
- `LetThemLurk`: if false, announces when a user enters and leaves chat.
|
||||
- `ListenAddress`: the port that MovieNight listens on, formatted as `:8089`.
|
||||
- `LogFile`: the path of the MovieNight logfile, relative to the executable.
|
||||
- `LogLevel`: the log level, defaults to `debug`.
|
||||
- `MaxMessageCount`: the number of messages displayed in the chat window.
|
||||
- `NewPin`: if true, regenerates `RoomAccessPin` when the server starts.
|
||||
- `PageTitle`: The base string used in the `<title>` element of the page. When
|
||||
the stream title is set with `/playing`, it is appended; e.g., `Movie Night | The Man Who Killed Hitler and Then the Bigfoot`
|
||||
- `RegenAdminPass`: if true, regenerates `AdminPassword` when the server starts.
|
||||
- `RoomAccess`: the access policy of the chat room; this is managed by the
|
||||
application and should not be edited manually.
|
||||
- `RoomAccessPin`: if set, serves as the password required to enter the chatroom.
|
||||
- `SessionKey`: key used for storing session data (cookies etc.)
|
||||
- `StreamKey`: the key that OBS will use to connect to MovieNight.
|
||||
- `StreamStats`: if true, prints statistics for the stream on server shutdown.
|
||||
- `TitleLength`: the maximum allowed length for the stream title (set with `/playing`).
|
||||
- `TwitchClientID`: OAuth client ID for the Twitch API, used for fetching emotes
|
||||
- `TwitchClientSecret`: OAuth client secret for the Twitch API; [can be generated locally with curl](https://dev.twitch.tv/docs/authentication/getting-tokens-oauth#oauth-client-credentials-flow).
|
||||
- `WrappedEmotesOnly`: if true, requires that emote codes be wrapped in colons
|
||||
or brackets; e.g., `:PogChamp:`
|
||||
- `RateLimitChat`: the number of seconds between each message a non-privileged
|
||||
user can post in chat.
|
||||
- `RateLimitNick`: the number of seconds before a user can change their nick again.
|
||||
- `RakeLimitColor`: the number of seconds before a user can change their color again.
|
||||
- `RateLimitAuth`: the number of seconds between each allowed auth attempt
|
||||
- `RateLimitDuplicate`: the numeber of seconds before a user can post a
|
||||
duplicate message.
|
||||
- `NoCache`: if true, set `Cache-Control: no-cache, must-revalidate` in the HTTP
|
||||
header, to prevent caching responses.
|
||||
|
|
38
settings.go
38
settings.go
|
@ -23,24 +23,26 @@ type Settings struct {
|
|||
cmdLineKey string // stream key from the command line
|
||||
|
||||
// Saved settings
|
||||
StreamStats bool
|
||||
MaxMessageCount int
|
||||
TitleLength int // maximum length of the title that can be set with the /playing
|
||||
AdminPassword string
|
||||
RegenAdminPass bool // regenerate admin password on start?
|
||||
StreamKey string
|
||||
ListenAddress string
|
||||
ApprovedEmotes []string // list of channels that have been approved for emote use. Global emotes are always "approved".
|
||||
TwitchClientID string // client id from twitch developers portal
|
||||
SessionKey string // key for session data
|
||||
Bans []BanInfo
|
||||
LogLevel common.LogLevel
|
||||
LogFile string
|
||||
RoomAccess AccessMode
|
||||
RoomAccessPin string // The current pin
|
||||
NewPin bool // Auto generate a new pin on start. Overwrites RoomAccessPin if set.
|
||||
|
||||
WrappedEmotesOnly bool // only allow "wrapped" emotes. eg :Kappa: and [Kappa] but not Kappa
|
||||
AdminPassword string
|
||||
ApprovedEmotes []string // list of channels that have been approved for emote use. Global emotes are always "approved".
|
||||
Bans []BanInfo
|
||||
LetThemLurk bool // whether or not to announce users joining/leaving chat
|
||||
ListenAddress string
|
||||
LogFile string
|
||||
LogLevel common.LogLevel
|
||||
MaxMessageCount int
|
||||
NewPin bool // Auto generate a new pin on start. Overwrites RoomAccessPin if set.
|
||||
PageTitle string // primary value for the page <title> element
|
||||
RegenAdminPass bool // regenerate admin password on start?
|
||||
RoomAccess AccessMode
|
||||
RoomAccessPin string // The current pin
|
||||
SessionKey string // key for session data
|
||||
StreamKey string
|
||||
StreamStats bool
|
||||
TitleLength int // maximum length of the title that can be set with the /playing
|
||||
TwitchClientID string // client id from twitch developers portal
|
||||
TwitchClientSecret string // OAuth from twitch developers portal: https://dev.twitch.tv/docs/authentication/getting-tokens-oauth#oauth-client-credentials-flow
|
||||
WrappedEmotesOnly bool // only allow "wrapped" emotes. eg :Kappa: and [Kappa] but not Kappa
|
||||
|
||||
// Rate limiting stuff, in seconds
|
||||
RateLimitChat time.Duration
|
||||
|
|
|
@ -1,19 +1,23 @@
|
|||
{
|
||||
"MaxMessageCount": 300,
|
||||
"TitleLength": 50,
|
||||
"AdminPassword": "",
|
||||
"RegenAdminPass": true,
|
||||
"Bans": [],
|
||||
"StreamKey": "ALongStreamKey",
|
||||
"ListenAddress": ":8089",
|
||||
"ApprovedEmotes": null,
|
||||
"LogLevel": "debug",
|
||||
"Bans": [],
|
||||
"LetThemLurk": false,
|
||||
"ListenAddress": ":8089",
|
||||
"LogFile": "thelog.log",
|
||||
"RateLimitChat": 1,
|
||||
"RateLimitNick": 300,
|
||||
"RateLimitColor": 60,
|
||||
"RateLimitAuth": 5,
|
||||
"RateLimitDuplicate": 30,
|
||||
"LogLevel": "debug",
|
||||
"MaxMessageCount": 300,
|
||||
"NoCache": false,
|
||||
"PageTitle": "Movie Night",
|
||||
"RateLimitAuth": 5,
|
||||
"RateLimitChat": 1,
|
||||
"RateLimitColor": 60,
|
||||
"RateLimitDuplicate": 30,
|
||||
"RateLimitNick": 300,
|
||||
"RegenAdminPass": true,
|
||||
"StreamKey": "ALongStreamKey",
|
||||
"TitleLength": 50,
|
||||
"TwitchClientID": "",
|
||||
"TwitchClientSecret": "",
|
||||
"WrappedEmotesOnly": false
|
||||
}
|
||||
|
|
|
@ -15,9 +15,7 @@
|
|||
<body class="scrollbar">
|
||||
<img id="remote" src="/static/img/remote.png" onclick="flipRemote();" />
|
||||
<div id="devKeys"></div>
|
||||
<div class="root">
|
||||
{{template "body" .}}
|
||||
</div>
|
||||
{{template "body" .}}
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
@ -56,12 +56,13 @@ input[type=text] {
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
.root {
|
||||
max-width: var(--var-max-width);
|
||||
max-height: var(--var-max-height);
|
||||
height: var(--var-max-height);
|
||||
width: var(--var-max-width);
|
||||
margin: 0px 1vw;
|
||||
.grid-root {
|
||||
display: grid;
|
||||
height: var(--var-max-height);
|
||||
margin: 0px 1vw;
|
||||
max-height: var(--var-max-height);
|
||||
max-width: var(--var-max-width);
|
||||
width: var(--var-max-width);
|
||||
}
|
||||
|
||||
.pretty-button {
|
||||
|
@ -110,16 +111,17 @@ input[type=text] {
|
|||
}
|
||||
|
||||
#emotesbody {
|
||||
color: var(--var-message-color);
|
||||
color: var(--var-message-color);
|
||||
}
|
||||
|
||||
.emotedef {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
float: left;
|
||||
padding: 5px 5px 15px 5px;
|
||||
}
|
||||
|
||||
.emotedef div {
|
||||
padding: 5px;
|
||||
.emotedef img {
|
||||
height: 112px;
|
||||
width: 112px;
|
||||
}
|
||||
|
||||
.notice {
|
||||
|
@ -200,7 +202,7 @@ input[type=text] {
|
|||
height: 100%;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
background-color: rgb(0, 0, 0, 0.75);
|
||||
background-color: rgba(0, 0, 0, 0.75);
|
||||
z-index: 3;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
|
@ -400,3 +402,21 @@ input[type=text] {
|
|||
z-index: 99;
|
||||
color: var(--var-contrast-color);
|
||||
}
|
||||
|
||||
/* ------------------- */
|
||||
/* CONDITIONAL CLASSES */
|
||||
/* ------------------- */
|
||||
|
||||
/* ------------- */
|
||||
/* COMBINED MODE */
|
||||
/* ------------- */
|
||||
.combined {
|
||||
grid-template-columns: 5fr 1fr;
|
||||
}
|
||||
|
||||
/* --------------- */
|
||||
/* VIDEO ONLY MODE */
|
||||
/* --------------- */
|
||||
.video-only #videoElement {
|
||||
height: 99vh;
|
||||
}
|
||||
|
|
|
@ -29,4 +29,4 @@
|
|||
</dl>
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
|
|
@ -23,10 +23,10 @@ function deleteCookie(cname) {
|
|||
function setPlaying(title, link) {
|
||||
if (title !== "") {
|
||||
$('#playing').text(title);
|
||||
document.title = "Movie Night | " + title;
|
||||
document.title = pageTitle + " | " + title;
|
||||
} else {
|
||||
$('#playing').text("");
|
||||
document.title = "Movie Night";
|
||||
document.title = pageTitle;
|
||||
}
|
||||
|
||||
$('#playing').removeAttr('href');
|
||||
|
|
|
@ -1,39 +1,31 @@
|
|||
{{define "header"}}
|
||||
<script>pageTitle = {{ .Title }}</script>
|
||||
{{if .Chat}}
|
||||
<script type="application/javascript" src="/static/js/wasm_exec.js"></script>
|
||||
<script type="application/javascript" src="/static/js/chat.js"></script>
|
||||
<script>
|
||||
maxMessageCount = {{.MessageHistoryCount }}
|
||||
</script>
|
||||
<style>
|
||||
.root {
|
||||
display: grid;
|
||||
}
|
||||
</style>
|
||||
{{end}}
|
||||
|
||||
{{if .Video}}
|
||||
<script type="application/javascript" src="/static/js/flv.min.js"></script>
|
||||
<script type="application/javascript" src="/static/js/video.js"></script>
|
||||
{{if not .Chat}}
|
||||
<style>
|
||||
#videoElement {
|
||||
height: 99vh;
|
||||
}
|
||||
</style>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
{{if and .Video .Chat}}
|
||||
<style>
|
||||
.root {
|
||||
grid-template-columns: 5fr 1fr;
|
||||
}
|
||||
</style>
|
||||
{{end}}
|
||||
{{/* end define header */}}
|
||||
{{end}}
|
||||
|
||||
{{define "body"}}
|
||||
|
||||
{{ if and .Chat .Video }}
|
||||
<div class="grid-root combined">
|
||||
{{ else if .Video }}
|
||||
<div class="grid-root video-only">
|
||||
{{ else }}
|
||||
<div class="grid-root">
|
||||
{{ end }}
|
||||
|
||||
{{if .Video}}
|
||||
<div id="videoWrapper">
|
||||
<div id="videoOverlay">
|
||||
|
@ -124,4 +116,4 @@
|
|||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
|
Loading…
Reference in New Issue