Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion krillnotes-core/src/core/accepted_invite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ impl AcceptedInviteManager {
}
}
}
records.sort_by(|a, b| b.accepted_at.cmp(&a.accepted_at));
records.sort_by_key(|r| std::cmp::Reverse(r.accepted_at));
Ok(records)
}

Expand Down
16 changes: 6 additions & 10 deletions krillnotes-core/src/core/export_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -636,15 +636,8 @@ fn test_import_stamps_importer_identity_on_notes() {
)
.unwrap();

let ws_b = Workspace::open(
temp_dst.path(),
"",
"identity-b",
key_b,
test_gate(),
None,
)
.unwrap();
let ws_b =
Workspace::open(temp_dst.path(), "", "identity-b", key_b, test_gate(), None).unwrap();

// Importer is owner
assert!(ws_b.is_owner(), "importer should be workspace owner");
Expand Down Expand Up @@ -1150,5 +1143,8 @@ fn test_import_makes_importer_the_owner() {
pubkey_b,
"importer should become workspace owner after import"
);
assert!(imported_ws.is_owner(), "importer should be recognized as owner");
assert!(
imported_ws.is_owner(),
"importer should be recognized as owner"
);
}
4 changes: 2 additions & 2 deletions krillnotes-core/src/core/identity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -452,15 +452,15 @@ impl IdentityManager {
}
}
}
refs.sort_by(|a, b| b.last_used.cmp(&a.last_used));
refs.sort_by_key(|r| std::cmp::Reverse(r.last_used));
Ok(refs)
}

/// Look up the display name for a given base64-encoded public key.
/// Reads each identity file until a match is found. Returns `None` if
/// no local identity has that public key.
pub fn lookup_display_name(&self, public_key: &str) -> Option<String> {
for (_uuid, folder_name) in &self.folder_cache {
for folder_name in self.folder_cache.values() {
let identity_json = self
.home_dir
.join(folder_name)
Expand Down
2 changes: 1 addition & 1 deletion krillnotes-core/src/core/invite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ impl InviteManager {
let record: InviteRecord = serde_json::from_str(&json)?;
records.push(record);
}
records.sort_by(|a, b| b.created_at.cmp(&a.created_at));
records.sort_by_key(|r| std::cmp::Reverse(r.created_at));
Ok(records)
}

Expand Down
2 changes: 1 addition & 1 deletion krillnotes-core/src/core/received_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ impl ReceivedResponseManager {
}
}
}
records.sort_by(|a, b| b.received_at.cmp(&a.received_at));
records.sort_by_key(|r| std::cmp::Reverse(r.received_at));
Ok(records)
}

Expand Down
7 changes: 2 additions & 5 deletions krillnotes-core/src/core/scripting/display_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,10 +221,7 @@ pub fn table(headers: Array, rows: Array) -> String {
out.push_str("<tr class=\"kn-view-tr\">");
if let Ok(cells) = row.clone().try_cast::<Array>().ok_or(()) {
for cell in &cells {
out.push_str(&format!(
"<td class=\"kn-view-td\">{}</td>",
cell.to_string()
));
out.push_str(&format!("<td class=\"kn-view-td\">{cell}</td>",));
}
}
out.push_str("</tr>");
Expand Down Expand Up @@ -316,7 +313,7 @@ pub fn view_text(content: String) -> String {
pub fn list(items: Array) -> String {
let mut out = String::from("<ul class=\"kn-view-list\">");
for item in &items {
out.push_str(&format!("<li>{}</li>", item.to_string()));
out.push_str(&format!("<li>{item}</li>"));
}
out.push_str("</ul>");
out
Expand Down
2 changes: 1 addition & 1 deletion krillnotes-core/src/core/scripting/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ impl ScriptRegistry {
// argument means Rhai will dispatch any value type to this function.
engine.register_raw_fn(
"set_field",
&[
[
std::any::TypeId::of::<rhai::ImmutableString>(),
std::any::TypeId::of::<rhai::ImmutableString>(),
std::any::TypeId::of::<Dynamic>(),
Expand Down
4 changes: 3 additions & 1 deletion krillnotes-core/src/core/scripting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use std::sync::{Arc, Mutex};
// ── Thread-local SaveTransaction for Rhai write-path hooks ────────────────────

thread_local! {
static SAVE_TX: RefCell<Option<SaveTransaction>> = RefCell::new(None);
static SAVE_TX: RefCell<Option<SaveTransaction>> = const { RefCell::new(None) };
}

/// Sets the active [`SaveTransaction`] for the current thread.
Expand Down Expand Up @@ -308,6 +308,7 @@ impl ScriptRegistry {
///
/// Returns [`KrillnotesError::Scripting`] if the hook throws a Rhai error
/// or returns a malformed map.
#[allow(clippy::too_many_arguments)]
pub fn run_on_add_child_hook(
&self,
parent_schema_name: &str,
Expand Down Expand Up @@ -368,6 +369,7 @@ impl ScriptRegistry {
}

/// Returns `(schema_name, schema_version, migrations, ast)` for every registered schema.
#[allow(clippy::type_complexity)]
pub fn get_versioned_schemas(
&self,
) -> Vec<(
Expand Down
2 changes: 2 additions & 0 deletions krillnotes-core/src/core/scripting/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,7 @@ impl SchemaRegistry {

/// Returns `(schema_name, schema_version, migrations, ast)` for every registered schema.
/// Used by the Phase D migration pipeline to detect and migrate stale notes.
#[allow(clippy::type_complexity)]
pub(super) fn get_versioned_schemas(
&self,
) -> Vec<(
Expand Down Expand Up @@ -1022,6 +1023,7 @@ impl SchemaRegistry {
///
/// The hook must use the gated SaveTransaction API (`set_field`, `set_title`, `commit`).
/// Hooks that return a map (old-style direct mutation) are rejected with a migration error.
#[allow(clippy::too_many_arguments)]
pub(super) fn run_on_add_child_hook(
&self,
engine: &Engine,
Expand Down
9 changes: 2 additions & 7 deletions krillnotes-core/src/core/sync/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,15 @@ pub enum SendResult {
NotDelivered { reason: String },
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ChannelType {
Relay,
Folder,
#[default]
Manual,
}

impl Default for ChannelType {
fn default() -> Self {
ChannelType::Manual
}
}

impl std::fmt::Display for ChannelType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Expand Down
2 changes: 1 addition & 1 deletion krillnotes-core/src/core/sync/folder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ impl FolderChannel {

for entry in entries.flatten() {
let path = entry.path();
if path.extension().map_or(true, |ext| ext != "swarm") {
if path.extension().is_none_or(|ext| ext != "swarm") {
continue;
}

Expand Down
2 changes: 1 addition & 1 deletion krillnotes-core/src/core/workspace/attachments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ impl Workspace {
meta.note_id,
meta.filename,
meta.mime_type,
meta.size_bytes as i64,
meta.size_bytes,
meta.hash_sha256,
salt_bytes.as_slice(),
meta.created_at,
Expand Down
4 changes: 2 additions & 2 deletions krillnotes-core/src/core/workspace/hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ impl Workspace {
iters += 1;
if iters > new_creates.len() * new_creates.len() + 1 {
// Cycle guard — should never happen in practice; break to avoid infinite loop.
ordered_creates.extend(new_creates.drain(..));
ordered_creates.append(&mut new_creates);
break;
}
let mut next = Vec::with_capacity(new_creates.len());
Expand Down Expand Up @@ -386,7 +386,7 @@ impl Workspace {
new_creates = next;
if new_creates.len() == remaining {
// No progress — break to avoid infinite loop.
ordered_creates.extend(new_creates.drain(..));
ordered_creates.append(&mut new_creates);
break;
}
remaining = new_creates.len();
Expand Down
14 changes: 6 additions & 8 deletions krillnotes-core/src/core/workspace/notes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ impl Workspace {
device_id: self.device_id.clone(),
note_id: new_id.clone(),
parent_id: new_parent,
position: this_position as f64,
position: this_position,
schema: note.schema.clone(),
title: note.title.clone(),
fields: note.fields.clone(),
Expand Down Expand Up @@ -814,10 +814,10 @@ impl Workspace {
}
for value in n.fields.values() {
match value {
FieldValue::Text(s) | FieldValue::Email(s) => {
if s.to_lowercase().contains(&query_lower) {
return true;
}
FieldValue::Text(s) | FieldValue::Email(s)
if s.to_lowercase().contains(&query_lower) =>
{
return true;
}
_ => {}
}
Expand Down Expand Up @@ -913,8 +913,6 @@ impl Workspace {
/// HTML view when no hook is registered.
///
/// The default view auto-renders `textarea` fields as CommonMark markdown.
///

pub fn toggle_note_expansion(&mut self, note_id: &str) -> Result<()> {
let tx = self.storage.connection_mut().transaction()?;

Expand Down Expand Up @@ -1695,7 +1693,7 @@ impl Workspace {
/// 1. Evaluate group visibility
/// 2. Run field `validate` closures (only on visible fields)
/// 3. Check required constraints (only on visible fields)
/// 4-7. Delegate to `update_note` (on_save hook + DB write)
/// 4-7. Delegate to `update_note` (on_save hook + DB write)
///
/// Returns `SaveResult::ValidationErrors` when any step produces errors.
/// Returns `SaveResult::Ok(note)` on success.
Expand Down
12 changes: 9 additions & 3 deletions krillnotes-core/src/core/workspace/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,8 +422,14 @@ impl Workspace {
// 6. Apply the state change to working tables.
let mut scripts_changed = false;
// (attachment_id, note_id, filename, mime_type, blob)
let mut pending_attachment: Option<(String, String, String, Option<String>, Vec<u8>)> =
None;
#[allow(clippy::type_complexity)]
let mut pending_attachment: Option<(
String,
String,
String,
Option<String>,
Vec<u8>,
)> = None;
let mut pending_attachment_delete: Option<String> = None;
let tx = self.storage.connection_mut().transaction()?;
match &op {
Expand Down Expand Up @@ -738,7 +744,7 @@ impl Workspace {
pub fn import_snapshot_json(&mut self, data: &[u8]) -> Result<usize> {
log::info!(target: "krillnotes::sync", "importing snapshot ({} bytes)", data.len());
let snapshot: WorkspaceSnapshot =
serde_json::from_slice(data).map_err(|e| KrillnotesError::Json(e))?;
serde_json::from_slice(data).map_err(KrillnotesError::Json)?;

let note_count = snapshot.notes.len();
log::debug!(target: "krillnotes::sync", "snapshot contains {} notes, {} scripts", note_count, snapshot.user_scripts.len());
Expand Down
10 changes: 5 additions & 5 deletions krillnotes-core/src/core/workspace/undo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ impl Workspace {
/// The value is clamped to `[1, 500]`. If the new limit is smaller than
/// the current stack depth, the oldest entries are dropped.
pub fn set_undo_limit(&mut self, limit: usize) -> Result<()> {
let limit = limit.max(1).min(500);
let limit = limit.clamp(1, 500);
self.storage.connection().execute(
"INSERT OR REPLACE INTO workspace_meta (key, value) VALUES ('undo_limit', ?)",
[limit.to_string()],
Expand Down Expand Up @@ -331,13 +331,13 @@ impl Workspace {
/// would require:
///
/// - `DeleteNote` (undo was: un-do a CreateNote) → redo re-deletes.
/// Build `SubtreeRestore` from current state.
/// Build `SubtreeRestore` from current state.
/// - `SubtreeRestore` (undo was: un-do a DeleteNote) → redo re-deletes root.
/// Build `DeleteNote`.
/// Build `DeleteNote`.
/// - `NoteRestore` → redo re-updates. Capture current state as `NoteRestore`.
/// - `PositionRestore`→ redo re-moves. Capture current position as `PositionRestore`.
/// - `DeleteScript` → redo re-deletes. Script no longer exists post-undo;
/// use a stub `ScriptRestore` (deletion needs no data).
/// use a stub `ScriptRestore` (deletion needs no data).
/// - `ScriptRestore` → redo re-restores. Build `DeleteScript`.
/// - `Batch` → recurse in reverse LIFO order.
fn build_redo_inverse(&self, undo_entry: &UndoEntry) -> Result<RetractInverse> {
Expand Down Expand Up @@ -520,7 +520,7 @@ impl Workspace {
VALUES (?,?,?,?,?,?,?,?)",
rusqlite::params![
att.id, att.note_id, att.filename, att.mime_type,
att.size_bytes as i64, att.hash_sha256,
att.size_bytes, att.hash_sha256,
salt_bytes.as_slice(), att.created_at,
],
)?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ pub fn list_accepted_invites(
Ok(records.into_iter().map(AcceptedInviteInfo::from).collect())
}

#[allow(clippy::too_many_arguments)]
#[tauri::command]
pub fn save_accepted_invite(
state: State<'_, AppState>,
Expand Down
39 changes: 18 additions & 21 deletions krillnotes-desktop/src-tauri/src/commands/identity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,28 +348,25 @@ pub fn unlock_identity(
&account.relay_url,
);
id_client.set_session_token(&session.session_token);
match id_client.add_device(&identity_pubkey_hex) {
Ok(result) => {
if let Ok(nonce) =
krillnotes_core::core::sync::relay::auth::decrypt_pop_challenge(
&identity_signing_key,
&result.challenge.encrypted_nonce,
&result.challenge.server_public_key,
)
{
let _ = id_client.verify_device(
&identity_pubkey_hex,
&hex::encode(&nonce),
None,
);
log::info!(
"Registered identity public key on {}",
account.relay_url
);
}
if let Ok(result) = id_client.add_device(&identity_pubkey_hex) {
if let Ok(nonce) =
krillnotes_core::core::sync::relay::auth::decrypt_pop_challenge(
&identity_signing_key,
&result.challenge.encrypted_nonce,
&result.challenge.server_public_key,
)
{
let _ = id_client.verify_device(
&identity_pubkey_hex,
&hex::encode(&nonce),
None,
);
log::info!(
"Registered identity public key on {}",
account.relay_url
);
}
Err(_) => {} // 409 KEY_EXISTS expected
}
} // Err: 409 KEY_EXISTS expected
}

// Update account with new session + device key
Expand Down
1 change: 1 addition & 0 deletions krillnotes-desktop/src-tauri/src/commands/invites.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ pub fn list_invites(
Ok(records.into_iter().map(InviteInfo::from).collect())
}

#[allow(clippy::too_many_arguments)]
#[tauri::command]
pub fn create_invite(
window: tauri::Window,
Expand Down
4 changes: 3 additions & 1 deletion krillnotes-desktop/src-tauri/src/commands/notes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,9 @@ pub fn get_note_verified_by(
let label = window.label();
let workspaces = state.workspaces.lock().expect("Mutex poisoned");
let ws = workspaces.get(label).ok_or("No workspace open")?;
let raw_key = ws.get_note_verified_by(&note_id).map_err(|e| e.to_string())?;
let raw_key = ws
.get_note_verified_by(&note_id)
.map_err(|e| e.to_string())?;

if raw_key.is_empty() {
return Ok(String::new());
Expand Down
1 change: 1 addition & 0 deletions krillnotes-desktop/src-tauri/src/commands/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ pub async fn poll_sync(

/// One-click command: create an invite + upload it to the relay + return the
/// shareable URL. The invite record is persisted with `relay_url` set.
#[allow(clippy::too_many_arguments)]
#[tauri::command]
pub async fn share_invite_link(
window: Window,
Expand Down
Loading
Loading