roundabout,
created on Saturday, 3 February 2024, 21:17:22 (1706995042),
received on Wednesday, 31 July 2024, 06:54:41 (1722408881)
Author identity: vlad <vlad.muntoiu@gmail.com>
cce99a745230754db3843b0e5651cab61d202e46
static/efficient-ui/THEME.css
@@ -343,12 +343,32 @@
--color-navbar-link: var(--color-primary-text);
--height-navbar: 56px;
--padding-navbar: 16px;
--gap-navbar: 8px;
--width-navbar-button: 56px;
--padding-navbar: 0;
--gap-navbar: 0;
--shadow-navbar: 0 7px 25px -10px rgba(0, 0, 0, 0.12), 0 7px 25px 0 rgba(0, 0, 0, 0.24), 0 1px 8px 0 rgba(0, 0, 0, 0.12);
--border-navbar: none;
--radius-navbar: 0;
/* NAVRAIL */
--color-navrail: #455a64; --color-navrail-text: var(--color-primary-text);
--color-navrail-link: var(--color-primary-text);
--color-navrail-link-hover: var(--color-primary-3);
--color-navrail-link-selected: var(--color-primary-3);
--width-navrail: 72px;
--height-navrail-button: 56px;
--padding-navrail: 0;
--gap-navrail: 0;
--shadow-navrail: 0 7px 25px -10px rgba(0, 0, 0, 0.12), 0 7px 25px 0 rgba(0, 0, 0, 0.24), 0 1px 8px 0 rgba(0, 0, 0, 0.12);
--border-navrail: none;
--radius-navrail: 0;
/* SIDENAV */
--color-sidenav: transparent; --color-sidenav-text: var(--color-caption-text);
--gap-sidenav-item: 1ch;
--padding-sidenav: 8px;
/* BREADCRUMBS */
--color-breadcrumbs: #455A64; --color-breadcrumbs-text: var(--color-primary-1-text);
--color-breadcrumbs-link: var(--color-primary-1-text);
@@ -788,3 +808,35 @@ dialog::backdrop {
opacity: 1;
}
}
:where(.navrail, .navbar, .sidenav) iconify-icon {
font-size: 1.5rem;
}
:is(.navrail, .navbar) a {
position: relative;
overflow: hidden;
}
.navrail :any-link {
font-weight: 500;
font-size: 0.875em;
}
.navrail :any-link.selected {
font-weight: 600;
}
.navbar > *, .navbar > ul > li > * {
height: var(--height-navbar);
display: flex;
align-items: center;
justify-content: center;
}
.navrail a {
width: var(--width-navrail);
display: flex;
align-items: center;
justify-content: center;
}
static/efficient-ui/breadcrumbs.css
@@ -11,10 +11,12 @@
color: var(--color-breadcrumbs-text);
}
.breadcrumbs ul {
.breadcrumbs ul, .breadcrumbs-list {
display: flex;
list-style: none;
gap: var(--gap-breadcrumbs);
padding: 0;
margin: 0;
}
.breadcrumbs {
@@ -25,6 +27,6 @@
color: var(--color-breadcrumbs-link);
}
.breadcrumbs li:not(:last-child)::after {
.breadcrumbs li:not(:last-child)::after, .breadcrumbs-list li:not(:last-child) > a::after {
content: var(--separator-breadcrumbs);
}
static/efficient-ui/navbar.css
@@ -5,13 +5,29 @@
background: var(--color-navbar);
height: var(--height-navbar);
box-shadow: var(--shadow-navbar);
border: var(--shadow-navbar);
border: var(--border-navbar);
padding: var(--padding-navbar);
border-radius: var(--radius-navbar);
color: var(--color-navbar-text);
z-index: 1;
}
.navrail {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
background: var(--color-navrail);
width: var(--width-navrail);
height: 100%;
box-shadow: var(--shadow-navrail);
border: var(--border-navrail);
padding: var(--padding-navrail);
border-radius: var(--radius-navrail);
color: var(--color-navrail-text);
z-index: 1;
}
.navbar ul {
display: flex;
list-style: none;
@@ -20,10 +36,56 @@
margin: 0 !important;
}
.navrail ul {
display: flex;
flex-direction: column;
list-style: none;
gap: var(--gap-navrail);
padding: 0;
margin: 0 !important;
}
.navrail ul :any-link {
color: var(--color-navrail-link);
text-decoration: none;
}
.navrail ul :any-link:hover {
color: var(--color-navrail-link-hover);
text-decoration: none;
}
.navrail ul li > a {
display: flex;
flex-direction: column;
text-align: center;
min-height: var(--height-navrail-button);
}
.navrail ul li.selected :any-link {
color: var(--color-navrail-link-selected);
}
.navbar {
width: 100%;
}
.navbar :is(:any-link, a:hover:visited) {
color: var(--color-navbar-link);
min-width: var(--width-navbar-button);
}
.sidenav ul {
list-style: none;
margin: 0 !important;
}
.sidenav li > a {
display: flex;
gap: var(--gap-sidenav-item);
padding: var(--padding-sidenav);
margin: 0;
color: var(--color-sidenav-text) !important;
background: var(--color-sidenav);
text-decoration: none;
}
static/ripples.js
@@ -1,5 +1,5 @@
(() => {
const rippleHosts = document.querySelectorAll('.button, button, input, select');
const rippleHosts = document.querySelectorAll('.button, button, input, select, .navbar a, .navrail a');
function generateRipple(rippleX, rippleY, rippleDimensions) {
const div = document.createElement('div');
static/style.css
@@ -38,12 +38,14 @@ button, input, .button, select {
height: 100%;
}
/*
@media screen and (max-width: 896px) {
.navbar {
flex-flow: column nowrap;
height: fit-content;
}
}
*/
@media screen and (max-width: 640px) {
#repo-table > * > tr > :is(td, th):is(:nth-child(3), :nth-child(4)) {
@@ -55,6 +57,7 @@ button, input, .button, select {
}
}
/*
@media screen and (max-width: 544px) {
.navbar > ul {
flex-flow: row wrap;
@@ -64,7 +67,6 @@ button, input, .button, select {
align-items: stretch;
}
}
@media screen and (max-width: 512px) {
.breadcrumbs {
flex-flow: column nowrap;
@@ -73,6 +75,7 @@ button, input, .button, select {
gap: 1em;
}
}
*/
.file-icon {
font-size: 1.25em;
@@ -89,20 +92,10 @@ button, input, .button, select {
text-decoration: none;
}
#repo-tabs, #global-nav > ul, #home-tabs {
padding: 0;
margin: 0;
}
.button {
text-decoration: none;
}
/* for now */
#repo-table > * > tr > :is(td, th):nth-child(1) {
display: none;
}
.password-error {
background: var(--color-error);
color: var(--color-error-text);
@@ -124,12 +117,12 @@ button, input, .button, select {
height: 100%;
}
body > footer {
footer {
background: var(--color-callout-1);
color: var(--color-callout-1-text);
padding: 16px;
}
body > footer a {
footer a {
color: var(--color-callout-1-text) !important;
}
body {
@@ -188,3 +181,18 @@ dd {
transform: translateX(-200%);
}
}
@media screen and (min-width: 641px) {
#sidenav-trigger {
display: none;
}
#global-nav {
padding-left: 16px;
}
}
@media screen and (max-width: 640px) {
#navbar-separator ~ a {
display: none;
}
}
templates/default.html
@@ -16,74 +16,120 @@
<meta name="viewport" content="width=device-width, initial-scale=1" />
{% endblock %}
</head>
<body>
<header>
<nav id="global-nav" class="breadcrumbs">
<ul>
<li><a href="/">roundabout</a></li>
{% block breadcrumbs %}{% endblock %}
</ul>
<x-hbox style="--gap: 2ch;">
<body style="overflow: hidden;">
<dialog id="sidenav" class="sheet-left">
<x-frame style="--width: 320px; --margin: 0;">
<article class="card">
<section class="card-main">
<nav class="sidenav">
<ul>
{% if logged_in_user %}
<li><a href="/{{ logged_in_user }}">
<img src="/info/{{ logged_in_user }}/avatar" class="avatar" style="width: 1em; height: 1em;">
{{ logged_in_user }}
</a></li>
<li><a href="/notifications">
<iconify-icon icon="ic:baseline-inbox" data-badge="{{ unread }}"></iconify-icon>
Notifications
</a></li>
<li><a href="/newrepo">
<iconify-icon icon="mdi:folder-plus"></iconify-icon>
Create repository
</a></li>
<li><a href="/favourites">
<iconify-icon icon="mdi:star"></iconify-icon>
Your favourites
</a></li>
<li><a href="/settings">
<iconify-icon icon="mdi:cog"></iconify-icon>
Settings
</a></li>
<li><a href="/logout">
<iconify-icon icon="mdi:logout"></iconify-icon>
Log out
</a></li>
{% else %}
<li><a href="/accounts">
<iconify-icon icon="mdi:account"></iconify-icon>
Log in or sign up
</a></li>
{% endif %}
</ul>
</nav>
</section>
</article>
</x-frame>
</dialog>
{% block dialogs %}
{% endblock %}
<x-vbox class="nopad" style="align-items: stretch; height: 100vh;">
<header>
<nav id="global-nav" class="navbar" style="padding-right: 0; justify-content: flex-start;">
<a href="javascript:document.getElementById('sidenav').showModal();" id="sidenav-trigger">
<iconify-icon icon="mdi:menu"></iconify-icon>
</a>
<ul class="breadcrumbs-list">
<li><a href="/">roundabout</a></li>
{% block breadcrumbs %}{% endblock %}
</ul>
<div class="flexible-space" id="navbar-separator"></div>
{% if logged_in_user %}
<a href="/newrepo">
<x-hbox style="gap: 0.75ch;" class="box-center">
<iconify-icon icon="mdi:folder-plus"></iconify-icon>
Create
</x-hbox>
</a>
<a href="/notifications" data-badge="{{ unread }}">
<x-hbox style="gap: 0.75ch;" class="box-center">
<iconify-icon icon="ic:baseline-inbox"></iconify-icon>
</x-hbox>
</a>
<a href="/{{ logged_in_user }}">
<x-hbox style="gap: 0.75ch;" class="box-center">
<img src="/info/{{ logged_in_user }}/avatar" class="avatar" style="width: 1em; height: 1em;">
{{ logged_in_user }}
</x-hbox>
<img src="/info/{{ logged_in_user }}/avatar" class="avatar" style="width: 1em; height: 1em;">
{{ logged_in_user }}
</a>
<a href="/logout">
<x-hbox style="gap: 0.75ch;" class="box-center">
<iconify-icon icon="mdi:logout" title="Log out"></iconify-icon>
</x-hbox>
<a href="/notifications">
<iconify-icon icon="ic:baseline-inbox" data-badge="{{ unread }}"></iconify-icon>
</a>
<a href="/newrepo">
<iconify-icon icon="mdi:folder-plus" title="Create repository"></iconify-icon>
</a>
<a href="/favourites">
<x-hbox style="gap: 0.75ch;" class="box-center">
<iconify-icon icon="mdi:star" title="Favourites"></iconify-icon>
</x-hbox>
<iconify-icon icon="mdi:star" title="Favourites"></iconify-icon>
</a>
<a href="/settings">
<x-hbox style="gap: 0.75ch;" class="box-center">
<iconify-icon icon="mdi:cog" title="User settings"></iconify-icon>
</x-hbox>
<iconify-icon icon="mdi:cog" title="User settings"></iconify-icon>
</a>
<a href="/logout">
<iconify-icon icon="mdi:logout" title="Log out"></iconify-icon>
</a>
{% else %}
<a href="/accounts">Log in or sign up</a>
{% endif %}
</x-hbox>
</nav>
{% block nav %}{% endblock %}
</header>
<main>
{% block content %}{% endblock %}
</main>
<footer>
<x-hbox>
<a href="/help">Help</a>
<a href="mailto:{{ config.CONTACT_EMAIL }}">Contact Us</a>
</nav>
</header>
<x-hbox class="flexible-space nopad" style="width: 100%; overflow: hidden; align-items: strech;">
<nav id="repo-nav" class="navrail" style="max-height: 100%;">
<ul id="repo-tabs">
{% block nav %}
{% endblock %}
</ul>
</nav>
<x-vbox style="overflow-y: scroll; flex: 1 1 auto; max-height: calc(100vh - var(--height-navbar));">
<main>
{% block content %}
{% endblock %}
</main>
<footer>
<x-hbox>
<a href="/help">Help</a>
<a href="mailto:{{ config.CONTACT_EMAIL }}">Contact Us</a>
</x-hbox>
<hr>
<p>
Alpha testing. Not for production use.
</p>
<p>
Application © 2023 Roundabout developers. Content belongs to the repository contributors,
unless otherwise stated.
</p>
<p>
<a href="/about">Powered by Roundabout (alpha testing)</a>
</p>
</footer>
</x-vbox>
</x-hbox>
<hr>
<p>
Alpha testing. Not for production use.
</p>
<p>
Application © 2023 Roundabout developers. Content belongs to the repository contributors,
unless otherwise stated.
</p>
<p>
<a href="/about">Powered by Roundabout (alpha testing)</a>
</p>
</footer>
</x-vbox>
{% with messages = get_flashed_messages(with_categories=true) %}
<ol class="toast-container">
{% for category, message in messages %}
templates/repo.html
@@ -3,11 +3,10 @@
{{ username }}/{{ repository }}
{% endblock %}
{% block breadcrumbs %}
<li><a href="/{{ username }}">{{ username }}</li>
<li><a href="/{{ username }}">{{ username }}</a></li>
<li><a href="/{{ username }}/{{ repository }}">{{ repository }}</a></li>
{% endblock %}
{% block nav %}
{% block dialogs %}
<dialog id="clone-info">
<article class="card">
<header class="card-top">
@@ -30,40 +29,103 @@
</section>
</article>
</dialog>
<nav id="repo-nav" class="navbar">
<ul id="repo-tabs">
<li><a href="/{{ username }}/{{ repository }}/tree">Tree</a></li>
<li><a href="/{{ username }}/{{ repository }}/branches">Branches</a></li>
<li><a href="/{{ username }}/{{ repository }}/log">History</a></li>
<li><a href="/{{ username }}/{{ repository }}/prs">PRs</a></li>
<li><a href="/{{ username }}/{{ repository }}/forum">Forum</a></li>
<li><a href="/{{ username }}/{{ repository }}/users">Users</a></li>
<li><a href="/{{ username }}/{{ repository }}/settings">Settings</a></li>
</ul>
<x-buttonbox>
{% if logged_in_user %}
<a class="button" href="/{{ username }}/{{ repository }}/favourite">
{% if not is_favourite %}
<iconify-icon icon="mdi:star"></iconify-icon>
Favourite
{% else %}
<iconify-icon icon="mdi:star"></iconify-icon>
Remove favourite
{% endif %}
</a>
{% endif %}
<!-- <button>-->
<!-- <iconify-icon icon="mdi:chat-alert"></iconify-icon>-->
<!-- follow-->
<!-- </button>-->
<button onclick="document.getElementById('clone-info').showModal();">
<iconify-icon icon="mdi:swap-vertical-bold"></iconify-icon>
Clone
</button>
<!-- <button>-->
<!-- <iconify-icon icon="mdi:directions-fork"></iconify-icon>-->
<!-- fork-->
<!-- </button>-->
</x-buttonbox>
</nav>
{% endblock %}
{% block nav %}
<ul id="repo-tabs">
<li class="{% if active_page == 'tree' %}selected{% endif %}">
<a href="/{{ username }}/{{ repository }}/tree">
{% if active_page == 'tree' %}
<iconify-icon icon="ic:baseline-folder-copy"></iconify-icon>
{% else %}
<iconify-icon icon="ic:outline-folder-copy"></iconify-icon>
{% endif %}
Files
</a>
</li>
<li class="{% if active_page == 'branches' %}selected{% endif %}">
<a href="/{{ username }}/{{ repository }}/branches">
{% if active_page == 'branches' %}
<iconify-icon icon="mdi:directions-fork"></iconify-icon>
{% else %}
<iconify-icon icon="mdi:directions-fork"></iconify-icon>
{% endif %}
Branches
</a>
</li>
<li class="{% if active_page == 'log' %}selected{% endif %}">
<a href="/{{ username }}/{{ repository }}/log">
{% if active_page == 'log' %}
<iconify-icon icon="ic:baseline-history"></iconify-icon>
{% else %}
<iconify-icon icon="ic:outline-history"></iconify-icon>
{% endif %}
History
</a>
</li>
<li class="{% if active_page == 'prs' %}selected{% endif %}">
<a href="/{{ username }}/{{ repository }}/prs">
{% if active_page == 'prs' %}
<iconify-icon icon="mdi:comment-arrow-left"></iconify-icon>
{% else %}
<iconify-icon icon="mdi:comment-arrow-left-outline"></iconify-icon>
{% endif %}
PRs
</a>
</li>
<li class="{% if active_page == 'forum' %}selected{% endif %}">
<a href="/{{ username }}/{{ repository }}/forum">
{% if active_page == 'forum' %}
<iconify-icon icon="ic:baseline-forum"></iconify-icon>
{% else %}
<iconify-icon icon="ic:outline-forum"></iconify-icon>
{% endif %}
Forum
</a>
</li>
<li class="{% if active_page == 'users' %}selected{% endif %}">
<a href="/{{ username }}/{{ repository }}/users">
{% if active_page == 'users' %}
<iconify-icon icon="mdi:users"></iconify-icon>
{% else %}
<iconify-icon icon="mdi:users-outline"></iconify-icon>
{% endif %}
Users
</a>
</li>
<li class="{% if active_page == 'settings' %}selected{% endif %}">
<a href="/{{ username }}/{{ repository }}/settings">
{% if active_page == 'settings' %}
<iconify-icon icon="mdi:settings"></iconify-icon>
{% else %}
<iconify-icon icon="mdi:settings-outline"></iconify-icon>
{% endif %}
Settings
</a>
</li>
</ul>
{% endblock %}
<!-- <x-buttonbox>-->
<!-- {% if logged_in_user %}-->
<!-- <a class="button" href="/{{ username }}/{{ repository }}/favourite">-->
<!-- {% if not is_favourite %}-->
<!-- <iconify-icon icon="mdi:star"></iconify-icon>-->
<!-- Favourite-->
<!-- {% else %}-->
<!-- <iconify-icon icon="mdi:star"></iconify-icon>-->
<!-- Remove favourite-->
<!-- {% endif %}-->
<!-- </a>-->
<!-- {% endif %}-->
<!-- <!– <button>–>-->
<!-- <!– <iconify-icon icon="mdi:chat-alert"></iconify-icon>–>-->
<!-- <!– follow–>-->
<!-- <!– </button>–>-->
<!-- <button onclick="document.getElementById('clone-info').showModal();">-->
<!-- <iconify-icon icon="mdi:swap-vertical-bold"></iconify-icon>-->
<!-- Clone-->
<!-- </button>-->
<!-- <!– <button>–>-->
<!-- <!– <iconify-icon icon="mdi:directions-fork"></iconify-icon>–>-->
<!-- <!– fork–>-->
<!-- <!– </button>–>-->
<!-- </x-buttonbox>-->
templates/repository/repo-branches.html
@@ -1,4 +1,6 @@
{% extends "repo.html" %}
{% set active_page = "branches" %}
{% block title %}
Branches of {{ username }}/{{ repository }}
{% endblock %}
templates/repository/repo-file.html
@@ -1,4 +1,6 @@
{% extends "repo.html" %}
{% set active_page = "tree" %}
{% block title %}
{{ basename }} in {{ username }}/{{ repository }}
{% endblock %}
templates/repository/repo-forum-thread.html
@@ -1,4 +1,6 @@
{% extends "repo.html" %}
{% set active_page = "forum" %}
{% set parent = Post.query.filter_by(repo=repo_data, number=post_id).first() %}
{% block title %}
{{ parent.subject }} in {{ username }}/{{ repository }}
templates/repository/repo-forum.html
@@ -1,4 +1,6 @@
{% extends "repo.html" %}
{% set active_page = "forum" %}
{% block title %}
Forum of {{ username }}/{{ repository }}
{% endblock %}
templates/repository/repo-log.html
@@ -1,4 +1,6 @@
{% extends "repo.html" %}
{% set active_page = "log" %}
{% block title %}
History of {{ username }}/{{ repository }}
{% endblock %}
templates/repository/repo-prs.html
@@ -1,4 +1,6 @@
{% extends "repo.html" %}
{% set active_page = "prs" %}
{% block title %}
PRs of {{ username }}/{{ repository }}
{% endblock %}
templates/repository/repo-tree.html
@@ -1,4 +1,6 @@
{% extends "repo.html" %}
{% set active_page = "tree" %}
{% block title %}
Tree of {{ username }}/{{ repository }}
{% endblock %}
templates/repository/repo-users.html
@@ -1,4 +1,6 @@
{% extends "repo.html" %}
{% set active_page = "users" %}
{% block title %}
Users of {{ username }}/{{ repository }}
{% endblock %}
templates/tree-view.html
@@ -1,15 +1,6 @@
<style>
#repo-table td:nth-child(1) {
text-align: center;
vertical-align: middle;
width: 0;
}
</style>
<table style="width: 100%; table-layout: fixed;" id="repo-table">
<thead>
<tr>
<th style="width: 2em;"><input type="checkbox" id="tree-select-all"></th>
<th style="text-align: left;">File name</th>
<th style="text-align: left;">Media type</th>
<th style="width: 12ch; text-align: right;">Size</th>
@@ -19,7 +10,6 @@
<tbody>
{% for file in files %}
<tr>
<td style="text-align: center; padding: 0;"><input type="checkbox"></td>
<td>
<a href="{{ file.link }}" class="file-link" title="{{ file.name }}">
<x-hbox style="align-items: center; gap: 0.5ch;">