+ added theme api

+ added switcher from dark and light theme
- deleted profiles directory for now
+ added theme config option
* added boilerplate to circle picker and useridenticons
master
Kevin Froman 2019-10-05 18:35:40 -05:00
parent 578a238f2e
commit 7e9fe03235
No known key found for this signature in database
GPG Key ID: 0D414D0FE405B63B
18 changed files with 171 additions and 44 deletions

View File

@ -20,6 +20,8 @@
import os import os
from httpapi import security, friendsapi, profilesapi, configapi, insertblock, miscclientapi, onionrsitesapi, apiutils from httpapi import security, friendsapi, profilesapi, configapi, insertblock, miscclientapi, onionrsitesapi, apiutils
from httpapi import directconnections from httpapi import directconnections
from httpapi import themeapi
def register_private_blueprints(private_api, app): def register_private_blueprints(private_api, app):
app.register_blueprint(security.client.ClientAPISecurity(private_api).client_api_security_bp) app.register_blueprint(security.client.ClientAPISecurity(private_api).client_api_security_bp)
app.register_blueprint(friendsapi.friends) app.register_blueprint(friendsapi.friends)
@ -32,4 +34,5 @@ def register_private_blueprints(private_api, app):
app.register_blueprint(apiutils.shutdown.shutdown_bp) app.register_blueprint(apiutils.shutdown.shutdown_bp)
app.register_blueprint(miscclientapi.staticfiles.static_files_bp) app.register_blueprint(miscclientapi.staticfiles.static_files_bp)
app.register_blueprint(directconnections.DirectConnectionManagement(private_api).direct_conn_management_bp) app.register_blueprint(directconnections.DirectConnectionManagement(private_api).direct_conn_management_bp)
app.register_blueprint(themeapi.theme_blueprint)
return app return app

View File

@ -24,7 +24,7 @@ from . import pluginwhitelist
# Be extremely mindful of this. These are endpoints available without a password # Be extremely mindful of this. These are endpoints available without a password
whitelist_endpoints = ['www', 'staticfiles.homedata', 'staticfiles.sharedContent', whitelist_endpoints = ['www', 'staticfiles.homedata', 'staticfiles.sharedContent',
'staticfiles.friends', 'staticfiles.friendsindex', 'siteapi.site', 'staticfiles.onionrhome'] 'staticfiles.friends', 'staticfiles.friendsindex', 'siteapi.site', 'staticfiles.onionrhome', 'themes.getTheme']
class ClientAPISecurity: class ClientAPISecurity:
def __init__(self, client_api): def __init__(self, client_api):

View File

@ -0,0 +1,46 @@
"""
Onionr - Private P2P Communication
API to get current CSS theme for the client web UI
"""
"""
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
from flask import Blueprint, Response
import config
from utils import readstatic
theme_blueprint = Blueprint('themes', __name__)
LIGHT_THEME_FILES = ['bulma-light.min.css', 'styles-light.css']
DARK_THEME_FILES = ['bulma-dark.min.css', 'styles-dark.css']
def _load_from_files(file_list: list)->str:
"""Loads multiple static dir files and returns them in combined string format (non-binary)"""
combo_data = ''
for f in file_list:
combo_data += readstatic.read_static('www/shared/main/themes/' + f)
return combo_data
@theme_blueprint.route('/gettheme', endpoint='getTheme')
def get_theme_file()->Response:
"""Returns the css theme data"""
css: str
theme = config.get('ui.theme', 'dark').lower()
if theme == 'dark':
css = _load_from_files(DARK_THEME_FILES)
elif theme == 'light':
css = _load_from_files(LIGHT_THEME_FILES)
return Response(css, mimetype='text/css')

View File

@ -18,6 +18,10 @@
"show_notifications": true "show_notifications": true
}, },
"ui": {
"theme": "dark"
},
"plugins": { "plugins": {
"enabled": { "enabled": {

View File

@ -25,6 +25,8 @@ newPostForm = document.getElementById('addMsg')
firstLoad = true firstLoad = true
lastLoadedBoard = 'global' lastLoadedBoard = 'global'
loadingMessage = document.getElementById('loadingBoard') loadingMessage = document.getElementById('loadingBoard')
loadedAny = false
loadingTimeout = 8000
let toggleLoadingMessage = function(){ let toggleLoadingMessage = function(){
switch (loadingMessage.style.display){ switch (loadingMessage.style.display){
@ -107,6 +109,7 @@ function appendMessages(msg, blockHash, beforeHash){
div[4].textContent = msgDate div[4].textContent = msgDate
loadingMessage.style.display = "none" loadingMessage.style.display = "none"
loadedAny = true
if (firstLoad){ if (firstLoad){
//feed.appendChild(clone) //feed.appendChild(clone)
feed.prepend(clone) feed.prepend(clone)
@ -130,10 +133,16 @@ function getBlocks(){
var ch = document.getElementById('feedIDInput').value var ch = document.getElementById('feedIDInput').value
if (lastLoadedBoard !== ch){ if (lastLoadedBoard !== ch){
toggleLoadingMessage() toggleLoadingMessage()
loadedAny = false
while (feed.firstChild) { while (feed.firstChild) {
feed.removeChild(feed.firstChild); feed.removeChild(feed.firstChild);
} }
requested = [] // reset requested list requested = [] // reset requested list
setTimeout(function(){
if (! loadedAny && ch == document.getElementById('feedIDInput').value){
PNotify.notice("There are no posts for " + ch + " (yet).")
}
}, loadingTimeout)
} }
lastLoadedBoard = ch lastLoadedBoard = ch
@ -142,7 +151,7 @@ function getBlocks(){
} }
var feedText = httpGet('/flow/getpostsbyboard/' + ch) var feedText = httpGet('/flow/getpostsbyboard/' + ch) // TODO switch to fetch
var blockList = feedText.split(',') var blockList = feedText.split(',')
for (i = 0; i < blockList.length; i++){ for (i = 0; i < blockList.length; i++){
@ -183,7 +192,6 @@ function loadMessage(blockHash, blockList, count){
}) })
} }
document.getElementById('refreshFeed').onclick = function(){ document.getElementById('refreshFeed').onclick = function(){
getBlocks() getBlocks()
} }

View File

@ -1,3 +1,22 @@
/*
Onionr - Private P2P Communication
Handle default board picker
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
recommendedIDs = document.getElementById('recommendedBoards') recommendedIDs = document.getElementById('recommendedBoards')
recommendedIDs.onchange = function(){ recommendedIDs.onchange = function(){

View File

@ -11,9 +11,7 @@
<link rel='shortcut icon' type='image/ico' href='/shared/images/favicon.ico'> <link rel='shortcut icon' type='image/ico' href='/shared/images/favicon.ico'>
<link rel='stylesheet' href='/shared/main/PNotifyBrightTheme.css'> <link rel='stylesheet' href='/shared/main/PNotifyBrightTheme.css'>
<link rel="stylesheet" href="/shared/fontawesome-free-5.10.2/css/all.min.css"> <link rel="stylesheet" href="/shared/fontawesome-free-5.10.2/css/all.min.css">
<link rel='stylesheet' href='/shared/main/bulma.min.css'> <link rel="stylesheet" href="/gettheme">
<link rel='stylesheet' href='/shared/main/bulmaswatch.min.css'>
<link rel="stylesheet" href='/shared/main/styles-new.css'>
<link rel="stylesheet" href="theme.css"> <link rel="stylesheet" href="theme.css">
<script defer src="/shared/base32.js"></script> <script defer src="/shared/base32.js"></script>
<script defer src="/shared/identicon.js"></script> <script defer src="/shared/identicon.js"></script>

View File

@ -9,8 +9,7 @@
Onionr Chat Onionr Chat
</title> </title>
<link rel='shortcut icon' type='image/ico' href='/shared/images/favicon.ico'> <link rel='shortcut icon' type='image/ico' href='/shared/images/favicon.ico'>
<link rel="stylesheet" href="/shared/main/bulma.min.css"> <link rel="stylesheet" href="/gettheme">
<link rel="stylesheet" href="/shared/main/styles-new.css">
<link rel="stylesheet" href="/chat/css/convos.css"> <link rel="stylesheet" href="/chat/css/convos.css">
<script defer src='/shared/navbar.js'></script> <script defer src='/shared/navbar.js'></script>
<script defer src='/shared/misc.js'></script> <script defer src='/shared/misc.js'></script>

View File

@ -10,9 +10,7 @@
</title> </title>
<link rel='shortcut icon' type='image/ico' href='/shared/images/favicon.ico'> <link rel='shortcut icon' type='image/ico' href='/shared/images/favicon.ico'>
<link rel='stylesheet' href='/shared/main/PNotifyBrightTheme.css'> <link rel='stylesheet' href='/shared/main/PNotifyBrightTheme.css'>
<link rel='stylesheet' href='/shared/main/bulma.min.css'> <link rel="stylesheet" href="/gettheme">
<link rel='stylesheet' href='/shared/main/bulmaswatch.min.css'>
<link rel='stylesheet' href='/shared/main/styles-new.css'>
<link rel='stylesheet' href='/friends/style.css'> <link rel='stylesheet' href='/friends/style.css'>
<script defer src="/shared/node_modules/pnotify/dist/iife/PNotify.js"></script> <script defer src="/shared/node_modules/pnotify/dist/iife/PNotify.js"></script>
<script defer src="/shared/node_modules/pnotify/dist/iife/PNotifyButtons.js"></script> <script defer src="/shared/node_modules/pnotify/dist/iife/PNotifyButtons.js"></script>

View File

@ -10,9 +10,7 @@
<link rel='shortcut icon' type='image/ico' href='/shared/images/favicon.ico'> <link rel='shortcut icon' type='image/ico' href='/shared/images/favicon.ico'>
<link rel="stylesheet" href="/shared/fontawesome-free-5.10.2/css/all.min.css"> <link rel="stylesheet" href="/shared/fontawesome-free-5.10.2/css/all.min.css">
<link rel='stylesheet' href="/shared/main/PNotifyBrightTheme.css"> <link rel='stylesheet' href="/shared/main/PNotifyBrightTheme.css">
<link rel="stylesheet" href="/shared/main/bulma.min.css"> <link rel="stylesheet" href="/gettheme">
<link rel='stylesheet' href='/shared/main/bulmaswatch.min.css'>
<link rel="stylesheet" href="/shared/main/styles-new.css">
<link rel="stylesheet" href="/mail/mail.css"> <link rel="stylesheet" href="/mail/mail.css">
<script defer src='/shared/node_modules/pnotify/dist/iife/PNotify.js'></script> <script defer src='/shared/node_modules/pnotify/dist/iife/PNotify.js'></script>
<script defer src='/shared/node_modules/pnotify/dist/iife/PNotifyButtons.js'></script> <script defer src='/shared/node_modules/pnotify/dist/iife/PNotifyButtons.js'></script>

View File

@ -12,9 +12,7 @@
<link rel="stylesheet" href="/private/main.css"> <link rel="stylesheet" href="/private/main.css">
<link rel="stylesheet" href="/shared/fontawesome-free-5.10.2/css/all.min.css"> <link rel="stylesheet" href="/shared/fontawesome-free-5.10.2/css/all.min.css">
<link rel='stylesheet' href='/shared/main/PNotifyBrightTheme.css'> <link rel='stylesheet' href='/shared/main/PNotifyBrightTheme.css'>
<link rel="stylesheet" href="/shared/main/bulma.min.css"> <link rel="stylesheet" href="/gettheme">
<link rel='stylesheet' href='/shared/main/bulmaswatch.min.css'>
<link rel="stylesheet" href="/shared/main/styles-new.css">
<script defer src="/shared/node_modules/pnotify/dist/iife/PNotify.js"></script> <script defer src="/shared/node_modules/pnotify/dist/iife/PNotify.js"></script>
<script defer src="/shared/node_modules/pnotify/dist/iife/PNotifyButtons.js"></script> <script defer src="/shared/node_modules/pnotify/dist/iife/PNotifyButtons.js"></script>
<script defer src='/shared/navbar.js'></script> <script defer src='/shared/navbar.js'></script>

View File

@ -1,20 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>
Onionr Profiles
</title>
<link rel='shortcut icon' type='image/ico' href='/shared/images/favicon.ico'>
<link rel='stylesheet' href='/shared/style/modal.css'>
<link rel='stylesheet' href='/shared/main/style.css'>
</head>
<body>
<div class='content'>
<p></p>
</div>
<script src='/shared/navbar.js'></script>
<script src='/shared/misc.js'></script>
<script src='/profiles/profiles.js'></script>
</body>
</html>

View File

@ -0,0 +1,57 @@
/* Config on homepage */
#configContent{
display:none;
}
#configContent.show{
display:block; /* P.S: Use `!important` if missing `#content` (selector specificity). */
}
.hiddenOverlay {
visibility: hidden;
position: absolute;
left: 0px;
top: 0px;
width:100%;
height:100%;
}
/* https://stackoverflow.com/a/16778646/
* Kept due to shutdown message on homepage
*/
.overlay {
visibility: hidden;
position: absolute;
left: 0px;
top: 0px;
width:100%;
height:100%;
text-align:left;
z-index: 1000;
background-color: #2c2b3f;
color: white;
}
.closeOverlay{
background-color: white;
color: black;
border: 1px solid red;
border-radius: 5px;
float: right;
font-family: sans-serif;
}
.closeOverlay:after{
content: '❌';
padding: 5px;
}
.navbarLogo{
margin-right: 5px;
color: red;
}
.aboutLogo{
max-width: 25%;
margin-bottom: 1em;
}

View File

@ -1,15 +1,33 @@
/*
Onionr - Private P2P Communication
Provides userIcon which generates SVG identicons from a Onionr user pubkey
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
function toHexString(byteArray) { function toHexString(byteArray) {
// cc-by-sa-4 https://stackoverflow.com/a/44608819 by https://stackoverflow.com/users/1883624/grantpatterson // cc-by-sa-4 https://stackoverflow.com/a/44608819 by https://stackoverflow.com/users/1883624/grantpatterson
var s = '0x'; var s = '0x'
byteArray.forEach(function(byte) { byteArray.forEach(function(byte) {
s += ('0' + (byte & 0xFF).toString(16)).slice(-2); s += ('0' + (byte & 0xFF).toString(16)).slice(-2)
}); })
return s; return s
} }
async function sha256(str) { async function sha256(str) {
const buf = await crypto.subtle.digest("SHA-256", new TextEncoder("utf-8").encode(str)); const buf = await crypto.subtle.digest("SHA-256", new TextEncoder("utf-8").encode(str))
return Array.prototype.map.call(new Uint8Array(buf), x=>(('00'+x.toString(16)).slice(-2))).join(''); return Array.prototype.map.call(new Uint8Array(buf), x=>(('00'+x.toString(16)).slice(-2))).join('')
} }
async function userIcon(pubkey, imgSize=64){ async function userIcon(pubkey, imgSize=64){