Radish alpha
r
rad:z4D5UCArafTzTQpDZNQRuqswh3ury
Radicle desktop app
Radicle
Git
Fix inbox pagination cursor and sorting
Open did:key:z6MkkfM3...sVz5 opened 1 year ago
7 files changed +40 -44 87f54917 fb1649cc
modified crates/radicle-tauri/src/commands/inbox.rs
@@ -21,7 +21,7 @@ pub fn list_notifications(
    sqlite_service: tauri::State<Service<Sqlite>>,
    params: notification::RepoGroupParams,
) -> Result<
-
    PaginatedQuery<BTreeMap<git::Qualified<'static>, Vec<notification::NotificationItem>>>,
+
    PaginatedQuery<Vec<(git::Qualified<'static>, Vec<notification::NotificationItem>)>>,
    Error,
> {
    let profile = &ctx.profile;
@@ -127,7 +127,7 @@ pub fn list_notifications(
            (qualified, items)
        })
        .filter(|(_, v)| !v.is_empty())
-
        .collect::<BTreeMap<git::Qualified<'static>, Vec<notification::NotificationItem>>>();
+
        .collect::<Vec<(git::Qualified<'static>, Vec<notification::NotificationItem>)>>();

    Ok(PaginatedQuery {
        cursor,
modified crates/radicle-types/src/domain/inbox/models/notification.rs
@@ -33,7 +33,7 @@ pub struct NotificationRow {
    pub new: Option<git::Oid>,
}

-
pub type RepoGroup = std::collections::BTreeMap<git::Qualified<'static>, Vec<NotificationRow>>;
+
pub type RepoGroup = Vec<(git::Qualified<'static>, Vec<NotificationRow>)>;
pub type CountByRepo = (identity::RepoId, usize);

#[derive(Clone, Debug)]
modified crates/radicle-types/src/domain/inbox/service.rs
@@ -1,7 +1,5 @@
-
use radicle::git;
-

use crate::domain::inbox::models::notification::{
-
    CountByRepo, ListNotificationsError, NotificationRow, RepoGroupParams,
+
    CountByRepo, ListNotificationsError, RepoGroup, RepoGroupParams,
};
use crate::domain::inbox::traits::{InboxService, InboxStorage};

@@ -35,13 +33,7 @@ where
        self.inbox.counts_by_repo()
    }

-
    fn repo_group(
-
        &self,
-
        params: RepoGroupParams,
-
    ) -> Result<
-
        std::collections::BTreeMap<git::Qualified<'static>, Vec<NotificationRow>>,
-
        ListNotificationsError,
-
    > {
+
    fn repo_group(&self, params: RepoGroupParams) -> Result<RepoGroup, ListNotificationsError> {
        self.inbox.repo_group(params)
    }
}
modified crates/radicle-types/src/outbound/sqlite.rs
@@ -1,4 +1,3 @@
-
use std::collections::BTreeMap;
use std::path::Path;
use std::str::FromStr;
use std::sync::Arc;
@@ -137,17 +136,24 @@ impl InboxStorage for Sqlite {
    fn repo_group(
        &self,
        params: notification::RepoGroupParams,
-
    ) -> Result<
-
        std::collections::BTreeMap<git::Qualified<'static>, Vec<notification::NotificationRow>>,
-
        notification::ListNotificationsError,
-
    > {
+
    ) -> Result<notification::RepoGroup, notification::ListNotificationsError> {
        let mut stmt = self.db.prepare(
-
        "SELECT ref, substr(ref, 66) ref_without_namespace, json_group_array(json_object('row_id', rowid, 'timestamp', timestamp, 'remote', substr(ref, 17, 48), 'old', old, 'new', new)) as value
-
        FROM 'repository-notifications'
-
        WHERE repo = ?
-
        GROUP BY ref_without_namespace
-
        ORDER BY timestamp DESC"
-
    )?;
+
            "SELECT ref, substr(ref, 66) ref_without_namespace,
+
                json_group_array(
+
                    json_object(
+
                        'row_id', rowid,
+
                        'timestamp', timestamp,
+
                        'remote', substr(ref, 17, 48),
+
                        'old', old,
+
                        'new', new
+
                    )
+
                ) as value,
+
                MAX(timestamp) AS latest_timestamp
+
            FROM 'repository-notifications'
+
            WHERE repo = ?
+
            GROUP BY ref_without_namespace
+
            ORDER BY latest_timestamp DESC",
+
        )?;
        stmt.bind((1, &params.repo))?;

        stmt.into_iter()
@@ -160,9 +166,6 @@ impl InboxStorage for Sqlite {

                Ok((reference.to_owned(), items))
            })
-
            .collect::<Result<
-
                BTreeMap<git::Qualified<'static>, Vec<notification::NotificationRow>>,
-
                notification::ListNotificationsError,
-
            >>()
+
            .collect::<Result<notification::RepoGroup, notification::ListNotificationsError>>()
    }
}
modified src/components/RepoNotifications.svelte
@@ -12,7 +12,7 @@
    clearByIds: (rid: string, ids: string[]) => Promise<void>;
    clearByRepo: (rid: string) => Promise<void>;
    repo: HomeInboxTab;
-
    items: Record<string, NotificationItem[]>;
+
    items: [string, NotificationItem[]][];
    more: boolean;
  }

@@ -53,7 +53,7 @@
{/if}

<div class="container">
-
  {#each Object.entries(items).sort((a, b) => b[1][0].timestamp - a[1][0].timestamp) as [_, notificationItems]}
+
  {#each items.sort((a, b) => b[1][0].timestamp - a[1][0].timestamp) as [_, notificationItems]}
    <NotificationTeaser
      {clearByIds}
      rid={repo.rid}
modified src/lib/router/definitions.ts
@@ -49,7 +49,7 @@ interface LoadedInboxRoute {
      string,
      {
        repo: HomeInboxTab;
-
        items: Record<string, NotificationItem[]>;
+
        items: [string, NotificationItem[]][];
        pagination: { cursor: number; more: boolean };
      }
    >;
@@ -115,7 +115,7 @@ export async function loadRoute(
      new SvelteMap();
    if (route.activeTab) {
      const items = await invoke<
-
        PaginatedQuery<Record<string, NotificationItem[]>>
+
        PaginatedQuery<[string, NotificationItem[]][]>
      >("list_notifications", {
        params: {
          repo: route.activeTab.rid,
@@ -129,7 +129,7 @@ export async function loadRoute(
    } else {
      for (const [rid, item] of notificationCount) {
        const result = await invoke<
-
          PaginatedQuery<Record<string, NotificationItem[]>>
+
          PaginatedQuery<[string, NotificationItem[]][]>
        >("list_notifications", {
          params: {
            repo: rid,
modified src/views/home/Inbox.svelte
@@ -24,7 +24,7 @@
      string,
      {
        repo: HomeInboxTab;
-
        items: Record<string, NotificationItem[]>;
+
        items: [string, NotificationItem[]][];
        pagination: { cursor: number; more: boolean };
      }
    >;
@@ -94,7 +94,7 @@
  async function reload(rids: string[]) {
    for (const rid of rids) {
      const [n, count] = await Promise.all([
-
        invoke<PaginatedQuery<Record<string, NotificationItem[]>>>(
+
        invoke<PaginatedQuery<[string, NotificationItem[]][]>>(
          "list_notifications",
          {
            params: {
@@ -123,16 +123,17 @@

  async function loadMoreContent() {
    if (more && activeTab) {
-
      const c = cursor ? cursor : 20;
-
      const p = await invoke<
-
        PaginatedQuery<Record<string, NotificationItem[]>>
-
      >("list_notifications", {
-
        params: {
-
          repo: activeTab.rid,
-
          skip: more ? c + 20 : c,
-
          take: 20,
+
      const c = cursor ? cursor : 0;
+
      const p = await invoke<PaginatedQuery<[string, NotificationItem[]][]>>(
+
        "list_notifications",
+
        {
+
          params: {
+
            repo: activeTab.rid,
+
            skip: more ? c + 20 : c,
+
            take: 20,
+
          },
        },
-
      });
+
      );

      cursor = p.cursor;
      more = p.more;