@ai-matrx/coding-sessions 0.1.166 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/dist/engine/index.cjs +273 -59
- package/dist/engine/index.cjs.map +1 -1
- package/dist/engine/index.d.cts +1 -1
- package/dist/engine/index.d.ts +1 -1
- package/dist/engine/index.js +269 -58
- package/dist/engine/index.js.map +1 -1
- package/dist/{index-CDeDKQHe.d.cts → index-Bbe11HoB.d.cts} +108 -3
- package/dist/{index-CDeDKQHe.d.ts → index-Bbe11HoB.d.ts} +108 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -1
- package/dist/index.d.ts +30 -1
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +47 -6
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +37 -0
- package/dist/react/index.d.ts +37 -0
- package/dist/react/index.js +47 -6
- package/dist/react/index.js.map +1 -1
- package/dist/server/index.cjs +241 -57
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +2 -2
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +241 -57
- package/dist/server/index.js.map +1 -1
- package/dist/sessions/index.cjs +360 -0
- package/dist/sessions/index.cjs.map +1 -0
- package/dist/sessions/index.d.cts +71 -0
- package/dist/sessions/index.d.ts +71 -0
- package/dist/sessions/index.js +337 -0
- package/dist/sessions/index.js.map +1 -0
- package/dist/titles-DjxUb0ji.d.cts +48 -0
- package/dist/titles-DjxUb0ji.d.ts +48 -0
- package/dist/ui/assets/index-BqzTnRFe.css +2 -0
- package/dist/ui/assets/{index-7eK8XQtL.js → index-U98AY8r-.js} +17 -17
- package/dist/ui/index.html +2 -2
- package/package.json +13 -3
- package/dist/ui/assets/index-BqpVx_My.css +0 -2
package/dist/react/index.d.cts
CHANGED
|
@@ -2,6 +2,10 @@ import { ReactNode } from 'react';
|
|
|
2
2
|
import { JsonValue } from '@ai-matrx/agents/portable';
|
|
3
3
|
import { ChatThreadStore, ChatMessage } from '@ai-matrx/chat';
|
|
4
4
|
|
|
5
|
+
/** Where a title came from, strongest first. */
|
|
6
|
+
declare const TITLE_PRECEDENCE: readonly ["override", "app", "app-remembered", "custom-title", "ai-title", "agent-name", "summary", "first-prompt", "last-prompt"];
|
|
7
|
+
type TitleSource = (typeof TITLE_PRECEDENCE)[number];
|
|
8
|
+
|
|
5
9
|
/**
|
|
6
10
|
* The public contract of `@ai-matrx/coding-sessions`, shared by the engine
|
|
7
11
|
* (Node), the local host (Node) and the UI (browser). Pure types — nothing here
|
|
@@ -129,7 +133,22 @@ interface DiscoveredSession {
|
|
|
129
133
|
provider: CodingProvider;
|
|
130
134
|
providerSessionId: string;
|
|
131
135
|
cwd: string | null;
|
|
136
|
+
/**
|
|
137
|
+
* The chat's own title by the one rule (`./sessions`): the coding app's title when the owner of
|
|
138
|
+
* the apps' index supplied it (title hints), else the transcript's. Never the person's rename —
|
|
139
|
+
* that is applied once, by the screen, from the preferences.
|
|
140
|
+
*/
|
|
132
141
|
title: string;
|
|
142
|
+
/** Where `title` came from (`TITLE_PRECEDENCE`). */
|
|
143
|
+
titleSource?: TitleSource | "unknown" | undefined;
|
|
144
|
+
/** The app's title is still on its way (hints not loaded yet); `title` is the transcript's for now. */
|
|
145
|
+
titlePending?: boolean | undefined;
|
|
146
|
+
/** Archived in the app (hidden by default, like Code › Chats). */
|
|
147
|
+
archived?: boolean | undefined;
|
|
148
|
+
/** A scheduled or automated run (hidden by default). */
|
|
149
|
+
scheduled?: boolean | undefined;
|
|
150
|
+
/** The app lists it but its conversation file is gone: why. Shown, cannot be taken over. */
|
|
151
|
+
unavailable?: string | null | undefined;
|
|
133
152
|
updatedAt: string;
|
|
134
153
|
/** Where it was started, when the provider records it ("cli", "vscode", "exec", …). */
|
|
135
154
|
source: string | null;
|
|
@@ -244,6 +263,11 @@ type TranscriptItem = {
|
|
|
244
263
|
id: string;
|
|
245
264
|
text: string;
|
|
246
265
|
};
|
|
266
|
+
interface TitleStatus {
|
|
267
|
+
owner: boolean;
|
|
268
|
+
pending: boolean;
|
|
269
|
+
problem: string | null;
|
|
270
|
+
}
|
|
247
271
|
/** Everything the engine pushes to a listener. */
|
|
248
272
|
type CodingEvent = {
|
|
249
273
|
type: "session";
|
|
@@ -254,6 +278,10 @@ type CodingEvent = {
|
|
|
254
278
|
} | {
|
|
255
279
|
type: "preferences";
|
|
256
280
|
preferences: Record<string, ChatPreference>;
|
|
281
|
+
}
|
|
282
|
+
/** The apps' titles changed (or finished loading): re-read the discovered chats. */
|
|
283
|
+
| {
|
|
284
|
+
type: "titles";
|
|
257
285
|
} | {
|
|
258
286
|
type: "item";
|
|
259
287
|
sessionId: string;
|
|
@@ -409,6 +437,10 @@ interface CodingSessionsApi {
|
|
|
409
437
|
discoverSessions(options?: {
|
|
410
438
|
limit?: number;
|
|
411
439
|
}): Promise<DiscoveredSession[]>;
|
|
440
|
+
/** Where the apps' own titles stand: an owner supplies them (`owner`), still loading, or failing (`problem`, shown with Retry). */
|
|
441
|
+
titleStatus(): Promise<TitleStatus>;
|
|
442
|
+
/** Ask the owner of the apps' titles again (the Retry). */
|
|
443
|
+
retryTitles(): Promise<void>;
|
|
412
444
|
recentFolders(): Promise<RecentFolder[]>;
|
|
413
445
|
listSessions(): Promise<CodingSession[]>;
|
|
414
446
|
listRuns(sessionId: string): Promise<RunRecord[]>;
|
|
@@ -533,6 +565,8 @@ interface CodingSessionsState {
|
|
|
533
565
|
preferences: Record<string, ChatPreference>;
|
|
534
566
|
/** How many of "Your other chats" to list (grows with "Show more"). */
|
|
535
567
|
discoveredLimit: number;
|
|
568
|
+
/** Where the apps' own titles stand (null until first asked; an engine without the method says nothing). */
|
|
569
|
+
titles: TitleStatus | null;
|
|
536
570
|
}
|
|
537
571
|
/** A run that just ended — for the tab badge and the desktop notification. */
|
|
538
572
|
interface RunFinished {
|
|
@@ -595,6 +629,9 @@ declare class CodingSessionsClient {
|
|
|
595
629
|
private load;
|
|
596
630
|
refreshProviders: () => Promise<void>;
|
|
597
631
|
refreshDiscovered: () => Promise<void>;
|
|
632
|
+
refreshTitleStatus: () => Promise<void>;
|
|
633
|
+
/** The Retry beside "app titles unavailable". */
|
|
634
|
+
retryTitles: () => Promise<void>;
|
|
598
635
|
/** List more of "Your other chats". */
|
|
599
636
|
showMoreDiscovered: () => Promise<void>;
|
|
600
637
|
refreshPreferences: () => Promise<void>;
|
package/dist/react/index.d.ts
CHANGED
|
@@ -2,6 +2,10 @@ import { ReactNode } from 'react';
|
|
|
2
2
|
import { JsonValue } from '@ai-matrx/agents/portable';
|
|
3
3
|
import { ChatThreadStore, ChatMessage } from '@ai-matrx/chat';
|
|
4
4
|
|
|
5
|
+
/** Where a title came from, strongest first. */
|
|
6
|
+
declare const TITLE_PRECEDENCE: readonly ["override", "app", "app-remembered", "custom-title", "ai-title", "agent-name", "summary", "first-prompt", "last-prompt"];
|
|
7
|
+
type TitleSource = (typeof TITLE_PRECEDENCE)[number];
|
|
8
|
+
|
|
5
9
|
/**
|
|
6
10
|
* The public contract of `@ai-matrx/coding-sessions`, shared by the engine
|
|
7
11
|
* (Node), the local host (Node) and the UI (browser). Pure types — nothing here
|
|
@@ -129,7 +133,22 @@ interface DiscoveredSession {
|
|
|
129
133
|
provider: CodingProvider;
|
|
130
134
|
providerSessionId: string;
|
|
131
135
|
cwd: string | null;
|
|
136
|
+
/**
|
|
137
|
+
* The chat's own title by the one rule (`./sessions`): the coding app's title when the owner of
|
|
138
|
+
* the apps' index supplied it (title hints), else the transcript's. Never the person's rename —
|
|
139
|
+
* that is applied once, by the screen, from the preferences.
|
|
140
|
+
*/
|
|
132
141
|
title: string;
|
|
142
|
+
/** Where `title` came from (`TITLE_PRECEDENCE`). */
|
|
143
|
+
titleSource?: TitleSource | "unknown" | undefined;
|
|
144
|
+
/** The app's title is still on its way (hints not loaded yet); `title` is the transcript's for now. */
|
|
145
|
+
titlePending?: boolean | undefined;
|
|
146
|
+
/** Archived in the app (hidden by default, like Code › Chats). */
|
|
147
|
+
archived?: boolean | undefined;
|
|
148
|
+
/** A scheduled or automated run (hidden by default). */
|
|
149
|
+
scheduled?: boolean | undefined;
|
|
150
|
+
/** The app lists it but its conversation file is gone: why. Shown, cannot be taken over. */
|
|
151
|
+
unavailable?: string | null | undefined;
|
|
133
152
|
updatedAt: string;
|
|
134
153
|
/** Where it was started, when the provider records it ("cli", "vscode", "exec", …). */
|
|
135
154
|
source: string | null;
|
|
@@ -244,6 +263,11 @@ type TranscriptItem = {
|
|
|
244
263
|
id: string;
|
|
245
264
|
text: string;
|
|
246
265
|
};
|
|
266
|
+
interface TitleStatus {
|
|
267
|
+
owner: boolean;
|
|
268
|
+
pending: boolean;
|
|
269
|
+
problem: string | null;
|
|
270
|
+
}
|
|
247
271
|
/** Everything the engine pushes to a listener. */
|
|
248
272
|
type CodingEvent = {
|
|
249
273
|
type: "session";
|
|
@@ -254,6 +278,10 @@ type CodingEvent = {
|
|
|
254
278
|
} | {
|
|
255
279
|
type: "preferences";
|
|
256
280
|
preferences: Record<string, ChatPreference>;
|
|
281
|
+
}
|
|
282
|
+
/** The apps' titles changed (or finished loading): re-read the discovered chats. */
|
|
283
|
+
| {
|
|
284
|
+
type: "titles";
|
|
257
285
|
} | {
|
|
258
286
|
type: "item";
|
|
259
287
|
sessionId: string;
|
|
@@ -409,6 +437,10 @@ interface CodingSessionsApi {
|
|
|
409
437
|
discoverSessions(options?: {
|
|
410
438
|
limit?: number;
|
|
411
439
|
}): Promise<DiscoveredSession[]>;
|
|
440
|
+
/** Where the apps' own titles stand: an owner supplies them (`owner`), still loading, or failing (`problem`, shown with Retry). */
|
|
441
|
+
titleStatus(): Promise<TitleStatus>;
|
|
442
|
+
/** Ask the owner of the apps' titles again (the Retry). */
|
|
443
|
+
retryTitles(): Promise<void>;
|
|
412
444
|
recentFolders(): Promise<RecentFolder[]>;
|
|
413
445
|
listSessions(): Promise<CodingSession[]>;
|
|
414
446
|
listRuns(sessionId: string): Promise<RunRecord[]>;
|
|
@@ -533,6 +565,8 @@ interface CodingSessionsState {
|
|
|
533
565
|
preferences: Record<string, ChatPreference>;
|
|
534
566
|
/** How many of "Your other chats" to list (grows with "Show more"). */
|
|
535
567
|
discoveredLimit: number;
|
|
568
|
+
/** Where the apps' own titles stand (null until first asked; an engine without the method says nothing). */
|
|
569
|
+
titles: TitleStatus | null;
|
|
536
570
|
}
|
|
537
571
|
/** A run that just ended — for the tab badge and the desktop notification. */
|
|
538
572
|
interface RunFinished {
|
|
@@ -595,6 +629,9 @@ declare class CodingSessionsClient {
|
|
|
595
629
|
private load;
|
|
596
630
|
refreshProviders: () => Promise<void>;
|
|
597
631
|
refreshDiscovered: () => Promise<void>;
|
|
632
|
+
refreshTitleStatus: () => Promise<void>;
|
|
633
|
+
/** The Retry beside "app titles unavailable". */
|
|
634
|
+
retryTitles: () => Promise<void>;
|
|
598
635
|
/** List more of "Your other chats". */
|
|
599
636
|
showMoreDiscovered: () => Promise<void>;
|
|
600
637
|
refreshPreferences: () => Promise<void>;
|
package/dist/react/index.js
CHANGED
|
@@ -305,6 +305,7 @@ function sessionEntry(session, prefs) {
|
|
|
305
305
|
updatedAt: session.updatedAt,
|
|
306
306
|
pinned: pref.pinned === true,
|
|
307
307
|
hidden: pref.hidden === true,
|
|
308
|
+
hiddenBy: pref.hidden === true ? "you" : null,
|
|
308
309
|
session,
|
|
309
310
|
discovered: null
|
|
310
311
|
};
|
|
@@ -322,7 +323,9 @@ function discoveredEntry(d, prefs) {
|
|
|
322
323
|
cwd: d.cwd,
|
|
323
324
|
updatedAt: d.updatedAt,
|
|
324
325
|
pinned: pref.pinned === true,
|
|
325
|
-
|
|
326
|
+
// Archived chats and scheduled runs are hidden by default, as in Code › Chats; a pin shows them.
|
|
327
|
+
hidden: pref.hidden === true || pref.pinned !== true && (d.archived === true || d.scheduled === true),
|
|
328
|
+
hiddenBy: pref.hidden === true ? "you" : pref.pinned === true ? null : d.archived ? "archived" : d.scheduled ? "scheduled" : null,
|
|
326
329
|
session: null,
|
|
327
330
|
discovered: d
|
|
328
331
|
};
|
|
@@ -1268,6 +1271,14 @@ function ChooseAgentDialog(props) {
|
|
|
1268
1271
|
] }) });
|
|
1269
1272
|
}
|
|
1270
1273
|
|
|
1274
|
+
// src/sessions/titles.ts
|
|
1275
|
+
var DISPLAY_MAX = 100;
|
|
1276
|
+
var LEADING_NOISE = /^(?:\s*(?:\d{1,3}[.)]|[-*•]|#{1,6}|>)\s+|\s*["“'‘`]+)+/;
|
|
1277
|
+
function displayTitle(title, max = DISPLAY_MAX) {
|
|
1278
|
+
const stripped = title.replace(LEADING_NOISE, "").replace(/["”'’`]+$/, "").trim() || title.trim();
|
|
1279
|
+
return stripped.length > max ? `${stripped.slice(0, max - 1).trimEnd()}\u2026` : stripped;
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1271
1282
|
// src/react/sidebar.tsx
|
|
1272
1283
|
import { useCallback, useEffect as useEffect3, useMemo as useMemo3, useRef as useRef2, useState as useState5 } from "react";
|
|
1273
1284
|
import {
|
|
@@ -1381,7 +1392,7 @@ function Row(props) {
|
|
|
1381
1392
|
/* @__PURE__ */ jsx6("span", { className: "pointer-events-none mt-0.5 shrink-0", children: props.live ? /* @__PURE__ */ jsx6(SpinnerIcon, { size: 16, className: "text-primary" }) : /* @__PURE__ */ jsx6(ProviderMark, { provider: entry.provider, size: 16 }) }),
|
|
1382
1393
|
/* @__PURE__ */ jsxs6("span", { className: "cs-row__body", children: [
|
|
1383
1394
|
renaming ? /* @__PURE__ */ jsx6("span", { className: "pointer-events-auto relative z-10 block", children: /* @__PURE__ */ jsx6(RenameInput, { initial: entry.title, onDone: rename }) }) : /* @__PURE__ */ jsxs6("span", { className: "flex items-center gap-1", children: [
|
|
1384
|
-
/* @__PURE__ */ jsx6("span", { className: "min-w-0 truncate text-[13px] font-medium leading-5", children: entry.title }),
|
|
1395
|
+
/* @__PURE__ */ jsx6("span", { className: "min-w-0 truncate text-[13px] font-medium leading-5", children: displayTitle(entry.title) }),
|
|
1385
1396
|
entry.pinned ? /* @__PURE__ */ jsx6(PinIcon, { size: 11, className: "shrink-0 text-muted-foreground", "aria-label": "Pinned" }) : null
|
|
1386
1397
|
] }),
|
|
1387
1398
|
/* @__PURE__ */ jsx6("span", { className: "block truncate text-[11.5px] leading-4 text-muted-foreground", children: props.meta }),
|
|
@@ -1483,6 +1494,8 @@ function Sidebar(props) {
|
|
|
1483
1494
|
const [search, searchMore] = useContentSearch(query);
|
|
1484
1495
|
const [groupMode, setGroupMode] = useState5(() => readLocal("coding-sessions.group", ["date", "folder"], "date"));
|
|
1485
1496
|
const [showHidden, setShowHidden] = useState5(false);
|
|
1497
|
+
const titlesProblem = state.titles?.problem ?? null;
|
|
1498
|
+
const titlesUpdating = !titlesProblem && state.discovered.data.some((d) => d.titlePending === true);
|
|
1486
1499
|
const [takingOver, setTakingOver] = useState5(null);
|
|
1487
1500
|
const [takeoverError, setTakeoverError] = useState5(null);
|
|
1488
1501
|
const prefs = state.preferences;
|
|
@@ -1536,6 +1549,7 @@ function Sidebar(props) {
|
|
|
1536
1549
|
"Running in ",
|
|
1537
1550
|
PROVIDER_LABEL[entry.provider]
|
|
1538
1551
|
] });
|
|
1552
|
+
else if (d?.unavailable) meta = `${PROVIDER_LABEL[entry.provider]} \xB7 file missing \xB7 ${relativeTime(entry.updatedAt, now)}`;
|
|
1539
1553
|
else {
|
|
1540
1554
|
const status = run ? run.status === "failed" ? "Failed \xB7 " : run.status === "stopped" ? "Stopped \xB7 " : "" : "";
|
|
1541
1555
|
const where = entry.cwd ? prettyPath2(entry.cwd) : "unknown folder";
|
|
@@ -1625,7 +1639,7 @@ function Sidebar(props) {
|
|
|
1625
1639
|
] }) : null,
|
|
1626
1640
|
/* @__PURE__ */ jsx6(SectionLabel, { children: "Recent" }),
|
|
1627
1641
|
state.sessions.loading && state.sessions.loadedAt === null ? /* @__PURE__ */ jsx6(SidebarSkeleton, {}) : state.sessions.error ? /* @__PURE__ */ jsx6("p", { className: "px-4 py-1 text-[12px] text-destructive", children: state.sessions.error }) : recent.length === 0 ? running.length === 0 ? /* @__PURE__ */ jsx6("p", { className: "px-4 py-1 text-[12px] leading-5 text-muted-foreground", children: "Sessions you start or take over here will appear here." }) : null : recent.map((e) => renderEntry(e)),
|
|
1628
|
-
/* @__PURE__ */
|
|
1642
|
+
/* @__PURE__ */ jsxs6(
|
|
1629
1643
|
SectionLabel,
|
|
1630
1644
|
{
|
|
1631
1645
|
action: /* @__PURE__ */ jsxs6("span", { className: "flex items-center gap-0.5", children: [
|
|
@@ -1653,7 +1667,15 @@ function Sidebar(props) {
|
|
|
1653
1667
|
}
|
|
1654
1668
|
)
|
|
1655
1669
|
] }),
|
|
1656
|
-
children:
|
|
1670
|
+
children: [
|
|
1671
|
+
"Your other chats",
|
|
1672
|
+
titlesUpdating ? /* @__PURE__ */ jsx6("span", { className: "ml-1 font-normal normal-case text-muted-foreground", "data-cs-titles": "updating", children: "\xB7 titles updating" }) : null,
|
|
1673
|
+
titlesProblem ? /* @__PURE__ */ jsxs6("span", { className: "ml-1 font-normal normal-case text-destructive", "data-cs-titles": "unavailable", title: titlesProblem, children: [
|
|
1674
|
+
"\xB7 app titles unavailable \u2014",
|
|
1675
|
+
" ",
|
|
1676
|
+
/* @__PURE__ */ jsx6("button", { type: "button", className: "cs-link", onClick: () => void client.retryTitles(), children: "Retry" })
|
|
1677
|
+
] }) : null
|
|
1678
|
+
]
|
|
1657
1679
|
}
|
|
1658
1680
|
),
|
|
1659
1681
|
state.discovered.loading && state.discovered.loadedAt === null ? /* @__PURE__ */ jsx6(SidebarSkeleton, {}) : state.discovered.error ? /* @__PURE__ */ jsx6("p", { className: "px-4 py-1 text-[12px] text-destructive", children: state.discovered.error }) : otherList.length === 0 ? /* @__PURE__ */ jsx6("p", { className: "px-4 py-1 text-[12px] leading-5 text-muted-foreground", children: others.length > 0 ? "Every chat found here is pinned or hidden." : "No other Claude Code or Codex chats were found on this computer." }) : /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
@@ -2122,7 +2144,8 @@ var CodingSessionsClient = class {
|
|
|
2122
2144
|
folders: loadable([]),
|
|
2123
2145
|
runs: {},
|
|
2124
2146
|
preferences: {},
|
|
2125
|
-
discoveredLimit: DISCOVERED_PAGE
|
|
2147
|
+
discoveredLimit: DISCOVERED_PAGE,
|
|
2148
|
+
titles: null
|
|
2126
2149
|
};
|
|
2127
2150
|
transport.onStatus((connection) => {
|
|
2128
2151
|
const wasOpen = this.state.connection.state === "open";
|
|
@@ -2171,6 +2194,10 @@ var CodingSessionsClient = class {
|
|
|
2171
2194
|
} else if (event.type === "preferences") {
|
|
2172
2195
|
this.set({ preferences: event.preferences });
|
|
2173
2196
|
return;
|
|
2197
|
+
} else if (event.type === "titles") {
|
|
2198
|
+
void this.refreshDiscovered();
|
|
2199
|
+
void this.refreshSessions();
|
|
2200
|
+
return;
|
|
2174
2201
|
}
|
|
2175
2202
|
const sessionId = event.type === "session" ? event.session.id : event.type === "run" ? event.run.sessionId : event.sessionId;
|
|
2176
2203
|
this.transcripts.get(sessionId)?.onEvent(event);
|
|
@@ -2187,7 +2214,21 @@ var CodingSessionsClient = class {
|
|
|
2187
2214
|
}
|
|
2188
2215
|
}
|
|
2189
2216
|
refreshProviders = () => this.load("providers", () => this.transport.call("providers"));
|
|
2190
|
-
refreshDiscovered =
|
|
2217
|
+
refreshDiscovered = async () => {
|
|
2218
|
+
void this.refreshTitleStatus();
|
|
2219
|
+
await this.load("discovered", () => this.transport.call("discoverSessions", { limit: this.state.discoveredLimit }));
|
|
2220
|
+
};
|
|
2221
|
+
refreshTitleStatus = async () => {
|
|
2222
|
+
try {
|
|
2223
|
+
this.set({ titles: await this.transport.call("titleStatus") });
|
|
2224
|
+
} catch {
|
|
2225
|
+
}
|
|
2226
|
+
};
|
|
2227
|
+
/** The Retry beside "app titles unavailable". */
|
|
2228
|
+
retryTitles = async () => {
|
|
2229
|
+
await this.transport.call("retryTitles").catch(() => void 0);
|
|
2230
|
+
await this.refreshTitleStatus();
|
|
2231
|
+
};
|
|
2191
2232
|
/** List more of "Your other chats". */
|
|
2192
2233
|
showMoreDiscovered = async () => {
|
|
2193
2234
|
this.set({ discoveredLimit: this.state.discoveredLimit + DISCOVERED_PAGE });
|