[verified] Publish ReelBox source under GPLv3

This commit is contained in:
Hermes committed 2026-11-12 23:41:13 +00:00
commit db2b505ca3
445 files changed
+105274

No files matched your search

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

+57
View File
@@ -0,0 +1,57 @@
user www-data;
worker_processes 1;
pid /run/reelbox-web/nginx.pid;
error_log /var/log/reelbox/error.log warn;
events { worker_connections 256; }
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
client_body_temp_path /run/reelbox-web/client_temp;
proxy_temp_path /run/reelbox-web/proxy_temp;
fastcgi_temp_path /run/reelbox-web/fastcgi_temp;
uwsgi_temp_path /run/reelbox-web/uwsgi_temp;
scgi_temp_path /run/reelbox-web/scgi_temp;
server_tokens off;
sendfile on;
tcp_nopush on;
keepalive_timeout 30;
client_max_body_size 1k;
access_log off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_session_cache shared:ReelboxTLS:1m;
ssl_session_timeout 1d;
ssl_session_tickets off;
server {
# Verify ownership/firewall rules on a new host before enabling 443.
listen 443 ssl http2;
listen [::]:443 ssl http2;
# Keep the legacy listener available for previously released clients.
listen 8443 ssl http2;
listen [::]:8443 ssl http2;
server_name reelbox.dartty.top;
ssl_certificate /etc/letsencrypt/live/reelbox.dartty.top/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/reelbox.dartty.top/privkey.pem;
include /etc/reelbox/api-locations.conf;
root /var/www/reelbox/current;
index index.html;
include /etc/reelbox/security-headers.conf;
location / {
limit_except GET { deny all; }
try_files $uri $uri/ =404;
}
location /downloads/ {
limit_except GET { deny all; }
types {
application/vnd.android.package-archive apk;
application/zip zip;
text/plain txt;
}
autoindex off;
max_ranges 1;
try_files $uri =404;
include /etc/reelbox/security-headers.conf;
add_header Content-Disposition "attachment";
}
location ~ /\. { return 404; }
}
}
+30
View File
@@ -0,0 +1,30 @@
[Unit]
Description=Reelbox HTTPS download website
After=network.target
[Service]
Type=simple
RuntimeDirectory=reelbox-web
RuntimeDirectoryMode=0755
ExecStartPre=/usr/sbin/nginx -t -c /etc/reelbox/nginx.conf
ExecStart=/usr/sbin/nginx -c /etc/reelbox/nginx.conf -g "daemon off;"
ExecReload=/usr/sbin/nginx -t -c /etc/reelbox/nginx.conf
ExecReload=/usr/sbin/nginx -c /etc/reelbox/nginx.conf -s reload
KillSignal=SIGQUIT
TimeoutStopSec=15
Restart=on-failure
RestartSec=3
PrivateTmp=true
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
ReadWritePaths=/run/reelbox-web /var/log/reelbox
MemoryMax=64M
TasksMax=16
LimitNOFILE=2048
[Install]
WantedBy=multi-user.target
+8
View File
@@ -0,0 +1,8 @@
#!/bin/sh
set -eu
if [ "${RENEWED_LINEAGE:-}" = /etc/letsencrypt/live/reelbox.dartty.top ]; then
if systemctl is-active --quiet reelbox-web.service; then
/usr/sbin/nginx -t -c /etc/reelbox/nginx.conf
systemctl reload reelbox-web.service
fi
fi
+6
View File
@@ -0,0 +1,6 @@
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer" always;
add_header X-Frame-Options "DENY" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header Content-Security-Policy "default-src 'none'; img-src 'self'; style-src 'self'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'; upgrade-insecure-requests" always;
add_header Strict-Transport-Security "max-age=86400" always;
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><rect width="32" height="32" rx="8" fill="#0d0e11"/><path d="M10 7h12v19l-6-4-6 4Z" fill="none" stroke="#ff8075" stroke-width="2" stroke-linejoin="round"/></svg>

After

Width:  |  Height:  |  Size: 222 B

+53
View File
@@ -0,0 +1,53 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#0d0e11">
<meta name="description" content="Reelbox is an independent Android app for films, series and a device-local library. No accounts or subscriptions.">
<title>Reelbox — Your library, your device</title>
<link rel="canonical" href="https://reelbox.dartty.top/">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="stylesheet" href="/styles.css">
</head>
<body>
<a class="skip" href="#main">Skip to content</a>
<div class="page">
<header>
<a class="wordmark" href="/" aria-label="Reelbox home">Reelbox</a>
</header>
<main id="main">
<section class="hero" aria-labelledby="title">
<div class="copy">
<p class="eyebrow">For Android · Open source</p>
<h1 id="title">Films, series.<br>Your own library.</h1>
<p class="description">Watch films and series, save favourites and download for offline viewing. No account or subscription.</p>
<div class="actions">
<a class="download" href="/downloads/reelbox-0.4.4-arm64.apk" download>
<svg aria-hidden="true" viewBox="0 0 24 24"><path d="M12 3v12m-5-5 5 5 5-5M5 16v4h14v-4"/></svg>
Download for Android
</a>
</div>
<p class="release">v0.4.4 <span>·</span> ARM64 <span>·</span> Android 7.0+</p>
<p class="private-note"><svg aria-hidden="true" viewBox="0 0 24 24"><path d="M6 3h12v18l-6-4-6 4V3Z"/></svg>Your watchlist and history stay on your device</p>
</div>
<figure class="product">
<div class="screen"><img src="/assets/reelbox-intro.webp" width="780" height="1688" fetchpriority="high" alt="Reelbox’s first-run screen, with English and Persian language choices and the Start watching button"></div>
<figcaption>Inside Reelbox <span>English / فارسی</span></figcaption>
</figure>
</section>
</main>
<footer>
<p class="credit">Built by Darioush</p>
<div class="footer-links"><a href="/downloads/reelbox-0.4.4-source.zip">Source archive</a><a href="https://github.com/Ahoura239/ReelBox/blob/main/LICENSE">GPLv3</a><a href="/downloads/SHA256SUMS.txt">Checksums</a></div>
</footer>
</div>
</body>
<!-- Design process adapted from Unslop by Damir Sokolovsky (@heydamir),
https://heydamir.design/unslop, CC BY 4.0:
https://creativecommons.org/licenses/by/4.0/.
Original Reelbox implementation; source attribution, not visible promotion. -->
</html>
+48
View File
@@ -0,0 +1,48 @@
:root{color-scheme:dark;--bg:#0d0e11;--surface:#111216;--border:#303034;--ink:#f0e7e5;--secondary:#b8aeac;--muted:#99918f;--accent:#ff8075;--on-accent:#261312}
*{box-sizing:border-box}
html{min-width:320px;background:var(--bg);scroll-behavior:auto}
body{margin:0;color:var(--ink);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Arial,sans-serif;font-size:16px;font-weight:400;line-height:1.5;-webkit-font-smoothing:antialiased}
a{color:inherit;text-decoration:none;transition:color 140ms ease,background-color 140ms ease,border-color 140ms ease}
a:hover{color:var(--ink)}
a:focus-visible{outline:2px solid var(--accent);outline-offset:6px;border-radius:4px}
svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;flex:none}
.page{width:min(1184px,100%);margin:0 auto;padding:0 32px;min-height:100svh;display:flex;flex-direction:column}
header{display:flex;align-items:center;justify-content:space-between;gap:24px;min-height:104px;border-bottom:1px solid var(--border)}
.wordmark{font-size:28px;font-weight:500;line-height:36px;letter-spacing:-.6px}
.source-link{display:inline-flex;align-items:center;gap:8px;font-size:14px;color:var(--secondary)}
main{flex:1;display:flex;align-items:center}
.hero{width:100%;display:grid;grid-template-columns:minmax(0,1fr) 320px;align-items:center;gap:80px;padding:56px 0 64px}
.copy{max-width:640px}
p,h1,figure{margin:0}
.eyebrow{font-size:14px;line-height:20px;color:var(--secondary);margin-bottom:24px}
h1{font-size:clamp(48px,5.2vw,72px);line-height:1.06;letter-spacing:-2.4px;font-weight:400;text-wrap:balance}
.description{max-width:460px;font-size:18px;line-height:28px;color:var(--secondary);margin-top:28px}
.actions{display:flex;align-items:center;gap:16px;margin-top:36px}
.download{display:inline-flex;justify-content:center;align-items:center;gap:12px;min-height:52px;padding:12px 24px;border:1px solid transparent;border-radius:8px;background:var(--accent);color:var(--on-accent);font-weight:500;font-size:16px;line-height:24px}
.download:hover{color:var(--on-accent);background:#ff958c}
.download:active{background:#f47268}
.release{margin-top:16px;font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:12px;line-height:20px;font-variant-numeric:tabular-nums;color:var(--muted)}
.release span{padding:0 4px}
.private-note{display:flex;align-items:center;gap:12px;margin-top:36px;color:var(--secondary);font-size:14px;line-height:20px}
.private-note svg{color:var(--muted)}
.product{width:320px}
.screen{padding:12px;border:1px solid var(--border);border-radius:24px;background:var(--surface);box-shadow:0 16px 40px #0003;height:444px;overflow:hidden}
.screen img{display:block;width:100%;height:auto;border-radius:12px}
figcaption{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:16px;font-size:12px;line-height:20px;color:var(--muted)}
figcaption span{color:var(--secondary)}
footer{border-top:1px solid var(--border);padding:24px 0 28px;display:grid;grid-template-columns:1fr auto;gap:16px 32px;font-size:12px;line-height:20px;color:var(--muted)}
.credit{font-size:14px;color:var(--ink)}
.fine-print{margin-top:4px}
.copy .fine-print{font-size:12px;line-height:20px;color:var(--muted)}
.footer-links{display:flex;align-items:flex-start;gap:24px;padding-top:4px;color:var(--secondary)}
.footnote{grid-column:1/-1;display:flex;justify-content:space-between;flex-wrap:wrap;gap:8px 24px;font-size:11px;line-height:16px}
.footnote a{text-decoration:underline;text-underline-offset:3px;text-decoration-color:var(--border)}
.skip{position:absolute;left:16px;top:-80px;padding:12px 16px;background:var(--ink);color:var(--bg);z-index:10}
.skip:focus{top:16px}
@media(min-width:1600px){.hero{gap:112px;padding-top:80px;padding-bottom:80px}}
@media(max-width:960px){.hero{grid-template-columns:minmax(0,1fr) 280px;gap:40px}h1{font-size:56px;letter-spacing:-1.6px}.product{width:280px}.screen{height:392px;border-radius:24px}.description{font-size:16px;line-height:24px}.release span{padding:0 2px}}
@media(max-width:720px){.page{padding:0 24px}header{min-height:80px}.wordmark{font-size:24px;line-height:32px}.source-link{font-size:12px}.hero{grid-template-columns:1fr;gap:48px;padding:48px 0}.copy{max-width:520px}h1{font-size:48px;line-height:52px;letter-spacing:-1.6px}.eyebrow{margin-bottom:20px}.description{margin-top:24px;max-width:400px}.actions{margin-top:28px}.release{font-size:11px;line-height:20px}.private-note{margin-top:28px;font-size:12px}.product{width:min(320px,100%);justify-self:center}.screen{height:444px}.footer-links{gap:20px;flex-wrap:wrap}footer{grid-template-columns:1fr;gap:20px}.footnote{grid-column:auto;display:grid;gap:12px}.footnote span{display:block}}
@media(max-width:380px){.page{padding:0 20px}.source-link{gap:4px}h1{font-size:40px;line-height:44px;letter-spacing:-1.2px}.download{padding:12px 20px;font-size:14px}.product{width:280px}.screen{height:392px}}
@media(prefers-reduced-motion:reduce){a{transition:none}}
/* Design process: Unslop by Damir Sokolovsky (@heydamir), CC BY 4.0.
https://heydamir.design/unslop — original Reelbox implementation. */