intermediate

This commit is contained in:
Patrick Jentsch 2020-10-23 08:51:46 +02:00
parent 0ef7355ca1
commit 23441dab2e
19 changed files with 1249 additions and 1149 deletions

View File

@ -0,0 +1,12 @@
/*
* The sidenav-fixed class is used which causes the sidenav to be fixed and open
* on large screens and hides to the regular functionality on smaller screens.
* In order to prevent the sidenav to overlap the content, the content (in our
* case header, main and footer) gets an offset equal to the width of the
* sidenav.
*/
@media only screen and (min-width : 993px) {
header, main, footer {padding-left: 300px;}
.modal:not(.bottom-sheet) {left: 300px;}
.navbar-fixed > nav {width: calc(100% - 300px)}
}

View File

@ -0,0 +1,13 @@
/*
* Force the footer to always stay on the bottom of the page regardless of how
* little content is on the page.
*/
body {
display: flex;
min-height: 100vh;
flex-direction: column;
}
main {
flex: 1 0 auto;
}

View File

@ -1,19 +1,3 @@
/*
* ### Start sticky footer ###
* Force the footer to always stay on the bottom of the page regardless of how
* little content is on the page.
*/
body {
display: flex;
min-height: 100vh;
flex-direction: column;
}
main {
flex: 1 0 auto;
}
/* ### End sticky footer ### */
/* add custom bold class */
.bold {
font-weight: bold;

View File

@ -4,12 +4,8 @@
*/
var nopaque = {};
// nopaque ressources
nopaque.socket = undefined;
// User data
nopaque.user = {};
nopaque.user.isAuthenticated = undefined;
nopaque.user.settings = {};
nopaque.user.settings.darkMode = undefined;
nopaque.corporaSubscribers = [];
@ -25,14 +21,10 @@ nopaque.foreignCorporaSubscribers = [];
nopaque.foreignJobsSubscribers = [];
nopaque.foreignQueryResultsSubscribers = [];
nopaque.flashedMessages = undefined;
// nopaque functions
nopaque.socket = {};
nopaque.socket.init = function() {
nopaque.socket = io({transports: ['websocket']});
// Add event handlers
nopaque.socket.on("user_data_stream_init", function(msg) {
nopaque.socket = io({transports: ['websocket']});
// Add event handlers
nopaque.socket.on("user_data_stream_init", function(msg) {
nopaque.user = JSON.parse(msg);
for (let subscriber of nopaque.corporaSubscribers) {
subscriber._init(nopaque.user.corpora);
@ -43,9 +35,9 @@ nopaque.socket.init = function() {
for (let subscriber of nopaque.queryResultsSubscribers) {
subscriber._init(nopaque.user.query_results);
}
});
});
nopaque.socket.on("user_data_stream_update", function(msg) {
nopaque.socket.on("user_data_stream_update", function(msg) {
var patch;
patch = JSON.parse(msg);
@ -72,9 +64,9 @@ nopaque.socket.init = function() {
}
}
}
});
});
nopaque.socket.on("foreign_user_data_stream_init", function(msg) {
nopaque.socket.on("foreign_user_data_stream_init", function(msg) {
nopaque.foreignUser = JSON.parse(msg);
for (let subscriber of nopaque.foreignCorporaSubscribers) {
subscriber._init(nopaque.foreignUser.corpora);
@ -85,9 +77,9 @@ nopaque.socket.init = function() {
for (let subscriber of nopaque.foreignQueryResultsSubscribers) {
subscriber._init(nopaque.foreignUser.query_results);
}
});
});
nopaque.socket.on("foreign_user_data_stream_update", function(msg) {
nopaque.socket.on("foreign_user_data_stream_update", function(msg) {
var patch;
patch = JSON.parse(msg);
@ -98,8 +90,7 @@ nopaque.socket.init = function() {
for (let subscriber of nopaque.foreignCorporaSubscribers) {subscriber._update(corpora_patch);}
for (let subscriber of nopaque.foreignJobsSubscribers) {subscriber._update(jobs_patch);}
for (let subscriber of nopaque.foreignQueryResultsSubscribers) {subscriber._update(query_results_patch);}
});
}
});
nopaque.Forms = {};
nopaque.Forms.init = function() {
@ -173,32 +164,10 @@ nopaque.Forms.init = function() {
}
}
nopaque.Navigation = {};
nopaque.Navigation.init = function() {
/* ### Initialize sidenav-main ### */
for (let entry of document.querySelectorAll("#sidenav-main a")) {
if (entry.href === window.location.href) {
entry.parentNode.classList.add("active");
}
}
}
nopaque.flash = function() {
var classes, toast, toastActionElement;
switch (arguments.length) {
case 1:
category = "message";
message = arguments[0];
break;
case 2:
message = arguments[0];
category = arguments[1];
break;
default:
console.error("Usage: nopaque.flash(message) or nopaque.flash(message, category)")
}
nopaque.flash = function(message, category) {
let toast;
let toastActionElement;
switch (category) {
case "corpus":
@ -219,27 +188,5 @@ nopaque.flash = function() {
<i class="material-icons">close</i>
</button>`});
toastActionElement = toast.el.querySelector('.toast-action[data-action="close"]');
if (toastActionElement) {
toastActionElement.addEventListener('click', function() {
toast.dismiss();
});
}
toastActionElement.addEventListener('click', () => {toast.dismiss();});
}
document.addEventListener('DOMContentLoaded', () => {
// Disable all option elements with no value
for (let optionElement of document.querySelectorAll('option[value=""]')) {
optionElement.disabled = true;
}
M.AutoInit();
M.CharacterCounter.init(document.querySelectorAll('input[data-length][type="text"]'));
M.Dropdown.init(document.querySelectorAll('#nav-notifications, #nav-account'),
{alignment: 'right', constrainWidth: false, coverTrigger: false});
nopaque.Forms.init();
nopaque.Navigation.init();
while (nopaque.flashedMessages.length) {
flashedMessage = nopaque.flashedMessages.shift();
nopaque.flash(flashedMessage[1], flashedMessage[0]);
}
});

View File

@ -0,0 +1,19 @@
{% set colors = {'primary': '#00426f',
'secondary': '#b1b3b4',
'corpus_analysis': '#aa9cc9',
'corpus_analysis_darken': '#6b3f89',
'corpus_analysis_lighten': '#ebe8f6',
'file_setup': '#d5dc95',
'file_setup_darken': '#a1b300',
'file_setup_lighten': '#f2f3e1',
'nlp': '#98acd2',
'nlp_darken': '#0064a3',
'nlp_lighten': '#e5e8f5',
'ocr': '#a9d8c8',
'ocr_darken': '#00a58b',
'ocr_lighten': '#e7f4f1'} %}
{% if main_class is not defined %}
{% set main_class = 'grey lighten-5' %}
{% endif %}

View File

@ -1,8 +1,8 @@
{% extends "nopaque.html.j2" %}
{% import 'materialize/wtf.html.j2' as wtf %}
{% set headline = ' ' %}
{% block page_content %}
{% block styles %}
{{ super() }}
<style>
main {
background-image: url("{{ url_for('static', filename='images/parallax_lq/04_german_text_book_paper.jpg') }}");
@ -10,39 +10,45 @@
background-size: cover;
}
</style>
{% endblock styles %}
<div class="col s12 m4">
{% block page_content %}
<div class="container">
<div class="row">
<div class="col s12 m4">
<div class="card medium">
<div class="card-content">
<h2>Log in</h2>
<h1>{{ title }}</h1>
<p>Want to boost your research and get going? nopaque is free and no download is needed. Register now!</p>
</div>
<div class="card-action right-align">
<a class="btn" href="{{ url_for('auth.register') }}"><i class="material-icons left">person_add</i>Register</a>
<a class="btn" href="{{ url_for('.register') }}"><i class="material-icons left">person_add</i>Register</a>
</div>
</div>
</div>
</div>
<div class="col s12 m8">
<div class="col s12 m8">
<div class="card medium">
<form method="POST">
<div class="card-content">
{{ login_form.hidden_tag() }}
{{ M.render_field(login_form.user, material_icon='person') }}
{{ M.render_field(login_form.password, material_icon='vpn_key') }}
{{ wtf.render_field(login_form.user, material_icon='person') }}
{{ wtf.render_field(login_form.password, material_icon='vpn_key') }}
<div class="row" style="margin-bottom: 0;">
<div class="col s6 left-align">
<a href="{{ url_for('auth.reset_password_request') }}">Forgot your password?</a>
<a href="{{ url_for('.reset_password_request') }}">Forgot your password?</a>
</div>
<div class="col s6 right-align">
{{ M.render_field(login_form.remember_me) }}
{{ wtf.render_field(login_form.remember_me) }}
</div>
</div>
</div>
<div class="card-action right-align">
{{ M.render_field(login_form.submit, material_icon='send') }}
{{ wtf.render_field(login_form.submit, material_icon='send') }}
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,8 +1,8 @@
{% extends "nopaque.html.j2" %}
{% import 'materialize/wtf.html.j2' as wtf %}
{% set headline = ' ' %}
{% block page_content %}
{% block styles %}
{{ super() }}
<style>
main {
background-image: url("{{ url_for('static', filename='images/parallax_lq/02_concept_document_focus_letter.jpg') }}");
@ -10,32 +10,38 @@
background-size: cover;
}
</style>
{% endblock styles %}
<div class="col s12 m4">
{% block page_content %}
<div class="container">
<div class="row">
<div class="col s12 m4">
<div class="card medium">
<div class="card-content">
<h2>Register</h2>
<h1>Register</h1>
<p>Simply enter a username and password to receive your registration email. After that you can start right away.</p>
<p>It goes without saying that the <a href="{{ url_for('main.privacy_policy') }}">General Data Protection Regulation</a> applies, only necessary data is stored.</p>
<p>Please also read our <a href="{{ url_for('main.terms_of_use') }}">terms of use</a> before signing up for nopaque!</p>
</div>
</div>
</div>
</div>
<div class="col s12 m8">
<div class="col s12 m8">
<div class="card medium">
<form method="POST">
<div class="card-content">
{{ registration_form.hidden_tag() }}
{{ M.render_field(registration_form.username, data_length='64', material_icon='person') }}
{{ M.render_field(registration_form.password, data_length='128', material_icon='vpn_key') }}
{{ M.render_field(registration_form.password_confirmation, data_length='128', material_icon='vpn_key') }}
{{ M.render_field(registration_form.email, class_='validate', material_icon='email', type='email') }}
{{ wtf.render_field(registration_form.username, data_length='64', material_icon='person') }}
{{ wtf.render_field(registration_form.password, data_length='128', material_icon='vpn_key') }}
{{ wtf.render_field(registration_form.password_confirmation, data_length='128', material_icon='vpn_key') }}
{{ wtf.render_field(registration_form.email, class_='validate', material_icon='email', type='email') }}
</div>
<div class="card-action right-align">
{{ M.render_field(registration_form.submit, material_icon='send') }}
{{ wtf.render_field(registration_form.submit, material_icon='send') }}
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,23 +1,31 @@
{% extends "nopaque.html.j2" %}
{% import 'materialize/wtf.html.j2' as wtf %}
{% block page_content %}
<div class="col s12 m4">
<h3>Lorem ipsum</h3>
<p>dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren,</p>
</div>
<div class="container">
<div class="row">
<div class="col s12">
<h1>{{ title }}</h1>
</div>
<div class="col s12 m8">
<div class="col s12 m4">
<p>dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren,</p>
</div>
<div class="col s12 m8">
<div class="card">
<form method="POST">
<div class="card-content">
{{ reset_password_form.hidden_tag() }}
{{ M.render_field(reset_password_form.password, data_length='128') }}
{{ M.render_field(reset_password_form.password_confirmation, data_length='128') }}
{{ wtf.render_field(reset_password_form.password, data_length='128') }}
{{ wtf.render_field(reset_password_form.password_confirmation, data_length='128') }}
</div>
<div class="card-action right-align">
{{ M.render_field(reset_password_form.submit, material_icon='send') }}
{{ wtf.render_field(reset_password_form.submit, material_icon='send') }}
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,21 +1,30 @@
{% extends "nopaque.html.j2" %}
{% import 'materialize/wtf.html.j2' as wtf %}
{% block page_content %}
<div class="col s12 m4">
<p>After entering your email address you will receive instructions on how to reset your password.</p>
</div>
<div class="container">
<div class="row">
<div class="col s12">
<h1>{{ title }}</h1>
</div>
<div class="col s12 m8">
<div class="col s12 m4">
<p>After entering your email address you will receive instructions on how to reset your password.</p>
</div>
<div class="col s12 m8">
<div class="card">
<form method="POST">
<div class="card-content">
{{ reset_password_request_form.hidden_tag() }}
{{ M.render_field(reset_password_request_form.email, class_='validate', material_icon='email', type='email') }}
{{ wtf.render_field(reset_password_request_form.email, class_='validate', material_icon='email', type='email') }}
</div>
<div class="card-action right-align">
{{ M.render_field(reset_password_request_form.submit, material_icon='send') }}
{{ wtf.render_field(reset_password_request_form.submit, material_icon='send') }}
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,20 +1,25 @@
{% extends "nopaque.html.j2" %}
{% block title %}Opaque - Confirm your account{% endblock %}
{% block page_content %}
<div class="page-header">
<h1>
Hello, {{ current_user.username }}!
</h1>
<h3>You have not confirmed your account yet.</h3>
<p>
Before you can access this site you need to confirm your account.
Check your inbox, you should have received an email with a confirmation link.
</p>
<p>
Need another confirmation email?
<a href="{{ url_for('auth.resend_confirmation') }}">Click here</a>
</p>
<div class="container">
<div class="row">
<div class="col s12">
<h1>{{ title }}</h1>
</div>
<div class="col s12">
<div class="card">
<div class="card-content">
<span class="card-title">Hello, {{ current_user.username }}!</span>
<p><b>You have not confirmed your account yet.</b></p>
<p>Before you can access this site you need to confirm your account. Check your inbox, you should have received an email with a confirmation link.</p>
<p>Need another confirmation email? <a href="{{ url_for('.resend_confirmation') }}">Click here</a></p>
</div>
<div class="card-action right-align">
<a class="btn" href="{{ url_for('.register') }}"><i class="material-icons left">person_add</i>Register</a>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,8 +1,13 @@
{% extends "nopaque.html.j2" %}
{% block page_content %}
<div class="container">
<div class="row">
<div class="col s12">
<h1>{{ title }}</h1>
</div>
<div class="col s12">
<div class="col s12">
<div class="card">
<div class="card-content">
<span class="card-title">What is nopaque</span>
@ -26,9 +31,9 @@
</p>
</div>
</div>
</div>
</div>
<div class="col s12">
<div class="col s12">
<ul class="collapsible">
<li>
<div class="collapsible-header">1. Who is developing nopaque?</div>
@ -254,6 +259,7 @@
</div>
</li>
</ul>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,7 +1,13 @@
{% extends "nopaque.html.j2" %}
{% block page_content %}
<div class="col s12">
<div class="container">
<div class="row">
<div class="col s12">
<h1>{{ title }}</h1>
</div>
<div class="col s12">
<h3>My Corpora and Query results</h3>
<p>Create a corpus to interactively perform linguistic analysis or import query results to save interesting passages.</p>
<div class="row">
@ -81,9 +87,9 @@
</div>
</div>
</div>
</div>
</div>
<div class="col s12" id="jobs">
<div class="col s12" id="jobs">
<h3>My Jobs</h3>
<p>A job is the execution of a service provided by nopaque. You can create any number of jobs and let them be processed simultaneously.</p>
<div class="card">
@ -160,12 +166,17 @@
<a href="#!" class="modal-close waves-effect waves-light btn-flat">Close</a>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
{{ super() }}
<script type="module">
import {RessourceList} from '../../static/js/nopaque.lists.js';
let corpusList = new RessourceList("corpora", nopaque.corporaSubscribers, "Corpus");
let jobList = new RessourceList("jobs", nopaque.jobsSubscribers, "Job");
let queryResultList = new RessourceList("query-results", nopaque.queryResultsSubscribers, "QueryResult");
</script>
{% endblock %}
{% endblock scripts %}

View File

@ -1,6 +1,5 @@
{% extends "nopaque.html.j2" %}
{% set parallax = True %}
{% import 'materialize/wtf.html.j2' as wtf %}
{% block page_content %}
<div class="section white">
@ -157,19 +156,19 @@
<div class="card-content">
<span class="card-title">Log in</span>
{{ login_form.hidden_tag() }}
{{ M.render_field(login_form.user, material_icon='person') }}
{{ M.render_field(login_form.password, material_icon='vpn_key') }}
{{ wtf.render_field(login_form.user, material_icon='person') }}
{{ wtf.render_field(login_form.password, material_icon='vpn_key') }}
<div class="row" style="margin-bottom: 0;">
<div class="col s6 left-align">
<a href="{{ url_for('auth.reset_password_request') }}">Forgot your password?</a>
</div>
<div class="col s6 right-align">
{{ M.render_field(login_form.remember_me) }}
{{ wtf.render_field(login_form.remember_me) }}
</div>
</div>
</div>
<div class="card-action right-align">
{{ M.render_field(login_form.submit, material_icon='send') }}
{{ wtf.render_field(login_form.submit, material_icon='send') }}
</div>
</form>
</div>

View File

@ -1,7 +1,12 @@
{% extends "nopaque.html.j2" %}
{% block page_content %}
<div class="col s12">
<div class="container">
<div class="row">
<div class="col s12">
<h1>{{ title }}</h1>
</div>
<div class="col s12">
<div class="card" id="beta-launch">
<div class="card-content">
<span class="card-title">nopaque's beta launch</span>
@ -11,5 +16,7 @@
<p>We are happy to help you with any issues and will use the feedback to fix all mentioned bugs!</p>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,11 +1,17 @@
{% extends "nopaque.html.j2" %}
{% block page_content %}
<div class="col s12">
<p>With these data protection notices, Bielefeld University fulfils its obligation to provide information in accordance with Articles 13 & 14 of the EU General Data Protection Regulation (GDPR) on the above-mentioned processing of personal data. Terms such as "personal data", "processing", "data controller", "third party", etc. are used as defined in Article 4 GDPR.</p>
</div>
<div class="container">
<div class="row">
<div class="col s12">
<h1>{{ title }}</h1>
</div>
<div class="col s12">
<div class="col s12">
<p>With these data protection notices, Bielefeld University fulfils its obligation to provide information in accordance with Articles 13 & 14 of the EU General Data Protection Regulation (GDPR) on the above-mentioned processing of personal data. Terms such as "personal data", "processing", "data controller", "third party", etc. are used as defined in Article 4 GDPR.</p>
</div>
<div class="col s12">
<div class="card">
<div class="card-content">
<span class="card-title">§ 1 Contact Details</span>
@ -44,9 +50,9 @@
</ul>
</div>
</div>
</div>
</div>
<div class="col s12">
<div class="col s12">
<div class="card">
<div class="card-content">
<span class="card-title">§ 2 General information on data processing and its purpose</span>
@ -86,9 +92,9 @@
<p>According to § 4 paragraph 2 of the General Terms of Use for the use of NOPAQUE at Bielefeld University, the users themselves are responsible for the content they post and must comply with the legal provisions of data protection. This includes in particular the deletion of personal data that may no longer be processed.</p>
</div>
</div>
</div>
</div>
<div class="col s12">
<div class="col s12">
<div class="card">
<div class="card-content">
<span class="card-title">§ 3 Legal basis of the data processing</span>
@ -96,9 +102,9 @@
<p>The collection of personal data for user authentication is based on the consent of the data subjects as stated in <b>Article 6 (1) letter a GDPR</b>. The legal basis for the transmission of personal data is <b>Article 6 (1) letter c GDPR</b>.</p>
</div>
</div>
</div>
</div>
<div class="col s12">
<div class="col s12">
<div class="card">
<div class="card-content">
<span class="card-title">§ 4 Data transmissions</span>
@ -106,18 +112,18 @@
<p>In individual cases, data may also be legally transmitted to third parties, for example, to law enforcement authorities for the investigation of criminal offences within the framework of the <b>Code of Criminal Procedure (StPO)</b>. If technical service providers are given access to personal data, this is done on the basis of a contract in accordance with <b>Article 28 GDPR</b>.</p>
</div>
</div>
</div>
</div>
<div class="col s12">
<div class="col s12">
<div class="card">
<div class="card-content">
<span class="card-title">§ 5 Duration of processing / data deletion</span>
<p>Data processed for user authentication are deleted immediately after account deletion.</p>
</div>
</div>
</div>
</div>
<div class="col s12">
<div class="col s12">
<div class="card">
<div class="card-content">
<span class="card-title">§ 6 Your rights as a data subject</span>
@ -142,6 +148,7 @@
</ul>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,21 +1,26 @@
{% extends "nopaque.html.j2" %}
{% block page_content %}
<div class="container">
<div class="row">
<div class="col s12">
<h1>{{ title }}</h1>
</div>
<div class="col s12">
<div class="col s12">
<p>With the usage of the nopaque platform you declare your acceptance of the General Terms of Use and that you have taken note of the legal framework and the data protection declaration.</p>
</div>
</div>
<div class="col s12">
<div class="col s12">
<div class="card">
<div class="card-content">
<span class="card-title">§ 1 Scope</span>
<p>The General Terms of Use for the nopaque platform apply to everyone who uses the system as an authorised user in the sense of <b>§ 2</b> (1) of the General Terms of Use. By using the system and with your consent you accept these terms of use.</p>
</div>
</div>
</div>
</div>
<div class="col s12">
<div class="col s12">
<div class="card">
<div class="card-content">
<span class="card-title">§ 2 Right of use</span>
@ -30,9 +35,9 @@
<p>(3) The duration of the right of use ends with the deletion of the user account by the user (see <b>§ 7</b>)</p>
</div>
</div>
</div>
</div>
<div class="col s12">
<div class="col s12">
<div class="card">
<div class="card-content">
<span class="card-title">§ 3 Purpose of the Services</span>
@ -45,9 +50,9 @@
<p>On nopaque, a contact form is available. As far as possible the SFB 1288 INF staff will try to provide user support.</p>
</div>
</div>
</div>
</div>
<div class="col s12">
<div class="col s12">
<div class="card">
<div class="card-content">
<span class="card-title">§ 4 Obligations of the User</span>
@ -69,9 +74,9 @@
<p>The user is obliged to indemnify Bielefeld University against all claims by third parties based on the data stored by him/her and to reimburse Bielefeld University for any costs incurred as a result of possible legal infringements. This also includes the costs incurred by Bielefeld University for extrajudicial and judicial defense against these claims.</p>
</div>
</div>
</div>
</div>
<div class="col s12">
<div class="col s12">
<div class="card">
<div class="card-content">
<span class="card-title">§ 5 Liability of Bielefeld University</span>
@ -80,18 +85,18 @@
<p>nopaque is available in accordance with normal operational care based on the "Best Effort" practice. No liability is assumed for the consequences of failures or errors of the nopaque platform. Bielefeld University does not guarantee that the systems will run error-free and without interruption at all times. Bielefeld University accepts no responsibility for technical quality. Nor is it liable for the content, in particular for the accuracy, completeness, and timeliness of information to which it merely provides access for use.</p>
</div>
</div>
</div>
</div>
<div class="col s12">
<div class="col s12">
<div class="card">
<div class="card-content">
<span class="card-title">§ 6 Data Protection</span>
<p>Information on the handling of personal data during the operation of the service can be found in the separate data protection policy.</p>
</div>
</div>
</div>
</div>
<div class="col s12">
<div class="col s12">
<div class="card">
<div class="card-content">
<span class="card-title">§ 7 Duration and Termination</span>
@ -100,6 +105,7 @@
<p>Bielefeld University may exclude the user from using the service without notice for an important reason. Important reasons include, in particular, repeated violations of the provisions of these Terms of Use or of applicable laws.</p>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,35 @@
{% block doc %}
<!DOCTYPE html>
<html{% block html_attribs %}{% endblock html_attribs %}>
{% block html %}
<head>
{% block head %}
<title>{% block title %}{{title|default}}{% endblock title %}</title>
{% block metas %}
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{% endblock metas %}
{% block styles %}
<link href="{{ url_for('static', filename='css/material_design_icons.min.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='css/materialize.min.css') }}" media="screen,projection" rel="stylesheet">
{% endblock styles %}
{% endblock head %}
</head>
<body{% block body_attribs %}{% endblock body_attribs %}>
{% block body %}
{% block navbar %}
{% endblock navbar %}
{% block sidenav %}
{% endblock sidenav %}
{% block content %}
{% endblock content %}
{% block scripts %}
<script src="{{ url_for('static', filename='js/materialize.min.js') }}"></script>
{% endblock scripts %}
{% endblock body %}
</body>
{% endblock html %}
</html>
{% endblock doc %}

View File

@ -0,0 +1,101 @@
{% macro render_field(field) %}
{% if field.type == 'BooleanField' %}
{{ render_boolean_field(field, *args, **kwargs) }}
{% elif field.type == 'DecimalRangeField' %}
{{ render_decimal_range_field(field, *args, **kwargs) }}
{% elif field.type == 'SubmitField' %}
{{ render_submit_field(field, *args, **kwargs) }}
{% elif field.type in ['FileField', 'MultipleFileField'] %}
{{ render_file_field(field, *args, **kwargs) }}
{% else %}
{% if 'class_' in kwargs and 'validate' not in kwargs['class_'] %}
{% set tmp = kwargs.update({'class_': kwargs['class_'] + ' validate'}) %}
{% else %}
{% set tmp = kwargs.update({'class_': 'validate'}) %}
{% endif %}
{{ render_generic_field(field, *args, **kwargs) }}
{% endif %}
{% endmacro %}
{% macro render_boolean_field(field) %}
{% set label = kwargs.pop('label', True) %}
<div class="switch">
{% if 'material_icon' in kwargs %}
<i class="material-icons prefix">{{ kwargs.pop('material_icon') }}</i>
{% endif %}
<label>
{{ field(*args, **kwargs) }}
<span class="lever"></span>
{% if label %}
{{ field.label.text }}
{% endif %}
</label>
{% for error in field.errors %}
<span class="helper-text red-text">{{ error }}</span>
{% endfor %}
</div>
{% endmacro %}
{% macro render_file_field(field) %}
{% set placeholder = kwargs.pop('placeholder', '') %}
<div class="file-field input-field">
<div class="btn">
<span>{{ field.label.text }}</span>
{{ field(*args, **kwargs) }}
</div>
<div class="file-path-wrapper">
<input class="file-path validate" type="text" placeholder="{{ placeholder }}">
</div>
{% for error in field.errors %}
<span class="helper-text red-text">{{ error }}</span>
{% endfor %}
</div>
{% endmacro %}
{% macro render_generic_field(field) %}
{% if field.type == 'TextAreaField' and 'materialize-textarea' not in kwargs['class_'] %}
{% set tmp = kwargs.update({'class_': kwargs['class_'] + ' materialize-textarea'}) %}
{% elif field.type == 'IntegerField' %}
{% set tmp = kwargs.update({'type': 'number'}) %}
{% endif %}
{% set label = kwargs.pop('label', True) %}
<div class="input-field">
{% if 'material_icon' in kwargs %}
<i class="material-icons prefix">{{ kwargs.pop('material_icon') }}</i>
{% endif %}
{{ field(*args, **kwargs) }}
{% if label %}
{{ field.label }}
{% endif %}
{% for error in field.errors %}
<span class="helper-text red-text">{{ error }}</span>
{% endfor %}
</div>
{% endmacro %}
{% macro render_submit_field(field) %}
{% if 'class_' in kwargs and 'btn' not in kwargs['class_'] %}
{% set tmp = kwargs.update({'class_': kwargs['class_'] + ' btn'}) %}
{% else %}
{% set tmp = kwargs.update({'class_': 'btn'}) %}
{% endif %}
{% if 'waves-effect' not in kwargs['class_'] %}
{% set tmp = kwargs.update({'class_': kwargs['class_'] + ' waves-effect'}) %}
{% endif %}
{% if 'waves-light' not in kwargs['class_'] %}
{% set tmp = kwargs.update({'class_': kwargs['class_'] + ' waves-light'}) %}
{% endif %}
<button class="{{ kwargs['class_'] }}"
id="{{ field.id }}"
name="{{ field.name }}"
type="submit"
value="{{ field.label.text }}"
{% if 'style' in kwargs %}
style="{{ kwargs.pop('style') }}"
{% endif %}>
{{ field.label.text }}
{% if 'material_icon' in kwargs %}
<i class="material-icons right">{{ kwargs.pop('material_icon') }}</i>
{% endif %}
</button>
{% endmacro %}

View File

@ -1,244 +1,152 @@
{% import "utils/macros.html.j2" as Macros %}
{% import "utils/materialize.html.j2" as M %}
{% extends "materialize/base.html.j2" %}
{% from '_variables.html.j2' import colors %}
{% block html_attribs %} lang="en"{% endblock html_attribs %}
{% if title is not defined %}
{% set title = None %}
{% block head %}
{{ super() }}
<link href="{{ url_for('static', filename='images/nopaque_-_favicon.png') }}" rel="icon">
{% endblock head %}
{% block metas %}
<meta charset="UTF-8">
{{ super() }}
{% endblock metas %}
{% block title %}{% if request.path != url_for('main.index') and title is defined %}{{title}} | {% endif %}nopaque{% endblock title %}
{% block styles %}
{{ super() }}
{% if current_user.is_authenticated %}
<link href="{{ url_for('static', filename='css/materialize.fix.sidenav-fixed.css') }}" media="screen,projection" rel="stylesheet">
{% endif %}
<link href="{{ url_for('static', filename='css/materialize.fix.sticky-footer.css') }}" media="screen,projection" rel="stylesheet">
<link href="{{ url_for('static', filename='css/nopaque.css') }}" media="screen,projection" rel="stylesheet">
<style>
.primary-color {background-color: {{ colors.primary }} !important;}
.primary-color-text {color: {{ colors.primary }} !important;}
.secondary-color {background-color: {{ colors.secondary }} !important;}
.secondary-color-text {color: {{ colors.secondary }} !important;}
{% if headline is not defined %}
{% set headline = title %}
{% endif %}
.corpus-analysis-color {background-color: {{ colors.corpus_analysis }} !important;}
.corpus-analysis-color-text {color: {{ colors.corpus_analysis }} !important;}
.corpus-analysis-color.darken {background-color: {{ colors.corpus_analysis_darken }} !important;}
.corpus-analysis-color-text.text-darken {color: {{ colors.corpus_analysis_darken }} !important;}
.corpus-analysis-color.lighten {background-color: {{ colors.corpus_analysis_lighten }} !important;}
.corpus-analysis-color-text.text-lighten {color: {{ colors.corpus_analysis_lighten }} !important;}
{% if parallax is not defined %}
{% set parallax = False %}
{% endif %}
.file-setup-color {background-color: {{ colors.file_setup }} !important;}
.file-setup-color-text {color: {{ colors.file_setup }} !important;}
.file-setup-color.darken {background-color: {{ colors.file_setup_darken }} !important;}
.file-setup-color-text.text-darken {color: {{ colors.file_setup_darken }} !important;}
.file-setup-color.lighten {background-color: {{ colors.file_setup_lighten }} !important;}
.file-setup-color-text.text-lighten {color: {{ colors.file_setup_lighten }} !important;}
{% if main_class is not defined %}
{% set main_class = 'grey lighten-5' %}
{% endif %}
.ocr-color {background-color: {{ colors.ocr }} !important;}
.ocr-color-text {color: {{ colors.ocr }} !important;}
.ocr-color.darken {background-color: {{ colors.ocr_darken }} !important;}
.ocr-color-text.text-darken {color: {{ colors.ocr_darken }} !important;}
.ocr-color.lighten {background-color: {{ colors.ocr_lighten }} !important;}
.ocr-color-text.text-lighten {color: {{ colors.ocr_lighten }} !important;}
{% set primary_color = '#00426f' %}
{% set secondary_color = '#b1b3b4' %}
.nlp-color {background-color: {{ colors.nlp }} !important;}
.nlp-color-text {color: {{ colors.nlp }} !important;}
.nlp-color.darken {background-color: {{ colors.nlp_darken }} !important;}
.nlp-color-text.text-darken {color: {{ colors.nlp_darken }} !important;}
.nlp-color.lighten {background-color: {{ colors.nlp_lighten }} !important;}
.nlp-color-text.text-lighten {color: {{ colors.nlp_lighten }} !important;}
{% set corpus_analysis_color = '#aa9cc9' %}
{% set corpus_analysis_color_darken = '#6b3f89' %}
{% set corpus_analysis_color_lighten = '#ebe8f6' %}
{% set file_setup_color = '#d5dc95' %}
{% set file_setup_color_darken = '#a1b300' %}
{% set file_setup_color_lighten = '#f2f3e1' %}
{% set nlp_color = '#98acd2' %}
{% set nlp_color_darken = '#0064a3' %}
{% set nlp_color_lighten = '#e5e8f5' %}
{% set ocr_color = '#a9d8c8' %}
{% set ocr_color_darken = '#00a58b' %}
{% set ocr_color_lighten = '#e7f4f1' %}
{%- macro insert_content() -%}
{% block page_content %}{% endblock %}
{%- endmacro -%}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="theme-color" content="#ee6e73">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
nopaque
{% if request.path != url_for('main.index') %} {{ title }}{% endif %}
</title>
<link rel="icon" href="{{ url_for('static', filename='images/nopaque_-_favicon.png') }}">
<!--Import Google Icon Font-->
<link rel="stylesheet" href="{{ url_for('static', filename='css/material_design_icons.min.css') }}">
<!--Import materialize.css-->
<link rel="stylesheet" href="{{ url_for('static', filename='css/materialize.min.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/nopaque.css') }}">
<style>
.primary-color {background-color: {{ primary_color }} !important;}
.primary-color-text {color: {{ primary_color }} !important;}
.secondary-color {background-color: {{ secondary_color }} !important;}
.secondary-color-text {color: {{ secondary_color }} !important;}
.corpus-analysis-color {background-color: {{ corpus_analysis_color }} !important;}
.corpus-analysis-color-text {color: {{ corpus_analysis_color }} !important;}
.corpus-analysis-color.darken {background-color: {{ corpus_analysis_color_darken }} !important;}
.corpus-analysis-color-text.text-darken {color: {{ corpus_analysis_color_darken }} !important;}
.corpus-analysis-color.lighten {background-color: {{ corpus_analysis_color_lighten }} !important;}
.corpus-analysis-color-text.text-lighten {color: {{ corpus_analysis_color_lighten }} !important;}
.file-setup-color {background-color: {{ file_setup_color }} !important;}
.file-setup-color-text {color: {{ file_setup_color }} !important;}
.file-setup-color.darken {background-color: {{ file_setup_color_darken }} !important;}
.file-setup-color-text.text-darken {color: {{ file_setup_color_darken }} !important;}
.file-setup-color.lighten {background-color: {{ file_setup_color_lighten }} !important;}
.file-setup-color-text.text-lighten {color: {{ file_setup_color_lighten }} !important;}
.ocr-color {background-color: {{ ocr_color }} !important;}
.ocr-color-text {color: {{ ocr_color }} !important;}
.ocr-color.darken {background-color: {{ ocr_color_darken }} !important;}
.ocr-color-text.text-darken {color: {{ ocr_color_darken }} !important;}
.ocr-color.lighten {background-color: {{ ocr_color_lighten }} !important;}
.ocr-color-text.text-lighten {color: {{ ocr_color_lighten }} !important;}
.nlp-color {background-color: {{ nlp_color }} !important;}
.nlp-color-text {color: {{ nlp_color }} !important;}
.nlp-color.darken {background-color: {{ nlp_color_darken }} !important;}
.nlp-color-text.text-darken {color: {{ nlp_color_darken }} !important;}
.nlp-color.lighten {background-color: {{ nlp_color_lighten }} !important;}
.nlp-color-text.text-lighten {color: {{ nlp_color_lighten }} !important;}
.pagination li.active {background-color: {{ primary_color }};}
.table-of-contents a.active {border-color: {{ primary_color }};}
.pagination li.active {background-color: {{ colors.primary }};}
.table-of-contents a.active {border-color: {{ colors.primary }};}
.tabs .tab a {color: inherit; /* Custom Text Color */}
.tabs .tab a:hover {color: {{ primary_color }}; /* Custom Color On Hover */}
.tabs .tab a:hover {color: {{ colors.primary }}; /* Custom Color On Hover */}
.tabs .tab a.active, .tabs .tab a:focus.active {
color: {{ primary_color }}; /* Custom Text Color While Active */
background-color: {{ primary_color }}28; /* Custom Background Color While Active */
color: {{ colors.primary }}; /* Custom Text Color While Active */
background-color: {{ colors.primary }}28; /* Custom Background Color While Active */
}
.tabs .indicator {background-color: {{ primary_color }}; /* Custom Color Of Indicator */}
{% if current_user.is_authenticated %}
/*
* ### Start sidenav-fixed offset ###
* The sidenav-fixed class is used which causes the sidenav to be fixed and open
* on large screens and hides to the regular functionality on smaller screens.
* In order to prevent the sidenav to overlap the content, the content (in our
* case header, main and footer) gets an offset equal to the width of the
* sidenav.
*/
@media only screen and (min-width : 993px) {
header, main, footer {padding-left: 300px;}
.modal:not(.bottom-sheet) {left: 300px;}
.navbar-fixed > nav {width: calc(100% - 300px)}
}
/* ### End sidenav-fixed offset ### */
{% endif %}
</style>
</head>
<body>
<header>
.tabs .indicator {background-color: {{ colors.primary }}; /* Custom Color Of Indicator */}
</style>
{% endblock styles %}
{% block navbar %}
<header>
<div class="navbar-fixed">
<nav class="nav-extended primary-color white-text">
<div class="nav-wrapper">
<nav class="nav-extended">
<div class="nav-wrapper primary-color">
{% if current_user.is_authenticated %}
<a href="#" data-target="sidenav" class="sidenav-trigger"><i class="material-icons">menu</i></a>
{% endif %}
<a href="{{ url_for('main.index') }}" class="brand-logo hide-on-med-and-down" style="height: 100%; overflow: hidden;"><img src="{{ url_for('static', filename='images/nopaque_-_logo_name_slogan.svg') }}" style="height: 128px; margin-top: -32px;"></a>
<a href="{{ url_for('main.index') }}" class="brand-logo hide-on-large-only" style="height: 100%; overflow: hidden;"><img src="{{ url_for('static', filename='images/nopaque_-_logo.svg') }}" style="height: 128px; margin-top: -32px;"></a>
{% if current_user.is_authenticated %}
<a href="#" data-target="sidenav-main" class="sidenav-trigger"><i class="material-icons">menu</i></a>
{% endif %}
<ul class="right">
{% if current_user.is_authenticated %}
<li>
<a id="nav-notifications" class="dropdown-trigger no-autoinit" href="{{ url_for('main.news') }}" data-target="nav-notifications-dropdown">
<span class="hide-on-small-only">News</span>
<i class="material-icons right">notifications</i>
</a>
</li>
{% endif %}
<li>
<a id="nav-account" class="dropdown-trigger no-autoinit" href="#!" data-target="nav-account-dropdown">
{% if current_user.is_authenticated %}
<span class="hide-on-small-only">{{ current_user.username }}</span><i class="material-icons right">account_circle</i>
<ul class="right hide-on-med-and-down">
<li{% if request.path == url_for('main.news') %} class="active"{% endif %}><a href="{{ url_for('main.news') }}"><i class="material-icons left">notifications</i>News</a></li>
{% if current_user.is_anonymous %}
<li{% if request.path == url_for('auth.register') %} class="active"{% endif %}><a href="{{ url_for('auth.register') }}"><i class="material-icons left">assignment</i>Register</a></li>
<li{% if request.path == url_for('auth.login') %} class="active"{% endif %}><a href="{{ url_for('auth.login') }}"><i class="material-icons left">login</i>Log in</a></li>
{% else %}
<i class="material-icons">account_circle</i>
<li{% if request.path == url_for('main.dashboard', _anchor='corpora') %} class="active"{% endif %}><a href="{{ url_for('main.dashboard', _anchor='corpora') }}"><i class="material-icons left">book</i>My Corpora</a></li>
<li{% if request.path == url_for('main.dashboard', _anchor='jobs') %} class="active"{% endif %}><a href="{{ url_for('main.dashboard', _anchor='jobs') }}"><i class="material-icons left">work</i>My Jobs</a></li>
<li><a class="dropdown-trigger no-autoinit" data-target="nav-more-dropdown" href="#!" id="nav-more-dropdown-trigger"><i class="material-icons">more_vert</i></a></li>
{% endif %}
</a>
</li>
</ul>
</div>
<div class="nav-content">
<noscript>
<div class="card z-depth-0" style="background-color: inherit;">
<div class="card-content">
<span class="card-title">JavaScript is disabled</span>
<p>
You have JavaScript disabled. Nopaque uses javascript and
sockets to send data in realtime to you. For example showing
you the status of your jobs and your corpora.
Please activate JavaScript to make full use of nopaque.</p>
<p>Some services are still useable without Javascript.</p>
</div>
<div class="card-action">
<a href="#">What services can I still use?</a>
<a href="#">What services and functions are not available?</a>
</div>
</div>
</noscript>
<div class="nav-content secondary-color">
{% block nav_content %}{% endblock nav_content %}
</div>
</nav>
</div>
<!-- Dropdown menus for the navbar -->
<div id="nav-notifications-dropdown" class="dropdown-content">
<li>
<a href="{{ url_for('main.news', _anchor='beta-launch') }}"><i class="material-icons">error_outline</i>nopaque's beta launch</a>
</li>
</div>
<ul id="nav-account-dropdown" class="dropdown-content">
{% if current_user.is_authenticated %}
<li><a href="{{ url_for('profile.settings') }}"><i class="material-icons">settings</i>Settings</a></li>
<li><a href="{{ url_for('auth.logout') }}"><i class="material-icons">power_settings_new</i>Log out</a></li>
{% else %}
<li><a href="{{ url_for('auth.login') }}"><i class="material-icons">login</i>Log in</a></li>
<li><a href="{{ url_for('auth.register') }}"><i class="material-icons">assignment</i>Register</a></li>
{% endif %}
<ul class="dropdown-content" id="nav-more-dropdown">
<li><a href="{{ url_for('profile.settings') }}"><i class="material-icons left">settings</i>Settings</a></li>
<li class="divider" tabindex="-1"></li>
<li><a href="{{ url_for('auth.logout') }}">Log out</a></li>
</ul>
{% endif %}
</header>
{% endblock navbar %}
<ul id="sidenav-main" class="sidenav sidenav-fixed{% if not current_user.is_authenticated %} hide{% endif %}">
<li><a href="{{ url_for('main.index') }}"><i class="material-icons">opacity</i>nopaque</a></li>
{% block sidenav %}
<ul class="sidenav sidenav-fixed{% if not current_user.is_authenticated %} hide{% endif %}" id="sidenav">
{% if current_user.is_authenticated %}
<li>
<div class="user-view">
<div class="background primary-color"></div>
<span class="white-text name">{{ current_user.username }}</span>
<span class="white-text email">{{ current_user.email }}</span>
</div>
</li>
<li><a href="#"><i class="material-icons">linear_scale</i>Workflow</a></li>
<li><a href="{{ url_for('main.dashboard') }}"><i class="material-icons">dashboard</i>Dashboard</a></li>
<li><a href="{{ url_for('main.dashboard', _anchor='corpora') }}" style="padding-left: 47px;"><i class="material-icons">book</i>My Corpora</a></li>
<li><a href="{{ url_for('main.dashboard', _anchor='jobs') }}" style="padding-left: 47px;"><i class="material-icons">work</i>My Jobs</a></li>
<li><div class="divider"></div></li>
<li><a class="subheader">Processes & Services</a></li>
<li style="background-color: {{ file_setup_color }}; border-left: 10px solid {{ file_setup_color_darken }};"><a href="{{ url_for('services.service', service='file-setup') }}"><i class="material-icons">burst_mode</i>File setup</a></li>
<li style="background-color: {{ ocr_color }}; border-left: 10px solid {{ ocr_color_darken }}; margin-top: 5px;"><a href="{{ url_for('services.service', service='ocr') }}"><i class="material-icons">find_in_page</i>OCR</a></li>
<li style="background-color: {{ nlp_color }}; border-left: 10px solid {{ nlp_color_darken }}; margin-top: 5px;"><a href="{{ url_for('services.service', service='nlp') }}"><i class="material-icons">format_textdirection_l_to_r</i>NLP</a></li>
<li style="background-color: {{ corpus_analysis_color }}; border-left: 10px solid {{ corpus_analysis_color_darken }}; margin-top: 5px;"><a href="{{ url_for('services.service', service='corpus_analysis') }}"><i class="material-icons">search</i>Corpus analysis</a></li>
<li><div class="divider"></div></li>
<li><a class="subheader">Account</a></li>
{% if current_user.is_authenticated %}
<li><a href="{{ url_for('profile.settings') }}"><i class="material-icons">settings</i>Settings</a></li>
<li><a href="{{ url_for('auth.logout') }}"><i class="material-icons">power_settings_new</i>Log out</a></li>
<li style="background-color: {{ colors.file_setup }}; border-left: 10px solid {{ colors.file_setup_darken }};"><a href="{{ url_for('services.service', service='file-setup') }}"><i class="material-icons">burst_mode</i>File setup</a></li>
<li style="background-color: {{ colors.ocr }}; border-left: 10px solid {{ colors.ocr_darken }}; margin-top: 5px;"><a href="{{ url_for('services.service', service='ocr') }}"><i class="material-icons">find_in_page</i>OCR</a></li>
<li style="background-color: {{ colors.nlp }}; border-left: 10px solid {{ colors.nlp_darken }}; margin-top: 5px;"><a href="{{ url_for('services.service', service='nlp') }}"><i class="material-icons">format_textdirection_l_to_r</i>NLP</a></li>
<li style="background-color: {{ colors.corpus_analysis }}; border-left: 10px solid {{ colors.corpus_analysis_darken }}; margin-top: 5px;"><a href="{{ url_for('services.service', service='corpus_analysis') }}"><i class="material-icons">search</i>Corpus analysis</a></li>
<li class="hide-on-large-only"><div class="divider"></div></li>
<li class="hide-on-large-only"><a href="{{ url_for('profile.settings') }}"><i class="material-icons">settings</i>Settings</a></li>
<li class="hide-on-large-only"><a href="{{ url_for('auth.logout') }}">Log out</a></li>
{% else %}
<li><a href="{{ url_for('auth.login') }}"><i class="material-icons">person</i>Log in</a></li>
<li><a href="{{ url_for('auth.register') }}"><i class="material-icons">person_add</i>Register</a></li>
<li class="hide-on-large-only"><a href="{{ url_for('auth.register') }}"><i class="material-icons">assignment</i>Register</a></li>
<li class="hide-on-large-only"><a href="{{ url_for('auth.login') }}"><i class="material-icons">login</i>Log in</a></li>
{% endif %}
{% if current_user.is_administrator() %}
<li><div class="divider"></div></li>
<li><a class="subheader">Administration</a></li>
<li><a href="{{ url_for('admin.index') }}"><i class="material-icons">build</i>Administration tools</a></li>
{% endif %}
</ul>
</header>
</ul>
{% endblock sidenav %}
{% if parallax %}
<main>
{{ insert_content() }}
</main>
{% else %}
<main class="{{ main_class }}">
{% if not full_width %}
<div class="container">
{% endif %}
<div class="row">
<div class="col s12" id="headline">
<h2>{{ headline }}</h2>
</div>
{{ insert_content() }}
</div>
{% if not full_width %}
</div>
{% endif %}
</div>
{% endif %}
</main>
{% block content %}
<main>
{% block page_content %}{% endblock page_content %}
</main>
<footer class="page-footer secondary-color white-text">
<footer class="page-footer secondary-color">
<div class="container">
<div class="row">
<div class="col s6 m3">
@ -262,7 +170,7 @@
</div>
</div>
</div>
<div class="footer-copyright primary-color white-text">
<div class="footer-copyright primary-color">
<div class="container">
<div class="row" style="margin-bottom: 0;">
<div class="col s12 m3">
@ -270,31 +178,42 @@
</div>
<div class="col s12 m9 right-align">
<a class="btn-small blue waves-effect waves-light" href="{{ url_for('main.about_and_faq') }}"><i class="left material-icons">info_outline</i>About and faq</a>
<a class="btn-small pink waves-effect waves-light" href="mailto:{{ config.CONTACT_EMAIL_ADRESS }}?subject={{ config.NOPAQUE_MAIL_SUBJECT_PREFIX }} Contact"><i class="left material-icons">rate_review</i>Contact</a>
<a class="btn-small green waves-effect waves-light" href="mailto:{{ config.CONTACT_EMAIL_ADRESS }}?subject={{ config.NOPAQUE_MAIL_SUBJECT_PREFIX }} Feedback"><i class="left material-icons">feedback</i>Feedback</a>
<a class="btn-small orange waves-effect waves-light" href="https://gitlab.ub.uni-bielefeld.de/sfb1288inf/opaque"><i class="left material-icons">code</i>GitLab</a>
{% if config.CONTACT_EMAIL_ADRESS %}
<a class="btn-small pink waves-effect waves-light" href="mailto:{{ config.CONTACT_EMAIL_ADRESS }}?subject=[nopaque] Contact"><i class="left material-icons">rate_review</i>Contact</a>
<a class="btn-small green waves-effect waves-light" href="mailto:{{ config.CONTACT_EMAIL_ADRESS }}?subject=[nopaque] Feedback"><i class="left material-icons">feedback</i>Feedback</a>
{% endif %}
<a class="btn-small orange waves-effect waves-light" href="https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque"><i class="left material-icons">code</i>GitLab</a>
</div>
</div>
</div>
</div>
</footer>
<script src="{{ url_for('static', filename='js/darkreader.js') }}"></script>
<script src="{{ url_for('static', filename='js/jsonpatch.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/list.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/materialize.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/socket.io.slim.js') }}"></script>
<script src="{{ url_for('static', filename='js/nopaque.js') }}"></script>
<script>
{% if current_user.is_authenticated %}
</footer>
{% endblock content %}
{% block scripts %}
{{ super() }}
<script src="{{ url_for('static', filename='js/darkreader.js') }}"></script>
<script src="{{ url_for('static', filename='js/jsonpatch.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/list.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/socket.io.slim.js') }}"></script>
<script src="{{ url_for('static', filename='js/nopaque.js') }}"></script>
<script>
{% if current_user.setting_dark_mode %}
DarkReader.enable({brightness: 150, contrast: 100, sepia: 0});
{% endif %}
document.addEventListener('DOMContentLoaded', () => {
nopaque.socket.init();
// Disable all option elements with no value
for (let optionElement of document.querySelectorAll('option[value=""]')) {
optionElement.disabled = true;
}
M.AutoInit();
M.CharacterCounter.init(document.querySelectorAll('input[data-length][type="email"], input[data-length][type="password"], input[data-length][type="text"], textarea[data-length]'));
M.Dropdown.init(document.querySelectorAll('#nav-more-dropdown-trigger'), {alignment: 'right', constrainWidth: false, coverTrigger: false});
nopaque.Forms.init();
{% if current_user.is_authenticated %}
nopaque.socket.emit('user_data_stream_init');
});
{% endif %}
nopaque.flashedMessages = {{ get_flashed_messages(with_categories=True)|tojson }};
</script>
</body>
</html>
for (let flashedMessage of {{ get_flashed_messages(with_categories=True)|tojson }}) {
nopaque.flash(flashedMessage[1], flashedMessage[0]);
}
</script>
{% endblock scripts %}