v6.8.6: desktop 1.0.4 downloads, and a roadmap without status labels

This commit is contained in:
lockbitchat
2026-09-23 23:33:33 -04:00
parent 02380a7ecd
commit eac3009339
54 changed files with 334 additions and 475 deletions
+1 -1
View File
@@ -1696,7 +1696,7 @@ import { GroupCallMedia, mediaErrorCode } from './group/groupCallMedia.js';
// /download/v0.3.0/SecureBit.Chat_0.1.0_x64-setup.exe, a file that never
// existed, and the download 404s. A pinned tag keeps serving a real
// installer instead.
const SB_DESKTOP_VERSION = '1.0.3';
const SB_DESKTOP_VERSION = '1.0.4';
const SB_DESKTOP_RELEASE = `https://github.com/SecureBitChat/securebit-desktop/releases/download/v${SB_DESKTOP_VERSION}`;
const DOWNLOADS = {
mac: { name: 'macOS', format: '.dmg · Apple Silicon & Intel', icon: 'fab fa-apple', url: `${SB_DESKTOP_RELEASE}/SecureBit.Chat_${SB_DESKTOP_VERSION}_x64.dmg` },
+1 -1
View File
@@ -5,7 +5,7 @@
// The tag is pinned rather than using /releases/latest/download/: the filenames
// carry the version, so a `latest` link 404s the moment a newer release exists,
// whereas a pinned tag keeps serving a working (if older) installer.
const DESKTOP_VERSION = '1.0.3';
const DESKTOP_VERSION = '1.0.4';
const DESKTOP_RELEASE = `https://github.com/SecureBitChat/securebit-desktop/releases/download/v${DESKTOP_VERSION}`;
const DownloadApps = () => {
+8 -32
View File
@@ -44,33 +44,21 @@ function Roadmap() {
features: tList(`roadmap.${d.k}.features`)
}));
// `rgb` is the same colour as `color`, published as bare channels. The pill draws
// its fill and border from it at low alpha, and there is no way to add an alpha to
// a colour that a custom property has already resolved — hence the pair, which has
// to be kept in step.
// Three forms of the same status colour, because they are used three ways and only
// one of them is text. `color` is the word — it darkens in the light theme so it can
// be read on white. `solid` is the dot, which is a mark rather than a label and
// stays the brand colour in both themes. `rgb` is the channels, for the pill's fill
// and border at low alpha. The three have to be kept in step.
// The status of a milestone is shown by its marker on the timeline and the colour of
// its bullets, not by a word: the labels (Released, In development, ...) were taken
// out. `solid` is the dot colour, `line` the spine below it.
const META = {
released: { word: t('roadmap.status.released'), color: "var(--sb-green)", solid: "var(--sb-green-solid)", rgb: "var(--sb-green-rgb)", line: "rgba(var(--sb-green-rgb), 0.32)" },
current: { word: t('roadmap.status.current'), color: "var(--sb-orange)", solid: "var(--sb-orange-solid)", rgb: "var(--sb-orange-rgb)", line: "rgba(var(--sb-orange-rgb), 0.32)" },
dev: { word: t('roadmap.status.dev'), color: "var(--sb-yellow-2)", solid: "var(--sb-yellow-2-solid)", rgb: "var(--sb-yellow-2-rgb)", line: "rgba(var(--sb-ink), 0.08)" },
planned: { word: t('roadmap.status.planned'), color: "var(--sb-text-7)", solid: "var(--sb-text-7)", rgb: "var(--sb-text-7-rgb)", line: "rgba(var(--sb-ink), 0.08)" },
research: { word: t('roadmap.status.research'), color: "var(--sb-text-9)", solid: "var(--sb-text-9)", rgb: "var(--sb-text-9-rgb)", line: "rgba(var(--sb-ink), 0.08)" }
released: { solid: "var(--sb-green-solid)", line: "rgba(var(--sb-green-rgb), 0.32)" },
current: { solid: "var(--sb-orange-solid)", line: "rgba(var(--sb-orange-rgb), 0.32)" },
dev: { solid: "var(--sb-yellow-2-solid)", line: "rgba(var(--sb-ink), 0.08)" },
planned: { solid: "var(--sb-text-7)", line: "rgba(var(--sb-ink), 0.08)" },
research: { solid: "var(--sb-text-9)", line: "rgba(var(--sb-ink), 0.08)" }
};
const [open, setOpen] = React.useState({});
const isOpen = (i) => (open[i] === undefined ? DATA[i].status === 'current' : open[i]);
const toggle = (i) => setOpen((s) => ({ ...s, [i]: !isOpen(i) }));
// Was hexA(), which took the literal hex out of META and split it into channels by
// hand. Those literals are custom properties now, so there is nothing to parse at
// runtime — the browser does the substitution instead, and it does it again when
// the theme changes, which the old version could not.
const tint = (channels, a) => `rgba(${channels}, ${a})`;
const total = DATA.length;
const shipped = DATA.filter((d) => d.status === 'released' || d.status === 'current').length;
const upcoming = total - shipped;
@@ -162,18 +150,6 @@ function Roadmap() {
{!isMobile && <div style={{ marginTop: '3px', fontSize: '13.5px', color: 'var(--sb-text-6)' }}>{d.sub}</div>}
</div>
<div style={{ flex: 'none', display: 'flex', alignItems: 'center', gap: isMobile ? '8px' : '14px' }}>
{/* The status pill is desktop-only. On a phone its
word does not fit, and what was left — a bordered
box around a single coloured dot — said nothing the
marker on the timeline was not already saying in
the same colour, while taking room from the title.
So the whole pill goes, not just its label. */}
{!isMobile && (
<span style={{ display: 'inline-flex', alignItems: 'center', gap: '7px', padding: '6px 11px', borderRadius: '8px', background: tint(meta.rgb, 0.1), border: `1px solid ${tint(meta.rgb, 0.22)}`, fontFamily: MONO, fontSize: '10.5px', fontWeight: 600, color: meta.color, textTransform: 'uppercase', letterSpacing: '0.8px', whiteSpace: 'nowrap' }}>
<span style={{ width: '6px', height: '6px', borderRadius: '50%', background: meta.solid }} />
{meta.word}
</span>
)}
{!isMobile && <span style={{ fontFamily: MONO, fontSize: '12px', fontWeight: 500, color: 'var(--sb-text-7)', whiteSpace: 'nowrap', minWidth: '74px', textAlign: 'end' }}>{d.date}</span>}
<span style={{ color: 'var(--sb-text-9)', display: 'inline-flex', transition: 'transform .22s cubic-bezier(.2,.7,.3,1)', transform: opened ? 'rotate(180deg)' : 'rotate(0deg)' }}>
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.1" strokeLinecap="round" strokeLinejoin="round"><path d="M6 9l6 6 6-6" /></svg>
-5
View File
@@ -73,11 +73,6 @@ export const DICTIONARY = {
"roadmap.progress": "أُنجزت {shipped} من أصل {total} محطّة",
"roadmap.upcoming": "{upcoming} في الطريق",
"roadmap.keyFeatures": "أبرز المزايا",
"roadmap.status.released": "صدرت",
"roadmap.status.current": "الحالية",
"roadmap.status.dev": "قيد التطوير",
"roadmap.status.planned": "مُخطّطة",
"roadmap.status.research": "قيد البحث",
"hero.headlineTop": "خطٌّ مباشر",
"hero.headlineBottom": "لا يقرأه إلّا أنتما.",
"hero.subheading": "تُولَّد المفاتيح على جهازك وتُتبادَل ندّاً لندّ. بلا حسابات وبلا خوادم تحفظ رسائلك.",
-5
View File
@@ -73,11 +73,6 @@ export const DICTIONARY = {
"roadmap.progress": "{shipped} von {total} Meilensteinen erreicht",
"roadmap.upcoming": "{upcoming} in Arbeit",
"roadmap.keyFeatures": "Kernfunktionen",
"roadmap.status.released": "Veröffentlicht",
"roadmap.status.current": "Aktuell",
"roadmap.status.dev": "In Entwicklung",
"roadmap.status.planned": "Geplant",
"roadmap.status.research": "Forschung",
"hero.headlineTop": "Eine direkte Leitung,",
"hero.headlineBottom": "die nur Sie beide lesen können.",
"hero.subheading": "Die Schlüssel entstehen auf Ihrem Gerät und werden direkt zwischen den Geräten ausgetauscht. Keine Konten, keine Server, die Ihre Nachrichten speichern.",
-5
View File
@@ -73,11 +73,6 @@ export const DICTIONARY = {
"roadmap.progress": "{shipped} of {total} milestones shipped",
"roadmap.upcoming": "{upcoming} on the way",
"roadmap.keyFeatures": "Key features",
"roadmap.status.released": "Released",
"roadmap.status.current": "Current",
"roadmap.status.dev": "In development",
"roadmap.status.planned": "Planned",
"roadmap.status.research": "Research",
"hero.headlineTop": "A direct line",
"hero.headlineBottom": "only you two can read.",
"hero.subheading": "Keys are generated on your device and exchanged peer-to-peer. No accounts, no servers storing your messages.",
-5
View File
@@ -73,11 +73,6 @@ export const DICTIONARY = {
"roadmap.progress": "{shipped} de {total} hitos completados",
"roadmap.upcoming": "{upcoming} en camino",
"roadmap.keyFeatures": "Funciones clave",
"roadmap.status.released": "Publicado",
"roadmap.status.current": "Actual",
"roadmap.status.dev": "En desarrollo",
"roadmap.status.planned": "Planificado",
"roadmap.status.research": "Investigación",
"hero.headlineTop": "Una línea directa",
"hero.headlineBottom": "que solo leéis vosotros dos.",
"hero.subheading": "Las claves se generan en tu dispositivo y se intercambian directamente entre pares. Sin cuentas y sin servidores que guarden tus mensajes.",
-5
View File
@@ -73,11 +73,6 @@ export const DICTIONARY = {
"roadmap.progress": "{shipped} از {total} نقطهٔ عطف انجام شد",
"roadmap.upcoming": "{upcoming} در راه است",
"roadmap.keyFeatures": "ویژگی‌های کلیدی",
"roadmap.status.released": "منتشر شد",
"roadmap.status.current": "کنونی",
"roadmap.status.dev": "در دست توسعه",
"roadmap.status.planned": "برنامه‌ریزی‌شده",
"roadmap.status.research": "پژوهش",
"hero.headlineTop": "خطی مستقیم",
"hero.headlineBottom": "که فقط شما دو نفر می‌خوانید.",
"hero.subheading": "کلیدها روی دستگاه شما ساخته و همتا‌به‌همتا مبادله می‌شوند. بدون حساب، بدون سروری که پیام‌هایتان را نگه دارد.",
-5
View File
@@ -73,11 +73,6 @@ export const DICTIONARY = {
"roadmap.progress": "{shipped} jalons sur {total} atteints",
"roadmap.upcoming": "{upcoming} à venir",
"roadmap.keyFeatures": "Fonctions clés",
"roadmap.status.released": "Publié",
"roadmap.status.current": "En cours",
"roadmap.status.dev": "En développement",
"roadmap.status.planned": "Planifié",
"roadmap.status.research": "Recherche",
"hero.headlineTop": "Une ligne directe",
"hero.headlineBottom": "que vous seuls pouvez lire.",
"hero.subheading": "Les clés sont créées sur votre appareil et échangées directement entre pairs. Aucun compte, aucun serveur ne conserve vos messages.",
-5
View File
@@ -73,11 +73,6 @@ export const DICTIONARY = {
"roadmap.progress": "{shipped} מתוך {total} אבני דרך הושלמו",
"roadmap.upcoming": "{upcoming} בדרך",
"roadmap.keyFeatures": "יכולות מרכזיות",
"roadmap.status.released": "שוחרר",
"roadmap.status.current": "נוכחי",
"roadmap.status.dev": "בפיתוח",
"roadmap.status.planned": "מתוכנן",
"roadmap.status.research": "מחקר",
"hero.headlineTop": "קו ישיר",
"hero.headlineBottom": "שרק שניכם יכולים לקרוא.",
"hero.subheading": "המפתחות נוצרים במכשיר שלכם ומוחלפים עמית־לעמית. בלי חשבונות, בלי שרתים ששומרים את ההודעות.",
-5
View File
@@ -73,11 +73,6 @@ export const DICTIONARY = {
"roadmap.progress": "{total} में से {shipped} पड़ाव पूरे",
"roadmap.upcoming": "{upcoming} बाक़ी",
"roadmap.keyFeatures": "मुख्य विशेषताएँ",
"roadmap.status.released": "जारी",
"roadmap.status.current": "अभी चालू",
"roadmap.status.dev": "विकास में",
"roadmap.status.planned": "नियोजित",
"roadmap.status.research": "शोध",
"hero.headlineTop": "एक सीधी लाइन,",
"hero.headlineBottom": "जिसे सिर्फ़ आप दोनों पढ़ सकें।",
"hero.subheading": "कुंजियाँ आपके उपकरण पर बनती हैं और सीधे दोनों पक्षों के बीच बदली जाती हैं। न कोई खाता, न कोई सर्वर जो आपके संदेश रखे।",
-5
View File
@@ -73,11 +73,6 @@ export const DICTIONARY = {
"roadmap.progress": "{total}개 중 {shipped}개 완료",
"roadmap.upcoming": "{upcoming}개 남음",
"roadmap.keyFeatures": "주요 기능",
"roadmap.status.released": "출시됨",
"roadmap.status.current": "진행 중",
"roadmap.status.dev": "개발 중",
"roadmap.status.planned": "예정",
"roadmap.status.research": "연구",
"hero.headlineTop": "두 사람만 읽을 수 있는",
"hero.headlineBottom": "직통 회선.",
"hero.subheading": "키는 여러분의 기기에서 만들어지고 두 기기 사이에서 곧바로 교환됩니다. 계정도 없고 메시지를 보관하는 서버도 없습니다.",
-5
View File
@@ -73,11 +73,6 @@ export const DICTIONARY = {
"roadmap.progress": "Пройдено {shipped} из {total} этапов",
"roadmap.upcoming": "{upcoming} впереди",
"roadmap.keyFeatures": "Ключевые возможности",
"roadmap.status.released": "Выпущено",
"roadmap.status.current": "Текущий",
"roadmap.status.dev": "В разработке",
"roadmap.status.planned": "Запланировано",
"roadmap.status.research": "Исследование",
"hero.headlineTop": "Прямая линия,",
"hero.headlineBottom": "которую прочитаете только вы двое.",
"hero.subheading": "Ключи создаются на вашем устройстве и передаются напрямую между участниками. Без учётных записей и без серверов, хранящих ваши сообщения.",
-5
View File
@@ -73,11 +73,6 @@ export const DICTIONARY = {
"roadmap.progress": "Пройдено {shipped} з {total} етапів",
"roadmap.upcoming": "{upcoming} попереду",
"roadmap.keyFeatures": "Ключові можливості",
"roadmap.status.released": "Випущено",
"roadmap.status.current": "Поточний",
"roadmap.status.dev": "У розробці",
"roadmap.status.planned": "Заплановано",
"roadmap.status.research": "Дослідження",
"hero.headlineTop": "Пряма лінія,",
"hero.headlineBottom": "яку прочитаєте лише ви двоє.",
"hero.subheading": "Ключі створюються на вашому пристрої й передаються напряму між учасниками. Без облікових записів і без серверів, що зберігають ваші повідомлення.",
-5
View File
@@ -73,11 +73,6 @@ export const DICTIONARY = {
"roadmap.progress": "{total} میں سے {shipped} سنگِ میل مکمل",
"roadmap.upcoming": "{upcoming} راستے میں",
"roadmap.keyFeatures": "نمایاں خصوصیات",
"roadmap.status.released": "جاری ہوا",
"roadmap.status.current": "موجودہ",
"roadmap.status.dev": "زیرِ تعمیر",
"roadmap.status.planned": "منصوبہ بند",
"roadmap.status.research": "تحقیق",
"hero.headlineTop": "ایک سیدھی لکیر",
"hero.headlineBottom": "جسے صرف آپ دونوں پڑھ سکتے ہیں۔",
"hero.subheading": "کلیدیں آپ کے آلے پر بنتی ہیں اور ہم‌سطح تبادلہ ہوتا ہے۔ نہ اکاؤنٹ، نہ کوئی سرور جو آپ کے پیغام محفوظ کرے۔",
-5
View File
@@ -73,11 +73,6 @@ export const DICTIONARY = {
"roadmap.progress": "已完成 {total} 个里程碑中的 {shipped} 个",
"roadmap.upcoming": "还有 {upcoming} 个",
"roadmap.keyFeatures": "核心功能",
"roadmap.status.released": "已发布",
"roadmap.status.current": "进行中",
"roadmap.status.dev": "开发中",
"roadmap.status.planned": "已规划",
"roadmap.status.research": "研究中",
"hero.headlineTop": "一条只有你们两人",
"hero.headlineBottom": "才能读懂的直连线路。",
"hero.subheading": "密钥在你的设备上生成,并在两端之间直接交换。无需账号,没有服务器保存你的消息。",