diff --git a/apps/web/src/components/status-bar/index.tsx b/apps/web/src/components/status-bar/index.tsx
index 6df557b19..a029bb10d 100644
--- a/apps/web/src/components/status-bar/index.tsx
+++ b/apps/web/src/components/status-bar/index.tsx
@@ -25,7 +25,6 @@ import {
Loading,
Update,
SyncError,
- Checkmark,
Alert,
Issue,
SyncOff,
@@ -33,7 +32,6 @@ import {
} from "../icons";
import { useStore as useUserStore } from "../../stores/user-store";
import { useStore as useAppStore } from "../../stores/app-store";
-import TimeAgo from "../time-ago";
import { hardNavigate, hashNavigate } from "../../navigation";
import { useAutoUpdater, UpdateStatus } from "../../hooks/use-auto-updater";
import {
@@ -43,7 +41,7 @@ import {
import useStatus, { statusToString } from "../../hooks/use-status";
import { ScopedThemeProvider } from "../theme-provider";
import { checkForUpdate, installUpdate } from "../../utils/updater";
-import { toTitleCase } from "@notesnook/common";
+import { getTimeAgo, toTitleCase } from "@notesnook/common";
import { User } from "@notesnook/core/dist/api/user-manager";
function StatusBar() {
@@ -68,11 +66,15 @@ function StatusBar() {
{isFocusMode ? (
) : (
-
+
{isLoggedIn ? (
<>
{user?.isEmailConfirmed ? (
-
+
) : (
);
}
-type SyncState = {
- key: SyncStatus;
- progress: number;
- type: SyncType;
-};
-type SyncType = "download" | "upload" | "sync";
type SyncStatus =
| "synced"
| "syncing"
@@ -278,14 +251,11 @@ type SyncStatusFilter = {
user: User | undefined,
lastSynced: number
) => boolean;
- text:
- | string
- | ((props: {
- type?: "download" | "upload" | "sync";
- user?: User;
- lastSynced: number;
- }) => JSX.Element);
- tooltip?: string;
+ text?: (props: {
+ type?: "download" | "upload" | "sync";
+ lastSynced: number;
+ }) => string;
+ tooltip: string;
iconColor?: string;
loading?: boolean;
};
@@ -293,14 +263,13 @@ type SyncStatusFilter = {
const syncStatusFilters: SyncStatusFilter[] = [
{
key: "synced",
- isActive: (syncStatus) => syncStatus === "synced",
+ isActive: (syncStatus) =>
+ syncStatus === "synced" || syncStatus === "completed",
icon: Sync,
text: ({ lastSynced }) =>
- lastSynced ? (
-
- ) : (
- <>click to sync>
- ),
+ lastSynced
+ ? `Synced ${getTimeAgo(lastSynced, "en_short", { minInterval: 1000 })}`
+ : "click to sync",
tooltip: "All changes are synced."
},
{
@@ -308,22 +277,15 @@ const syncStatusFilters: SyncStatusFilter[] = [
isActive: (syncStatus) => syncStatus === "syncing",
icon: Sync,
loading: true,
- text: ({ type }) => <>{toTitleCase(type || "sync")}ing>,
+ text: ({ type }) => `${toTitleCase(type || "sync")}ing`,
tooltip: "Syncing your notes..."
},
- {
- key: "completed",
- isActive: (syncStatus) => syncStatus === "completed",
- icon: Checkmark,
- iconColor: "var(--icon-success)",
- text: ""
- },
{
key: "conflicts",
isActive: (syncStatus) => syncStatus === "conflicts",
icon: Alert,
iconColor: "var(--icon-error)",
- text: "Merge conflicts",
+ text: () => "Merge conflicts",
tooltip: "Please resolve all merge conflicts and run the sync again."
},
{
@@ -331,7 +293,7 @@ const syncStatusFilters: SyncStatusFilter[] = [
isActive: (_syncStatus, user) => !user?.isEmailConfirmed,
icon: Alert,
iconColor: "var(--icon-error)",
- text: "Sync disabled",
+ text: () => "Sync disabled",
tooltip: "Please confirm your email to start syncing."
},
{
@@ -339,19 +301,17 @@ const syncStatusFilters: SyncStatusFilter[] = [
isActive: (syncStatus) => syncStatus === "failed",
icon: SyncError,
iconColor: "var(--icon-error)",
- text: "Sync failed",
+ text: () => "Sync failed",
tooltip: "Sync failed to completed. Please try again."
},
{
key: "offline",
isActive: (syncStatus) => syncStatus === "offline",
icon: SyncOff,
- text: ({ lastSynced }) => (
- <>
- {" "}
- (offline)
- >
- ),
+ text: ({ lastSynced }) =>
+ `Synced ${getTimeAgo(lastSynced, "en_short", {
+ minInterval: 1000
+ })} (offline)`,
tooltip: "You are offline."
},
{
@@ -359,7 +319,7 @@ const syncStatusFilters: SyncStatusFilter[] = [
iconColor: "var(--icon-disabled)",
isActive: (syncStatus) => syncStatus === "disabled",
icon: SyncOff,
- text: "Sync disabled",
+ text: () => "Sync disabled",
tooltip: "Sync is disabled."
}
];
diff --git a/apps/web/src/stores/app-store.ts b/apps/web/src/stores/app-store.ts
index ef5fbeb30..89fe2d642 100644
--- a/apps/web/src/stores/app-store.ts
+++ b/apps/web/src/stores/app-store.ts
@@ -50,7 +50,7 @@ type SyncState =
type SyncStatus = {
key: SyncState;
progress: number | null;
- type: "download" | "upload" | null;
+ type?: "download" | "upload" | "sync";
};
const networkCheck = new NetworkCheck();
let syncStatusTimeout = 0;
@@ -72,7 +72,7 @@ class AppStore extends BaseStore {
: "disabled"
: "offline",
progress: null,
- type: null
+ type: undefined
};
colors: Color[] = [];
notices: Notice[] = [];
@@ -122,12 +122,6 @@ class AppStore extends BaseStore {
this.updateSyncStatus("failed");
});
- db.eventManager.subscribe(EVENTS.syncCompleted, async () => {
- await this.updateLastSynced();
- this.updateSyncStatus("completed", true);
- this.refresh();
- });
-
onPageVisibilityChanged(async (type, documentHidden) => {
if (!documentHidden && type !== "offline") {
logger.info("Page visibility changed. Reconnecting SSE...");
@@ -340,7 +334,7 @@ class AppStore extends BaseStore {
updateSyncStatus = (key: SyncState, reset = false) => {
logger.info(`Sync status updated: ${key}`);
this.set((state) => {
- state.syncStatus = { key, progress: null, type: null };
+ state.syncStatus = { key, progress: null, type: undefined };
});
if (reset) {
diff --git a/packages/common/src/hooks/use-time-ago.ts b/packages/common/src/hooks/use-time-ago.ts
index 44c6ba446..9ea4a5ec6 100644
--- a/packages/common/src/hooks/use-time-ago.ts
+++ b/packages/common/src/hooks/use-time-ago.ts
@@ -18,7 +18,7 @@ along with this program. If not, see .
*/
import { useEffect, useState } from "react";
-import { TDate, format, register } from "timeago.js";
+import { Opts, TDate, format, register } from "timeago.js";
const shortLocale: [string, string][] = [
["now", "now"],
["%ss", "in %ss"],
@@ -55,8 +55,8 @@ const enShortLocale: [string, string][] = [
register("short", (_n, index) => shortLocale[index]);
register("en_short", (_n, index) => enShortLocale[index]);
-export function getTimeAgo(datetime: TDate, locale = "short") {
- return format(datetime, locale);
+export function getTimeAgo(datetime: TDate, locale = "short", opts?: Opts) {
+ return format(datetime, locale, opts);
}
type TimeAgoOptions = {