+ 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 useridenticonsmaster
parent
578a238f2e
commit
7e9fe03235
|
@ -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
|
|
@ -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):
|
||||||
|
|
|
@ -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')
|
|
@ -18,6 +18,10 @@
|
||||||
"show_notifications": true
|
"show_notifications": true
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"ui": {
|
||||||
|
"theme": "dark"
|
||||||
|
},
|
||||||
|
|
||||||
"plugins": {
|
"plugins": {
|
||||||
"enabled": {
|
"enabled": {
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(){
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
|
File diff suppressed because one or more lines are too long
|
@ -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;
|
||||||
|
}
|
|
@ -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){
|
||||||
|
|
Loading…
Reference in New Issue