Improvements to interface
This commit is contained in:
parent
8cc9cea24f
commit
acbd6fdd94
11 changed files with 675 additions and 415 deletions
|
@ -3,22 +3,23 @@
|
||||||
This server controls all hugveys and the processing of their narratives. It exposes itself for control to the panopticon server.
|
This server controls all hugveys and the processing of their narratives. It exposes itself for control to the panopticon server.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import asyncio
|
import os
|
||||||
import logging
|
|
||||||
import threading
|
|
||||||
import time
|
import time
|
||||||
import yaml
|
import yaml
|
||||||
import zmq
|
import zmq
|
||||||
from zmq.asyncio import Context
|
from zmq.asyncio import Context
|
||||||
|
|
||||||
|
import asyncio
|
||||||
from hugvey.communication import getTopic, zmqSend, zmqReceive
|
from hugvey.communication import getTopic, zmqSend, zmqReceive
|
||||||
from hugvey.panopticon import Panopticon
|
from hugvey.panopticon import Panopticon
|
||||||
from hugvey.story import Story
|
from hugvey.story import Story
|
||||||
from hugvey.voice.google import GoogleVoiceClient
|
from hugvey.voice.google import GoogleVoiceClient
|
||||||
from hugvey.voice.player import Player
|
from hugvey.voice.player import Player
|
||||||
from hugvey.voice.streamer import AudioStreamer
|
from hugvey.voice.streamer import AudioStreamer
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
import queue
|
import queue
|
||||||
import os
|
import threading
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger("command")
|
logger = logging.getLogger("command")
|
||||||
|
@ -72,7 +73,8 @@ class CentralCommand(object):
|
||||||
lang_filename = os.path.join(self.config['web']['files_dir'], lang['file'])
|
lang_filename = os.path.join(self.config['web']['files_dir'], lang['file'])
|
||||||
self.languageFiles[lang['code']] = lang['file']
|
self.languageFiles[lang['code']] = lang['file']
|
||||||
with open(lang_filename, 'r') as fp:
|
with open(lang_filename, 'r') as fp:
|
||||||
self.languages[lang['code']] = yaml.load(fp)
|
self.languages[lang['code']] = json.load(fp)
|
||||||
|
print(self.languages)
|
||||||
|
|
||||||
self.panopticon = Panopticon(self, self.config)
|
self.panopticon = Panopticon(self, self.config)
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,11 @@ def getWebSocketHandler(central_command):
|
||||||
|
|
||||||
return WebSocketHandler
|
return WebSocketHandler
|
||||||
|
|
||||||
|
class NonCachingStaticFileHandler(tornado.web.StaticFileHandler):
|
||||||
|
def set_extra_headers(self, path):
|
||||||
|
# Disable cache
|
||||||
|
self.set_header('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
|
||||||
|
|
||||||
def getUploadHandler(central_command):
|
def getUploadHandler(central_command):
|
||||||
class UploadHandler(tornado.web.RequestHandler):
|
class UploadHandler(tornado.web.RequestHandler):
|
||||||
def post(self):
|
def post(self):
|
||||||
|
@ -97,9 +102,10 @@ def getUploadHandler(central_command):
|
||||||
langCode = self.get_argument("language")
|
langCode = self.get_argument("language")
|
||||||
langFile = os.path.join(central_command.config['web']['files_dir'] , central_command.languageFiles[langCode])
|
langFile = os.path.join(central_command.config['web']['files_dir'] , central_command.languageFiles[langCode])
|
||||||
|
|
||||||
print(self.request.files['json'][0])
|
|
||||||
storyData = json.loads(self.request.files['json'][0]['body'])
|
storyData = json.loads(self.request.files['json'][0]['body'])
|
||||||
print(storyData)
|
# print(json.dumps(storyData))
|
||||||
|
# self.finish()
|
||||||
|
# return
|
||||||
|
|
||||||
if 'audio' in self.request.files:
|
if 'audio' in self.request.files:
|
||||||
msgId = self.get_argument("message_id")
|
msgId = self.get_argument("message_id")
|
||||||
|
@ -120,9 +126,10 @@ def getUploadHandler(central_command):
|
||||||
# fp.write(audioFile['body'])
|
# fp.write(audioFile['body'])
|
||||||
break
|
break
|
||||||
|
|
||||||
with open(langFile, 'r') as fp:
|
print(os.path.abspath(langFile))
|
||||||
logger.info(f'Save story to {langFile}')
|
with open(langFile, 'w') as json_fp:
|
||||||
# json.dump(storyData, fp)
|
logger.info(f'Save story to {langFile} {json_fp}')
|
||||||
|
json.dump(storyData, json_fp)
|
||||||
self.finish()
|
self.finish()
|
||||||
return UploadHandler
|
return UploadHandler
|
||||||
|
|
||||||
|
@ -132,7 +139,7 @@ class Panopticon(object):
|
||||||
self.config = config
|
self.config = config
|
||||||
self.application = tornado.web.Application([
|
self.application = tornado.web.Application([
|
||||||
(r"/ws", getWebSocketHandler(self.command)),
|
(r"/ws", getWebSocketHandler(self.command)),
|
||||||
(r"/local/(.*)", tornado.web.StaticFileHandler,
|
(r"/local/(.*)", NonCachingStaticFileHandler,
|
||||||
{"path": config['web']['files_dir']}),
|
{"path": config['web']['files_dir']}),
|
||||||
(r"/upload", getUploadHandler(self.command)),
|
(r"/upload", getUploadHandler(self.command)),
|
||||||
(r"/(.*)", tornado.web.StaticFileHandler,
|
(r"/(.*)", tornado.web.StaticFileHandler,
|
||||||
|
|
|
@ -2,13 +2,22 @@ body {
|
||||||
font-family: "Noto Sans", sans-serif;
|
font-family: "Noto Sans", sans-serif;
|
||||||
margin: 0; }
|
margin: 0; }
|
||||||
|
|
||||||
.btn {
|
.btn, input[type="submit"] {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background: #333;
|
background: #333;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
color: white;
|
color: white;
|
||||||
border-radius: 5px; }
|
border-radius: 5px;
|
||||||
|
margin-right: 5px;
|
||||||
|
white-space: nowrap;
|
||||||
|
border: none; }
|
||||||
|
.btn:hover, input[type="submit"]:hover {
|
||||||
|
background: #666; }
|
||||||
|
|
||||||
|
@keyframes dash-animation {
|
||||||
|
to {
|
||||||
|
stroke-dashoffset: -1000; } }
|
||||||
|
|
||||||
#interface {
|
#interface {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -29,6 +38,8 @@ body {
|
||||||
border: solid 1px;
|
border: solid 1px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
position: relative; }
|
position: relative; }
|
||||||
|
#status > div#overview {
|
||||||
|
width: 66.66667%; }
|
||||||
#status .hugvey {
|
#status .hugvey {
|
||||||
background-image: linear-gradient(to top, #587457, #35a589);
|
background-image: linear-gradient(to top, #587457, #35a589);
|
||||||
color: white;
|
color: white;
|
||||||
|
@ -52,11 +63,13 @@ body {
|
||||||
text-align: center; }
|
text-align: center; }
|
||||||
|
|
||||||
#story {
|
#story {
|
||||||
position: relative; }
|
position: relative;
|
||||||
|
width: calc(100% - 430px); }
|
||||||
#story #controls {
|
#story #controls {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 5px;
|
top: 5px;
|
||||||
left: 5px; }
|
left: 5px;
|
||||||
|
white-space: nowrap; }
|
||||||
#story svg#graph {
|
#story svg#graph {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -77,13 +90,22 @@ body {
|
||||||
font-size: 11pt;
|
font-size: 11pt;
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
fill: white; }
|
fill: white; }
|
||||||
|
#story text.msg_id {
|
||||||
|
transform: translateY(-20px);
|
||||||
|
opacity: .5; }
|
||||||
|
#story text.msg_txt {
|
||||||
|
font-weight: bold; }
|
||||||
#story line {
|
#story line {
|
||||||
marker-end: url("#arrowHead");
|
marker-end: url("#arrowHead");
|
||||||
stroke-width: 2px;
|
stroke-width: 2px;
|
||||||
stroke: black; }
|
stroke: black; }
|
||||||
#story line.link--noconditions {
|
#story line.link--noconditions {
|
||||||
stroke-dasharray: 5 4;
|
stroke-dasharray: 5 4;
|
||||||
stroke: red; }
|
stroke: red; }
|
||||||
|
#story line.dir-highlight {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
animation: dash-animation 20s infinite linear;
|
||||||
|
stroke-width: 3px; }
|
||||||
#story label::after {
|
#story label::after {
|
||||||
content: '';
|
content: '';
|
||||||
clear: both;
|
clear: both;
|
||||||
|
@ -109,6 +131,18 @@ body {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
background: lightgray; }
|
background: lightgray; }
|
||||||
|
#story #msg .direction {
|
||||||
|
position: relative; }
|
||||||
|
#story #msg .direction h3 {
|
||||||
|
margin-top: 0; }
|
||||||
|
#story #msg .direction .btn--delete {
|
||||||
|
position: absolute;
|
||||||
|
top: 5px;
|
||||||
|
right: 0px; }
|
||||||
|
#story #msg .direction .condition--add h4 {
|
||||||
|
margin: 0; }
|
||||||
|
#story #msg .direction .condition--add h4 + div {
|
||||||
|
margin-top: 10px; }
|
||||||
#story #nodes g:hover circle,
|
#story #nodes g:hover circle,
|
||||||
#story .selectedMsg circle {
|
#story .selectedMsg circle {
|
||||||
stroke: lightgreen;
|
stroke: lightgreen;
|
||||||
|
@ -130,3 +164,33 @@ body {
|
||||||
text-shadow: 2px 2px 2px lightgray,-2px 2px 2px lightgray,2px -2px 2px lightgray,-2px -2px 2px lightgray; }
|
text-shadow: 2px 2px 2px lightgray,-2px 2px 2px lightgray,2px -2px 2px lightgray,-2px -2px 2px lightgray; }
|
||||||
#story .condition--add {
|
#story .condition--add {
|
||||||
/* text-align: center; */ }
|
/* text-align: center; */ }
|
||||||
|
|
||||||
|
.flag-icon {
|
||||||
|
background-size: contain;
|
||||||
|
background-position: 50%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
width: 1.33333em;
|
||||||
|
line-height: 1em; }
|
||||||
|
.flag-icon:before {
|
||||||
|
content: '\00a0'; }
|
||||||
|
.flag-icon.flag-icon-squared {
|
||||||
|
width: 1em; }
|
||||||
|
.flag-icon.en-GB {
|
||||||
|
background-image: url("/images/gb.svg"); }
|
||||||
|
.flag-icon.de-DE {
|
||||||
|
background-image: url("/images/de.svg"); }
|
||||||
|
.flag-icon.fr-FR {
|
||||||
|
background-image: url("/images/fr.svg"); }
|
||||||
|
.flag-icon.nl-NL {
|
||||||
|
background-image: url("/images/nl.svg"); }
|
||||||
|
|
||||||
|
.divToggle {
|
||||||
|
cursor: pointer; }
|
||||||
|
.divToggle:hover {
|
||||||
|
text-decoration: underline; }
|
||||||
|
.divToggle.opened + div {
|
||||||
|
display: block; }
|
||||||
|
.divToggle + div {
|
||||||
|
display: none; }
|
||||||
|
|
7
www/images/be.svg
Normal file
7
www/images/be.svg
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icon-css-be" viewBox="0 0 640 480">
|
||||||
|
<g fill-rule="evenodd" stroke-width="1pt">
|
||||||
|
<path d="M0 0h213.3v480H0z"/>
|
||||||
|
<path fill="#ffd90c" d="M213.3 0h213.4v480H213.3z"/>
|
||||||
|
<path fill="#f31830" d="M426.7 0H640v480H426.7z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 290 B |
5
www/images/de.svg
Normal file
5
www/images/de.svg
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icon-css-de" viewBox="0 0 640 480">
|
||||||
|
<path fill="#ffce00" d="M0 320h640v160H0z"/>
|
||||||
|
<path d="M0 0h640v160H0z"/>
|
||||||
|
<path fill="#d00" d="M0 160h640v160H0z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 213 B |
7
www/images/fr.svg
Normal file
7
www/images/fr.svg
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icon-css-fr" viewBox="0 0 640 480">
|
||||||
|
<g fill-rule="evenodd" stroke-width="1pt">
|
||||||
|
<path fill="#fff" d="M0 0h640v480H0z"/>
|
||||||
|
<path fill="#00267f" d="M0 0h213.3v480H0z"/>
|
||||||
|
<path fill="#f31830" d="M426.7 0H640v480H426.7z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 292 B |
15
www/images/gb.svg
Normal file
15
www/images/gb.svg
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icon-css-gb" viewBox="0 0 640 480">
|
||||||
|
<defs>
|
||||||
|
<clipPath id="a">
|
||||||
|
<path fill-opacity=".7" d="M-85.3 0h682.6v512H-85.3z"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
<g clip-path="url(#a)" transform="translate(80) scale(.94)">
|
||||||
|
<g stroke-width="1pt">
|
||||||
|
<path fill="#012169" d="M-256 0H768v512H-256z"/>
|
||||||
|
<path fill="#fff" d="M-256 0v57.2L653.5 512H768v-57.2L-141.5 0H-256zM768 0v57.2L-141.5 512H-256v-57.2L653.5 0H768z"/>
|
||||||
|
<path fill="#fff" d="M170.7 0v512h170.6V0H170.7zM-256 170.7v170.6H768V170.7H-256z"/>
|
||||||
|
<path fill="#c8102e" d="M-256 204.8v102.4H768V204.8H-256zM204.8 0v512h102.4V0H204.8zM-256 512L85.3 341.3h76.4L-179.7 512H-256zm0-512L85.3 170.7H9L-256 38.2V0zm606.4 170.7L691.7 0H768L426.7 170.7h-76.3zM768 512L426.7 341.3H503l265 132.5V512z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 837 B |
7
www/images/nl.svg
Normal file
7
www/images/nl.svg
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icon-css-nl" viewBox="0 0 640 480">
|
||||||
|
<g fill-rule="evenodd" stroke-width="1pt" transform="scale(1.25 .9375)">
|
||||||
|
<rect width="512" height="509.8" fill="#fff" rx="0" ry="0"/>
|
||||||
|
<rect width="512" height="169.9" y="342.1" fill="#21468b" rx="0" ry="0"/>
|
||||||
|
<path fill="#ae1c28" d="M0 0h512v170H0z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 364 B |
|
@ -11,16 +11,18 @@
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="interface">
|
<div id="interface" class='showStatus'>
|
||||||
<div id='status'>
|
<div id='status'>
|
||||||
<div id='overview'>
|
<div id='overview'>
|
||||||
<dl>
|
<dl>
|
||||||
<dt>Uptime</dt>
|
<dt>Uptime</dt>
|
||||||
<dd>{{uptime}}</dd>
|
<dd>{{uptime}}</dd>
|
||||||
<dt>Languages</dt>
|
|
||||||
<dd v-for="lang in languages" :title="lang.file"
|
|
||||||
class="btn lang--btn" @click="loadNarrative(lang.code, lang.file)">{{lang.code}}</dd>
|
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
|
<ul id='languages'>
|
||||||
|
<li v-for="lang in languages" :title="lang.file"
|
||||||
|
class="btn lang--btn" @click="loadNarrative(lang.code, lang.file)"><span :class="['flag-icon', lang.code]"></span> {{lang.code}}</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class='hugvey' v-for="hv in hugveys"
|
<div class='hugvey' v-for="hv in hugveys"
|
||||||
:class="[{'hugvey--off': hv.status == 'off'},{'hugvey--on': hv.status != 'off'},{'hugvey--paused': hv.status == 'paused'},{'hugvey--running': hv.status == 'running'}]">
|
:class="[{'hugvey--off': hv.status == 'off'},{'hugvey--on': hv.status != 'off'},{'hugvey--paused': hv.status == 'paused'},{'hugvey--running': hv.status == 'running'}]">
|
||||||
|
@ -43,6 +45,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div id='story'>
|
<div id='story'>
|
||||||
<div id="controls">
|
<div id="controls">
|
||||||
|
<span id="current_lang"></span>
|
||||||
<div id="btn-save" class="btn">Save</div>
|
<div id="btn-save" class="btn">Save</div>
|
||||||
<div id="btn-addMsg" class="btn">Create message</div>
|
<div id="btn-addMsg" class="btn">Create message</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,15 +1,31 @@
|
||||||
|
$status_width: 430px;
|
||||||
|
$status_width_open: 860px;
|
||||||
|
|
||||||
body{
|
body{
|
||||||
font-family: "Noto Sans", sans-serif;
|
font-family: "Noto Sans", sans-serif;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn{
|
.btn, input[type="submit"]{
|
||||||
display:inline-block;
|
display:inline-block;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background: #333;
|
background: #333;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
color: white;
|
color: white;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
margin-right: 5px;
|
||||||
|
white-space: nowrap;
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
&:hover{
|
||||||
|
background: #666;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes dash-animation {
|
||||||
|
to {
|
||||||
|
stroke-dashoffset: -1000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#interface{
|
#interface{
|
||||||
|
@ -17,6 +33,9 @@ body{
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
|
|
||||||
|
&.showStatus{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#status{
|
#status{
|
||||||
|
@ -33,6 +52,10 @@ body{
|
||||||
border: solid 1px;
|
border: solid 1px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
&#overview{
|
||||||
|
width: 100% / 3 * 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.hugvey{
|
.hugvey{
|
||||||
|
@ -72,11 +95,13 @@ body{
|
||||||
|
|
||||||
#story{
|
#story{
|
||||||
position: relative;
|
position: relative;
|
||||||
|
width: calc(100% - #{$status_width});
|
||||||
|
|
||||||
#controls{
|
#controls{
|
||||||
position:absolute;
|
position:absolute;
|
||||||
top: 5px;
|
top: 5px;
|
||||||
left: 5px;
|
left: 5px;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
svg#graph{
|
svg#graph{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -106,15 +131,29 @@ body{
|
||||||
font-size: 11pt;
|
font-size: 11pt;
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
fill: white;
|
fill: white;
|
||||||
|
|
||||||
|
&.msg_id {
|
||||||
|
transform: translateY(-20px);
|
||||||
|
opacity: .5;
|
||||||
|
}
|
||||||
|
&.msg_txt{
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
line{
|
line{
|
||||||
marker-end: url('#arrowHead');
|
marker-end: url('#arrowHead');
|
||||||
stroke-width: 2px;
|
stroke-width: 2px;
|
||||||
stroke: black;
|
stroke: black;
|
||||||
}
|
|
||||||
line.link--noconditions{
|
&.link--noconditions{
|
||||||
stroke-dasharray: 5 4;
|
stroke-dasharray: 5 4;
|
||||||
stroke: red;
|
stroke: red;
|
||||||
|
}
|
||||||
|
&.dir-highlight{
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
animation: dash-animation 20s infinite linear;
|
||||||
|
stroke-width: 3px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
label::after {
|
label::after {
|
||||||
content: '';
|
content: '';
|
||||||
|
@ -148,6 +187,27 @@ body{
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
background:lightgray;
|
background:lightgray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.direction{
|
||||||
|
position: relative;
|
||||||
|
h3{
|
||||||
|
margin-top:0;
|
||||||
|
}
|
||||||
|
.btn--delete{
|
||||||
|
position: absolute;
|
||||||
|
top: 5px;
|
||||||
|
right: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.condition--add{
|
||||||
|
h4{
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
h4 +div {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#nodes g:hover circle,
|
#nodes g:hover circle,
|
||||||
|
@ -180,3 +240,53 @@ body{
|
||||||
/* text-align: center; */
|
/* text-align: center; */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.flag-icon {
|
||||||
|
background-size: contain;
|
||||||
|
background-position: 50%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
width: (4 / 3) * 1em;
|
||||||
|
line-height: 1em;
|
||||||
|
&:before {
|
||||||
|
content: '\00a0';
|
||||||
|
}
|
||||||
|
&.flag-icon-squared {
|
||||||
|
width: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.en-GB {
|
||||||
|
background-image: url('/images/gb.svg');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.de-DE {
|
||||||
|
background-image: url('/images/de.svg');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.fr-FR {
|
||||||
|
background-image: url('/images/fr.svg');
|
||||||
|
}
|
||||||
|
&.nl-NL {
|
||||||
|
background-image: url('/images/nl.svg');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.divToggle{
|
||||||
|
cursor: pointer;
|
||||||
|
&:hover{
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
&.opened {
|
||||||
|
+ div{
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ div{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue