Compare commits
2 commits
ec731fdb4b
...
c40e093d01
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c40e093d01 | ||
|
|
cba30a1bb3 |
12 changed files with 210 additions and 23 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "itsgoin-cli"
|
name = "itsgoin-cli"
|
||||||
version = "0.5.0"
|
version = "0.5.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "itsgoin-core"
|
name = "itsgoin-core"
|
||||||
version = "0.5.0"
|
version = "0.5.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
|
||||||
|
|
@ -150,26 +150,57 @@ pub async fn import_public_posts(
|
||||||
let mut imported = 0usize;
|
let mut imported = 0usize;
|
||||||
let mut blobs_imported = 0usize;
|
let mut blobs_imported = 0usize;
|
||||||
|
|
||||||
|
info!(post_count = parsed.posts.len(), skipped = parsed.skipped, "Import phase 2: storing to DB");
|
||||||
|
|
||||||
|
// Ensure we follow ourselves so imported posts appear in feed
|
||||||
|
{
|
||||||
|
let s = storage.get().await;
|
||||||
|
let _ = s.add_follow(our_node_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
let now = now_ms();
|
||||||
|
|
||||||
for (new_post, _vis, blob_data) in &parsed.posts {
|
for (new_post, _vis, blob_data) in &parsed.posts {
|
||||||
let new_id = compute_post_id(new_post);
|
let new_id = compute_post_id(new_post);
|
||||||
|
|
||||||
let s = storage.get().await;
|
let s = storage.get().await;
|
||||||
if s.get_post(&new_id).ok().flatten().is_some() {
|
if s.get_post(&new_id).ok().flatten().is_some() {
|
||||||
continue; // duplicate
|
|
||||||
}
|
|
||||||
s.store_post_with_visibility(&new_id, new_post, &PostVisibility::Public)?;
|
|
||||||
drop(s);
|
drop(s);
|
||||||
|
debug!(post = hex::encode(new_id), "Import: skipping duplicate post");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Store post with intent (matches create_post_with_visibility behavior)
|
||||||
|
s.store_post_with_intent(&new_id, new_post, &PostVisibility::Public, &crate::types::VisibilityIntent::Public)?;
|
||||||
|
|
||||||
|
// Store blobs + record them, matching normal post creation
|
||||||
for (att, data) in blob_data {
|
for (att, data) in blob_data {
|
||||||
if !blob_store.has(&att.cid) {
|
if !blob_store.has(&att.cid) {
|
||||||
blob_store.store(&att.cid, data)?;
|
blob_store.store(&att.cid, data)?;
|
||||||
let s = storage.get().await;
|
}
|
||||||
let _ = s.record_blob(&att.cid, &new_id, our_node_id, data.len() as u64, &att.mime_type, att.size_bytes);
|
s.record_blob(&att.cid, &new_id, our_node_id, data.len() as u64, &att.mime_type, att.size_bytes)?;
|
||||||
|
let _ = s.pin_blob(&att.cid);
|
||||||
blobs_imported += 1;
|
blobs_imported += 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// Create BlobHeader (matches what engagement/sync expects)
|
||||||
|
let header = crate::types::BlobHeader {
|
||||||
|
post_id: new_id,
|
||||||
|
author: *our_node_id,
|
||||||
|
reactions: vec![],
|
||||||
|
comments: vec![],
|
||||||
|
policy: crate::types::CommentPolicy::default(),
|
||||||
|
updated_at: now,
|
||||||
|
thread_splits: vec![],
|
||||||
|
receipt_slots: vec![],
|
||||||
|
comment_slots: vec![],
|
||||||
|
prior_author: None,
|
||||||
|
};
|
||||||
|
let header_json = serde_json::to_string(&header).unwrap_or_default();
|
||||||
|
let _ = s.store_blob_header(&new_id, our_node_id, &header_json, now);
|
||||||
|
drop(s);
|
||||||
|
|
||||||
imported += 1;
|
imported += 1;
|
||||||
|
debug!(imported, post = hex::encode(new_id), "Import: stored post");
|
||||||
}
|
}
|
||||||
|
|
||||||
info!(imported, skipped = parsed.skipped, blobs = blobs_imported, "Public post import complete");
|
info!(imported, skipped = parsed.skipped, blobs = blobs_imported, "Public post import complete");
|
||||||
|
|
|
||||||
|
|
@ -1561,6 +1561,10 @@ impl Network {
|
||||||
};
|
};
|
||||||
|
|
||||||
let (candidate_id, score) = match candidate {
|
let (candidate_id, score) = match candidate {
|
||||||
|
Some((nid, score)) if nid == self.our_node_id => {
|
||||||
|
debug!("Growth loop: skipping self as candidate");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
Some(c) => c,
|
Some(c) => c,
|
||||||
None => {
|
None => {
|
||||||
debug!("Growth loop: no N2 candidates available");
|
debug!("Growth loop: no N2 candidates available");
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "itsgoin-desktop"
|
name = "itsgoin-desktop"
|
||||||
version = "0.5.0"
|
version = "0.5.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -2144,6 +2144,72 @@
|
||||||
"const": "core:window:deny-unminimize",
|
"const": "core:window:deny-unminimize",
|
||||||
"markdownDescription": "Denies the unminimize command without any pre-configured scope."
|
"markdownDescription": "Denies the unminimize command without any pre-configured scope."
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"description": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n\n#### This default permission set includes:\n\n- `allow-message`\n- `allow-save`\n- `allow-open`",
|
||||||
|
"type": "string",
|
||||||
|
"const": "dialog:default",
|
||||||
|
"markdownDescription": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n\n#### This default permission set includes:\n\n- `allow-message`\n- `allow-save`\n- `allow-open`"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enables the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)",
|
||||||
|
"type": "string",
|
||||||
|
"const": "dialog:allow-ask",
|
||||||
|
"markdownDescription": "Enables the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enables the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)",
|
||||||
|
"type": "string",
|
||||||
|
"const": "dialog:allow-confirm",
|
||||||
|
"markdownDescription": "Enables the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enables the message command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "dialog:allow-message",
|
||||||
|
"markdownDescription": "Enables the message command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enables the open command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "dialog:allow-open",
|
||||||
|
"markdownDescription": "Enables the open command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enables the save command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "dialog:allow-save",
|
||||||
|
"markdownDescription": "Enables the save command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Denies the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)",
|
||||||
|
"type": "string",
|
||||||
|
"const": "dialog:deny-ask",
|
||||||
|
"markdownDescription": "Denies the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Denies the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)",
|
||||||
|
"type": "string",
|
||||||
|
"const": "dialog:deny-confirm",
|
||||||
|
"markdownDescription": "Denies the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Denies the message command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "dialog:deny-message",
|
||||||
|
"markdownDescription": "Denies the message command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Denies the open command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "dialog:deny-open",
|
||||||
|
"markdownDescription": "Denies the open command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Denies the save command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "dialog:deny-save",
|
||||||
|
"markdownDescription": "Denies the save command without any pre-configured scope."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"description": "This permission set configures which\nnotification features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all notification related features.\n\n\n#### This default permission set includes:\n\n- `allow-is-permission-granted`\n- `allow-request-permission`\n- `allow-notify`\n- `allow-register-action-types`\n- `allow-register-listener`\n- `allow-cancel`\n- `allow-get-pending`\n- `allow-remove-active`\n- `allow-get-active`\n- `allow-check-permissions`\n- `allow-show`\n- `allow-batch`\n- `allow-list-channels`\n- `allow-delete-channel`\n- `allow-create-channel`\n- `allow-permission-state`",
|
"description": "This permission set configures which\nnotification features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all notification related features.\n\n\n#### This default permission set includes:\n\n- `allow-is-permission-granted`\n- `allow-request-permission`\n- `allow-notify`\n- `allow-register-action-types`\n- `allow-register-listener`\n- `allow-cancel`\n- `allow-get-pending`\n- `allow-remove-active`\n- `allow-get-active`\n- `allow-check-permissions`\n- `allow-show`\n- `allow-batch`\n- `allow-list-channels`\n- `allow-delete-channel`\n- `allow-create-channel`\n- `allow-permission-state`",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
|
|
||||||
|
|
@ -2144,6 +2144,72 @@
|
||||||
"const": "core:window:deny-unminimize",
|
"const": "core:window:deny-unminimize",
|
||||||
"markdownDescription": "Denies the unminimize command without any pre-configured scope."
|
"markdownDescription": "Denies the unminimize command without any pre-configured scope."
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"description": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n\n#### This default permission set includes:\n\n- `allow-message`\n- `allow-save`\n- `allow-open`",
|
||||||
|
"type": "string",
|
||||||
|
"const": "dialog:default",
|
||||||
|
"markdownDescription": "This permission set configures the types of dialogs\navailable from the dialog plugin.\n\n#### Granted Permissions\n\nAll dialog types are enabled.\n\n\n\n#### This default permission set includes:\n\n- `allow-message`\n- `allow-save`\n- `allow-open`"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enables the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)",
|
||||||
|
"type": "string",
|
||||||
|
"const": "dialog:allow-ask",
|
||||||
|
"markdownDescription": "Enables the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enables the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)",
|
||||||
|
"type": "string",
|
||||||
|
"const": "dialog:allow-confirm",
|
||||||
|
"markdownDescription": "Enables the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `allow-message` and will be removed in v3)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enables the message command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "dialog:allow-message",
|
||||||
|
"markdownDescription": "Enables the message command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enables the open command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "dialog:allow-open",
|
||||||
|
"markdownDescription": "Enables the open command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Enables the save command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "dialog:allow-save",
|
||||||
|
"markdownDescription": "Enables the save command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Denies the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)",
|
||||||
|
"type": "string",
|
||||||
|
"const": "dialog:deny-ask",
|
||||||
|
"markdownDescription": "Denies the ask command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Denies the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)",
|
||||||
|
"type": "string",
|
||||||
|
"const": "dialog:deny-confirm",
|
||||||
|
"markdownDescription": "Denies the confirm command without any pre-configured scope. (**DEPRECATED**: This is now an alias to `deny-message` and will be removed in v3)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Denies the message command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "dialog:deny-message",
|
||||||
|
"markdownDescription": "Denies the message command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Denies the open command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "dialog:deny-open",
|
||||||
|
"markdownDescription": "Denies the open command without any pre-configured scope."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Denies the save command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"const": "dialog:deny-save",
|
||||||
|
"markdownDescription": "Denies the save command without any pre-configured scope."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"description": "This permission set configures which\nnotification features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all notification related features.\n\n\n#### This default permission set includes:\n\n- `allow-is-permission-granted`\n- `allow-request-permission`\n- `allow-notify`\n- `allow-register-action-types`\n- `allow-register-listener`\n- `allow-cancel`\n- `allow-get-pending`\n- `allow-remove-active`\n- `allow-get-active`\n- `allow-check-permissions`\n- `allow-show`\n- `allow-batch`\n- `allow-list-channels`\n- `allow-delete-channel`\n- `allow-create-channel`\n- `allow-permission-state`",
|
"description": "This permission set configures which\nnotification features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all notification related features.\n\n\n#### This default permission set includes:\n\n- `allow-is-permission-granted`\n- `allow-request-permission`\n- `allow-notify`\n- `allow-register-action-types`\n- `allow-register-listener`\n- `allow-cancel`\n- `allow-get-pending`\n- `allow-remove-active`\n- `allow-get-active`\n- `allow-check-permissions`\n- `allow-show`\n- `allow-batch`\n- `allow-list-channels`\n- `allow-delete-channel`\n- `allow-create-channel`\n- `allow-permission-state`",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"productName": "itsgoin",
|
"productName": "itsgoin",
|
||||||
"version": "0.5.0",
|
"version": "0.5.1",
|
||||||
"identifier": "com.itsgoin.app",
|
"identifier": "com.itsgoin.app",
|
||||||
"build": {
|
"build": {
|
||||||
"frontendDist": "../../frontend",
|
"frontendDist": "../../frontend",
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"security": {
|
"security": {
|
||||||
"csp": "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' blob: http://asset.localhost; media-src 'self' blob:",
|
"csp": "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' blob: http://asset.localhost; media-src 'self' blob: http://asset.localhost",
|
||||||
"assetProtocol": {
|
"assetProtocol": {
|
||||||
"enable": true,
|
"enable": true,
|
||||||
"scope": ["$APPDATA/**", "$HOME/.local/share/itsgoin/**"]
|
"scope": ["$APPDATA/**", "$HOME/.local/share/itsgoin/**"]
|
||||||
|
|
@ -33,6 +33,11 @@
|
||||||
"icons/128x128@2x.png",
|
"icons/128x128@2x.png",
|
||||||
"icons/icon.icns",
|
"icons/icon.icns",
|
||||||
"icons/icon.ico"
|
"icons/icon.ico"
|
||||||
]
|
],
|
||||||
|
"linux": {
|
||||||
|
"appimage": {
|
||||||
|
"bundleMediaFramework": true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3514,7 +3514,6 @@ $('#import-btn').addEventListener('click', () => {
|
||||||
}
|
}
|
||||||
status.textContent = result;
|
status.textContent = result;
|
||||||
toast('Import complete!');
|
toast('Import complete!');
|
||||||
loadFeed(true);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
status.textContent = 'Error: ' + e;
|
status.textContent = 'Error: ' + e;
|
||||||
toast('Import failed: ' + e);
|
toast('Import failed: ' + e);
|
||||||
|
|
@ -3674,7 +3673,7 @@ async function init() {
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
if (isFirstRun) {
|
if (isFirstRun) {
|
||||||
// First-run chooser: start fresh or import
|
// First-run: start fresh or import
|
||||||
const chooser = document.createElement('div');
|
const chooser = document.createElement('div');
|
||||||
chooser.className = 'image-lightbox';
|
chooser.className = 'image-lightbox';
|
||||||
chooser.style.cursor = 'default';
|
chooser.style.cursor = 'default';
|
||||||
|
|
@ -3698,6 +3697,10 @@ async function init() {
|
||||||
// Open the import wizard
|
// Open the import wizard
|
||||||
document.getElementById('import-btn')?.click();
|
document.getElementById('import-btn')?.click();
|
||||||
});
|
});
|
||||||
|
} else if (info && !info.hasProfile) {
|
||||||
|
// Not first run, but no profile set — show name setup
|
||||||
|
setupOverlay.classList.remove('hidden');
|
||||||
|
setupName.focus();
|
||||||
}
|
}
|
||||||
// Pre-load feed + messages from local DB (instant — no network needed)
|
// Pre-load feed + messages from local DB (instant — no network needed)
|
||||||
await loadFeed(true).catch(() => {});
|
await loadFeed(true).catch(() => {});
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
|
|
||||||
<div class="container wide">
|
<div class="container wide">
|
||||||
<section>
|
<section>
|
||||||
<span class="version-badge">v0.5.0-beta — 2026-04-05</span>
|
<span class="version-badge">v0.5.1-beta — 2026-04-16</span>
|
||||||
<h1 style="font-size: 2rem; font-weight: 800; letter-spacing: -0.03em; margin-bottom: 0.5rem;">Design Document</h1>
|
<h1 style="font-size: 2rem; font-weight: 800; letter-spacing: -0.03em; margin-bottom: 0.5rem;">Design Document</h1>
|
||||||
<p>This is the canonical technical reference for ItsGoin. It describes the vision, the architecture, and the current state of every subsystem — with full implementation detail. This document is versioned; each update records what changed.</p>
|
<p>This is the canonical technical reference for ItsGoin. It describes the vision, the architecture, and the current state of every subsystem — with full implementation detail. This document is versioned; each update records what changed.</p>
|
||||||
<div class="card" style="margin-top: 1rem;">
|
<div class="card" style="margin-top: 1rem;">
|
||||||
|
|
|
||||||
|
|
@ -41,21 +41,21 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2 style="margin-top: 2rem;">Beta Release</h2>
|
<h2 style="margin-top: 2rem;">Beta Release</h2>
|
||||||
<p style="color: var(--text-muted); font-size: 0.85rem;">Version 0.5.0-beta — April 5, 2026</p>
|
<p style="color: var(--text-muted); font-size: 0.85rem;">Version 0.5.1-beta — April 16, 2026</p>
|
||||||
<p style="color: var(--text-muted); font-size: 0.85rem;">Multi-identity, export/import, post merge with decryption key. May contain bugs — stable release recommended for daily use.</p>
|
<p style="color: var(--text-muted); font-size: 0.85rem;">Multi-identity, export/import, post merge with decryption key. May contain bugs — stable release recommended for daily use.</p>
|
||||||
|
|
||||||
<div class="downloads">
|
<div class="downloads">
|
||||||
<a href="itsgoin-0.5.0-beta.apk" class="download-btn btn-android" style="border-color: var(--accent);">
|
<a href="itsgoin-0.5.1-beta.apk" class="download-btn btn-android" style="border-color: var(--accent);">
|
||||||
Android APK
|
Android APK
|
||||||
<span class="sub">v0.5.0-beta</span>
|
<span class="sub">v0.5.1-beta</span>
|
||||||
</a>
|
</a>
|
||||||
<a href="itsgoin_0.5.0-beta_amd64.AppImage" class="download-btn btn-linux" style="border-color: var(--accent);">
|
<a href="itsgoin_0.5.1-beta_amd64.AppImage" class="download-btn btn-linux" style="border-color: var(--accent);">
|
||||||
Linux AppImage
|
Linux AppImage
|
||||||
<span class="sub">v0.5.0-beta</span>
|
<span class="sub">v0.5.1-beta</span>
|
||||||
</a>
|
</a>
|
||||||
<a href="itsgoin-cli-0.5.0-beta-linux-amd64" class="download-btn btn-linux" style="border-color: var(--accent);">
|
<a href="itsgoin-cli-0.5.1-beta-linux-amd64" class="download-btn btn-linux" style="border-color: var(--accent);">
|
||||||
Linux CLI / Anchor
|
Linux CLI / Anchor
|
||||||
<span class="sub">v0.5.0-beta</span>
|
<span class="sub">v0.5.1-beta</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -105,6 +105,18 @@
|
||||||
<section>
|
<section>
|
||||||
<h2>Changelog</h2>
|
<h2>Changelog</h2>
|
||||||
<div class="changelog">
|
<div class="changelog">
|
||||||
|
<div class="changelog-date">v0.5.1-beta — April 16, 2026</div>
|
||||||
|
<ul>
|
||||||
|
<li><strong>AppImage video fix</strong> — Bundled full GStreamer media framework. Video and audio now play correctly in AppImage builds (previously caused WebKit freeze due to missing plugins).</li>
|
||||||
|
<li><strong>Import fix</strong> — Imported posts now create proper BlobHeaders, visibility intents, and pinned blobs. Imported posts are indistinguishable from locally created ones.</li>
|
||||||
|
<li><strong>First-run chooser</strong> — New installs show “Start Fresh” or “Import an Identity” dialog instead of a blank profile setup.</li>
|
||||||
|
<li><strong>File pickers</strong> — Native Browse buttons on export (folder picker) and import (ZIP file picker) dialogs.</li>
|
||||||
|
<li><strong>Identity switch fix</strong> — Old node properly shut down before starting new one. Prevents zombie background tasks after multiple identity switches.</li>
|
||||||
|
<li><strong>Export path fix</strong> — Relative output paths (e.g. “Downloads”) resolve to home directory instead of process working directory.</li>
|
||||||
|
<li><strong>Lightbox fix</strong> — Clicking form elements inside wizards no longer closes the overlay.</li>
|
||||||
|
<li><strong>Lock contention</strong> — Three remaining handlers (pull request, address request, session relay) converted to brief-lock pattern.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<div class="changelog-date">v0.5.0-beta — April 5, 2026</div>
|
<div class="changelog-date">v0.5.0-beta — April 5, 2026</div>
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>Multi-identity</strong> — Create, switch, and delete multiple identities on one device. Per-identity data directories with hot-swap switching (~3s). Legacy flat layout auto-migrates on first launch.</li>
|
<li><strong>Multi-identity</strong> — Create, switch, and delete multiple identities on one device. Per-identity data directories with hot-swap switching (~3s). Legacy flat layout auto-migrates on first launch.</li>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue