Commit 3063ae18 authored by Deano Centrella's avatar Deano Centrella
Browse files

Improved the language selector and introduced improved navigation options.

- On small screens the user can now trigger the language selector via a new menu button at the top of the page, rather than having to scroll down below the content to access it.
- No longer requires javascript.
- Brings the user to the same page they were viewing but in the selected language, rather than sending the user to the landing page and having them try to navigate their way back to the page that they wanted to read.
- The icon for the language selector has a retina display variant (not hugely important to include a low resolution version of the icon except for the fact that some rendering engines add white artifacts to the edges of png images if they are shown much smaller than what the resolution of the image actually is (Firefox).
parent b74767d8
Pipeline #120633800 passed with stage
in 42 minutes and 57 seconds
- key : browse
title : browse__title
url : /packages/
- key : forum
url : https://forum.f-droid.org
external : true
locations : {"hero",
"dropMenu", # drop-down menu AND footer
"internal"}
- key : about
url : /about/
locations : {"hero",
"dropMenu",
"internal"}
- key : installation
title : installation__title
url : /docs/Security_Model/#secure-initial-installation
locations : {"dropMenu"}
- key : faq
url : /docs/
locations : {"hero",
"dropMenu",
"internal"}
- key : documentation
url : /docs/
locations : {"community"} # first of the 'Community' links
- key : news
title : news__title
url : /news/
locations : {"hero",
"dropMenu",
"internal"}
- key : forum
url : https://forum.f-droid.org
external : true
locations : {"hero",
"internal",
"community"}
# drop-down menu and footer 'secondary links'
- key : security
title : security__title
url : /docs/Security_Model/
locations : {"drop2"}
- key : privacy
url : /2019/05/05/trust-privacy-and-free-software.html
locations : {"drop2"}
- key : contacts
title : contacts__title
url : /about/#contact
locations : {"drop2"}
# the remaining 'Community' links
- key : repo
url : https://gitlab.com/fdroid/fdroidclient
external : true
locations : {"community"}
- key : issues
title : issues__title
url : /issues/
locations : {"community"}
- key : become_a_mirror
url : /docs/Running_a_Mirror/
locations : {"community"}
- key : contribute
url : /contribute/
- key : about
url : /about/
locations : {"internal",
"community"}
- key : social__fediverse__alt
title : social__fediverse__title
url : https://mastodon.technology/@fdroidorg
class : fediverse
external : true
locations : {"social"}
- key : social__twitter__alt
title : social__twitter__title
url : https://twitter.com/fdroidorg
class : twitter
external : true
locations : {"social"}
- key : social__rss__alt
title : social__rss__title
url : https://f-droid.org/en/feed.xml
class : rss
external : true
locations : {"social"}
# Search
- key : search_site
url : https://search.f-droid.org/
......@@ -20,12 +20,35 @@
},
"navigation": {
"about": "About",
"browse": "Browse",
"become_a_mirror": "Become a Mirror",
"browse": "Apps",
"browse__title": "App list from A to Z",
"celebrating_10yrs_service": "Celebrating 10 years of service since 2010",
"community": "Community",
"contacts": "Contacts",
"contacts__title": "Contributors and Consultants",
"contribute": "Contribute",
"documentation": "Docs",
"documentation__alt": "Documentation",
"faq": "FAQs",
"forum": "Forum",
"issues": "Issues",
"news": "News"
"gitlab__title": "F-Droid source-code",
"installation": "Installation",
"installation__title": "Secure download and install",
"issues": "Report issues",
"issues__title": "See and report issues",
"news": "News",
"news__title": "Posts by F-Droid Contributors",
"privacy": "Privacy",
"repo": "Gitlab",
"security": "Security",
"security__title": "Our Security Model",
"social__fediverse__alt": "Mastodon icon",
"social__fediverse__title": "Toot us on the Fediverse",
"social__rss__alt": "RSS icon",
"social__rss__title": "Our RSS feed",
"social__twitter__alt": "Twitter icon",
"social__twitter__title": "Our tweets"
},
"package": {
"anti_features": "Anti-Features",
......
......@@ -62,7 +62,7 @@ and the [Signing Process](../Signing_Process) are documented
separately.
## Initial Installs
## Secure Initial Installation
Most users of F-Droid download the APK from _f-droid.org_ and install
it. This is a potential vector of attack that built-in app stores do
......
......@@ -3,18 +3,40 @@
<a class="site-title" href="{{ site.baseurl }}/">
<img src="{{ site.baseurl }}/assets/fdroid-logo-text.svg" alt="{{ site.header-title }}" />
</a>
<div class="cb-menu--outer on-white">
{% include language-selector.html checkbox_menu_id="header-lang" hideOnPhone=true %}
<nav class="site-nav">
{% for nav-item in site.data.navigation %}
{% if nav-item.key %}
{% assign title = site.data.strings.navigation[nav-item.key] %}
{% if nav-item.external %}
<a class="page-link" href="{{ nav-item.url }}">{{ title }}</a>
{% else %}
<a class="page-link {% if page.url contains nav-item.url %} current {% endif %}" href="{{ nav-item.url | prepend: site.baseurl }}">{{ title }}</a>
{% endif %}
{% endif %}
{% endfor %}
</nav>
<div class="checkbox-menu icon ellipsis">
{% assign menu_id = "header-ellipsis" %}
<input type="radio" id="opener--{{ menu_id }}" name="checkbox-menu-item" />
<label for="opener--{{ menu_id }}">&#9776;</label>
<div class="checkbox-menu close-checkbox-menu">
<input type="radio" id="closer--{{ menu_id }}" name="checkbox-menu-item" />
<label for="closer--{{ menu_id }}">&#9776;</label>
</div>
<div class="cbm-content wide dropdown-menu">
{% include underlined-search.html %}
<div class="two-columns">
<div class="community-links">
<h5>Community</h5>
{% include nav-generator.html nav_location="community" %}
<div class="social-links">
{% include nav-generator.html nav_location="social" %}
</div>
</div>
<div class="main-links">
<div class="cb-menu--outer second-level on-dark">
{% include language-selector.html checkbox_menu_id="moreLinks-lang" secondLevel=true %}
</div>
{% include nav-generator.html nav_location="dropMenu" %}
<br />&nbsp;<br />
{% include nav-generator.html nav_location="drop2" %}
</div>
</div>
</div>
</div>
</div>
</header>
<nav class="site-nav">
{% include nav-generator.html nav_location="internal" %}
</nav>
{% comment %}
The language chooser is now a checkbox/radio button hack that opens a dropdown list of the languages
that can be scrolled through on small screens which link to the same page but in the different language.
{% endcomment %}
{% assign strings = site.data.strings.sidebars.lang %}
<div class="checkbox-menu icon with-caret language-select {% if include.hideOnPhone %}hide-on-phone{% endif %}">
<input type="radio" id="opener--{{ include.checkbox_menu_id }}" name="checkbox-menu-item{% if include.secondLevel %}--level-two{% endif %}" />
<label for="opener--{{ include.checkbox_menu_id }}">Language select</label>
<div class="checkbox-menu close-checkbox-menu">
<input type="radio" id="closer--{{ include.checkbox_menu_id }}" name="checkbox-menu-item{% if include.secondLevel %}--level-two{% endif %}" />
<label for="closer--{{ include.checkbox_menu_id }}">Language select</label>
</div>
<div class="cbm-content">
<div>
{% for lang in site.languages %}
<a href="{% if lang != site.active_lang %}{{ site.baseurl }}/{{ lang }}{{ page.url }}{% endif %}"
{% if lang == site.active_lang %}class="selected"{% endif %}>
{{ site.data.languagenames[lang] }}
</a>
{% endfor %}
</div>
</div>
</div>
{% for nav-item in site.data.navigation %}
{% if nav-item.key and nav-item.locations contains include.nav_location %}
{% assign text = site.data.strings.navigation[nav-item.key] %}
{% assign title = site.data.strings.navigation[nav-item.title] %}
{% if nav-item.external %}
<a class="page-link {% if nav-item.class %} {{ nav-item.class }} {% endif %}" href="{{ nav-item.url }}" title="{{ title }}">{{ text }}</a>
{% else %}
<a class="page-link {% if nav-item.class %} {{ nav-item.class }} {% endif %}{% if page.url contains nav-item.url %} current {% endif %}" href="{{ nav-item.url | prepend: site.baseurl }}" title="{{ title }}">{{ text }}</a>
{% endif %}
{% endif %}
{% endfor %}
{% comment %}
The language chooser is a drop down list which displays the relevant flag to the left.
If JavaScript is enabled, then it will automatically redirect to the relevant translation when changed.
If the user has JavaScript disabled, then it will show a submit button, and the .htaccess file will rewrite
the incoming "?lang=..." query parameter to the correct translated path.
{% endcomment %}
{% assign strings = site.data.strings.sidebars.lang %}
<form action="{{site.baseurl}}{{ page.url }}" method="get">
<select id="language-chooser-select" name="lang" autocomplete="off">
{% for lang in site.languages %}
<option value="{{ lang }}" {% if lang == site.active_lang %}selected="selected"{% endif %}>
{{ site.data.languagenames[lang] }}
</option>
{% endfor %}
</select>
<script src="{{site.baseurl}}/js/sidebar-lang.js"></script>
<noscript>
<input id="language-chooser-submit" type="submit" value="{{ strings.change }}" />
</noscript>
</form>
{% comment %}
See 'post.html' for reasoning on the below annoying loop
{% endcomment %}
{% assign searchUrl = 0 %}
{% for navItem in site.data.navigation %}
{% if navItem.key == 'search_site' %}
{% assign searchUrl = navItem.url %}
{% break %}
{% endif %}
{% endfor %}
<h3>{{ site.data.strings.sidebars.search.heading }}</h3>
<div>
<form method="get" class="search-form" action="https://search.f-droid.org/">
<form method="get" class="search-form" action="{{ site.data.navigation.[search_site] }} {{ searchUrl }}">
<div class="search-input-wrp">
<input type="search" class="search-input" name="q">
</div>
......
{% comment %}
See 'post.html' for reasoning on the below annoying loop
{% endcomment %}
{% assign searchUrl = 0 %}
{% for navItem in site.data.navigation %}
{% if navItem.key == 'search_site' %}
{% assign searchUrl = navItem.url %}
{% break %}
{% endif %}
{% endfor %}
<form method="get" class="underlined-search-form" action="{{ searchUrl }}">
<div class="underliner">
<input type="search" placeholder="{{ site.data.strings.sidebars.search.heading }}" class="search-input" name="q" />
<input type="hidden" name="lang" value="{{ site.active_lang }}" />
<input type="submit" value="{{ site.data.strings.sidebars.search.search }}" title="{{ site.data.strings.sidebars.search.search }}" class="search-button" />
</div>
</form>
......@@ -21,7 +21,9 @@
<div class="sidebar">
<div class="sidebar-widget language">
{% include sidebar-lang.html %}
<div class="cb-menu--outer on-white">
{% include language-selector.html checkbox_menu_id="afterContent-lang" %}
</div>
</div>
<div class="sidebar-widget">
......
......@@ -21,7 +21,9 @@
<div class="sidebar">
<div class="sidebar-widget language">
{% include sidebar-lang.html %}
<div class="cb-menu--outer on-white">
{% include language-selector.html checkbox_menu_id="afterContent-lang" %}
</div>
</div>
<div class="sidebar-widget">
......
......@@ -65,6 +65,446 @@ pre {
}
}
/**
* ------------------------
* Checkbox menu hack based on a version from CSS-Tricks and adapted for F-Droid by Dario Centrella
* ------------------------
*/
.site-wrapper {
overflow: hidden; // stops the scale(1.5) (below) from introducing a horizontal scrollbar to the site on small devices.
}
.cb-menu--outer {
position: relative;
margin: 0 ($spacing-unit /2);
line-height: 5em;
max-height: 5em; // Without this you'll get a buggy hit-box below the buttons
clear: both;
text-align: right;
html[dir=rtl] & {
text-align: left;
}
.checkbox-menu & { // second level
margin: 0;
}
}
.checkbox-menu {
position: relative;
display: inline-block;
label {
display: table-cell;
padding: 0 ($spacing-unit/2.5);
cursor: pointer;
transition: background-color .05s;
text-align: right;
border-top-left-radius:10px;
border-top-right-radius:10px;
overflow: hidden;
html[dir=rtl] & {
text-align: left;
}
}
[type="radio"]:hover ~ label{
background-color: rgba(0,0,0, .04);
}
&.close-checkbox-menu [type="radio"]:hover ~ label {
background-color: lighten($text-color, 4%);
}
[type="radio"] {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
margin: 0;
z-index: 1;
cursor: pointer;
}
.cbm-content .checkbox-menu { // ie. second level
label {
border-radius: 10px;
}
&.close-checkbox-menu > label {
html:not([dir=rtl]) & {
right: 0;
position: fixed;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
html[dir=rtl] & {
left: 0;
position: fixed;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
}
}
&.with-caret {
$padding-caret-side: 27px;
> label,
> .close-checkbox-menu > label {
html:not([dir=rtl]) & {
padding-right: $padding-caret-side;
}
html[dir=rtl] & {
padding-left: $padding-caret-side;
}
&:before {
content: "";
position: absolute;
color: $text-color;
font-size: $small-font-size;
html:not([dir=rtl]) & {
right: 12px;
}
html[dir=rtl] & {
left: 12px;
}
}
}
> label:before { // the (down) caret itself
display: block;
top: 39px;
border: 4px solid transparent;
border-top-color: $text-color;
}
> .close-checkbox-menu > label:before {
content: "\2716";
color: #fff;
display: inline-;
html:not([dir=rtl]) & {
right: $padding-caret-side/2 - 3;
}
html[dir=rtl] & {
left: $padding-caret-side/2 - 3;
}
}
}
}
.close-checkbox-menu {
position: absolute;
z-index: -1;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
label {
color: #fff;
background-color: $text-color;
}
}
.cbm-content {
position: absolute;
top: 99%;
background-color: $text-color;
color: white;
padding: $spacing-unit / 2;
display: none;
border-radius: 10px;
text-align: right;
line-height: $small-font-size * 1.6;
z-index: 2;
h1,h2,h3,h4,h5,h6 {
font-variant-caps: all-petite-caps;
letter-spacing: 0.2em;
color: lighten($text-color, 50%);
}
html:not([dir=rtl]) & {
right: 0;
border-top-right-radius: 0;
}
html[dir=rtl] & {
left: 0;
text-align:left;
border-top-left-radius: 0;
}
ul {
margin: 0;
padding: 0;
list-style: none;
}
a {
color: white;
display: block;
white-space: nowrap;
text-decoration: none;
padding: 5px;
&:hover {
background-color: lighten($text-color, 7%);
}
&.selected {
background-color: lighten($text-color, 4%);
}
}
.cbm-content { // second level
html:not([dir=rtl]) & {
text-align:left;
}
html[dir=rtl] & {
text-align:right;
}
}
}
header {
.cb-menu--outer:not(.second-level) {
@include media-query($phone) {
html:not([dir=rtl]) & {
margin-right: 0;
}
html[dir=rtl] & {
margin-left: 0;
}
}
> .checkbox-menu > input[type="radio"]:checked ~ .close-checkbox-menu > label {
position: fixed;
top: 0px;
}
}
}
header .cbm-content {
position: fixed;
padding-top: 3em;
top: 2.8em;
bottom: 10%;
> div {
height: 100%;
overflow: auto;
}
html:not([dir=rtl]) & {
left: 64%;
right: $spacing-unit;
border-top-right-radius: 10px;
@include media-query($tablet) {
right: 0;
left: 53%;
border-top-right-radius: 0;
}
@include media-query($phone) {
left: 34%;
}
}
html[dir=rtl] & {
right: 64%;
left: $spacing-unit;
border-top-left-radius: 10px;
@include media-query($tablet) {
left: 0;
right: 53%;
border-top-left-radius: 0;
}
@include media-query($phone) {
right: 34%;
}
}
&.wide {
html:not([dir=rtl]) & {
left: 57%;
@include media-query($tablet) {
left: 34%;
}
@include media-query($phone) {
left: 7%;
}
}
html[dir=rtl] & {
right: 57%;
@include media-query($tablet) {
right: 34%;
}
@include media-query($phone) {
right: 7%;
}
}
}
}
header .cb-menu--outer > .checkbox-menu > .cbm-content {
html:not([dir=rtl]) & {