Add website

This commit is contained in:
Martchus 2024-04-21 21:19:57 +02:00
commit a176dbb2ac
16 changed files with 897 additions and 0 deletions

60
css/basics.css Normal file
View File

@ -0,0 +1,60 @@
/* style for basic HTML elements */
html, body {
background: white;
color: #222;
font: normal 16px sans-serif;
margin: 0px;
padding: 0px;
}
h1, h2, h3, h4, h5, h6 {
padding: 0px;
}
h1 {
font-size: 150%;
margin: 15px 0px;
}
h2 {
font-size: 130%;
margin: 10px 0px;
}
h3 {
font-size: 110%;
margin: 10px 0px;
}
a:link {
color: #07b;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a:visited {
color: #666;
}
pre {
border: 1px solid #aaa;
background-color: white;
margin: 5px;
padding: 5px;
white-space: pre-wrap;
overflow-x: auto;
}
fieldset {
border: 1px dotted #999;
background: #f6f9fc;
font-size: .846em;
}
fieldset legend {
font-weight: bold;
margin-bottom: 5px;
}
button, input[type="button"] {
border: 1px solid #aaa;
padding: 3px;
}

144
css/layout.css Normal file
View File

@ -0,0 +1,144 @@
/* style for defining the overall layout of the page (header, navigation, main container) */
ul {
margin: 0px;
}
header nav {
margin: 0px;
display: block;
background-color: #ffffff;
border-bottom: 5px #08c solid!important;
color: #0891d1;
font-weight: bold;
cursor: default;
width: 100%;
z-index: 1000;
}
header nav > div {
box-sizing: border-box;
list-style-type: none;
width: 100%;
padding-top: 8px;
margin-bottom: 10px;
padding-left: 0em;
}
header nav > div > span {
font-size: 90%;
font-weight: normal;
}
header nav > div img {
float: left;
height: 40px;
margin-left: 15px;
margin-right: 10px;
}
header nav ul {
padding: 0px;
margin: 0px;
border-top: 1px solid #222;
}
header nav li {
display: inline-block;
margin: 0px;
padding: 0px;
background-repeat: no-repeat;
background-size: auto 45%;
background-position: center 20%;
opacity: .6;
}
header nav li.active {
filter: invert(100%);
}
header nav ul li a, header nav ul li a:link, header nav ul li a:visited {
display: inline-block;
position: relative;
box-sizing: border-box;
text-decoration: none;
padding-left: 20px;
padding-top: 35px;
padding-bottom: 5px;
padding-right: 20px;
/*color: #08c;*/
color: #000;
font-weight: bold;
font-size: 90%;
}
header nav ul li a:hover {
text-decoration: none;
}
header nav ul li.active a {
color: #000;
text-decoration: none;
}
header nav ul li.progress a:after {
content: '';
box-sizing: border-box;
position: absolute;
left: 0px;
bottom: 0px;
height: 5px;
width: 100%;
background: #ff7733;
animation: loading 2s infinite;
}
@keyframes loading {
0% {
margin-left: 0%;
width: 30%;
}
15% {
margin-left: 35%;
width: 50%;
}
50% {
margin-left: 70%;
width: 30%;
}
65% {
margin-left: 15%;
width: 50%;
}
100% {
margin-left: 0%;
width: 30%;
}
}
header nav li.active {
background-color: #ff7733; /* inverted from #0088cc */
}
header nav ul li:hover {
opacity: .9;
}
@media (min-width: 950px) {
header nav {
position: fixed;
}
header nav ul {
float: right;
border-top: none;
}
header nav > div {
position: absolute;
top: 50%;
transform: translate(0%, -50%);
margin: 0px;
padding: 0px;
z-index: -1000;
}
}
main {
padding-left: 0.5em;
padding-right: 0.5em;
}
@media (min-width: 950px) {
main {
padding-top: 55px;
}
}
section {
background-color: white;
padding: 10px;
}

154
css/specifics.css Normal file
View File

@ -0,0 +1,154 @@
/* style for page-specific elements */
/* icons of buttons within navigation */
#back-nav-link {
background-image: url(../img/icon/chevron-left.svg);
background-size: contain;
margin-right: -5px;
filter: invert(100%);
}
#back-nav-link a {
margin-right: 0px;
filter: none;
}
#intro-nav-link {
background-image: url(../img/icon/information.svg);
}
#downloads-nav-link {
background-image: url(../img/icon/download.svg);
}
#doc-nav-link {
background-image: url(../img/icon/book-open-variant.svg);
}
#contact-nav-link {
background-image: url(../img/icon/forum.svg);
}
#code-nav-link {
background-image: url(../img/icon/code-braces.svg);
}
/* elements of intro section */
#intro-section {
font-size: 120%;
line-height: 140%;
}
.banner {
margin: -23px;
margin-bottom: 10px;
background-image: url(../img/screenshots/plasma.png);
background-position-y: -758px;
background-position-x: right;
background-repeat: no-repeat;
background-color: #416da0;
height: 655px;
width: calc(100% + 41px);
box-sizing: border-box;
border-bottom: 5px #08c solid!important;
}
@media (max-width: 1050px) {
.banner {
background-position-x: -1500px;
}
}
@media (min-width: 1010px) {
.banner-info {
height: 0px;
}
.banner-info p {
position: relative;
top: -610px;
right: 50px;
margin-left: auto;
width: 300px;
background-color: #ffffffad;
border: 1px solid #aaa;
border-radius: 5px;
padding: 10px;
line-height: 170%;
box-sizing: border-box;
}
}
@media (min-width: 1730px) {
.banner-info p {
margin-left: 0px;
left: 100px;
width: 30%;
}
}
@media (max-width: 1010px) {
.banner-info p {
}
}
@media (max-width: 950px) {
.banner {
margin-top: -10px;
}
}
/* elements of downloads section */
.downloads-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 40px;
}
.downloads-grid h3 {
margin-top: 20px;
}
.downloads-grid h3 + p {
margin: 10px 0px;
}
@media (max-width: 900px) {
.downloads-grid {
display: block;
}
}
.downloads-platform {
padding: 5px;
}
.downloads-platform input[type="checkbox"] {
display: none;
}
.downloads-platform label {
display: block;
margin: 0px -5px -10px -5px;
padding: 0px;
font-weight: bold;
/*background-color: #e0e0ff;*/
cursor: pointer;
user-select: none;
}
.downloads-platform label:before {
display: inline-block;
width: 20px;
content: "⮞ ";
opacity: 0.5;
}
.downloads-platform > ul {
list-style: none;
padding-bottom: 5px;
border-bottom: 1px solid #aaa;
}
.downloads-platform input + label ~ * {
margin-top: 10px;
display: none;
padding-left: 0px;
margin-left: 20px;
}
.downloads-platform input:checked + label ~ * {
display: block;
}
.downloads-platform input:checked + label:before {
content: "⮟ ";
}
.downloads-platform p {
font-size: 90%;
padding: 5px !important;
border-radius: 5px;
border: 1px solid #ddd;
background-color: #e5f3ff;
}
/* elements of the documentation section */
#doc-section p {
line-height: 140%;
}

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 21.5C10.65 20.65 8.2 20 6.5 20C4.85 20 3.15 20.3 1.75 21.05C1.65 21.1 1.6 21.1 1.5 21.1C1.25 21.1 1 20.85 1 20.6V6C1.6 5.55 2.25 5.25 3 5C4.11 4.65 5.33 4.5 6.5 4.5C8.45 4.5 10.55 4.9 12 6C13.45 4.9 15.55 4.5 17.5 4.5C18.67 4.5 19.89 4.65 21 5C21.75 5.25 22.4 5.55 23 6V20.6C23 20.85 22.75 21.1 22.5 21.1C22.4 21.1 22.35 21.1 22.25 21.05C20.85 20.3 19.15 20 17.5 20C15.8 20 13.35 20.65 12 21.5M12 8V19.5C13.35 18.65 15.8 18 17.5 18C18.7 18 19.9 18.15 21 18.5V7C19.9 6.65 18.7 6.5 17.5 6.5C15.8 6.5 13.35 7.15 12 8M13 11.5C14.11 10.82 15.6 10.5 17.5 10.5C18.41 10.5 19.26 10.59 20 10.78V9.23C19.13 9.08 18.29 9 17.5 9C15.73 9 14.23 9.28 13 9.84V11.5M17.5 11.67C15.79 11.67 14.29 11.93 13 12.46V14.15C14.11 13.5 15.6 13.16 17.5 13.16C18.54 13.16 19.38 13.24 20 13.4V11.9C19.13 11.74 18.29 11.67 17.5 11.67M20 14.57C19.13 14.41 18.29 14.33 17.5 14.33C15.67 14.33 14.17 14.6 13 15.13V16.82C14.11 16.16 15.6 15.83 17.5 15.83C18.54 15.83 19.38 15.91 20 16.07V14.57Z" /></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M15.41,16.58L10.83,12L15.41,7.41L14,6L8,12L14,18L15.41,16.58Z" /></svg>

After

Width:  |  Height:  |  Size: 356 B

1
img/icon/code-braces.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8,3A2,2 0 0,0 6,5V9A2,2 0 0,1 4,11H3V13H4A2,2 0 0,1 6,15V19A2,2 0 0,0 8,21H10V19H8V14A2,2 0 0,0 6,12A2,2 0 0,0 8,10V5H10V3M16,3A2,2 0 0,1 18,5V9A2,2 0 0,0 20,11H21V13H20A2,2 0 0,0 18,15V19A2,2 0 0,1 16,21H14V19H16V14A2,2 0 0,1 18,12A2,2 0 0,1 16,10V5H14V3H16Z" /></svg>

After

Width:  |  Height:  |  Size: 339 B

1
img/icon/download.svg Normal file
View File

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M5,20H19V18H5M19,9H15V3H9V9H5L12,16L19,9Z" /></svg>

After

Width:  |  Height:  |  Size: 337 B

1
img/icon/forum.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17,12V3A1,1 0 0,0 16,2H3A1,1 0 0,0 2,3V17L6,13H16A1,1 0 0,0 17,12M21,6H19V15H6V17A1,1 0 0,0 7,18H18L22,22V7A1,1 0 0,0 21,6Z" /></svg>

After

Width:  |  Height:  |  Size: 203 B

1
img/icon/information.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13,9H11V7H13M13,17H11V11H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z" /></svg>

After

Width:  |  Height:  |  Size: 184 B

32
img/logo.svg Normal file
View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 117.3 117.3" enable-background="new 0 0 117.3 117.3" xml:space="preserve">
<g>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="58.666" y1="117.332" x2="58.666" y2="0">
<stop offset="0" style="stop-color:#0882C8"/>
<stop offset="1" style="stop-color:#26B6DB"/>
</linearGradient>
<circle fill="url(#SVGID_1_)" cx="58.7" cy="58.7" r="58.7"/>
<g>
<circle fill="none" stroke="#FFFFFF" stroke-width="6" stroke-miterlimit="10" cx="58.7" cy="58.5" r="43.7"/>
<g>
<path fill="#FFFFFF" d="M94.7,47.8c4.7,1.6,9.8-0.9,11.4-5.6c1.6-4.7-0.9-9.8-5.6-11.4c-4.7-1.6-9.8,0.9-11.4,5.6
C87.5,41.1,90,46.2,94.7,47.8z"/>
<line fill="none" stroke="#FFFFFF" stroke-width="6" stroke-miterlimit="10" x1="97.6" y1="39.4" x2="67.5" y2="64.4"/>
</g>
<g>
<path fill="#FFFFFF" d="M77.6,91c-0.4,4.9,3.2,9.3,8.2,9.8c5,0.4,9.3-3.2,9.8-8.2c0.4-4.9-3.2-9.3-8.2-9.8
C82.4,82.4,78,86,77.6,91z"/>
<line fill="none" stroke="#FFFFFF" stroke-width="6" stroke-miterlimit="10" x1="86.5" y1="91.8" x2="67.5" y2="64.4"/>
</g>
<path fill="#FFFFFF" d="M60,69.3c2.7,4.2,8.3,5.4,12.4,2.7c4.2-2.7,5.4-8.3,2.7-12.4c-2.7-4.2-8.3-5.4-12.4-2.7
C58.5,59.5,57.3,65.1,60,69.3z"/>
<g>
<path fill="#FFFFFF" d="M21.2,61.4c-4.3-2.5-9.8-1.1-12.3,3.1c-2.5,4.3-1.1,9.8,3.1,12.3c4.3,2.5,9.8,1.1,12.3-3.1
C26.8,69.5,25.4,64,21.2,61.4z"/>
<line fill="none" stroke="#FFFFFF" stroke-width="6" stroke-miterlimit="10" x1="16.6" y1="69.1" x2="67.5" y2="64.4"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
img/screenshots/plasma.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

BIN
img/screenshots/webview.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

251
index.html Normal file
View File

@ -0,0 +1,251 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Syncthing Tray</title>
<meta charset="UTF-8" />
<meta name="description" content="A GUI integration" />
<meta name="author" content="Martchus" />
<meta name="keywords" content="Syncthing Tray, Syncthing, GUI" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<script type="module" src="js/main.js"></script>
<link rel="stylesheet" type="text/css" href="css/basics.css" />
<link rel="stylesheet" type="text/css" href="css/layout.css" />
<link rel="stylesheet" type="text/css" href="css/specifics.css" />
<link rel="shortcut icon" href="img/logo.svg" />
</head>
<body>
<header>
<nav>
<div>
<img src="img/logo.svg" alt="Logo" />
Syncthing Tray<br />
<span>Tray application and Dolphin/Plasma integration for Syncthing</span>
</div>
<ul>
<li id="intro-nav-link">
<a href="#intro-section" title="Intro">Intro</a>
</li>
<li id="downloads-nav-link">
<a href="#downloads-section" title="Downloads">Downloads</a>
</li>
<li id="doc-nav-link">
<a href="#doc-section" title="Documentation">Docs</a>
</li>
<li id="contact-nav-link">
<a href="#contact-section" title="Contact">Contact</a>
</li>
<li id="code-nav-link">
<a href="https://github.com/Martchus/syncthingtray" target="blank" title="Code">Code</a>
</li>
</ul>
</nav>
</header>
<main>
<section id="intro-section">
<div class="banner">
</div>
<div class="banner-info">
<p>
<strong>Syncthing Tray provides a tray icon and further platform integration for Syncthing.</strong><br />
It focuses on GNU/Linux and Windows.
If you don't know Syncthing yet, it makes most sense to checkout the <a href="https://syncthing.net" target="blank">website of Syncthing</a> itself first.
</p>
<p>
This website is meant to provide an overview. Checkout the <a href="https://github.com/Martchus/syncthingtray/blob/master/README.md" target="blank">README
on GitHub</a> for many more (technical) details.
</p>
</div>
Syncthing Tray complements the normal web-based UI of Syncthing itself providing the following features:
<ul>
<li>A tray icon showing the overall status of Syncthing</li>
<li>A tray menu showing more detailed status information that also allows to quickly perform common actions such as triggering a rescan</li>
<li>Quick access to the normal web-based UI of Syncthing</li>
<li>A launcher for Syncthing (e.g. useful under Windows to avoid having a console window around)</li>
<li>
A context menu for the <a href="https://apps.kde.org/de/dolphin" target="blank">Dolphin file manager</a> to show the status of a folder and triggering
common actions
</li>
</ul>
<p>
The screenshot shows Syncthing Tray on <a href="https://kde.org/de/plasma-desktop" target="blank">KDE Plasma</a>.
Checkout the <a href="https://github.com/Martchus/syncthingtray?tab=readme-ov-file#screenshots" target="blank">screenshots section in the README</a> for
screenshots on other platforms.
</p>
</section>
<section id="downloads-section" style="display: none">
<h2>Downloads</h2>
<p id="downloads-loading">
Loading the latest release info from GitHub…
</p>
<p id="downloads-release-info" style="display: none">
The latest release is <span id="downloads-latest-release"></span>.
Checkout the <a href="https://github.com/Martchus/syncthingtray/releases" target="blank">releases section
on GitHub</a> for older releases.
</p>
<p>
This page is supposed to provide an overview. Checkout the <a href="https://github.com/Martchus/syncthingtray/blob/master/README.md#download" target="blank">"Downloads"-section</a>
of the README for all options and further details.
</p>
<div class="downloads-grid">
<div id="official-downloads">
<h3>Official downloads</h3>
<p>
Official downloads are signed with the GPG key
<a href="https://keyserver.ubuntu.com/pks/lookup?search=B9E36A7275FC61B464B67907E06FE8F53CDC6A4C&fingerprint=on&op=index" target="blank">B9E36A7275FC61B464B67907E06FE8F53CDC6A4C</a>
(except those hosted on OBS).
</p>
<div class="downloads-by-platform">
<div class="downloads-platform">
<input type="checkbox" id="downloads-checkbox-arch"/><label for="downloads-checkbox-arch">Arch Linux</label>
<ul id="downloads-platform-obs">
<li><a href="https://aur.archlinux.org/packages?K=Martchus&SeB=m" target="blank">AUR</a></li>
<li><a href="https://martchus.no-ip.biz/repo/arch/ownstuff" target="blank">Binary repository</a></li>
</ul>
<div>
Available packages:
<ul style="border: none;">
<li><code>syncthingtray</code>/<code>syncthingtray-qt6</code>: the latest release</li>
<li><code>syncthingtray-git</code>: Git version</li>
</ul>
</div>
<p>
<strong>Install preferably the <code>*-qt6</code> package.</strong> For KDE integrations, the major Qt version must match the
major KDE version.
</p>
<p>
<strong>Manually built packages from the AUR need to be re-built manually</strong> when a dependency such as Boost changes its
<a href="https://en.wikipedia.org/wiki/Soname" target="blank">soname</a>. This does <em>not</em> mean the package is out of date.
Note that this also counts when using an AUR helper.
</p>
<p>The binary repository can <strong>not</strong> be used on derivats such as Manjaro Linux.</p>
</div>
<div class="downloads-platform">
<input type="checkbox" id="downloads-checkbox-obs"/><label for="downloads-checkbox-obs">openSUSE Tumbleweed and Leap, Fedora</label>
<ul id="downloads-platform-obs">
<li>
<a href="https://software.opensuse.org/download.html?project=home:mkittler&package=syncthingtray" target="blank">Latest releases</a>
(<a href="https://download.opensuse.org/repositories/home:/mkittler">repository URL</a>)
</li>
<li>
<a href="https://software.opensuse.org/download.html?project=home:mkittler:vcs&package=syncthingtray" target="blank">Git versions</a>
(<a href="https://download.opensuse.org/repositories/home:/mkittler:/vcs">repository URL</a>)
</li>
</ul>
<div>
Available packages:
<ul style="border: none;">
<li><code>syncthingtray</code>/<code>syncthingtray-qt6</code>: Qt-widgets based GUI</li>
<li><code>syncthingplasmoid</code>/<code>syncthingplasmoid-qt6</code>: applet/plasmoid for Plasma desktop</li>
<li><code>syncthingfileitemaction</code>/<code>syncthingfileitemaction-qt6</code>: Dolphin/KIO integration</li>
<li><code>syncthingctl</code>/<code>syncthingctl-qt6</code>: command-line interface</li>
</ul>
</div>
<p>Install preferably the <code>*-qt6</code> packages if available for your OS.</p>
<p>Be sure to add the repository that matches the version of your OS and to keep it in sync when upgrading.</p>
<p>The linked download pages might be incomplete, use the repositories URL for a full list.</p>
</div>
<div class="downloads-platform">
<input type="checkbox" id="downloads-checkbox-pc-linux-gnu"/><label for="downloads-checkbox-pc-linux-gnu">GNU/Linux</label>
<ul id="downloads-platform-pc-linux-gnu"></ul>
<p>Requires <code>glibc>=2.26</code>, OpenGL and libX11. The distributions openSUSE Leap 15, Fedora 27, Debian 10 and Ubuntu 18.04 are recent enough (be sure the package <code>libopengl0</code> is installed on Debian/Ubuntu).</p>
<p>These downloads cannot include the Plasmoid/Applet (for the Plasma desktop) and the Dolphin integration for technical reasons. The KDE integrations therefore need to be installed via distribution-specific packages.</p>
</div>
<div class="downloads-platform">
<input type="checkbox" id="downloads-checkbox-windows10"/><label for="downloads-checkbox-windows10">Windows 10 and 11</label>
<ul id="downloads-platform-windows10"></ul>
<p>
These downloads require Windows 10 version 1809 or newer.
</p>
<p>
Windows SmartScreen will likely block the execution (you'll get a window saying "Windows protected your PC"); right click on the executable, select properties and tick the checkbox to allow the execution.
</p>
<p>
Antivirus software often <strong>wrongly</strong> considers the executable harmful. This is a known problem. Please don't create issues about it.
</p>
<p>
32-bit releases work and Pentium Pro or newer Intel/AMD-CPUs.
</p>
</div>
<div class="downloads-platform">
<input type="checkbox" id="downloads-checkbox-windows"/><label for="downloads-checkbox-windows">Windows 7 and newer</label>
<ul id="downloads-platform-windows"></ul>
<p>
On Windows 7 the bundled Go/Syncthing does not work. Use a version of Go/Syncthing that is older than 1.21/1.27.0 instead.
</p>
<p>
32-bit releases work on Pentium Pro or newer Intel/AMD-CPUs.
</p>
</div>
<div class="downloads-platform">
<input type="checkbox" id="downloads-checkbox-other"/><label for="downloads-checkbox-other">Other</label>
<ul id="downloads-platform-other"></ul>
</div>
</div>
</div>
<div id="community-downloads">
<h3>Community downloads</h3>
<p>
Those packages are provided by the community and might be more convenient to use depending on preferences. Community packages might not always
be up-to-date, though. Checkout <a href="https://repology.org/project/syncthingtray" target="blank">Repology</a> for a more detailed
list of packages and their versions.
</p>
<div class="downloads-platform">
<input type="checkbox" id="downloads-community-checkbox-debian"/><label for="downloads-community-checkbox-debian">Debian</label>
<ul>
<li>Generic tray application: <code>sudo apt install syncthingtray</code></li>
<li>KDE integrations: <code>sudo apt install syncthingtray-kde-plasma</code></li>
</ul>
<p>
Those packages <em>may</em> be available on Debian derivats (Ubuntu, Pop!_OS, …) as well.
</p>
</div>
<div class="downloads-platform">
<input type="checkbox" id="downloads-community-checkbox-windows10"/><label for="downloads-community-checkbox-windows10">Windows 10 and 11</label>
<ul>
<li><a href="https://community.chocolatey.org/packages/syncthingtray" target="blank">Chocolatey package</a></li>
<li><a href="https://winstall.app/apps/Martchus.syncthingtray" target="blank"><code>winget</code> package</a></li>
</ul>
</div>
</div>
</div>
</section>
<section id="doc-section" style="display: none">
<h2>Documentation</h2>
<p>
Syncthing Tray contains a wizard that will guide you though the setup of Syncthing Tray and Syncthing. It will allow you to use your currently running
Syncthing instance but can also start Syncthing for you (checkout
<a href="https://github.com/Martchus/syncthingtray/blob/master/README.md#does-this-launch-or-bundle-syncthing-itself-what-about-my-existing-syncthing-installation" target="blank">
the relevant README section</a> for details). Then you are ready to use Syncthing. That means pairing devices and adding folders to sync. For this, you should proceed
reading the <a href="https://docs.syncthing.net/intro/getting-started.html#configuring" target="blank">"Getting started" documentation of Syncthing itself</a>.
</p>
<p>
Syncthing Tray itself also has many configuration options. So it may be worthwhile to browse though the pages of the configuration dialog to tweak Syncthing
Tray to your needs, e.g. to turn off notification you may find annoying. Further documentation on how to configure Syncthing Tray can also be found in the README
as of the <a href="https://github.com/Martchus/syncthingtray/blob/master/README.md#general-remarks-on-the-configuration" target="blank">"General remarks on the configuration"
section</a>.
</p>
<h3>License and attribution</h3>
<p>
Copyright © Marius Kittler
</p>
<p>
Syncthing Tray is licensed under GPL-2-or-later. It also contains 3rd party content. Checkout the sections about licensing and attributions in
the <a href="https://github.com/Martchus/syncthingtray/blob/master/README.md">README on GitHub</a> for details. The icons on this website are from
<a href="https://materialdesignicons.com" target="blank">Material Design Icons</a>.
</p>
</section>
<section id="contact-section" style="display: none">
<h2>Contact</h2>
<p>
Issues can be <a href="https://github.com/Martchus/syncthingtray/issues/new/choose" target="blank">reported on GitHub</a>.
Please read the instructions in the issue template before filing an issue.
</p>
<p>
Discussions are welcome <a href="https://github.com/Martchus/syncthingtray/discussions" target="blank">on GitHub</a> and in the
<a href="https://forum.syncthing.net/t/yet-another-syncthing-tray" target="blank">Syncthing Tray thread</a> on the Syncthing forum.
</p>
</ul>
</section>
</main>
</body>
</html>

28
js/ajaxhelper.js Normal file

File diff suppressed because one or more lines are too long

161
js/main.js Normal file
View File

@ -0,0 +1,161 @@
import * as AjaxHelper from './ajaxhelper.js'
import * as SinglePage from './singlepage.js';
function main()
{
SinglePage.initPage({
'intro': {
},
'downloads': {
initializer: initializeDownloadsSection,
state: {params: undefined},
},
'doc': {
},
'contact': {
},
});
}
function initializeDownloadsSection()
{
if (window.downloadsInitialized) {
return true;
}
const query = new URLSearchParams(window.location.search);
queryReleases();
renderUserAgent(query.get("useragent") ?? window.navigator.userAgent);
return window.downloadsInitialized = true;
}
function renderUserAgent(userAgent)
{
const platform = determinePlatformFromUserAgent(userAgent);
const platformCheckbox = document.getElementById("downloads-checkbox-" + platform);
if (platformCheckbox) {
platformCheckbox.checked = true;
}
}
function queryReleases()
{
AjaxHelper.queryRoute("GET", "https://api.github.com/repos/Martchus/syncthingtray/releases", (xhr, ok) => {
if (!ok) {
return;
}
const releases = JSON.parse(xhr.responseText);
for (const release of releases) {
if (!release.draft) {
return renderRelease(release);
}
}
});
}
function determinePlatformFromAssetName(name)
{
if (name.includes("mingw32")) {
return name.includes("-qt5") && !name.includes("-qt6") ? "windows" : "windows10";
} else if (name.includes("pc-linux-gnu")) {
return "pc-linux-gnu";
}
}
function determinePlatformFromUserAgent(userAgent)
{
if (userAgent.includes("Linux")) {
return "pc-linux-gnu";
} else if (userAgent.includes("Windows")) {
return "windows10";
}
}
function determineDisplayNameForAsset(name)
{
let arch;
if (name.includes("i686-")) {
arch = "32-bit (Intel/AMD)";
} else if (name.includes("x86_64-")) {
arch = "64-bit (Intel/AMD)";
}
let component;
if (name.startsWith("syncthingctl-")) {
component = "Additional command-line client for Syncthing";
} else if (name.startsWith("syncthingtray-")) {
component = "Tray application";
}
if (arch && component) {
return `${arch}: ${component}`;
}
return name;
}
function renderAsset(asset)
{
const name = asset.name;
if (name.endsWith(".sig")) {
return;
}
const platform = determinePlatformFromAssetName(name);
const platformList = document.getElementById("downloads-platform-" + platform) ?? document.getElementById("downloads-platform-other");
const liElement = document.createElement("li");
const aElement = document.createElement("a");
const important = name.startsWith("syncthingtray-");
liElement.id = "downloads-asset-" + name;
aElement.target = "blank";
aElement.href = asset.browser_download_url;
aElement.appendChild(document.createTextNode(determineDisplayNameForAsset(name)));
liElement.appendChild(aElement);
if (important) {
aElement.style.fontWeight = "bold";
platformList.prepend(liElement);
} else {
platformList.appendChild(liElement);
}
}
function renderAssetSignature(asset)
{
const name = asset.name;
if (!name.endsWith(".sig")) {
return;
}
const nameWithoutSig = name.substr(0, name.length - 4);
const liElement = document.getElementById("downloads-asset-" + nameWithoutSig);
if (!liElement) {
return;
}
const aElement = document.createElement("a");
aElement.target = "blank";
aElement.href = asset.browser_download_url;
aElement.appendChild(document.createTextNode("signature"));
liElement.appendChild(document.createTextNode(" ("));
liElement.appendChild(aElement);
liElement.appendChild(document.createTextNode(")"));
}
function renderRelease(releaseInfo)
{
const releaseName = releaseInfo.name ?? "unknown";
const releaseDate = releaseInfo.published_at ?? "unknown";
document.getElementById("downloads-latest-release").innerText = `${releaseName} from ${releaseDate}`;
const assets = Array.isArray(releaseInfo.assets) ? releaseInfo.assets : [];
for (const asset of assets) {
renderAsset(asset);
}
for (const asset of assets) {
renderAssetSignature(asset);
}
const lists = document.querySelectorAll(".downloads-platform ul");
for (const list of lists) {
if (!list.firstChild) {
list.parentElement.style.display = 'none';
}
}
document.getElementById('downloads-loading').style.display = 'none';
document.getElementById('downloads-release-info').style.display = 'block';
}
main();

61
js/singlepage.js Normal file
View File

@ -0,0 +1,61 @@
export let sections = {};
export let sectionNames = [];
/// \brief 'main()' function which initializes the single page app.
export function initPage(pageSections)
{
sections = pageSections;
sectionNames = Object.keys(sections);
handleHashChange();
document.body.onhashchange = handleHashChange;
}
let preventHandlingHashChange = false;
let preventSectionInitializer = false;
function splitHashParts()
{
const currentHash = location.hash.substr(1);
const hashParts = currentHash.split('?');
for (let i = 0, len = hashParts.length; i != len; ++i) {
hashParts[i] = decodeURIComponent(hashParts[i]);
}
return hashParts;
}
/// \brief Shows the current section and hides other sections.
function handleHashChange()
{
if (preventHandlingHashChange) {
return;
}
const hashParts = splitHashParts();
const currentSectionName = hashParts.shift() || 'intro-section';
if (!currentSectionName.endsWith('-section')) {
return;
}
sectionNames.forEach(function (sectionName) {
const sectionData = sections[sectionName];
const sectionElement = document.getElementById(sectionName + '-section');
if (sectionElement.id === currentSectionName) {
const sectionInitializer = sectionData.initializer;
if (sectionInitializer === undefined || preventSectionInitializer || sectionInitializer(sectionElement, sectionData, hashParts)) {
sectionElement.style.display = 'block';
}
} else {
const sectionDestructor = sectionData.destructor;
if (sectionDestructor === undefined || sectionDestructor(sectionElement, sectionData, hashParts)) {
sectionElement.style.display = 'none';
}
}
const navLinkElement = document.getElementById(sectionName + '-nav-link');
if (sectionElement.id === currentSectionName) {
navLinkElement.classList.add('active');
} else {
navLinkElement.classList.remove('active');
}
});
}