header adjustments for small screens; adjust to new config structure;

This commit is contained in:
Ginger Wong 2020-06-30 02:36:10 -07:00
parent 5a3aed9587
commit 6803f7e7e8
7 changed files with 118 additions and 99 deletions

View File

@ -3,7 +3,7 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
<title>Owncast Demo Server</title> <title>{{title}}</title>
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" /> <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
@ -21,15 +21,12 @@
GW TODO: GW TODO:
- off line/ video done mode. - off line/ video done mode.
- remove listeners on unload? - remove listeners on unload?
- config customizations
- expand user name change text box on focus.chat
- accessilbity - accessilbity
- expect urls out of social list, not usernames
- convert all the https://robohash.org/username123 areas to {{}}, put into util - convert all the https://robohash.org/username123 areas to {{}}, put into util
- generate ?set=x(1-1)&size=10x10 - generate ?set=x(1-1)&size=10x10
- don't force logo to be square. use as bg image :contain
*/ */
</script> </script>
<body class="bg-gray-300 text-gray-800"> <body class="bg-gray-300 text-gray-800">
@ -38,10 +35,14 @@ GW TODO:
<div id="top-content"> <div id="top-content">
<header class="flex border-b border-gray-900 border-solid shadow-md"> <header class="flex border-b border-gray-900 border-solid shadow-md">
<h1 v-cloak class="flex text-gray-400"> <h1 v-cloak class="flex text-gray-400">
<span id="logo-container" class="rounded-full bg-white mx-2 px-1 py-1"> <span
<img class="logo" v-bind:src="logo"> id="logo-container"
class="rounded-full bg-white px-1 py-1"
v-bind:style="{ backgroundImage: 'url(' + logo + ')' }"
>
<img class="logo visually-hidden" v-bind:src="logo">
</span> </span>
<span>{{title}}</span> <span class="instance-title">{{title}}</span>
</h1> </h1>
<div id="user-options-container" class="flex"> <div id="user-options-container" class="flex">
@ -98,10 +99,13 @@ GW TODO:
v-bind:platforms="socialHandles" v-bind:platforms="socialHandles"
v-bind:summary="summary" v-bind:summary="summary"
v-bind:tags="tags" v-bind:tags="tags"
v-bind:extraContent="extraUserContent"
>{{streamerName}}</user-details> >{{streamerName}}</user-details>
<div v-html="extraUserContent">{{extraUserContent}}</div>
</section> </section>
<owncast-footer v-if="layout === 'desktop'" v-bind:appVersion="appVersion"></owncast-footer>
<owncast-footer v-if="layout === 'desktop'" v-bind:app-version="appVersion"></owncast-footer>
</div> </div>
@ -114,10 +118,11 @@ GW TODO:
v-bind:platforms="socialHandles" v-bind:platforms="socialHandles"
v-bind:summary="summary" v-bind:summary="summary"
v-bind:tags="tags" v-bind:tags="tags"
v-bind:extraContent="extraUserContent"
>{{streamerName}}</user-details> >{{streamerName}}</user-details>
<owncast-footer v-bind:appVersion="appVersion"></owncast-footer> <div v-html="extraUserContent">{{extraUserContent}}</div>
<owncast-footer v-bind:app-version="appVersion"></owncast-footer>
</div> </div>
@ -175,7 +180,7 @@ GW TODO:
<script src="js/utils.js"></script> <script src="js/utils.js"></script>
<script src="js/message.js"></script> <script src="js/message.js"></script>
<script src="js/social.js"></script> <script src="js/social.js"></script>
<script src="js/footer.js"></script> <script src="js/components.js"></script>
<script src="js/app.js"></script> <script src="js/app.js"></script>
<script src="js/player/airplay.js"></script> <script src="js/player/airplay.js"></script>
<script src="js/player/player.js"></script> <script src="js/player/player.js"></script>

View File

@ -12,6 +12,7 @@ async function setupApp() {
extraUserContent: "", extraUserContent: "",
isOnline: false, isOnline: false,
layout: "desktop", layout: "desktop",
// from config // from config
logo: null, logo: null,
socialHandles: [], socialHandles: [],
@ -20,7 +21,6 @@ async function setupApp() {
tags: [], tags: [],
title: "", title: "",
appVersion: "", appVersion: "",
}, },
watch: { watch: {
messages: { messages: {
@ -41,24 +41,24 @@ async function setupApp() {
appMessaging.init(); appMessaging.init();
const config = await new Config().init(); const config = await new Config().init();
app.logo = config.logo; app.logo = config.logo.small;
app.socialHandles = config.socialHandles; app.socialHandles = config.socialHandles;
app.streamerName = config.name; app.streamerName = config.name;
app.summary = config.summary && addNewlines(config.summary); app.summary = config.summary && addNewlines(config.summary);
app.tags = config.tags; app.tags = config.tags;
app.title = config.title; app.title = config.title;
app.appVersion = config.appVersion;
// const configFileLocation = "../js/config.json";
try { try {
const pageContentFile = "../static/content.md" const pageContentFile = config.extraUserInfoFileName;
const response = await fetch(pageContentFile); const response = await fetch(pageContentFile);
const descriptionMarkdown = await response.text() const descriptionMarkdown = await response.text()
const descriptionHTML = new showdown.Converter().makeHtml(descriptionMarkdown); const descriptionHTML = new showdown.Converter().makeHtml(descriptionMarkdown);
app.extraUserContent = descriptionHTML; app.extraUserContent = descriptionHTML;
return this; return this;
} catch (error) { } catch (error) {
console.log(error); console.log("Error",error);
} }
} }

View File

@ -35,11 +35,17 @@ Vue.component('stream-tags', {
}); });
Vue.component('user-details', { Vue.component('user-details', {
props: ['logo', 'platforms', 'summary', 'tags', 'extraContent'], props: ['logo', 'platforms', 'summary', 'tags'],
template: ` template: `
<div class="user-content"> <div class="user-content">
<div class="user-image rounded-full bg-white"> <div
<img class="logo" alt="Logo" v-bind:src="logo"> class="user-image rounded-full bg-white"
v-bind:style="{ backgroundImage: 'url(' + logo + ')' }"
>
<img
class="logo visually-hidden"
alt="Logo"
v-bind:src="logo">
</div> </div>
<div class="user-content-header border-b border-gray-500 border-solid"> <div class="user-content-header border-b border-gray-500 border-solid">
<h2 class="font-semibold"> <h2 class="font-semibold">
@ -51,9 +57,6 @@ Vue.component('user-details', {
<div class="stream-summary" v-html="summary"></div> <div class="stream-summary" v-html="summary"></div>
<stream-tags v-bind:tags="tags"></stream-tags> <stream-tags v-bind:tags="tags"></stream-tags>
</div> </div>
<div v-html="extraContent"></div>
</div> </div>
`, `,
}); });

View File

@ -1,7 +1,7 @@
// add more to the promises later. // add more to the promises later.
class Config { class Config {
async init() { async init() {
const configFileLocation = "/config"; const configFileLocation = "https://goth.land/config";
try { try {
const response = await fetch(configFileLocation); const response = await fetch(configFileLocation);

View File

@ -138,10 +138,17 @@ class Messaging {
handleShowChangeNameForm() { handleShowChangeNameForm() {
this.textUserInfoDisplay.style.display = "none"; this.textUserInfoDisplay.style.display = "none";
this.tagUserInfoChanger.style.display = "flex"; this.tagUserInfoChanger.style.display = "flex";
if (document.body.clientWidth < 640) {
this.tagChatToggle.style.display = "none";
}
} }
handleHideChangeNameForm() { handleHideChangeNameForm() {
this.textUserInfoDisplay.style.display = "flex"; this.textUserInfoDisplay.style.display = "flex";
this.tagUserInfoChanger.style.display = "none"; this.tagUserInfoChanger.style.display = "none";
if (document.body.clientWidth < 640) {
this.tagChatToggle.style.display = "inline-block";
}
} }
handleUpdateUsername() { handleUpdateUsername() {
var newValue = this.inputChangeUserName.value; var newValue = this.inputChangeUserName.value;

View File

@ -1,88 +1,71 @@
const SOCIAL_PLATFORMS_URLS = { const SOCIAL_PLATFORMS = {
default: { default: {
name: "default", name: "default",
urlPrefix: "",
imgPos: [0,0], // [row,col] imgPos: [0,0], // [row,col]
}, },
facebook: { facebook: {
name: "Facebook", name: "Facebook",
urlPrefix: "http://www.facebook.com/",
imgPos: [0,1], imgPos: [0,1],
}, },
twitter: { twitter: {
name: "Twitter", name: "Twitter",
urlPrefix: "http://www.twitter.com/",
imgPos: [0,2], imgPos: [0,2],
}, },
instagram: { instagram: {
name: "Instagram", name: "Instagram",
urlPrefix: "http://www.instagram.com/",
imgPos: [0,3], imgPos: [0,3],
}, },
snapchat: { snapchat: {
name: "Snapchat", name: "Snapchat",
urlPrefix: "http://www.snapchat.com/",
imgPos: [0,4], imgPos: [0,4],
}, },
tiktok: { tiktok: {
name: "TikTok", name: "TikTok",
urlPrefix: "http://www.tiktok.com/",
imgPos: [0,5], imgPos: [0,5],
}, },
soundcloud: { soundcloud: {
name: "Soundcloud", name: "Soundcloud",
urlPrefix: "http://www.soundcloud.com/",
imgPos: [0,6], imgPos: [0,6],
}, },
bandcamp: { bandcamp: {
name: "Bandcamp", name: "Bandcamp",
urlPrefix: "http://www.basecamp.com/",
imgPos: [0,7], imgPos: [0,7],
}, },
patreon: { patreon: {
name: "Patreon", name: "Patreon",
urlPrefix: "http://www.patreon.com/",
imgPos: [0,1], imgPos: [0,1],
}, },
youtube: { youtube: {
name: "YouTube", name: "YouTube",
urlPrefix: "http://www.youtube.com/",
imgPos: [0,9 ], imgPos: [0,9 ],
}, },
spotify: { spotify: {
name: "Spotify", name: "Spotify",
urlPrefix: "http://www.spotify.com/",
imgPos: [0,10], imgPos: [0,10],
}, },
twitch: { twitch: {
name: "Twitch", name: "Twitch",
urlPrefix: "http://www.twitch.com/",
imgPos: [0,11], imgPos: [0,11],
}, },
paypal: { paypal: {
name: "Paypal", name: "Paypal",
urlPrefix: "http://www.paypal.com/",
imgPos: [0,12], imgPos: [0,12],
}, },
github: { github: {
name: "Github", name: "Github",
urlPrefix: "http://www.github.com/",
imgPos: [0,13], imgPos: [0,13],
}, },
linkedin: { linkedin: {
name: "LinkedIn", name: "LinkedIn",
urlPrefix: "http://www.linkedin.com/",
imgPos: [0,14], imgPos: [0,14],
}, },
discord: { discord: {
name: "Discord", name: "Discord",
urlPrefix: "http://www.discord.com/",
imgPos: [0,15], imgPos: [0,15],
}, },
mastadon: { mastadon: {
name: "Mastadon", name: "Mastadon",
urlPrefix: "http://www.mastadon.com/",
imgPos: [0,16], imgPos: [0,16],
}, },
}; };
@ -98,7 +81,7 @@ Vue.component('social-list', {
v-if="item.platform && item.handle" v-if="item.platform && item.handle"
v-bind:key="index" v-bind:key="index"
v-bind:platform="item.platform" v-bind:platform="item.platform"
v-bind:username="item.handle" v-bind:url="item.url"
/> />
</ul> </ul>
`, `,
@ -106,25 +89,27 @@ Vue.component('social-list', {
}); });
Vue.component('user-social-icon', { Vue.component('user-social-icon', {
props: ['platform', 'username'], props: ['platform', 'url'],
data: function() { data: function() {
const platformInfo = SOCIAL_PLATFORMS_URLS[this.platform.toLowerCase()] || SOCIAL_PLATFORMS_URLS["default"]; const platformInfo = SOCIAL_PLATFORMS[this.platform.toLowerCase()];
const inList = !!platformInfo;
const imgRow = platformInfo.imgPos && platformInfo.imgPos[0] || 0; const imgRow = platformInfo.imgPos && platformInfo.imgPos[0] || 0;
const imgCol = platformInfo.imgPos && platformInfo.imgPos[1] || 0; const imgCol = platformInfo.imgPos && platformInfo.imgPos[1] || 0;
const useDefault = platformInfo.name === "default"; c
return { return {
name: platformInfo.name, name: inList ? platformInfo.name : this.platform,
link: platformInfo.name !== "default" ? `${platformInfo.urlPrefix}/${this.username}` : '#', link: url,
style: `--imgRow: -${imgRow}; --imgCol: -${imgCol};`, style: `--imgRow: -${imgRow}; --imgCol: -${imgCol};`,
itemClass: { itemClass: {
"user-social-item": true, "user-social-item": true,
"flex": true, "flex": true,
"rounded": useDefault, "rounded": inList,
"use-default": useDefault, "use-default": inList,
}, },
labelClass: { labelClass: {
"platform-label": true, "platform-label": true,
"visually-hidden": !useDefault, "visually-hidden": !inList,
"text-indigo-800": true, "text-indigo-800": true,
}, },
}; };
@ -137,7 +122,7 @@ Vue.component('user-social-icon', {
:href="link" :href="link"
> >
<span class="platform-icon rounded-lg" :style="style" /> <span class="platform-icon rounded-lg" :style="style" />
<span v-bind:class="labelClass">Find @{{username}} on {{platform}}</span> <span v-bind:class="labelClass">Find me on {{platform}}</span>
</a> </a>
</li> </li>
`, `,

View File

@ -60,17 +60,26 @@ header h1 {
text-transform: uppercase; text-transform: uppercase;
padding: .5em; padding: .5em;
white-space: nowrap; white-space: nowrap;
/* width: 20em; */
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
flex-direction: row; flex-direction: row;
overflow: hidden;
} }
img.logo { #logo-container{
height: 1.2em; height: 1.75em;
width: 1.2em; width: 1.75em;
min-height: 1.75em;
min-width: 1.75em;
margin-right: .5em;
display: inline-block; display: inline-block;
background-repeat: no-repeat;
background-position: center center;
background-size: 1.35em;
}
header .instance-title {
overflow: hidden;
text-overflow: ellipsis;
} }
#chat-toggle { #chat-toggle {
cursor: pointer; cursor: pointer;
text-align: center; text-align: center;
@ -132,13 +141,16 @@ footer span {
width: var(--user-image-width); width: var(--user-image-width);
height: var(--user-image-width); height: var(--user-image-width);
max-height: var(--user-image-width); max-height: var(--user-image-width);
background-repeat: no-repeat;
background-position: center center;
background-size: calc(var(--user-image-width) - 1em);
} }
.user-image img { /* .user-image img {
display: inline-block; display: inline-block;
width: 100%; width: 100%;
height: 100%; height: 100%;
} } */
.stream-summary { .stream-summary {
margin: 1em 0; margin: 1em 0;
} }
@ -414,44 +426,6 @@ h2 {
display: none; display: none;
} }
/* ************************************************8 */
@media screen and (max-width: 860px) {
:root {
--right-col-width: 20em;
--user-image-width: 6em;
}
#chat-container {
width: var(--right-col-width);
}
}
@media screen and (max-width: 640px ) {
.desktop {
--video-container-height: 50vh;
}
.desktop #chat-container {
height: auto;
position: relative;
right: unset;
top: unset;
width: 100%;
z-index: 1;
}
.desktop.chat #video-container,
.desktop.chat #stream-info,
.desktop.chat #user-content {
width: 100%;
}
.desktop #footer,
.desktop.chat #user-content {
display: none;
}
}
/* ************************************************8 */ /* ************************************************8 */
/* ************************************************8 */ /* ************************************************8 */
@ -524,11 +498,56 @@ h2 {
display: none; display: none;
} }
/* ************************************************8 */
@media screen and (max-width: 860px) {
:root {
--right-col-width: 20em;
--user-image-width: 6em;
}
#chat-container {
width: var(--right-col-width);
}
}
@media screen and (max-width: 640px ) { @media screen and (max-width: 640px ) {
:root { :root {
--video-container-height: 36vh; --video-container-height: 36vh;
} }
.desktop {
--video-container-height: 50vh;
}
.desktop #chat-container {
height: auto;
position: relative;
right: unset;
top: unset;
width: 100%;
z-index: 1;
}
.desktop.chat #video-container,
.desktop.chat #stream-info,
.desktop.chat #user-content {
width: 100%;
}
.desktop #footer,
.desktop.chat #user-content {
display: none;
}
#logo-container {
display: none;
}
header h1 {
max-width: 58%;
}
#user-options-container {
max-width: 41%;
}
} }
@media screen and (orientation: landscape) and (min-width: 1024px) { @media screen and (orientation: landscape) and (min-width: 1024px) {