xfeed 0.1.6 → 0.1.7

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.
Files changed (2) hide show
  1. package/dist/index.js +1472 -797
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -25,7 +25,7 @@ __export(exports_media, {
25
25
  });
26
26
  import { spawn as spawn2 } from "child_process";
27
27
  import { mkdir, writeFile, unlink } from "fs/promises";
28
- import { homedir as homedir3, platform as platform2, tmpdir } from "os";
28
+ import { homedir as homedir4, platform as platform2, tmpdir } from "os";
29
29
  import { join as join2, extname } from "path";
30
30
  function isUrlSafeToFetch(url) {
31
31
  try {
@@ -272,7 +272,7 @@ async function previewImageUrl(url, name) {
272
272
  }
273
273
  }
274
274
  async function downloadMedia(media, tweetId, index) {
275
- const downloadDir = join2(homedir3(), "Downloads", "xfeed");
275
+ const downloadDir = join2(homedir4(), "Downloads", "xfeed");
276
276
  const ext = getExtension(media);
277
277
  const filename = `${tweetId}_${index}${ext}`;
278
278
  const filepath = join2(downloadDir, filename);
@@ -298,7 +298,7 @@ async function downloadAllMedia(mediaItems, tweetId) {
298
298
  if (mediaItems.length === 1) {
299
299
  return downloadMedia(mediaItems[0], tweetId, 0);
300
300
  }
301
- const downloadDir = join2(homedir3(), "Downloads", "xfeed");
301
+ const downloadDir = join2(homedir4(), "Downloads", "xfeed");
302
302
  try {
303
303
  await mkdir(downloadDir, { recursive: true });
304
304
  let successCount = 0;
@@ -2029,7 +2029,7 @@ var ToasterRenderable = class extends BoxRenderable3 {
2029
2029
 
2030
2030
  // src/app.tsx
2031
2031
  import { useKeyboard as useKeyboard10, useRenderer as useRenderer3 } from "@opentui/react";
2032
- import { useCallback as useCallback15, useEffect as useEffect20, useRef as useRef12, useState as useState23 } from "react";
2032
+ import { useCallback as useCallback16, useEffect as useEffect22, useRef as useRef13, useState as useState28 } from "react";
2033
2033
 
2034
2034
  // src/components/Footer.tsx
2035
2035
  import { useTerminalDimensions as useTerminalDimensions2 } from "@opentui/react";
@@ -2058,6 +2058,7 @@ var DEFAULT_BINDINGS = [
2058
2058
  { key: "j/k", label: "nav" },
2059
2059
  { key: "l", label: "like" },
2060
2060
  { key: "b", label: "bookmark" },
2061
+ { key: "g", label: "goto" },
2061
2062
  { key: "r", label: "refresh" },
2062
2063
  { key: "Tab", label: "switch" },
2063
2064
  { key: "q", label: "quit" }
@@ -2235,7 +2236,7 @@ function getConfigPath() {
2235
2236
 
2236
2237
  // src/experiments/index.tsx
2237
2238
  import { QueryClientProvider } from "@tanstack/react-query";
2238
- import { useState as useState10 } from "react";
2239
+ import { useState as useState11 } from "react";
2239
2240
 
2240
2241
  // src/experiments/query-client.ts
2241
2242
  import { QueryClient } from "@tanstack/react-query";
@@ -2320,7 +2321,7 @@ var queryKeys = {
2320
2321
 
2321
2322
  // src/experiments/TimelineScreenExperimental.tsx
2322
2323
  import { useKeyboard as useKeyboard4 } from "@opentui/react";
2323
- import { useEffect as useEffect6, useRef as useRef5 } from "react";
2324
+ import { useEffect as useEffect6, useRef as useRef5, useState as useState6 } from "react";
2324
2325
 
2325
2326
  // src/components/ErrorBanner.tsx
2326
2327
  import { useEffect as useEffect3 } from "react";
@@ -2706,6 +2707,7 @@ var HEART_EMPTY = "\u2661";
2706
2707
  var HEART_FILLED = "\u2665";
2707
2708
  var FLAG_EMPTY = "\u2690";
2708
2709
  var FLAG_FILLED = "\u2691";
2710
+ var NOTE_INDICATOR = "+";
2709
2711
  function PostCard({
2710
2712
  post,
2711
2713
  isSelected,
@@ -2714,6 +2716,7 @@ function PostCard({
2714
2716
  isBookmarked,
2715
2717
  isJustLiked,
2716
2718
  isJustBookmarked,
2719
+ hasAnnotation,
2717
2720
  parentAuthorUsername,
2718
2721
  mainPostAuthorUsername,
2719
2722
  onCardClick,
@@ -2834,7 +2837,15 @@ function PostCard({
2834
2837
  /* @__PURE__ */ jsxDEV6("text", {
2835
2838
  fg: colors.dim,
2836
2839
  children: timeAgo ? ` \xB7 ${timeAgo}` : ""
2837
- }, undefined, false, undefined, this)
2840
+ }, undefined, false, undefined, this),
2841
+ hasAnnotation ? /* @__PURE__ */ jsxDEV6("text", {
2842
+ fg: colors.warning,
2843
+ children: [
2844
+ " [",
2845
+ NOTE_INDICATOR,
2846
+ "]"
2847
+ ]
2848
+ }, undefined, true, undefined, this) : null
2838
2849
  ]
2839
2850
  }, undefined, true, undefined, this),
2840
2851
  /* @__PURE__ */ jsxDEV6("box", {
@@ -3014,15 +3025,19 @@ function PostList({
3014
3025
  onSelectedIndexChange,
3015
3026
  onLike,
3016
3027
  onBookmark,
3028
+ onAnnotate,
3017
3029
  getActionState,
3018
3030
  initActionState,
3031
+ hasAnnotation,
3019
3032
  onLoadMore,
3020
3033
  loadingMore = false,
3021
- hasMore = true
3034
+ hasMore = true,
3035
+ refreshKey
3022
3036
  }) {
3023
3037
  const scrollRef = useRef3(null);
3024
3038
  const savedScrollTop = useRef3(0);
3025
3039
  const wasFocused = useRef3(focused);
3040
+ const prevRefreshKey = useRef3(refreshKey);
3026
3041
  useEffect4(() => {
3027
3042
  const scrollbox = scrollRef.current;
3028
3043
  if (!scrollbox)
@@ -3032,7 +3047,7 @@ function PostList({
3032
3047
  }
3033
3048
  wasFocused.current = focused;
3034
3049
  }, [focused]);
3035
- const { selectedIndex } = useListNavigation({
3050
+ const { selectedIndex, setSelectedIndex } = useListNavigation({
3036
3051
  itemCount: posts.length,
3037
3052
  enabled: focused,
3038
3053
  onSelect: (index) => {
@@ -3045,6 +3060,16 @@ function PostList({
3045
3060
  }
3046
3061
  }
3047
3062
  });
3063
+ useEffect4(() => {
3064
+ if (prevRefreshKey.current !== undefined && refreshKey !== undefined && refreshKey !== prevRefreshKey.current) {
3065
+ setSelectedIndex(0);
3066
+ if (scrollRef.current) {
3067
+ scrollRef.current.scrollTo(0);
3068
+ }
3069
+ savedScrollTop.current = 0;
3070
+ }
3071
+ prevRefreshKey.current = refreshKey;
3072
+ }, [refreshKey, setSelectedIndex]);
3048
3073
  useEffect4(() => {
3049
3074
  onSelectedIndexChange?.(selectedIndex);
3050
3075
  }, [selectedIndex, onSelectedIndexChange]);
@@ -3058,6 +3083,8 @@ function PostList({
3058
3083
  onLike?.(currentPost);
3059
3084
  } else if (key.name === "b") {
3060
3085
  onBookmark?.(currentPost);
3086
+ } else if (key.name === "a") {
3087
+ onAnnotate?.(currentPost);
3061
3088
  }
3062
3089
  });
3063
3090
  useEffect4(() => {
@@ -3131,6 +3158,7 @@ function PostList({
3131
3158
  isBookmarked: actionState?.bookmarked,
3132
3159
  isJustLiked: actionState?.justLiked,
3133
3160
  isJustBookmarked: actionState?.justBookmarked,
3161
+ hasAnnotation: hasAnnotation?.(post.id),
3134
3162
  onCardClick: () => onPostSelect?.(post),
3135
3163
  onLikeClick: () => onLike?.(post),
3136
3164
  onBookmarkClick: () => onBookmark?.(post)
@@ -3376,6 +3404,7 @@ function TimelineScreenExperimental({
3376
3404
  client,
3377
3405
  initialTab: preferences.timeline.default_tab
3378
3406
  });
3407
+ const [refreshKey, setRefreshKey] = useState6(0);
3379
3408
  useEffect6(() => {
3380
3409
  onPostCountChange?.(posts.length);
3381
3410
  }, [posts.length, onPostCountChange]);
@@ -3398,6 +3427,7 @@ function TimelineScreenExperimental({
3398
3427
  break;
3399
3428
  case "r":
3400
3429
  refresh();
3430
+ setRefreshKey((k) => k + 1);
3401
3431
  break;
3402
3432
  }
3403
3433
  });
@@ -3471,23 +3501,24 @@ function TimelineScreenExperimental({
3471
3501
  initActionState,
3472
3502
  onLoadMore: fetchNextPage,
3473
3503
  loadingMore: isFetchingNextPage,
3474
- hasMore: hasNextPage
3504
+ hasMore: hasNextPage,
3505
+ refreshKey
3475
3506
  }, undefined, false, undefined, this)
3476
3507
  ]
3477
3508
  }, undefined, true, undefined, this);
3478
3509
  }
3479
3510
  // src/experiments/use-profile-query.ts
3480
3511
  import { useQuery } from "@tanstack/react-query";
3481
- import { useCallback as useCallback5, useState as useState6 } from "react";
3512
+ import { useCallback as useCallback5, useState as useState7 } from "react";
3482
3513
  function useProfileQuery({
3483
3514
  client,
3484
3515
  username,
3485
3516
  isSelf = false
3486
3517
  }) {
3487
- const [likesEnabled, setLikesEnabled] = useState6(false);
3488
- const [repliesEnabled, setRepliesEnabled] = useState6(false);
3489
- const [mediaEnabled, setMediaEnabled] = useState6(false);
3490
- const [highlightsEnabled, setHighlightsEnabled] = useState6(false);
3518
+ const [likesEnabled, setLikesEnabled] = useState7(false);
3519
+ const [repliesEnabled, setRepliesEnabled] = useState7(false);
3520
+ const [mediaEnabled, setMediaEnabled] = useState7(false);
3521
+ const [highlightsEnabled, setHighlightsEnabled] = useState7(false);
3491
3522
  const {
3492
3523
  data: profileData,
3493
3524
  isLoading: isProfileLoading,
@@ -3872,7 +3903,7 @@ function useBookmarksQuery({
3872
3903
  }
3873
3904
  // src/experiments/use-bookmark-mutation.ts
3874
3905
  import { useMutation, useQueryClient as useQueryClient3 } from "@tanstack/react-query";
3875
- import { useCallback as useCallback7, useRef as useRef6, useState as useState7 } from "react";
3906
+ import { useCallback as useCallback7, useRef as useRef6, useState as useState8 } from "react";
3876
3907
  var JUST_ACTED_DURATION = 600;
3877
3908
  function useBookmarkMutation({
3878
3909
  client,
@@ -3880,8 +3911,8 @@ function useBookmarkMutation({
3880
3911
  onError
3881
3912
  }) {
3882
3913
  const queryClient = useQueryClient3();
3883
- const [pendingTweets, setPendingTweets] = useState7(new Set);
3884
- const [justBookmarkedTweets, setJustBookmarkedTweets] = useState7(new Set);
3914
+ const [pendingTweets, setPendingTweets] = useState8(new Set);
3915
+ const [justBookmarkedTweets, setJustBookmarkedTweets] = useState8(new Set);
3885
3916
  const justBookmarkedTimeouts = useRef6(new Map);
3886
3917
  const addMutation = useMutation({
3887
3918
  mutationFn: async (tweet) => {
@@ -4077,7 +4108,7 @@ import { useEffect as useEffect9, useMemo as useMemo6 } from "react";
4077
4108
 
4078
4109
  // src/components/ThreadView.prototype.tsx
4079
4110
  import { useKeyboard as useKeyboard5 } from "@opentui/react";
4080
- import { useState as useState8, useRef as useRef7, useEffect as useEffect8, useMemo as useMemo5 } from "react";
4111
+ import { useState as useState9, useRef as useRef7, useEffect as useEffect8, useMemo as useMemo5 } from "react";
4081
4112
  import { jsxDEV as jsxDEV10 } from "@opentui/react/jsx-dev-runtime";
4082
4113
  var SELECTED_BG = "#2a2a3e";
4083
4114
  var TREE = {
@@ -4319,8 +4350,8 @@ function ThreadViewPrototype({
4319
4350
  const scrollRef = useRef7(null);
4320
4351
  const savedScrollTop = useRef7(0);
4321
4352
  const wasFocused = useRef7(focused);
4322
- const [selectedIndex, setSelectedIndex] = useState8(0);
4323
- const [treeState, setTreeState] = useState8(replyTree);
4353
+ const [selectedIndex, setSelectedIndex] = useState9(0);
4354
+ const [treeState, setTreeState] = useState9(replyTree);
4324
4355
  useEffect8(() => {
4325
4356
  const scrollbox = scrollRef.current;
4326
4357
  if (!scrollbox)
@@ -4645,7 +4676,7 @@ function useThreadQuery({
4645
4676
  }
4646
4677
  // src/experiments/use-user-actions.ts
4647
4678
  import { useMutation as useMutation2, useQueryClient as useQueryClient5 } from "@tanstack/react-query";
4648
- import { useCallback as useCallback8, useState as useState9 } from "react";
4679
+ import { useCallback as useCallback8, useState as useState10 } from "react";
4649
4680
  function useUserActions({
4650
4681
  client,
4651
4682
  username,
@@ -4653,7 +4684,7 @@ function useUserActions({
4653
4684
  onError
4654
4685
  }) {
4655
4686
  const queryClient = useQueryClient5();
4656
- const [pendingAction, setPendingAction] = useState9(null);
4687
+ const [pendingAction, setPendingAction] = useState10(null);
4657
4688
  const updateProfileCache = useCallback8((updates) => {
4658
4689
  queryClient.setQueryData(queryKeys.user.profile(username), (old) => {
4659
4690
  if (!old?.success || !old.user)
@@ -4861,7 +4892,7 @@ function getQueryClient() {
4861
4892
  return queryClientInstance;
4862
4893
  }
4863
4894
  function QueryProvider({ children }) {
4864
- const [queryClient] = useState10(() => getQueryClient());
4895
+ const [queryClient] = useState11(() => getQueryClient());
4865
4896
  return /* @__PURE__ */ jsxDEV11(QueryClientProvider, {
4866
4897
  client: queryClient,
4867
4898
  children
@@ -4869,7 +4900,7 @@ function QueryProvider({ children }) {
4869
4900
  }
4870
4901
 
4871
4902
  // src/hooks/useActions.ts
4872
- import { useState as useState11, useCallback as useCallback9, useRef as useRef8 } from "react";
4903
+ import { useState as useState12, useCallback as useCallback9, useRef as useRef8 } from "react";
4873
4904
  var DEFAULT_STATE = {
4874
4905
  liked: false,
4875
4906
  bookmarked: false,
@@ -4887,7 +4918,7 @@ function useActions({
4887
4918
  bookmarkMutation,
4888
4919
  currentFolderId
4889
4920
  }) {
4890
- const [states, setStates] = useState11(new Map);
4921
+ const [states, setStates] = useState12(new Map);
4891
4922
  const justLikedTimeouts = useRef8(new Map);
4892
4923
  const justBookmarkedTimeouts = useRef8(new Map);
4893
4924
  const getState = useCallback9((tweetId) => {
@@ -5065,25 +5096,130 @@ function useActions({
5065
5096
  };
5066
5097
  }
5067
5098
 
5099
+ // src/hooks/useAnnotations.ts
5100
+ import { useState as useState13, useCallback as useCallback10, useEffect as useEffect10, useRef as useRef9 } from "react";
5101
+
5102
+ // src/config/annotations.ts
5103
+ import {
5104
+ chmodSync as chmodSync2,
5105
+ existsSync as existsSync2,
5106
+ mkdirSync as mkdirSync2,
5107
+ readFileSync as readFileSync2,
5108
+ writeFileSync as writeFileSync2
5109
+ } from "fs";
5110
+ import { homedir as homedir2 } from "os";
5111
+ import path2 from "path";
5112
+ var CONFIG_DIR2 = path2.join(homedir2(), ".config", "xfeed");
5113
+ var ANNOTATIONS_PATH = path2.join(CONFIG_DIR2, "annotations.json");
5114
+ var ANNOTATIONS_VERSION = 1;
5115
+ function loadAnnotations() {
5116
+ if (!existsSync2(ANNOTATIONS_PATH)) {
5117
+ return { version: ANNOTATIONS_VERSION, annotations: {} };
5118
+ }
5119
+ try {
5120
+ const content = readFileSync2(ANNOTATIONS_PATH, "utf-8");
5121
+ const parsed = JSON.parse(content);
5122
+ if (typeof parsed !== "object" || parsed === null) {
5123
+ return { version: ANNOTATIONS_VERSION, annotations: {} };
5124
+ }
5125
+ const file = parsed;
5126
+ if (typeof file.version !== "number") {
5127
+ return { version: ANNOTATIONS_VERSION, annotations: {} };
5128
+ }
5129
+ if (typeof file.annotations !== "object" || file.annotations === null) {
5130
+ return { version: ANNOTATIONS_VERSION, annotations: {} };
5131
+ }
5132
+ return {
5133
+ version: file.version,
5134
+ annotations: file.annotations
5135
+ };
5136
+ } catch {
5137
+ return { version: ANNOTATIONS_VERSION, annotations: {} };
5138
+ }
5139
+ }
5140
+ function saveAnnotations(file) {
5141
+ if (!existsSync2(CONFIG_DIR2)) {
5142
+ mkdirSync2(CONFIG_DIR2, { recursive: true });
5143
+ }
5144
+ writeFileSync2(ANNOTATIONS_PATH, JSON.stringify(file, null, 2) + `
5145
+ `);
5146
+ chmodSync2(ANNOTATIONS_PATH, 384);
5147
+ }
5148
+
5149
+ // src/hooks/useAnnotations.ts
5150
+ function useAnnotations() {
5151
+ const [annotationsFile, setAnnotationsFile] = useState13(() => loadAnnotations());
5152
+ const annotatedIdsRef = useRef9(new Set(Object.keys(annotationsFile.annotations)));
5153
+ useEffect10(() => {
5154
+ annotatedIdsRef.current = new Set(Object.keys(annotationsFile.annotations));
5155
+ }, [annotationsFile]);
5156
+ const getAnnotation = useCallback10((tweetId) => {
5157
+ return annotationsFile.annotations[tweetId]?.text;
5158
+ }, [annotationsFile]);
5159
+ const hasAnnotation = useCallback10((tweetId) => {
5160
+ return tweetId in annotationsFile.annotations;
5161
+ }, [annotationsFile]);
5162
+ const setAnnotation = useCallback10((tweetId, text) => {
5163
+ const now = new Date().toISOString();
5164
+ setAnnotationsFile((prev) => {
5165
+ const existing = prev.annotations[tweetId];
5166
+ const newAnnotation = existing ? { text, createdAt: existing.createdAt, updatedAt: now } : { text, createdAt: now, updatedAt: now };
5167
+ const updated = {
5168
+ ...prev,
5169
+ annotations: {
5170
+ ...prev.annotations,
5171
+ [tweetId]: newAnnotation
5172
+ }
5173
+ };
5174
+ saveAnnotations(updated);
5175
+ return updated;
5176
+ });
5177
+ }, []);
5178
+ const deleteAnnotation = useCallback10((tweetId) => {
5179
+ setAnnotationsFile((prev) => {
5180
+ if (!(tweetId in prev.annotations)) {
5181
+ return prev;
5182
+ }
5183
+ const { [tweetId]: _, ...rest } = prev.annotations;
5184
+ const updated = {
5185
+ ...prev,
5186
+ annotations: rest
5187
+ };
5188
+ saveAnnotations(updated);
5189
+ return updated;
5190
+ });
5191
+ }, []);
5192
+ const getAnnotatedTweetIds = useCallback10(() => {
5193
+ return annotatedIdsRef.current;
5194
+ }, []);
5195
+ return {
5196
+ getAnnotation,
5197
+ hasAnnotation,
5198
+ setAnnotation,
5199
+ deleteAnnotation,
5200
+ getAnnotatedTweetIds
5201
+ };
5202
+ }
5203
+
5068
5204
  // src/hooks/useNavigation.ts
5069
- import { useState as useState12, useCallback as useCallback10 } from "react";
5205
+ import { useState as useState14, useCallback as useCallback11 } from "react";
5070
5206
  function useNavigation(options) {
5071
5207
  const { initialView, mainViews } = options;
5072
- const [history, setHistory] = useState12([initialView]);
5208
+ const [history, setHistory] = useState14([initialView]);
5073
5209
  const currentView = history[history.length - 1];
5074
5210
  const previousView = history.length > 1 ? history[history.length - 2] : null;
5075
5211
  const canGoBack = history.length > 1;
5076
5212
  const isMainView = mainViews.includes(currentView);
5077
- const navigate = useCallback10((view) => {
5213
+ const navigate = useCallback11((view) => {
5078
5214
  setHistory((prev) => [...prev, view]);
5079
5215
  }, []);
5080
- const goBack = useCallback10(() => {
5216
+ const goBack = useCallback11(() => {
5081
5217
  if (history.length <= 1)
5082
5218
  return false;
5083
5219
  setHistory((prev) => prev.slice(0, -1));
5084
5220
  return true;
5085
5221
  }, [history.length]);
5086
- const cycleNext = useCallback10(() => {
5222
+ const cycleNext = useCallback11(() => {
5087
5223
  setHistory((prev) => {
5088
5224
  const current = prev[prev.length - 1];
5089
5225
  if (!mainViews.includes(current)) {
@@ -5147,20 +5283,189 @@ async function copyToClipboard(text) {
5147
5283
  });
5148
5284
  }
5149
5285
 
5286
+ // src/modals/AnnotationEditor.tsx
5287
+ import { useState as useState15 } from "react";
5288
+ import { jsxDEV as jsxDEV12, Fragment } from "@opentui/react/jsx-dev-runtime";
5289
+ var MAX_ANNOTATION_LENGTH = 500;
5290
+ var dialogColors = {
5291
+ bgDark: "#1e1e2e",
5292
+ bgPanel: "#181825",
5293
+ bgInput: "#11111b",
5294
+ textPrimary: "#cdd6f4",
5295
+ textSecondary: "#bac2de",
5296
+ textMuted: "#6c7086",
5297
+ accent: "#89b4fa"
5298
+ };
5299
+ function AnnotationEditorContent({
5300
+ initialText = "",
5301
+ hasExisting = false,
5302
+ resolve,
5303
+ dismiss,
5304
+ dialogId
5305
+ }) {
5306
+ const [value, setValue] = useState15(initialText);
5307
+ const [error, setError] = useState15(null);
5308
+ const handleSubmit = () => {
5309
+ const trimmed = value.trim();
5310
+ if (!trimmed) {
5311
+ if (hasExisting) {
5312
+ resolve({ action: "delete" });
5313
+ } else {
5314
+ setError("Annotation cannot be empty");
5315
+ }
5316
+ return;
5317
+ }
5318
+ if (trimmed.length > MAX_ANNOTATION_LENGTH) {
5319
+ setError(`Annotation must be ${MAX_ANNOTATION_LENGTH} characters or less`);
5320
+ return;
5321
+ }
5322
+ resolve({ action: "save", text: trimmed });
5323
+ };
5324
+ const handleDelete = () => {
5325
+ resolve({ action: "delete" });
5326
+ };
5327
+ useDialogKeyboard((key) => {
5328
+ if (key.name === "escape") {
5329
+ dismiss();
5330
+ return;
5331
+ }
5332
+ if (key.ctrl && key.name === "d" && hasExisting) {
5333
+ handleDelete();
5334
+ }
5335
+ }, dialogId);
5336
+ const title = hasExisting ? "Edit Annotation" : "Add Annotation";
5337
+ const isOverLimit = value.length > MAX_ANNOTATION_LENGTH;
5338
+ return /* @__PURE__ */ jsxDEV12("box", {
5339
+ flexDirection: "column",
5340
+ children: [
5341
+ /* @__PURE__ */ jsxDEV12("box", {
5342
+ backgroundColor: dialogColors.bgPanel,
5343
+ paddingLeft: 3,
5344
+ paddingRight: 3,
5345
+ paddingTop: 1,
5346
+ paddingBottom: 1,
5347
+ flexDirection: "row",
5348
+ gap: 1,
5349
+ width: 56,
5350
+ children: [
5351
+ /* @__PURE__ */ jsxDEV12("text", {
5352
+ fg: dialogColors.accent,
5353
+ children: "+"
5354
+ }, undefined, false, undefined, this),
5355
+ /* @__PURE__ */ jsxDEV12("text", {
5356
+ fg: dialogColors.textPrimary,
5357
+ children: /* @__PURE__ */ jsxDEV12("b", {
5358
+ children: title
5359
+ }, undefined, false, undefined, this)
5360
+ }, undefined, false, undefined, this)
5361
+ ]
5362
+ }, undefined, true, undefined, this),
5363
+ /* @__PURE__ */ jsxDEV12("box", {
5364
+ backgroundColor: dialogColors.bgDark,
5365
+ paddingLeft: 3,
5366
+ paddingRight: 3,
5367
+ paddingTop: 1,
5368
+ paddingBottom: 1,
5369
+ flexDirection: "column",
5370
+ gap: 1,
5371
+ width: 56,
5372
+ children: [
5373
+ /* @__PURE__ */ jsxDEV12("box", {
5374
+ backgroundColor: dialogColors.bgInput,
5375
+ borderStyle: "single",
5376
+ borderColor: dialogColors.accent,
5377
+ height: 3,
5378
+ children: /* @__PURE__ */ jsxDEV12("input", {
5379
+ value,
5380
+ placeholder: "Why did you save this tweet?",
5381
+ maxLength: MAX_ANNOTATION_LENGTH + 50,
5382
+ focused: true,
5383
+ onInput: (newValue) => {
5384
+ setValue(newValue);
5385
+ if (error)
5386
+ setError(null);
5387
+ },
5388
+ onSubmit: () => {
5389
+ handleSubmit();
5390
+ },
5391
+ textColor: dialogColors.textPrimary,
5392
+ placeholderColor: dialogColors.textMuted,
5393
+ cursorColor: dialogColors.accent,
5394
+ focusedBackgroundColor: "transparent"
5395
+ }, undefined, false, undefined, this)
5396
+ }, undefined, false, undefined, this),
5397
+ /* @__PURE__ */ jsxDEV12("text", {
5398
+ fg: isOverLimit ? colors.error : dialogColors.textMuted,
5399
+ children: [
5400
+ value.length,
5401
+ "/",
5402
+ MAX_ANNOTATION_LENGTH
5403
+ ]
5404
+ }, undefined, true, undefined, this),
5405
+ error ? /* @__PURE__ */ jsxDEV12("text", {
5406
+ fg: colors.error,
5407
+ children: error
5408
+ }, undefined, false, undefined, this) : null
5409
+ ]
5410
+ }, undefined, true, undefined, this),
5411
+ /* @__PURE__ */ jsxDEV12("box", {
5412
+ backgroundColor: dialogColors.bgPanel,
5413
+ paddingLeft: 3,
5414
+ paddingRight: 3,
5415
+ paddingTop: 1,
5416
+ paddingBottom: 1,
5417
+ flexDirection: "row",
5418
+ gap: 2,
5419
+ width: 56,
5420
+ children: [
5421
+ /* @__PURE__ */ jsxDEV12("text", {
5422
+ fg: dialogColors.textMuted,
5423
+ children: "Enter"
5424
+ }, undefined, false, undefined, this),
5425
+ /* @__PURE__ */ jsxDEV12("text", {
5426
+ fg: dialogColors.textSecondary,
5427
+ children: "save"
5428
+ }, undefined, false, undefined, this),
5429
+ /* @__PURE__ */ jsxDEV12("text", {
5430
+ fg: dialogColors.textMuted,
5431
+ children: "Esc"
5432
+ }, undefined, false, undefined, this),
5433
+ /* @__PURE__ */ jsxDEV12("text", {
5434
+ fg: dialogColors.textSecondary,
5435
+ children: "cancel"
5436
+ }, undefined, false, undefined, this),
5437
+ hasExisting ? /* @__PURE__ */ jsxDEV12(Fragment, {
5438
+ children: [
5439
+ /* @__PURE__ */ jsxDEV12("text", {
5440
+ fg: dialogColors.textMuted,
5441
+ children: "^D"
5442
+ }, undefined, false, undefined, this),
5443
+ /* @__PURE__ */ jsxDEV12("text", {
5444
+ fg: dialogColors.textSecondary,
5445
+ children: "delete"
5446
+ }, undefined, false, undefined, this)
5447
+ ]
5448
+ }, undefined, true, undefined, this) : null
5449
+ ]
5450
+ }, undefined, true, undefined, this)
5451
+ ]
5452
+ }, undefined, true, undefined, this);
5453
+ }
5454
+
5150
5455
  // src/modals/BookmarkFolderSelector.tsx
5151
- import { useEffect as useEffect11, useState as useState14 } from "react";
5456
+ import { useEffect as useEffect12, useState as useState17 } from "react";
5152
5457
 
5153
5458
  // src/hooks/useBookmarkFolders.ts
5154
- import { useState as useState13, useEffect as useEffect10, useCallback as useCallback11 } from "react";
5459
+ import { useState as useState16, useEffect as useEffect11, useCallback as useCallback12 } from "react";
5155
5460
  function useBookmarkFolders({
5156
5461
  client,
5157
5462
  enabled = true
5158
5463
  }) {
5159
- const [folders, setFolders] = useState13([]);
5160
- const [loading, setLoading] = useState13(false);
5161
- const [error, setError] = useState13(null);
5162
- const [refreshCounter, setRefreshCounter] = useState13(0);
5163
- const fetchFolders = useCallback11(async () => {
5464
+ const [folders, setFolders] = useState16([]);
5465
+ const [loading, setLoading] = useState16(false);
5466
+ const [error, setError] = useState16(null);
5467
+ const [refreshCounter, setRefreshCounter] = useState16(0);
5468
+ const fetchFolders = useCallback12(async () => {
5164
5469
  if (!enabled)
5165
5470
  return;
5166
5471
  setLoading(true);
@@ -5173,12 +5478,12 @@ function useBookmarkFolders({
5173
5478
  }
5174
5479
  setLoading(false);
5175
5480
  }, [client, enabled]);
5176
- useEffect10(() => {
5481
+ useEffect11(() => {
5177
5482
  if (enabled) {
5178
5483
  fetchFolders();
5179
5484
  }
5180
5485
  }, [fetchFolders, refreshCounter, enabled]);
5181
- const refresh = useCallback11(() => {
5486
+ const refresh = useCallback12(() => {
5182
5487
  setRefreshCounter((prev) => prev + 1);
5183
5488
  }, []);
5184
5489
  return {
@@ -5190,9 +5495,9 @@ function useBookmarkFolders({
5190
5495
  }
5191
5496
 
5192
5497
  // src/modals/BookmarkFolderSelector.tsx
5193
- import { jsxDEV as jsxDEV12 } from "@opentui/react/jsx-dev-runtime";
5498
+ import { jsxDEV as jsxDEV13 } from "@opentui/react/jsx-dev-runtime";
5194
5499
  var MAX_VISIBLE_ITEMS = 5;
5195
- var dialogColors = {
5500
+ var dialogColors2 = {
5196
5501
  bgDark: "#1e1e2e",
5197
5502
  bgPanel: "#181825",
5198
5503
  bgHover: "#313244",
@@ -5209,7 +5514,7 @@ function BookmarkFolderSelectorContent({
5209
5514
  dialogId
5210
5515
  }) {
5211
5516
  const { folders, loading, error } = useBookmarkFolders({ client });
5212
- const [windowStart, setWindowStart] = useState14(0);
5517
+ const [windowStart, setWindowStart] = useState17(0);
5213
5518
  const isViewingAllBookmarks = !currentFolder;
5214
5519
  const selectableFolders = currentFolder ? folders.filter((f) => f.id !== currentFolder.id) : folders;
5215
5520
  const items = isViewingAllBookmarks ? selectableFolders : [null, ...selectableFolders];
@@ -5227,7 +5532,7 @@ function BookmarkFolderSelectorContent({
5227
5532
  dismiss();
5228
5533
  }
5229
5534
  }, dialogId);
5230
- useEffect11(() => {
5535
+ useEffect12(() => {
5231
5536
  if (itemCount === 0)
5232
5537
  return;
5233
5538
  const windowEnd = windowStart + MAX_VISIBLE_ITEMS - 1;
@@ -5238,11 +5543,11 @@ function BookmarkFolderSelectorContent({
5238
5543
  }
5239
5544
  }, [selectedIndex, windowStart, itemCount]);
5240
5545
  if (loading) {
5241
- return /* @__PURE__ */ jsxDEV12("box", {
5546
+ return /* @__PURE__ */ jsxDEV13("box", {
5242
5547
  flexDirection: "column",
5243
5548
  children: [
5244
- /* @__PURE__ */ jsxDEV12("box", {
5245
- backgroundColor: dialogColors.bgPanel,
5549
+ /* @__PURE__ */ jsxDEV13("box", {
5550
+ backgroundColor: dialogColors2.bgPanel,
5246
5551
  paddingLeft: 3,
5247
5552
  paddingRight: 3,
5248
5553
  paddingTop: 1,
@@ -5250,31 +5555,31 @@ function BookmarkFolderSelectorContent({
5250
5555
  flexDirection: "row",
5251
5556
  gap: 1,
5252
5557
  children: [
5253
- /* @__PURE__ */ jsxDEV12("text", {
5254
- fg: dialogColors.accent,
5558
+ /* @__PURE__ */ jsxDEV13("text", {
5559
+ fg: dialogColors2.accent,
5255
5560
  children: "\uD83D\uDCC1"
5256
5561
  }, undefined, false, undefined, this),
5257
- /* @__PURE__ */ jsxDEV12("text", {
5258
- fg: dialogColors.textPrimary,
5259
- children: /* @__PURE__ */ jsxDEV12("b", {
5562
+ /* @__PURE__ */ jsxDEV13("text", {
5563
+ fg: dialogColors2.textPrimary,
5564
+ children: /* @__PURE__ */ jsxDEV13("b", {
5260
5565
  children: "Select Folder"
5261
5566
  }, undefined, false, undefined, this)
5262
5567
  }, undefined, false, undefined, this)
5263
5568
  ]
5264
5569
  }, undefined, true, undefined, this),
5265
- /* @__PURE__ */ jsxDEV12("box", {
5266
- backgroundColor: dialogColors.bgDark,
5570
+ /* @__PURE__ */ jsxDEV13("box", {
5571
+ backgroundColor: dialogColors2.bgDark,
5267
5572
  paddingLeft: 3,
5268
5573
  paddingRight: 3,
5269
5574
  paddingTop: 1,
5270
5575
  paddingBottom: 1,
5271
- children: /* @__PURE__ */ jsxDEV12("text", {
5272
- fg: dialogColors.textMuted,
5576
+ children: /* @__PURE__ */ jsxDEV13("text", {
5577
+ fg: dialogColors2.textMuted,
5273
5578
  children: "Loading folders..."
5274
5579
  }, undefined, false, undefined, this)
5275
5580
  }, undefined, false, undefined, this),
5276
- /* @__PURE__ */ jsxDEV12("box", {
5277
- backgroundColor: dialogColors.bgPanel,
5581
+ /* @__PURE__ */ jsxDEV13("box", {
5582
+ backgroundColor: dialogColors2.bgPanel,
5278
5583
  paddingLeft: 3,
5279
5584
  paddingRight: 3,
5280
5585
  paddingTop: 1,
@@ -5282,12 +5587,12 @@ function BookmarkFolderSelectorContent({
5282
5587
  flexDirection: "row",
5283
5588
  gap: 2,
5284
5589
  children: [
5285
- /* @__PURE__ */ jsxDEV12("text", {
5286
- fg: dialogColors.textMuted,
5590
+ /* @__PURE__ */ jsxDEV13("text", {
5591
+ fg: dialogColors2.textMuted,
5287
5592
  children: "Esc"
5288
5593
  }, undefined, false, undefined, this),
5289
- /* @__PURE__ */ jsxDEV12("text", {
5290
- fg: dialogColors.textSecondary,
5594
+ /* @__PURE__ */ jsxDEV13("text", {
5595
+ fg: dialogColors2.textSecondary,
5291
5596
  children: "cancel"
5292
5597
  }, undefined, false, undefined, this)
5293
5598
  ]
@@ -5296,11 +5601,11 @@ function BookmarkFolderSelectorContent({
5296
5601
  }, undefined, true, undefined, this);
5297
5602
  }
5298
5603
  if (error) {
5299
- return /* @__PURE__ */ jsxDEV12("box", {
5604
+ return /* @__PURE__ */ jsxDEV13("box", {
5300
5605
  flexDirection: "column",
5301
5606
  children: [
5302
- /* @__PURE__ */ jsxDEV12("box", {
5303
- backgroundColor: dialogColors.bgPanel,
5607
+ /* @__PURE__ */ jsxDEV13("box", {
5608
+ backgroundColor: dialogColors2.bgPanel,
5304
5609
  paddingLeft: 3,
5305
5610
  paddingRight: 3,
5306
5611
  paddingTop: 1,
@@ -5308,25 +5613,25 @@ function BookmarkFolderSelectorContent({
5308
5613
  flexDirection: "row",
5309
5614
  gap: 1,
5310
5615
  children: [
5311
- /* @__PURE__ */ jsxDEV12("text", {
5312
- fg: dialogColors.accent,
5616
+ /* @__PURE__ */ jsxDEV13("text", {
5617
+ fg: dialogColors2.accent,
5313
5618
  children: "\uD83D\uDCC1"
5314
5619
  }, undefined, false, undefined, this),
5315
- /* @__PURE__ */ jsxDEV12("text", {
5316
- fg: dialogColors.textPrimary,
5317
- children: /* @__PURE__ */ jsxDEV12("b", {
5620
+ /* @__PURE__ */ jsxDEV13("text", {
5621
+ fg: dialogColors2.textPrimary,
5622
+ children: /* @__PURE__ */ jsxDEV13("b", {
5318
5623
  children: "Select Folder"
5319
5624
  }, undefined, false, undefined, this)
5320
5625
  }, undefined, false, undefined, this)
5321
5626
  ]
5322
5627
  }, undefined, true, undefined, this),
5323
- /* @__PURE__ */ jsxDEV12("box", {
5324
- backgroundColor: dialogColors.bgDark,
5628
+ /* @__PURE__ */ jsxDEV13("box", {
5629
+ backgroundColor: dialogColors2.bgDark,
5325
5630
  paddingLeft: 3,
5326
5631
  paddingRight: 3,
5327
5632
  paddingTop: 1,
5328
5633
  paddingBottom: 1,
5329
- children: /* @__PURE__ */ jsxDEV12("text", {
5634
+ children: /* @__PURE__ */ jsxDEV13("text", {
5330
5635
  fg: colors.error,
5331
5636
  children: [
5332
5637
  "Error: ",
@@ -5334,8 +5639,8 @@ function BookmarkFolderSelectorContent({
5334
5639
  ]
5335
5640
  }, undefined, true, undefined, this)
5336
5641
  }, undefined, false, undefined, this),
5337
- /* @__PURE__ */ jsxDEV12("box", {
5338
- backgroundColor: dialogColors.bgPanel,
5642
+ /* @__PURE__ */ jsxDEV13("box", {
5643
+ backgroundColor: dialogColors2.bgPanel,
5339
5644
  paddingLeft: 3,
5340
5645
  paddingRight: 3,
5341
5646
  paddingTop: 1,
@@ -5343,12 +5648,12 @@ function BookmarkFolderSelectorContent({
5343
5648
  flexDirection: "row",
5344
5649
  gap: 2,
5345
5650
  children: [
5346
- /* @__PURE__ */ jsxDEV12("text", {
5347
- fg: dialogColors.textMuted,
5651
+ /* @__PURE__ */ jsxDEV13("text", {
5652
+ fg: dialogColors2.textMuted,
5348
5653
  children: "Esc"
5349
5654
  }, undefined, false, undefined, this),
5350
- /* @__PURE__ */ jsxDEV12("text", {
5351
- fg: dialogColors.textSecondary,
5655
+ /* @__PURE__ */ jsxDEV13("text", {
5656
+ fg: dialogColors2.textSecondary,
5352
5657
  children: "close"
5353
5658
  }, undefined, false, undefined, this)
5354
5659
  ]
@@ -5360,11 +5665,11 @@ function BookmarkFolderSelectorContent({
5360
5665
  const hasMoreBelow = windowStart + MAX_VISIBLE_ITEMS < itemCount;
5361
5666
  const visibleItems = items.slice(windowStart, windowStart + MAX_VISIBLE_ITEMS);
5362
5667
  const title = isViewingAllBookmarks ? "Switch to Folder" : "Switch View";
5363
- return /* @__PURE__ */ jsxDEV12("box", {
5668
+ return /* @__PURE__ */ jsxDEV13("box", {
5364
5669
  flexDirection: "column",
5365
5670
  children: [
5366
- /* @__PURE__ */ jsxDEV12("box", {
5367
- backgroundColor: dialogColors.bgPanel,
5671
+ /* @__PURE__ */ jsxDEV13("box", {
5672
+ backgroundColor: dialogColors2.bgPanel,
5368
5673
  paddingLeft: 3,
5369
5674
  paddingRight: 3,
5370
5675
  paddingTop: 1,
@@ -5372,18 +5677,18 @@ function BookmarkFolderSelectorContent({
5372
5677
  flexDirection: "row",
5373
5678
  gap: 1,
5374
5679
  children: [
5375
- /* @__PURE__ */ jsxDEV12("text", {
5376
- fg: dialogColors.accent,
5680
+ /* @__PURE__ */ jsxDEV13("text", {
5681
+ fg: dialogColors2.accent,
5377
5682
  children: "\uD83D\uDCC1"
5378
5683
  }, undefined, false, undefined, this),
5379
- /* @__PURE__ */ jsxDEV12("text", {
5380
- fg: dialogColors.textPrimary,
5381
- children: /* @__PURE__ */ jsxDEV12("b", {
5684
+ /* @__PURE__ */ jsxDEV13("text", {
5685
+ fg: dialogColors2.textPrimary,
5686
+ children: /* @__PURE__ */ jsxDEV13("b", {
5382
5687
  children: title
5383
5688
  }, undefined, false, undefined, this)
5384
5689
  }, undefined, false, undefined, this),
5385
- /* @__PURE__ */ jsxDEV12("text", {
5386
- fg: dialogColors.textMuted,
5690
+ /* @__PURE__ */ jsxDEV13("text", {
5691
+ fg: dialogColors2.textMuted,
5387
5692
  children: [
5388
5693
  "(",
5389
5694
  itemCount,
@@ -5392,16 +5697,16 @@ function BookmarkFolderSelectorContent({
5392
5697
  }, undefined, true, undefined, this)
5393
5698
  ]
5394
5699
  }, undefined, true, undefined, this),
5395
- /* @__PURE__ */ jsxDEV12("box", {
5396
- backgroundColor: dialogColors.bgDark,
5700
+ /* @__PURE__ */ jsxDEV13("box", {
5701
+ backgroundColor: dialogColors2.bgDark,
5397
5702
  paddingLeft: 3,
5398
5703
  paddingRight: 3,
5399
5704
  paddingTop: 1,
5400
5705
  paddingBottom: 1,
5401
5706
  flexDirection: "column",
5402
5707
  children: [
5403
- hasMoreAbove ? /* @__PURE__ */ jsxDEV12("text", {
5404
- fg: dialogColors.textMuted,
5708
+ hasMoreAbove ? /* @__PURE__ */ jsxDEV13("text", {
5709
+ fg: dialogColors2.textMuted,
5405
5710
  children: "\u2191 more"
5406
5711
  }, undefined, false, undefined, this) : null,
5407
5712
  visibleItems.map((item, visibleIndex) => {
@@ -5409,9 +5714,9 @@ function BookmarkFolderSelectorContent({
5409
5714
  const isSelected = actualIndex === selectedIndex;
5410
5715
  const isAllBookmarks = item === null;
5411
5716
  const label = isAllBookmarks ? "All Bookmarks" : item.name;
5412
- return /* @__PURE__ */ jsxDEV12("text", {
5413
- fg: isSelected ? dialogColors.textPrimary : dialogColors.textSecondary,
5414
- bg: isSelected ? dialogColors.bgHover : undefined,
5717
+ return /* @__PURE__ */ jsxDEV13("text", {
5718
+ fg: isSelected ? dialogColors2.textPrimary : dialogColors2.textSecondary,
5719
+ bg: isSelected ? dialogColors2.bgHover : undefined,
5415
5720
  children: [
5416
5721
  isSelected ? " \u203A " : " ",
5417
5722
  label,
@@ -5419,14 +5724,14 @@ function BookmarkFolderSelectorContent({
5419
5724
  ]
5420
5725
  }, isAllBookmarks ? "all" : item.id, true, undefined, this);
5421
5726
  }),
5422
- hasMoreBelow ? /* @__PURE__ */ jsxDEV12("text", {
5423
- fg: dialogColors.textMuted,
5727
+ hasMoreBelow ? /* @__PURE__ */ jsxDEV13("text", {
5728
+ fg: dialogColors2.textMuted,
5424
5729
  children: "\u2193 more"
5425
5730
  }, undefined, false, undefined, this) : null
5426
5731
  ]
5427
5732
  }, undefined, true, undefined, this),
5428
- /* @__PURE__ */ jsxDEV12("box", {
5429
- backgroundColor: dialogColors.bgPanel,
5733
+ /* @__PURE__ */ jsxDEV13("box", {
5734
+ backgroundColor: dialogColors2.bgPanel,
5430
5735
  paddingLeft: 3,
5431
5736
  paddingRight: 3,
5432
5737
  paddingTop: 1,
@@ -5434,28 +5739,28 @@ function BookmarkFolderSelectorContent({
5434
5739
  flexDirection: "row",
5435
5740
  gap: 2,
5436
5741
  children: [
5437
- /* @__PURE__ */ jsxDEV12("text", {
5438
- fg: dialogColors.textMuted,
5742
+ /* @__PURE__ */ jsxDEV13("text", {
5743
+ fg: dialogColors2.textMuted,
5439
5744
  children: "j/k"
5440
5745
  }, undefined, false, undefined, this),
5441
- /* @__PURE__ */ jsxDEV12("text", {
5442
- fg: dialogColors.textSecondary,
5746
+ /* @__PURE__ */ jsxDEV13("text", {
5747
+ fg: dialogColors2.textSecondary,
5443
5748
  children: "nav"
5444
5749
  }, undefined, false, undefined, this),
5445
- /* @__PURE__ */ jsxDEV12("text", {
5446
- fg: dialogColors.textMuted,
5750
+ /* @__PURE__ */ jsxDEV13("text", {
5751
+ fg: dialogColors2.textMuted,
5447
5752
  children: "Enter"
5448
5753
  }, undefined, false, undefined, this),
5449
- /* @__PURE__ */ jsxDEV12("text", {
5450
- fg: dialogColors.textSecondary,
5754
+ /* @__PURE__ */ jsxDEV13("text", {
5755
+ fg: dialogColors2.textSecondary,
5451
5756
  children: "select"
5452
5757
  }, undefined, false, undefined, this),
5453
- /* @__PURE__ */ jsxDEV12("text", {
5454
- fg: dialogColors.textMuted,
5758
+ /* @__PURE__ */ jsxDEV13("text", {
5759
+ fg: dialogColors2.textMuted,
5455
5760
  children: "Esc"
5456
5761
  }, undefined, false, undefined, this),
5457
- /* @__PURE__ */ jsxDEV12("text", {
5458
- fg: dialogColors.textSecondary,
5762
+ /* @__PURE__ */ jsxDEV13("text", {
5763
+ fg: dialogColors2.textSecondary,
5459
5764
  children: "cancel"
5460
5765
  }, undefined, false, undefined, this)
5461
5766
  ]
@@ -5465,9 +5770,9 @@ function BookmarkFolderSelectorContent({
5465
5770
  }
5466
5771
 
5467
5772
  // src/modals/DeleteFolderConfirmModal.tsx
5468
- import { useState as useState15 } from "react";
5469
- import { jsxDEV as jsxDEV13 } from "@opentui/react/jsx-dev-runtime";
5470
- var dialogColors2 = {
5773
+ import { useState as useState18 } from "react";
5774
+ import { jsxDEV as jsxDEV14 } from "@opentui/react/jsx-dev-runtime";
5775
+ var dialogColors3 = {
5471
5776
  bgDark: "#1e1e2e",
5472
5777
  bgPanel: "#181825",
5473
5778
  bgHover: "#313244",
@@ -5484,9 +5789,9 @@ function DeleteFolderConfirmContent({
5484
5789
  dismiss,
5485
5790
  dialogId
5486
5791
  }) {
5487
- const [selected, setSelected] = useState15("cancel");
5488
- const [isDeleting, setIsDeleting] = useState15(false);
5489
- const [error, setError] = useState15(null);
5792
+ const [selected, setSelected] = useState18("cancel");
5793
+ const [isDeleting, setIsDeleting] = useState18(false);
5794
+ const [error, setError] = useState18(null);
5490
5795
  const handleConfirm = async () => {
5491
5796
  if (isDeleting)
5492
5797
  return;
@@ -5519,11 +5824,11 @@ function DeleteFolderConfirmContent({
5519
5824
  dismiss();
5520
5825
  }
5521
5826
  }, dialogId);
5522
- return /* @__PURE__ */ jsxDEV13("box", {
5827
+ return /* @__PURE__ */ jsxDEV14("box", {
5523
5828
  flexDirection: "column",
5524
5829
  children: [
5525
- /* @__PURE__ */ jsxDEV13("box", {
5526
- backgroundColor: dialogColors2.bgPanel,
5830
+ /* @__PURE__ */ jsxDEV14("box", {
5831
+ backgroundColor: dialogColors3.bgPanel,
5527
5832
  paddingLeft: 3,
5528
5833
  paddingRight: 3,
5529
5834
  paddingTop: 1,
@@ -5531,20 +5836,20 @@ function DeleteFolderConfirmContent({
5531
5836
  flexDirection: "row",
5532
5837
  gap: 1,
5533
5838
  children: [
5534
- /* @__PURE__ */ jsxDEV13("text", {
5535
- fg: dialogColors2.red,
5839
+ /* @__PURE__ */ jsxDEV14("text", {
5840
+ fg: dialogColors3.red,
5536
5841
  children: "*"
5537
5842
  }, undefined, false, undefined, this),
5538
- /* @__PURE__ */ jsxDEV13("text", {
5539
- fg: dialogColors2.textPrimary,
5540
- children: /* @__PURE__ */ jsxDEV13("b", {
5843
+ /* @__PURE__ */ jsxDEV14("text", {
5844
+ fg: dialogColors3.textPrimary,
5845
+ children: /* @__PURE__ */ jsxDEV14("b", {
5541
5846
  children: "Delete Folder"
5542
5847
  }, undefined, false, undefined, this)
5543
5848
  }, undefined, false, undefined, this)
5544
5849
  ]
5545
5850
  }, undefined, true, undefined, this),
5546
- /* @__PURE__ */ jsxDEV13("box", {
5547
- backgroundColor: dialogColors2.bgDark,
5851
+ /* @__PURE__ */ jsxDEV14("box", {
5852
+ backgroundColor: dialogColors3.bgDark,
5548
5853
  paddingLeft: 3,
5549
5854
  paddingRight: 3,
5550
5855
  paddingTop: 1,
@@ -5552,33 +5857,33 @@ function DeleteFolderConfirmContent({
5552
5857
  flexDirection: "column",
5553
5858
  gap: 1,
5554
5859
  children: [
5555
- /* @__PURE__ */ jsxDEV13("text", {
5556
- fg: dialogColors2.textSecondary,
5860
+ /* @__PURE__ */ jsxDEV14("text", {
5861
+ fg: dialogColors3.textSecondary,
5557
5862
  children: "Are you sure you want to delete this folder?"
5558
5863
  }, undefined, false, undefined, this),
5559
- /* @__PURE__ */ jsxDEV13("text", {
5560
- fg: dialogColors2.textPrimary,
5864
+ /* @__PURE__ */ jsxDEV14("text", {
5865
+ fg: dialogColors3.textPrimary,
5561
5866
  children: [
5562
5867
  "\u2192 ",
5563
5868
  folderName
5564
5869
  ]
5565
5870
  }, undefined, true, undefined, this),
5566
- /* @__PURE__ */ jsxDEV13("text", {
5567
- fg: dialogColors2.textMuted,
5871
+ /* @__PURE__ */ jsxDEV14("text", {
5872
+ fg: dialogColors3.textMuted,
5568
5873
  children: "Bookmarks will be moved to All Bookmarks."
5569
5874
  }, undefined, false, undefined, this),
5570
- error ? /* @__PURE__ */ jsxDEV13("text", {
5875
+ error ? /* @__PURE__ */ jsxDEV14("text", {
5571
5876
  fg: colors.error,
5572
5877
  children: error
5573
5878
  }, undefined, false, undefined, this) : null,
5574
- isDeleting ? /* @__PURE__ */ jsxDEV13("text", {
5575
- fg: dialogColors2.textMuted,
5879
+ isDeleting ? /* @__PURE__ */ jsxDEV14("text", {
5880
+ fg: dialogColors3.textMuted,
5576
5881
  children: "Deleting..."
5577
5882
  }, undefined, false, undefined, this) : null
5578
5883
  ]
5579
5884
  }, undefined, true, undefined, this),
5580
- /* @__PURE__ */ jsxDEV13("box", {
5581
- backgroundColor: dialogColors2.bgPanel,
5885
+ /* @__PURE__ */ jsxDEV14("box", {
5886
+ backgroundColor: dialogColors3.bgPanel,
5582
5887
  paddingLeft: 3,
5583
5888
  paddingRight: 3,
5584
5889
  paddingTop: 1,
@@ -5587,18 +5892,18 @@ function DeleteFolderConfirmContent({
5587
5892
  gap: 2,
5588
5893
  justifyContent: "flex-end",
5589
5894
  children: [
5590
- /* @__PURE__ */ jsxDEV13("text", {
5591
- bg: selected === "cancel" ? dialogColors2.bgHover : undefined,
5592
- fg: dialogColors2.textSecondary,
5895
+ /* @__PURE__ */ jsxDEV14("text", {
5896
+ bg: selected === "cancel" ? dialogColors3.bgHover : undefined,
5897
+ fg: dialogColors3.textSecondary,
5593
5898
  children: [
5594
5899
  " ",
5595
5900
  "Cancel",
5596
5901
  " "
5597
5902
  ]
5598
5903
  }, undefined, true, undefined, this),
5599
- /* @__PURE__ */ jsxDEV13("text", {
5600
- bg: selected === "delete" ? dialogColors2.redBg : undefined,
5601
- fg: selected === "delete" ? "#ffffff" : dialogColors2.red,
5904
+ /* @__PURE__ */ jsxDEV14("text", {
5905
+ bg: selected === "delete" ? dialogColors3.redBg : undefined,
5906
+ fg: selected === "delete" ? "#ffffff" : dialogColors3.red,
5602
5907
  children: [
5603
5908
  " ",
5604
5909
  "Delete",
@@ -5612,11 +5917,11 @@ function DeleteFolderConfirmContent({
5612
5917
  }
5613
5918
 
5614
5919
  // src/modals/ExitConfirmationModal.tsx
5615
- import { useState as useState16 } from "react";
5616
- import { jsxDEV as jsxDEV14 } from "@opentui/react/jsx-dev-runtime";
5920
+ import { useState as useState19 } from "react";
5921
+ import { jsxDEV as jsxDEV15 } from "@opentui/react/jsx-dev-runtime";
5617
5922
  var OPTIONS = ["Logout and exit", "Just exit", "Cancel"];
5618
5923
  var OPTION_COUNT = OPTIONS.length;
5619
- var dialogColors3 = {
5924
+ var dialogColors4 = {
5620
5925
  bgDark: "#1e1e2e",
5621
5926
  bgPanel: "#181825",
5622
5927
  bgHover: "#313244",
@@ -5631,7 +5936,7 @@ function ExitConfirmationContent({
5631
5936
  dismiss,
5632
5937
  dialogId
5633
5938
  }) {
5634
- const [selectedIndex, setSelectedIndex] = useState16(2);
5939
+ const [selectedIndex, setSelectedIndex] = useState19(2);
5635
5940
  useDialogKeyboard((key) => {
5636
5941
  if (key.name === "l") {
5637
5942
  resolve("logout");
@@ -5663,11 +5968,11 @@ function ExitConfirmationContent({
5663
5968
  }
5664
5969
  }
5665
5970
  }, dialogId);
5666
- return /* @__PURE__ */ jsxDEV14("box", {
5971
+ return /* @__PURE__ */ jsxDEV15("box", {
5667
5972
  flexDirection: "column",
5668
5973
  children: [
5669
- /* @__PURE__ */ jsxDEV14("box", {
5670
- backgroundColor: dialogColors3.bgPanel,
5974
+ /* @__PURE__ */ jsxDEV15("box", {
5975
+ backgroundColor: dialogColors4.bgPanel,
5671
5976
  paddingLeft: 3,
5672
5977
  paddingRight: 3,
5673
5978
  paddingTop: 1,
@@ -5675,28 +5980,28 @@ function ExitConfirmationContent({
5675
5980
  flexDirection: "row",
5676
5981
  gap: 1,
5677
5982
  children: [
5678
- /* @__PURE__ */ jsxDEV14("text", {
5679
- fg: dialogColors3.warning,
5983
+ /* @__PURE__ */ jsxDEV15("text", {
5984
+ fg: dialogColors4.warning,
5680
5985
  children: "\u26A0"
5681
5986
  }, undefined, false, undefined, this),
5682
- /* @__PURE__ */ jsxDEV14("text", {
5683
- fg: dialogColors3.textPrimary,
5684
- children: /* @__PURE__ */ jsxDEV14("b", {
5987
+ /* @__PURE__ */ jsxDEV15("text", {
5988
+ fg: dialogColors4.textPrimary,
5989
+ children: /* @__PURE__ */ jsxDEV15("b", {
5685
5990
  children: "Exit xfeed?"
5686
5991
  }, undefined, false, undefined, this)
5687
5992
  }, undefined, false, undefined, this)
5688
5993
  ]
5689
5994
  }, undefined, true, undefined, this),
5690
- /* @__PURE__ */ jsxDEV14("box", {
5691
- backgroundColor: dialogColors3.bgDark,
5995
+ /* @__PURE__ */ jsxDEV15("box", {
5996
+ backgroundColor: dialogColors4.bgDark,
5692
5997
  paddingLeft: 3,
5693
5998
  paddingRight: 3,
5694
5999
  paddingTop: 1,
5695
6000
  paddingBottom: 1,
5696
6001
  flexDirection: "column",
5697
- children: OPTIONS.map((option, index) => /* @__PURE__ */ jsxDEV14("text", {
5698
- fg: selectedIndex === index ? dialogColors3.textPrimary : dialogColors3.textSecondary,
5699
- bg: selectedIndex === index ? dialogColors3.bgHover : undefined,
6002
+ children: OPTIONS.map((option, index) => /* @__PURE__ */ jsxDEV15("text", {
6003
+ fg: selectedIndex === index ? dialogColors4.textPrimary : dialogColors4.textSecondary,
6004
+ bg: selectedIndex === index ? dialogColors4.bgHover : undefined,
5700
6005
  children: [
5701
6006
  selectedIndex === index ? " \u203A " : " ",
5702
6007
  option,
@@ -5704,8 +6009,8 @@ function ExitConfirmationContent({
5704
6009
  ]
5705
6010
  }, option, true, undefined, this))
5706
6011
  }, undefined, false, undefined, this),
5707
- /* @__PURE__ */ jsxDEV14("box", {
5708
- backgroundColor: dialogColors3.bgPanel,
6012
+ /* @__PURE__ */ jsxDEV15("box", {
6013
+ backgroundColor: dialogColors4.bgPanel,
5709
6014
  paddingLeft: 3,
5710
6015
  paddingRight: 3,
5711
6016
  paddingTop: 1,
@@ -5713,28 +6018,28 @@ function ExitConfirmationContent({
5713
6018
  flexDirection: "row",
5714
6019
  gap: 2,
5715
6020
  children: [
5716
- /* @__PURE__ */ jsxDEV14("text", {
5717
- fg: dialogColors3.textMuted,
6021
+ /* @__PURE__ */ jsxDEV15("text", {
6022
+ fg: dialogColors4.textMuted,
5718
6023
  children: "l"
5719
6024
  }, undefined, false, undefined, this),
5720
- /* @__PURE__ */ jsxDEV14("text", {
5721
- fg: dialogColors3.textSecondary,
6025
+ /* @__PURE__ */ jsxDEV15("text", {
6026
+ fg: dialogColors4.textSecondary,
5722
6027
  children: "logout"
5723
6028
  }, undefined, false, undefined, this),
5724
- /* @__PURE__ */ jsxDEV14("text", {
5725
- fg: dialogColors3.textMuted,
6029
+ /* @__PURE__ */ jsxDEV15("text", {
6030
+ fg: dialogColors4.textMuted,
5726
6031
  children: "y"
5727
6032
  }, undefined, false, undefined, this),
5728
- /* @__PURE__ */ jsxDEV14("text", {
5729
- fg: dialogColors3.textSecondary,
6033
+ /* @__PURE__ */ jsxDEV15("text", {
6034
+ fg: dialogColors4.textSecondary,
5730
6035
  children: "exit"
5731
6036
  }, undefined, false, undefined, this),
5732
- /* @__PURE__ */ jsxDEV14("text", {
5733
- fg: dialogColors3.textMuted,
6037
+ /* @__PURE__ */ jsxDEV15("text", {
6038
+ fg: dialogColors4.textMuted,
5734
6039
  children: "n/Esc"
5735
6040
  }, undefined, false, undefined, this),
5736
- /* @__PURE__ */ jsxDEV14("text", {
5737
- fg: dialogColors3.textSecondary,
6041
+ /* @__PURE__ */ jsxDEV15("text", {
6042
+ fg: dialogColors4.textSecondary,
5738
6043
  children: "cancel"
5739
6044
  }, undefined, false, undefined, this)
5740
6045
  ]
@@ -5744,10 +6049,10 @@ function ExitConfirmationContent({
5744
6049
  }
5745
6050
 
5746
6051
  // src/modals/FolderNameInputModal.tsx
5747
- import { useState as useState17 } from "react";
5748
- import { jsxDEV as jsxDEV15 } from "@opentui/react/jsx-dev-runtime";
6052
+ import { useState as useState20 } from "react";
6053
+ import { jsxDEV as jsxDEV16 } from "@opentui/react/jsx-dev-runtime";
5749
6054
  var MAX_FOLDER_NAME_LENGTH = 25;
5750
- var dialogColors4 = {
6055
+ var dialogColors5 = {
5751
6056
  bgDark: "#1e1e2e",
5752
6057
  bgPanel: "#181825",
5753
6058
  bgInput: "#11111b",
@@ -5764,9 +6069,9 @@ function FolderNameInputContent({
5764
6069
  dismiss,
5765
6070
  dialogId
5766
6071
  }) {
5767
- const [value, setValue] = useState17(initialName);
5768
- const [isSubmitting, setIsSubmitting] = useState17(false);
5769
- const [error, setError] = useState17(null);
6072
+ const [value, setValue] = useState20(initialName);
6073
+ const [isSubmitting, setIsSubmitting] = useState20(false);
6074
+ const [error, setError] = useState20(null);
5770
6075
  const handleSubmit = async () => {
5771
6076
  const trimmed = value.trim();
5772
6077
  if (!trimmed) {
@@ -5798,11 +6103,11 @@ function FolderNameInputContent({
5798
6103
  }, dialogId);
5799
6104
  const title = mode === "create" ? "Create Folder" : "Rename Folder";
5800
6105
  const buttonText = mode === "create" ? "Create" : "Save";
5801
- return /* @__PURE__ */ jsxDEV15("box", {
6106
+ return /* @__PURE__ */ jsxDEV16("box", {
5802
6107
  flexDirection: "column",
5803
6108
  children: [
5804
- /* @__PURE__ */ jsxDEV15("box", {
5805
- backgroundColor: dialogColors4.bgPanel,
6109
+ /* @__PURE__ */ jsxDEV16("box", {
6110
+ backgroundColor: dialogColors5.bgPanel,
5806
6111
  paddingLeft: 3,
5807
6112
  paddingRight: 3,
5808
6113
  paddingTop: 1,
@@ -5810,20 +6115,20 @@ function FolderNameInputContent({
5810
6115
  flexDirection: "row",
5811
6116
  gap: 1,
5812
6117
  children: [
5813
- /* @__PURE__ */ jsxDEV15("text", {
5814
- fg: dialogColors4.accent,
6118
+ /* @__PURE__ */ jsxDEV16("text", {
6119
+ fg: dialogColors5.accent,
5815
6120
  children: "\uD83D\uDCC1"
5816
6121
  }, undefined, false, undefined, this),
5817
- /* @__PURE__ */ jsxDEV15("text", {
5818
- fg: dialogColors4.textPrimary,
5819
- children: /* @__PURE__ */ jsxDEV15("b", {
6122
+ /* @__PURE__ */ jsxDEV16("text", {
6123
+ fg: dialogColors5.textPrimary,
6124
+ children: /* @__PURE__ */ jsxDEV16("b", {
5820
6125
  children: title
5821
6126
  }, undefined, false, undefined, this)
5822
6127
  }, undefined, false, undefined, this)
5823
6128
  ]
5824
6129
  }, undefined, true, undefined, this),
5825
- /* @__PURE__ */ jsxDEV15("box", {
5826
- backgroundColor: dialogColors4.bgDark,
6130
+ /* @__PURE__ */ jsxDEV16("box", {
6131
+ backgroundColor: dialogColors5.bgDark,
5827
6132
  paddingLeft: 3,
5828
6133
  paddingRight: 3,
5829
6134
  paddingTop: 1,
@@ -5831,7 +6136,7 @@ function FolderNameInputContent({
5831
6136
  flexDirection: "column",
5832
6137
  gap: 1,
5833
6138
  children: [
5834
- /* @__PURE__ */ jsxDEV15("input", {
6139
+ /* @__PURE__ */ jsxDEV16("input", {
5835
6140
  value,
5836
6141
  placeholder: "Enter folder name...",
5837
6142
  maxLength: MAX_FOLDER_NAME_LENGTH,
@@ -5846,31 +6151,31 @@ function FolderNameInputContent({
5846
6151
  },
5847
6152
  width: 30,
5848
6153
  height: 1,
5849
- backgroundColor: dialogColors4.bgInput,
5850
- textColor: dialogColors4.textPrimary,
5851
- placeholderColor: dialogColors4.textMuted,
5852
- cursorColor: dialogColors4.accent
6154
+ backgroundColor: dialogColors5.bgInput,
6155
+ textColor: dialogColors5.textPrimary,
6156
+ placeholderColor: dialogColors5.textMuted,
6157
+ cursorColor: dialogColors5.accent
5853
6158
  }, undefined, false, undefined, this),
5854
- /* @__PURE__ */ jsxDEV15("text", {
5855
- fg: value.length > MAX_FOLDER_NAME_LENGTH ? colors.error : dialogColors4.textMuted,
6159
+ /* @__PURE__ */ jsxDEV16("text", {
6160
+ fg: value.length > MAX_FOLDER_NAME_LENGTH ? colors.error : dialogColors5.textMuted,
5856
6161
  children: [
5857
6162
  value.length,
5858
6163
  "/",
5859
6164
  MAX_FOLDER_NAME_LENGTH
5860
6165
  ]
5861
6166
  }, undefined, true, undefined, this),
5862
- error ? /* @__PURE__ */ jsxDEV15("text", {
6167
+ error ? /* @__PURE__ */ jsxDEV16("text", {
5863
6168
  fg: colors.error,
5864
6169
  children: error
5865
6170
  }, undefined, false, undefined, this) : null,
5866
- isSubmitting ? /* @__PURE__ */ jsxDEV15("text", {
5867
- fg: dialogColors4.textMuted,
6171
+ isSubmitting ? /* @__PURE__ */ jsxDEV16("text", {
6172
+ fg: dialogColors5.textMuted,
5868
6173
  children: "Saving..."
5869
6174
  }, undefined, false, undefined, this) : null
5870
6175
  ]
5871
6176
  }, undefined, true, undefined, this),
5872
- /* @__PURE__ */ jsxDEV15("box", {
5873
- backgroundColor: dialogColors4.bgPanel,
6177
+ /* @__PURE__ */ jsxDEV16("box", {
6178
+ backgroundColor: dialogColors5.bgPanel,
5874
6179
  paddingLeft: 3,
5875
6180
  paddingRight: 3,
5876
6181
  paddingTop: 1,
@@ -5878,20 +6183,20 @@ function FolderNameInputContent({
5878
6183
  flexDirection: "row",
5879
6184
  gap: 2,
5880
6185
  children: [
5881
- /* @__PURE__ */ jsxDEV15("text", {
5882
- fg: dialogColors4.textMuted,
6186
+ /* @__PURE__ */ jsxDEV16("text", {
6187
+ fg: dialogColors5.textMuted,
5883
6188
  children: "Enter"
5884
6189
  }, undefined, false, undefined, this),
5885
- /* @__PURE__ */ jsxDEV15("text", {
5886
- fg: dialogColors4.textSecondary,
6190
+ /* @__PURE__ */ jsxDEV16("text", {
6191
+ fg: dialogColors5.textSecondary,
5887
6192
  children: buttonText.toLowerCase()
5888
6193
  }, undefined, false, undefined, this),
5889
- /* @__PURE__ */ jsxDEV15("text", {
5890
- fg: dialogColors4.textMuted,
6194
+ /* @__PURE__ */ jsxDEV16("text", {
6195
+ fg: dialogColors5.textMuted,
5891
6196
  children: "Esc"
5892
6197
  }, undefined, false, undefined, this),
5893
- /* @__PURE__ */ jsxDEV15("text", {
5894
- fg: dialogColors4.textSecondary,
6198
+ /* @__PURE__ */ jsxDEV16("text", {
6199
+ fg: dialogColors5.textSecondary,
5895
6200
  children: "cancel"
5896
6201
  }, undefined, false, undefined, this)
5897
6202
  ]
@@ -5901,10 +6206,10 @@ function FolderNameInputContent({
5901
6206
  }
5902
6207
 
5903
6208
  // src/modals/FolderPicker.tsx
5904
- import { useEffect as useEffect12, useState as useState18 } from "react";
5905
- import { jsxDEV as jsxDEV16 } from "@opentui/react/jsx-dev-runtime";
6209
+ import { useEffect as useEffect13, useState as useState21 } from "react";
6210
+ import { jsxDEV as jsxDEV17 } from "@opentui/react/jsx-dev-runtime";
5906
6211
  var MAX_VISIBLE_FOLDERS = 5;
5907
- var dialogColors5 = {
6212
+ var dialogColors6 = {
5908
6213
  bgDark: "#1e1e2e",
5909
6214
  bgPanel: "#181825",
5910
6215
  bgHover: "#313244",
@@ -5920,7 +6225,7 @@ function FolderPickerContent({
5920
6225
  dialogId
5921
6226
  }) {
5922
6227
  const { folders, loading, error } = useBookmarkFolders({ client });
5923
- const [windowStart, setWindowStart] = useState18(0);
6228
+ const [windowStart, setWindowStart] = useState21(0);
5924
6229
  const { selectedIndex } = useListNavigation({
5925
6230
  itemCount: folders.length,
5926
6231
  enabled: !loading && !error && folders.length > 0,
@@ -5936,7 +6241,7 @@ function FolderPickerContent({
5936
6241
  dismiss();
5937
6242
  }
5938
6243
  }, dialogId);
5939
- useEffect12(() => {
6244
+ useEffect13(() => {
5940
6245
  if (folders.length === 0)
5941
6246
  return;
5942
6247
  const windowEnd = windowStart + MAX_VISIBLE_FOLDERS - 1;
@@ -5947,11 +6252,11 @@ function FolderPickerContent({
5947
6252
  }
5948
6253
  }, [selectedIndex, windowStart, folders.length]);
5949
6254
  if (loading) {
5950
- return /* @__PURE__ */ jsxDEV16("box", {
6255
+ return /* @__PURE__ */ jsxDEV17("box", {
5951
6256
  flexDirection: "column",
5952
6257
  children: [
5953
- /* @__PURE__ */ jsxDEV16("box", {
5954
- backgroundColor: dialogColors5.bgPanel,
6258
+ /* @__PURE__ */ jsxDEV17("box", {
6259
+ backgroundColor: dialogColors6.bgPanel,
5955
6260
  paddingLeft: 3,
5956
6261
  paddingRight: 3,
5957
6262
  paddingTop: 1,
@@ -5959,31 +6264,31 @@ function FolderPickerContent({
5959
6264
  flexDirection: "row",
5960
6265
  gap: 1,
5961
6266
  children: [
5962
- /* @__PURE__ */ jsxDEV16("text", {
5963
- fg: dialogColors5.accent,
6267
+ /* @__PURE__ */ jsxDEV17("text", {
6268
+ fg: dialogColors6.accent,
5964
6269
  children: "\uD83D\uDCC1"
5965
6270
  }, undefined, false, undefined, this),
5966
- /* @__PURE__ */ jsxDEV16("text", {
5967
- fg: dialogColors5.textPrimary,
5968
- children: /* @__PURE__ */ jsxDEV16("b", {
6271
+ /* @__PURE__ */ jsxDEV17("text", {
6272
+ fg: dialogColors6.textPrimary,
6273
+ children: /* @__PURE__ */ jsxDEV17("b", {
5969
6274
  children: "Move to Folder"
5970
6275
  }, undefined, false, undefined, this)
5971
6276
  }, undefined, false, undefined, this)
5972
6277
  ]
5973
6278
  }, undefined, true, undefined, this),
5974
- /* @__PURE__ */ jsxDEV16("box", {
5975
- backgroundColor: dialogColors5.bgDark,
6279
+ /* @__PURE__ */ jsxDEV17("box", {
6280
+ backgroundColor: dialogColors6.bgDark,
5976
6281
  paddingLeft: 3,
5977
6282
  paddingRight: 3,
5978
6283
  paddingTop: 1,
5979
6284
  paddingBottom: 1,
5980
- children: /* @__PURE__ */ jsxDEV16("text", {
5981
- fg: dialogColors5.textMuted,
6285
+ children: /* @__PURE__ */ jsxDEV17("text", {
6286
+ fg: dialogColors6.textMuted,
5982
6287
  children: "Loading folders..."
5983
6288
  }, undefined, false, undefined, this)
5984
6289
  }, undefined, false, undefined, this),
5985
- /* @__PURE__ */ jsxDEV16("box", {
5986
- backgroundColor: dialogColors5.bgPanel,
6290
+ /* @__PURE__ */ jsxDEV17("box", {
6291
+ backgroundColor: dialogColors6.bgPanel,
5987
6292
  paddingLeft: 3,
5988
6293
  paddingRight: 3,
5989
6294
  paddingTop: 1,
@@ -5991,12 +6296,12 @@ function FolderPickerContent({
5991
6296
  flexDirection: "row",
5992
6297
  gap: 2,
5993
6298
  children: [
5994
- /* @__PURE__ */ jsxDEV16("text", {
5995
- fg: dialogColors5.textMuted,
6299
+ /* @__PURE__ */ jsxDEV17("text", {
6300
+ fg: dialogColors6.textMuted,
5996
6301
  children: "Esc"
5997
6302
  }, undefined, false, undefined, this),
5998
- /* @__PURE__ */ jsxDEV16("text", {
5999
- fg: dialogColors5.textSecondary,
6303
+ /* @__PURE__ */ jsxDEV17("text", {
6304
+ fg: dialogColors6.textSecondary,
6000
6305
  children: "cancel"
6001
6306
  }, undefined, false, undefined, this)
6002
6307
  ]
@@ -6005,11 +6310,11 @@ function FolderPickerContent({
6005
6310
  }, undefined, true, undefined, this);
6006
6311
  }
6007
6312
  if (error) {
6008
- return /* @__PURE__ */ jsxDEV16("box", {
6313
+ return /* @__PURE__ */ jsxDEV17("box", {
6009
6314
  flexDirection: "column",
6010
6315
  children: [
6011
- /* @__PURE__ */ jsxDEV16("box", {
6012
- backgroundColor: dialogColors5.bgPanel,
6316
+ /* @__PURE__ */ jsxDEV17("box", {
6317
+ backgroundColor: dialogColors6.bgPanel,
6013
6318
  paddingLeft: 3,
6014
6319
  paddingRight: 3,
6015
6320
  paddingTop: 1,
@@ -6017,25 +6322,25 @@ function FolderPickerContent({
6017
6322
  flexDirection: "row",
6018
6323
  gap: 1,
6019
6324
  children: [
6020
- /* @__PURE__ */ jsxDEV16("text", {
6021
- fg: dialogColors5.accent,
6325
+ /* @__PURE__ */ jsxDEV17("text", {
6326
+ fg: dialogColors6.accent,
6022
6327
  children: "\uD83D\uDCC1"
6023
6328
  }, undefined, false, undefined, this),
6024
- /* @__PURE__ */ jsxDEV16("text", {
6025
- fg: dialogColors5.textPrimary,
6026
- children: /* @__PURE__ */ jsxDEV16("b", {
6329
+ /* @__PURE__ */ jsxDEV17("text", {
6330
+ fg: dialogColors6.textPrimary,
6331
+ children: /* @__PURE__ */ jsxDEV17("b", {
6027
6332
  children: "Move to Folder"
6028
6333
  }, undefined, false, undefined, this)
6029
6334
  }, undefined, false, undefined, this)
6030
6335
  ]
6031
6336
  }, undefined, true, undefined, this),
6032
- /* @__PURE__ */ jsxDEV16("box", {
6033
- backgroundColor: dialogColors5.bgDark,
6337
+ /* @__PURE__ */ jsxDEV17("box", {
6338
+ backgroundColor: dialogColors6.bgDark,
6034
6339
  paddingLeft: 3,
6035
6340
  paddingRight: 3,
6036
6341
  paddingTop: 1,
6037
6342
  paddingBottom: 1,
6038
- children: /* @__PURE__ */ jsxDEV16("text", {
6343
+ children: /* @__PURE__ */ jsxDEV17("text", {
6039
6344
  fg: colors.error,
6040
6345
  children: [
6041
6346
  "Error: ",
@@ -6043,8 +6348,8 @@ function FolderPickerContent({
6043
6348
  ]
6044
6349
  }, undefined, true, undefined, this)
6045
6350
  }, undefined, false, undefined, this),
6046
- /* @__PURE__ */ jsxDEV16("box", {
6047
- backgroundColor: dialogColors5.bgPanel,
6351
+ /* @__PURE__ */ jsxDEV17("box", {
6352
+ backgroundColor: dialogColors6.bgPanel,
6048
6353
  paddingLeft: 3,
6049
6354
  paddingRight: 3,
6050
6355
  paddingTop: 1,
@@ -6052,12 +6357,12 @@ function FolderPickerContent({
6052
6357
  flexDirection: "row",
6053
6358
  gap: 2,
6054
6359
  children: [
6055
- /* @__PURE__ */ jsxDEV16("text", {
6056
- fg: dialogColors5.textMuted,
6360
+ /* @__PURE__ */ jsxDEV17("text", {
6361
+ fg: dialogColors6.textMuted,
6057
6362
  children: "Esc"
6058
6363
  }, undefined, false, undefined, this),
6059
- /* @__PURE__ */ jsxDEV16("text", {
6060
- fg: dialogColors5.textSecondary,
6364
+ /* @__PURE__ */ jsxDEV17("text", {
6365
+ fg: dialogColors6.textSecondary,
6061
6366
  children: "close"
6062
6367
  }, undefined, false, undefined, this)
6063
6368
  ]
@@ -6066,11 +6371,11 @@ function FolderPickerContent({
6066
6371
  }, undefined, true, undefined, this);
6067
6372
  }
6068
6373
  if (folders.length === 0) {
6069
- return /* @__PURE__ */ jsxDEV16("box", {
6374
+ return /* @__PURE__ */ jsxDEV17("box", {
6070
6375
  flexDirection: "column",
6071
6376
  children: [
6072
- /* @__PURE__ */ jsxDEV16("box", {
6073
- backgroundColor: dialogColors5.bgPanel,
6377
+ /* @__PURE__ */ jsxDEV17("box", {
6378
+ backgroundColor: dialogColors6.bgPanel,
6074
6379
  paddingLeft: 3,
6075
6380
  paddingRight: 3,
6076
6381
  paddingTop: 1,
@@ -6078,20 +6383,20 @@ function FolderPickerContent({
6078
6383
  flexDirection: "row",
6079
6384
  gap: 1,
6080
6385
  children: [
6081
- /* @__PURE__ */ jsxDEV16("text", {
6082
- fg: dialogColors5.accent,
6386
+ /* @__PURE__ */ jsxDEV17("text", {
6387
+ fg: dialogColors6.accent,
6083
6388
  children: "\uD83D\uDCC1"
6084
6389
  }, undefined, false, undefined, this),
6085
- /* @__PURE__ */ jsxDEV16("text", {
6086
- fg: dialogColors5.textPrimary,
6087
- children: /* @__PURE__ */ jsxDEV16("b", {
6390
+ /* @__PURE__ */ jsxDEV17("text", {
6391
+ fg: dialogColors6.textPrimary,
6392
+ children: /* @__PURE__ */ jsxDEV17("b", {
6088
6393
  children: "Move to Folder"
6089
6394
  }, undefined, false, undefined, this)
6090
6395
  }, undefined, false, undefined, this)
6091
6396
  ]
6092
6397
  }, undefined, true, undefined, this),
6093
- /* @__PURE__ */ jsxDEV16("box", {
6094
- backgroundColor: dialogColors5.bgDark,
6398
+ /* @__PURE__ */ jsxDEV17("box", {
6399
+ backgroundColor: dialogColors6.bgDark,
6095
6400
  paddingLeft: 3,
6096
6401
  paddingRight: 3,
6097
6402
  paddingTop: 1,
@@ -6099,18 +6404,18 @@ function FolderPickerContent({
6099
6404
  flexDirection: "column",
6100
6405
  gap: 1,
6101
6406
  children: [
6102
- /* @__PURE__ */ jsxDEV16("text", {
6103
- fg: dialogColors5.textSecondary,
6407
+ /* @__PURE__ */ jsxDEV17("text", {
6408
+ fg: dialogColors6.textSecondary,
6104
6409
  children: "No folders yet."
6105
6410
  }, undefined, false, undefined, this),
6106
- /* @__PURE__ */ jsxDEV16("text", {
6107
- fg: dialogColors5.textMuted,
6411
+ /* @__PURE__ */ jsxDEV17("text", {
6412
+ fg: dialogColors6.textMuted,
6108
6413
  children: "Create folders on x.com"
6109
6414
  }, undefined, false, undefined, this)
6110
6415
  ]
6111
6416
  }, undefined, true, undefined, this),
6112
- /* @__PURE__ */ jsxDEV16("box", {
6113
- backgroundColor: dialogColors5.bgPanel,
6417
+ /* @__PURE__ */ jsxDEV17("box", {
6418
+ backgroundColor: dialogColors6.bgPanel,
6114
6419
  paddingLeft: 3,
6115
6420
  paddingRight: 3,
6116
6421
  paddingTop: 1,
@@ -6118,12 +6423,12 @@ function FolderPickerContent({
6118
6423
  flexDirection: "row",
6119
6424
  gap: 2,
6120
6425
  children: [
6121
- /* @__PURE__ */ jsxDEV16("text", {
6122
- fg: dialogColors5.textMuted,
6426
+ /* @__PURE__ */ jsxDEV17("text", {
6427
+ fg: dialogColors6.textMuted,
6123
6428
  children: "Esc"
6124
6429
  }, undefined, false, undefined, this),
6125
- /* @__PURE__ */ jsxDEV16("text", {
6126
- fg: dialogColors5.textSecondary,
6430
+ /* @__PURE__ */ jsxDEV17("text", {
6431
+ fg: dialogColors6.textSecondary,
6127
6432
  children: "close"
6128
6433
  }, undefined, false, undefined, this)
6129
6434
  ]
@@ -6134,11 +6439,11 @@ function FolderPickerContent({
6134
6439
  const hasMoreAbove = windowStart > 0;
6135
6440
  const hasMoreBelow = windowStart + MAX_VISIBLE_FOLDERS < folders.length;
6136
6441
  const visibleFolders = folders.slice(windowStart, windowStart + MAX_VISIBLE_FOLDERS);
6137
- return /* @__PURE__ */ jsxDEV16("box", {
6442
+ return /* @__PURE__ */ jsxDEV17("box", {
6138
6443
  flexDirection: "column",
6139
6444
  children: [
6140
- /* @__PURE__ */ jsxDEV16("box", {
6141
- backgroundColor: dialogColors5.bgPanel,
6445
+ /* @__PURE__ */ jsxDEV17("box", {
6446
+ backgroundColor: dialogColors6.bgPanel,
6142
6447
  paddingLeft: 3,
6143
6448
  paddingRight: 3,
6144
6449
  paddingTop: 1,
@@ -6146,18 +6451,18 @@ function FolderPickerContent({
6146
6451
  flexDirection: "row",
6147
6452
  gap: 1,
6148
6453
  children: [
6149
- /* @__PURE__ */ jsxDEV16("text", {
6150
- fg: dialogColors5.accent,
6454
+ /* @__PURE__ */ jsxDEV17("text", {
6455
+ fg: dialogColors6.accent,
6151
6456
  children: "\uD83D\uDCC1"
6152
6457
  }, undefined, false, undefined, this),
6153
- /* @__PURE__ */ jsxDEV16("text", {
6154
- fg: dialogColors5.textPrimary,
6155
- children: /* @__PURE__ */ jsxDEV16("b", {
6458
+ /* @__PURE__ */ jsxDEV17("text", {
6459
+ fg: dialogColors6.textPrimary,
6460
+ children: /* @__PURE__ */ jsxDEV17("b", {
6156
6461
  children: "Move to Folder"
6157
6462
  }, undefined, false, undefined, this)
6158
6463
  }, undefined, false, undefined, this),
6159
- /* @__PURE__ */ jsxDEV16("text", {
6160
- fg: dialogColors5.textMuted,
6464
+ /* @__PURE__ */ jsxDEV17("text", {
6465
+ fg: dialogColors6.textMuted,
6161
6466
  children: [
6162
6467
  "(",
6163
6468
  folders.length,
@@ -6166,24 +6471,24 @@ function FolderPickerContent({
6166
6471
  }, undefined, true, undefined, this)
6167
6472
  ]
6168
6473
  }, undefined, true, undefined, this),
6169
- /* @__PURE__ */ jsxDEV16("box", {
6170
- backgroundColor: dialogColors5.bgDark,
6474
+ /* @__PURE__ */ jsxDEV17("box", {
6475
+ backgroundColor: dialogColors6.bgDark,
6171
6476
  paddingLeft: 3,
6172
6477
  paddingRight: 3,
6173
6478
  paddingTop: 1,
6174
6479
  paddingBottom: 1,
6175
6480
  flexDirection: "column",
6176
6481
  children: [
6177
- hasMoreAbove ? /* @__PURE__ */ jsxDEV16("text", {
6178
- fg: dialogColors5.textMuted,
6482
+ hasMoreAbove ? /* @__PURE__ */ jsxDEV17("text", {
6483
+ fg: dialogColors6.textMuted,
6179
6484
  children: "\u2191 more"
6180
6485
  }, undefined, false, undefined, this) : null,
6181
6486
  visibleFolders.map((folder, visibleIndex) => {
6182
6487
  const actualIndex = windowStart + visibleIndex;
6183
6488
  const isSelected = actualIndex === selectedIndex;
6184
- return /* @__PURE__ */ jsxDEV16("text", {
6185
- fg: isSelected ? dialogColors5.textPrimary : dialogColors5.textSecondary,
6186
- bg: isSelected ? dialogColors5.bgHover : undefined,
6489
+ return /* @__PURE__ */ jsxDEV17("text", {
6490
+ fg: isSelected ? dialogColors6.textPrimary : dialogColors6.textSecondary,
6491
+ bg: isSelected ? dialogColors6.bgHover : undefined,
6187
6492
  children: [
6188
6493
  isSelected ? " \u203A " : " ",
6189
6494
  folder.name,
@@ -6191,14 +6496,14 @@ function FolderPickerContent({
6191
6496
  ]
6192
6497
  }, folder.id, true, undefined, this);
6193
6498
  }),
6194
- hasMoreBelow ? /* @__PURE__ */ jsxDEV16("text", {
6195
- fg: dialogColors5.textMuted,
6499
+ hasMoreBelow ? /* @__PURE__ */ jsxDEV17("text", {
6500
+ fg: dialogColors6.textMuted,
6196
6501
  children: "\u2193 more"
6197
6502
  }, undefined, false, undefined, this) : null
6198
6503
  ]
6199
6504
  }, undefined, true, undefined, this),
6200
- /* @__PURE__ */ jsxDEV16("box", {
6201
- backgroundColor: dialogColors5.bgPanel,
6505
+ /* @__PURE__ */ jsxDEV17("box", {
6506
+ backgroundColor: dialogColors6.bgPanel,
6202
6507
  paddingLeft: 3,
6203
6508
  paddingRight: 3,
6204
6509
  paddingTop: 1,
@@ -6206,28 +6511,28 @@ function FolderPickerContent({
6206
6511
  flexDirection: "row",
6207
6512
  gap: 2,
6208
6513
  children: [
6209
- /* @__PURE__ */ jsxDEV16("text", {
6210
- fg: dialogColors5.textMuted,
6514
+ /* @__PURE__ */ jsxDEV17("text", {
6515
+ fg: dialogColors6.textMuted,
6211
6516
  children: "j/k"
6212
6517
  }, undefined, false, undefined, this),
6213
- /* @__PURE__ */ jsxDEV16("text", {
6214
- fg: dialogColors5.textSecondary,
6518
+ /* @__PURE__ */ jsxDEV17("text", {
6519
+ fg: dialogColors6.textSecondary,
6215
6520
  children: "nav"
6216
6521
  }, undefined, false, undefined, this),
6217
- /* @__PURE__ */ jsxDEV16("text", {
6218
- fg: dialogColors5.textMuted,
6522
+ /* @__PURE__ */ jsxDEV17("text", {
6523
+ fg: dialogColors6.textMuted,
6219
6524
  children: "Enter"
6220
6525
  }, undefined, false, undefined, this),
6221
- /* @__PURE__ */ jsxDEV16("text", {
6222
- fg: dialogColors5.textSecondary,
6526
+ /* @__PURE__ */ jsxDEV17("text", {
6527
+ fg: dialogColors6.textSecondary,
6223
6528
  children: "select"
6224
6529
  }, undefined, false, undefined, this),
6225
- /* @__PURE__ */ jsxDEV16("text", {
6226
- fg: dialogColors5.textMuted,
6530
+ /* @__PURE__ */ jsxDEV17("text", {
6531
+ fg: dialogColors6.textMuted,
6227
6532
  children: "Esc"
6228
6533
  }, undefined, false, undefined, this),
6229
- /* @__PURE__ */ jsxDEV16("text", {
6230
- fg: dialogColors5.textSecondary,
6534
+ /* @__PURE__ */ jsxDEV17("text", {
6535
+ fg: dialogColors6.textSecondary,
6231
6536
  children: "cancel"
6232
6537
  }, undefined, false, undefined, this)
6233
6538
  ]
@@ -6238,8 +6543,8 @@ function FolderPickerContent({
6238
6543
 
6239
6544
  // src/modals/SessionExpiredModal.tsx
6240
6545
  import { useRenderer as useRenderer2 } from "@opentui/react";
6241
- import { jsxDEV as jsxDEV17 } from "@opentui/react/jsx-dev-runtime";
6242
- var dialogColors6 = {
6546
+ import { jsxDEV as jsxDEV18 } from "@opentui/react/jsx-dev-runtime";
6547
+ var dialogColors7 = {
6243
6548
  bgDark: "#1e1e2e",
6244
6549
  bgPanel: "#181825",
6245
6550
  textPrimary: "#cdd6f4",
@@ -6258,11 +6563,11 @@ function SessionExpiredContent({
6258
6563
  renderer.destroy();
6259
6564
  }
6260
6565
  }, dialogId);
6261
- return /* @__PURE__ */ jsxDEV17("box", {
6566
+ return /* @__PURE__ */ jsxDEV18("box", {
6262
6567
  flexDirection: "column",
6263
6568
  children: [
6264
- /* @__PURE__ */ jsxDEV17("box", {
6265
- backgroundColor: dialogColors6.bgPanel,
6569
+ /* @__PURE__ */ jsxDEV18("box", {
6570
+ backgroundColor: dialogColors7.bgPanel,
6266
6571
  paddingLeft: 3,
6267
6572
  paddingRight: 3,
6268
6573
  paddingTop: 1,
@@ -6270,20 +6575,237 @@ function SessionExpiredContent({
6270
6575
  flexDirection: "row",
6271
6576
  gap: 1,
6272
6577
  children: [
6273
- /* @__PURE__ */ jsxDEV17("text", {
6274
- fg: dialogColors6.red,
6578
+ /* @__PURE__ */ jsxDEV18("text", {
6579
+ fg: dialogColors7.red,
6275
6580
  children: "\u2715"
6276
6581
  }, undefined, false, undefined, this),
6277
- /* @__PURE__ */ jsxDEV17("text", {
6278
- fg: dialogColors6.textPrimary,
6279
- children: /* @__PURE__ */ jsxDEV17("b", {
6582
+ /* @__PURE__ */ jsxDEV18("text", {
6583
+ fg: dialogColors7.textPrimary,
6584
+ children: /* @__PURE__ */ jsxDEV18("b", {
6280
6585
  children: "Session Expired"
6281
6586
  }, undefined, false, undefined, this)
6282
6587
  }, undefined, false, undefined, this)
6283
6588
  ]
6284
6589
  }, undefined, true, undefined, this),
6285
- /* @__PURE__ */ jsxDEV17("box", {
6286
- backgroundColor: dialogColors6.bgDark,
6590
+ /* @__PURE__ */ jsxDEV18("box", {
6591
+ backgroundColor: dialogColors7.bgDark,
6592
+ paddingLeft: 3,
6593
+ paddingRight: 3,
6594
+ paddingTop: 1,
6595
+ paddingBottom: 1,
6596
+ flexDirection: "column",
6597
+ gap: 1,
6598
+ children: [
6599
+ /* @__PURE__ */ jsxDEV18("text", {
6600
+ fg: dialogColors7.textSecondary,
6601
+ children: "Your tokens are no longer valid."
6602
+ }, undefined, false, undefined, this),
6603
+ /* @__PURE__ */ jsxDEV18("text", {
6604
+ fg: dialogColors7.textMuted,
6605
+ children: "Please restart the app and log in again."
6606
+ }, undefined, false, undefined, this)
6607
+ ]
6608
+ }, undefined, true, undefined, this),
6609
+ /* @__PURE__ */ jsxDEV18("box", {
6610
+ backgroundColor: dialogColors7.bgPanel,
6611
+ paddingLeft: 3,
6612
+ paddingRight: 3,
6613
+ paddingTop: 1,
6614
+ paddingBottom: 1,
6615
+ flexDirection: "row",
6616
+ gap: 2,
6617
+ children: [
6618
+ /* @__PURE__ */ jsxDEV18("text", {
6619
+ fg: dialogColors7.textMuted,
6620
+ children: "Enter"
6621
+ }, undefined, false, undefined, this),
6622
+ /* @__PURE__ */ jsxDEV18("text", {
6623
+ fg: dialogColors7.textSecondary,
6624
+ children: "quit"
6625
+ }, undefined, false, undefined, this)
6626
+ ]
6627
+ }, undefined, true, undefined, this)
6628
+ ]
6629
+ }, undefined, true, undefined, this);
6630
+ }
6631
+
6632
+ // src/modals/UrlInputModal.tsx
6633
+ import { useAppContext } from "@opentui/react";
6634
+ import { useEffect as useEffect14, useState as useState22 } from "react";
6635
+
6636
+ // src/lib/url-parser.ts
6637
+ var RESERVED_PATHS = new Set([
6638
+ "home",
6639
+ "explore",
6640
+ "notifications",
6641
+ "messages",
6642
+ "settings",
6643
+ "i",
6644
+ "search",
6645
+ "compose",
6646
+ "intent",
6647
+ "hashtag",
6648
+ "lists"
6649
+ ]);
6650
+ function parseXUrl(input) {
6651
+ const trimmed = input.trim();
6652
+ if (!trimmed) {
6653
+ return { type: "invalid", error: "URL cannot be empty" };
6654
+ }
6655
+ let url;
6656
+ try {
6657
+ const withProtocol = trimmed.match(/^https?:\/\//i) ? trimmed : `https://${trimmed}`;
6658
+ url = new URL(withProtocol);
6659
+ } catch {
6660
+ return { type: "invalid", error: "Invalid URL format" };
6661
+ }
6662
+ const hostname = url.hostname.toLowerCase();
6663
+ if (hostname !== "x.com" && hostname !== "twitter.com" && hostname !== "www.x.com" && hostname !== "www.twitter.com" && hostname !== "mobile.x.com" && hostname !== "mobile.twitter.com") {
6664
+ return { type: "invalid", error: "Not an X or Twitter URL" };
6665
+ }
6666
+ const pathSegments = url.pathname.split("/").filter(Boolean);
6667
+ if (pathSegments.length === 0) {
6668
+ return { type: "invalid", error: "No username or tweet ID in URL" };
6669
+ }
6670
+ const firstSegment = pathSegments[0];
6671
+ if (!firstSegment) {
6672
+ return { type: "invalid", error: "No username or tweet ID in URL" };
6673
+ }
6674
+ if (RESERVED_PATHS.has(firstSegment.toLowerCase())) {
6675
+ return { type: "invalid", error: `"${firstSegment}" is not a profile` };
6676
+ }
6677
+ const username = firstSegment;
6678
+ if (pathSegments.length >= 3) {
6679
+ const secondSegment = pathSegments[1];
6680
+ const thirdSegment = pathSegments[2];
6681
+ if (secondSegment?.toLowerCase() === "status" && thirdSegment) {
6682
+ if (!/^\d+$/.test(thirdSegment)) {
6683
+ return { type: "invalid", error: "Invalid tweet ID" };
6684
+ }
6685
+ return { type: "tweet", username, tweetId: thirdSegment };
6686
+ }
6687
+ }
6688
+ if (pathSegments.length === 1) {
6689
+ return { type: "profile", username };
6690
+ }
6691
+ if (pathSegments.length >= 2) {
6692
+ const secondSegment = pathSegments[1]?.toLowerCase();
6693
+ const profileSubPages = new Set([
6694
+ "followers",
6695
+ "following",
6696
+ "likes",
6697
+ "with_replies",
6698
+ "media",
6699
+ "highlights",
6700
+ "articles",
6701
+ "verified_followers",
6702
+ "photo",
6703
+ "header_photo"
6704
+ ]);
6705
+ if (secondSegment && profileSubPages.has(secondSegment)) {
6706
+ return { type: "profile", username };
6707
+ }
6708
+ }
6709
+ return { type: "profile", username };
6710
+ }
6711
+
6712
+ // src/modals/UrlInputModal.tsx
6713
+ import { jsxDEV as jsxDEV19 } from "@opentui/react/jsx-dev-runtime";
6714
+ var dialogColors8 = {
6715
+ bgDark: "#1e1e2e",
6716
+ bgPanel: "#181825",
6717
+ bgInput: "#11111b",
6718
+ textPrimary: "#cdd6f4",
6719
+ textSecondary: "#bac2de",
6720
+ textMuted: "#6c7086",
6721
+ accent: "#89b4fa"
6722
+ };
6723
+ function UrlInputContent({
6724
+ onNavigateToTweet,
6725
+ onNavigateToProfile,
6726
+ resolve,
6727
+ dismiss,
6728
+ dialogId
6729
+ }) {
6730
+ const [value, setValue] = useState22("");
6731
+ const [isSubmitting, setIsSubmitting] = useState22(false);
6732
+ const [error, setError] = useState22(null);
6733
+ const { keyHandler } = useAppContext();
6734
+ useDialogKeyboard((key) => {
6735
+ if (isSubmitting)
6736
+ return;
6737
+ if (key.name === "escape") {
6738
+ dismiss();
6739
+ }
6740
+ }, dialogId);
6741
+ useEffect14(() => {
6742
+ if (!keyHandler || isSubmitting)
6743
+ return;
6744
+ const handlePaste = (event) => {
6745
+ setValue((prev) => prev + event.text);
6746
+ if (error)
6747
+ setError(null);
6748
+ };
6749
+ keyHandler.on("paste", handlePaste);
6750
+ return () => {
6751
+ keyHandler.off("paste", handlePaste);
6752
+ };
6753
+ }, [keyHandler, isSubmitting, error]);
6754
+ const handleSubmit = async () => {
6755
+ const trimmed = value.trim();
6756
+ if (!trimmed) {
6757
+ setError("Please paste an X URL");
6758
+ return;
6759
+ }
6760
+ const parsed = parseXUrl(trimmed);
6761
+ if (parsed.type === "invalid") {
6762
+ setError(parsed.error);
6763
+ return;
6764
+ }
6765
+ setIsSubmitting(true);
6766
+ setError(null);
6767
+ try {
6768
+ if (parsed.type === "tweet") {
6769
+ const result = await onNavigateToTweet(parsed.tweetId);
6770
+ if (result.success) {
6771
+ resolve(parsed);
6772
+ } else {
6773
+ setError(result.error ?? "Failed to load tweet");
6774
+ setIsSubmitting(false);
6775
+ }
6776
+ } else {
6777
+ const result = await onNavigateToProfile(parsed.username);
6778
+ if (result.success) {
6779
+ resolve(parsed);
6780
+ } else {
6781
+ setError(result.error ?? "Failed to load profile");
6782
+ setIsSubmitting(false);
6783
+ }
6784
+ }
6785
+ } catch (err) {
6786
+ setError(err instanceof Error ? err.message : "Failed to navigate");
6787
+ setIsSubmitting(false);
6788
+ }
6789
+ };
6790
+ return /* @__PURE__ */ jsxDEV19("box", {
6791
+ flexDirection: "column",
6792
+ width: 56,
6793
+ children: [
6794
+ /* @__PURE__ */ jsxDEV19("box", {
6795
+ backgroundColor: dialogColors8.bgPanel,
6796
+ paddingLeft: 3,
6797
+ paddingRight: 3,
6798
+ paddingTop: 1,
6799
+ paddingBottom: 1,
6800
+ flexDirection: "row",
6801
+ gap: 1,
6802
+ children: /* @__PURE__ */ jsxDEV19("text", {
6803
+ fg: dialogColors8.accent,
6804
+ children: "Go to URL"
6805
+ }, undefined, false, undefined, this)
6806
+ }, undefined, false, undefined, this),
6807
+ /* @__PURE__ */ jsxDEV19("box", {
6808
+ backgroundColor: dialogColors8.bgDark,
6287
6809
  paddingLeft: 3,
6288
6810
  paddingRight: 3,
6289
6811
  paddingTop: 1,
@@ -6291,18 +6813,41 @@ function SessionExpiredContent({
6291
6813
  flexDirection: "column",
6292
6814
  gap: 1,
6293
6815
  children: [
6294
- /* @__PURE__ */ jsxDEV17("text", {
6295
- fg: dialogColors6.textSecondary,
6296
- children: "Your tokens are no longer valid."
6816
+ /* @__PURE__ */ jsxDEV19("input", {
6817
+ value,
6818
+ placeholder: "Paste x.com URL...",
6819
+ focused: !isSubmitting,
6820
+ onInput: (newValue) => {
6821
+ setValue(newValue);
6822
+ if (error)
6823
+ setError(null);
6824
+ },
6825
+ onSubmit: () => {
6826
+ handleSubmit();
6827
+ },
6828
+ width: 50,
6829
+ height: 1,
6830
+ backgroundColor: dialogColors8.bgInput,
6831
+ textColor: dialogColors8.textPrimary,
6832
+ placeholderColor: dialogColors8.textMuted,
6833
+ cursorColor: dialogColors8.accent
6297
6834
  }, undefined, false, undefined, this),
6298
- /* @__PURE__ */ jsxDEV17("text", {
6299
- fg: dialogColors6.textMuted,
6300
- children: "Please restart the app and log in again."
6301
- }, undefined, false, undefined, this)
6835
+ /* @__PURE__ */ jsxDEV19("text", {
6836
+ fg: dialogColors8.textMuted,
6837
+ children: "Supports x.com/user/status/id and x.com/user"
6838
+ }, undefined, false, undefined, this),
6839
+ error ? /* @__PURE__ */ jsxDEV19("text", {
6840
+ fg: colors.error,
6841
+ children: error
6842
+ }, undefined, false, undefined, this) : null,
6843
+ isSubmitting ? /* @__PURE__ */ jsxDEV19("text", {
6844
+ fg: dialogColors8.textMuted,
6845
+ children: "Loading..."
6846
+ }, undefined, false, undefined, this) : null
6302
6847
  ]
6303
6848
  }, undefined, true, undefined, this),
6304
- /* @__PURE__ */ jsxDEV17("box", {
6305
- backgroundColor: dialogColors6.bgPanel,
6849
+ /* @__PURE__ */ jsxDEV19("box", {
6850
+ backgroundColor: dialogColors8.bgPanel,
6306
6851
  paddingLeft: 3,
6307
6852
  paddingRight: 3,
6308
6853
  paddingTop: 1,
@@ -6310,13 +6855,21 @@ function SessionExpiredContent({
6310
6855
  flexDirection: "row",
6311
6856
  gap: 2,
6312
6857
  children: [
6313
- /* @__PURE__ */ jsxDEV17("text", {
6314
- fg: dialogColors6.textMuted,
6858
+ /* @__PURE__ */ jsxDEV19("text", {
6859
+ fg: dialogColors8.textMuted,
6315
6860
  children: "Enter"
6316
6861
  }, undefined, false, undefined, this),
6317
- /* @__PURE__ */ jsxDEV17("text", {
6318
- fg: dialogColors6.textSecondary,
6319
- children: "quit"
6862
+ /* @__PURE__ */ jsxDEV19("text", {
6863
+ fg: dialogColors8.textSecondary,
6864
+ children: "go"
6865
+ }, undefined, false, undefined, this),
6866
+ /* @__PURE__ */ jsxDEV19("text", {
6867
+ fg: dialogColors8.textMuted,
6868
+ children: "Esc"
6869
+ }, undefined, false, undefined, this),
6870
+ /* @__PURE__ */ jsxDEV19("text", {
6871
+ fg: dialogColors8.textSecondary,
6872
+ children: "cancel"
6320
6873
  }, undefined, false, undefined, this)
6321
6874
  ]
6322
6875
  }, undefined, true, undefined, this)
@@ -6326,11 +6879,11 @@ function SessionExpiredContent({
6326
6879
 
6327
6880
  // src/screens/BookmarksScreen.tsx
6328
6881
  import { useKeyboard as useKeyboard6 } from "@opentui/react";
6329
- import { useEffect as useEffect13 } from "react";
6330
- import { jsxDEV as jsxDEV18 } from "@opentui/react/jsx-dev-runtime";
6882
+ import { useEffect as useEffect15, useState as useState23 } from "react";
6883
+ import { jsxDEV as jsxDEV20 } from "@opentui/react/jsx-dev-runtime";
6331
6884
  function ScreenHeader({ folderName, inFolder }) {
6332
6885
  const title = folderName ?? "All Bookmarks";
6333
- return /* @__PURE__ */ jsxDEV18("box", {
6886
+ return /* @__PURE__ */ jsxDEV20("box", {
6334
6887
  style: {
6335
6888
  flexShrink: 0,
6336
6889
  paddingLeft: 1,
@@ -6339,17 +6892,17 @@ function ScreenHeader({ folderName, inFolder }) {
6339
6892
  flexDirection: "row"
6340
6893
  },
6341
6894
  children: [
6342
- /* @__PURE__ */ jsxDEV18("text", {
6895
+ /* @__PURE__ */ jsxDEV20("text", {
6343
6896
  fg: colors.primary,
6344
- children: /* @__PURE__ */ jsxDEV18("b", {
6897
+ children: /* @__PURE__ */ jsxDEV20("b", {
6345
6898
  children: title
6346
6899
  }, undefined, false, undefined, this)
6347
6900
  }, undefined, false, undefined, this),
6348
- /* @__PURE__ */ jsxDEV18("text", {
6901
+ /* @__PURE__ */ jsxDEV20("text", {
6349
6902
  fg: colors.dim,
6350
6903
  children: [
6351
6904
  " ",
6352
- "(f folder, n new",
6905
+ "(a annotate, f folder, n new",
6353
6906
  inFolder ? ", e rename, D delete" : "",
6354
6907
  ")"
6355
6908
  ]
@@ -6367,8 +6920,10 @@ function BookmarksScreen({
6367
6920
  onPostSelect,
6368
6921
  onLike,
6369
6922
  onBookmark,
6923
+ onAnnotate,
6370
6924
  getActionState,
6371
6925
  initActionState,
6926
+ hasAnnotation,
6372
6927
  onCreateFolder,
6373
6928
  onEditFolder,
6374
6929
  onDeleteFolder
@@ -6382,10 +6937,11 @@ function BookmarksScreen({
6382
6937
  refresh,
6383
6938
  fetchNextPage
6384
6939
  } = useBookmarksQuery({ client, folderId: selectedFolder?.id });
6385
- useEffect13(() => {
6940
+ const [refreshKey, setRefreshKey] = useState23(0);
6941
+ useEffect15(() => {
6386
6942
  onPostCountChange?.(posts.length);
6387
6943
  }, [posts.length, onPostCountChange]);
6388
- useEffect13(() => {
6944
+ useEffect15(() => {
6389
6945
  onHasMoreChange?.(hasNextPage);
6390
6946
  }, [hasNextPage, onHasMoreChange]);
6391
6947
  useKeyboard6((key) => {
@@ -6393,6 +6949,7 @@ function BookmarksScreen({
6393
6949
  return;
6394
6950
  if (key.name === "r") {
6395
6951
  refresh();
6952
+ setRefreshKey((k) => k + 1);
6396
6953
  }
6397
6954
  if (key.name === "f") {
6398
6955
  onFolderPickerOpen?.();
@@ -6410,16 +6967,16 @@ function BookmarksScreen({
6410
6967
  const folderName = selectedFolder?.name ?? null;
6411
6968
  const inFolder = !!selectedFolder;
6412
6969
  if (isLoading) {
6413
- return /* @__PURE__ */ jsxDEV18("box", {
6970
+ return /* @__PURE__ */ jsxDEV20("box", {
6414
6971
  style: { flexDirection: "column", height: "100%" },
6415
6972
  children: [
6416
- /* @__PURE__ */ jsxDEV18(ScreenHeader, {
6973
+ /* @__PURE__ */ jsxDEV20(ScreenHeader, {
6417
6974
  folderName,
6418
6975
  inFolder
6419
6976
  }, undefined, false, undefined, this),
6420
- /* @__PURE__ */ jsxDEV18("box", {
6977
+ /* @__PURE__ */ jsxDEV20("box", {
6421
6978
  style: { padding: 2, flexGrow: 1 },
6422
- children: /* @__PURE__ */ jsxDEV18("text", {
6979
+ children: /* @__PURE__ */ jsxDEV20("text", {
6423
6980
  fg: colors.muted,
6424
6981
  children: "Loading bookmarks..."
6425
6982
  }, undefined, false, undefined, this)
@@ -6428,14 +6985,14 @@ function BookmarksScreen({
6428
6985
  }, undefined, true, undefined, this);
6429
6986
  }
6430
6987
  if (error) {
6431
- return /* @__PURE__ */ jsxDEV18("box", {
6988
+ return /* @__PURE__ */ jsxDEV20("box", {
6432
6989
  style: { flexDirection: "column", height: "100%" },
6433
6990
  children: [
6434
- /* @__PURE__ */ jsxDEV18(ScreenHeader, {
6991
+ /* @__PURE__ */ jsxDEV20(ScreenHeader, {
6435
6992
  folderName,
6436
6993
  inFolder
6437
6994
  }, undefined, false, undefined, this),
6438
- /* @__PURE__ */ jsxDEV18(ErrorBanner, {
6995
+ /* @__PURE__ */ jsxDEV20(ErrorBanner, {
6439
6996
  error,
6440
6997
  onRetry: refresh,
6441
6998
  retryDisabled: false
@@ -6444,16 +7001,16 @@ function BookmarksScreen({
6444
7001
  }, undefined, true, undefined, this);
6445
7002
  }
6446
7003
  if (posts.length === 0) {
6447
- return /* @__PURE__ */ jsxDEV18("box", {
7004
+ return /* @__PURE__ */ jsxDEV20("box", {
6448
7005
  style: { flexDirection: "column", height: "100%" },
6449
7006
  children: [
6450
- /* @__PURE__ */ jsxDEV18(ScreenHeader, {
7007
+ /* @__PURE__ */ jsxDEV20(ScreenHeader, {
6451
7008
  folderName,
6452
7009
  inFolder
6453
7010
  }, undefined, false, undefined, this),
6454
- /* @__PURE__ */ jsxDEV18("box", {
7011
+ /* @__PURE__ */ jsxDEV20("box", {
6455
7012
  style: { padding: 2, flexGrow: 1 },
6456
- children: /* @__PURE__ */ jsxDEV18("text", {
7013
+ children: /* @__PURE__ */ jsxDEV20("text", {
6457
7014
  fg: colors.muted,
6458
7015
  children: selectedFolder ? "No bookmarks in this folder. Press r to refresh." : "No bookmarks yet. Press r to refresh."
6459
7016
  }, undefined, false, undefined, this)
@@ -6461,24 +7018,27 @@ function BookmarksScreen({
6461
7018
  ]
6462
7019
  }, undefined, true, undefined, this);
6463
7020
  }
6464
- return /* @__PURE__ */ jsxDEV18("box", {
7021
+ return /* @__PURE__ */ jsxDEV20("box", {
6465
7022
  style: { flexDirection: "column", height: "100%" },
6466
7023
  children: [
6467
- /* @__PURE__ */ jsxDEV18(ScreenHeader, {
7024
+ /* @__PURE__ */ jsxDEV20(ScreenHeader, {
6468
7025
  folderName,
6469
7026
  inFolder
6470
7027
  }, undefined, false, undefined, this),
6471
- /* @__PURE__ */ jsxDEV18(PostList, {
7028
+ /* @__PURE__ */ jsxDEV20(PostList, {
6472
7029
  posts,
6473
7030
  focused,
6474
7031
  onPostSelect,
6475
7032
  onLike,
6476
7033
  onBookmark,
7034
+ onAnnotate,
6477
7035
  getActionState,
6478
7036
  initActionState,
7037
+ hasAnnotation,
6479
7038
  onLoadMore: fetchNextPage,
6480
7039
  loadingMore: isFetchingNextPage,
6481
- hasMore: hasNextPage
7040
+ hasMore: hasNextPage,
7041
+ refreshKey
6482
7042
  }, undefined, false, undefined, this)
6483
7043
  ]
6484
7044
  }, undefined, true, undefined, this);
@@ -6486,13 +7046,13 @@ function BookmarksScreen({
6486
7046
 
6487
7047
  // src/screens/NotificationsScreen.tsx
6488
7048
  import { useKeyboard as useKeyboard7 } from "@opentui/react";
6489
- import { useEffect as useEffect16 } from "react";
7049
+ import { useEffect as useEffect18 } from "react";
6490
7050
 
6491
7051
  // src/components/NotificationList.tsx
6492
- import { useEffect as useEffect14, useRef as useRef9 } from "react";
7052
+ import { useEffect as useEffect16, useRef as useRef10 } from "react";
6493
7053
 
6494
7054
  // src/components/NotificationItem.tsx
6495
- import { jsxDEV as jsxDEV19 } from "@opentui/react/jsx-dev-runtime";
7055
+ import { jsxDEV as jsxDEV21 } from "@opentui/react/jsx-dev-runtime";
6496
7056
  var ICON_MAP = {
6497
7057
  heart_icon: { symbol: "\u2665", color: colors.error, label: "like" },
6498
7058
  person_icon: { symbol: "\u2603", color: colors.primary, label: "follow" },
@@ -6511,7 +7071,7 @@ function NotificationItem({
6511
7071
  label: "notification"
6512
7072
  };
6513
7073
  const timeAgo = formatRelativeTime(notification.timestamp);
6514
- return /* @__PURE__ */ jsxDEV19("box", {
7074
+ return /* @__PURE__ */ jsxDEV21("box", {
6515
7075
  id,
6516
7076
  style: {
6517
7077
  flexDirection: "column",
@@ -6522,25 +7082,25 @@ function NotificationItem({
6522
7082
  backgroundColor: isSelected ? colors.selectedBg : undefined
6523
7083
  },
6524
7084
  children: [
6525
- /* @__PURE__ */ jsxDEV19("box", {
7085
+ /* @__PURE__ */ jsxDEV21("box", {
6526
7086
  style: { flexDirection: "row" },
6527
7087
  children: [
6528
- /* @__PURE__ */ jsxDEV19("text", {
7088
+ /* @__PURE__ */ jsxDEV21("text", {
6529
7089
  fg: iconInfo.color,
6530
7090
  children: isSelected ? "> " : " "
6531
7091
  }, undefined, false, undefined, this),
6532
- /* @__PURE__ */ jsxDEV19("text", {
7092
+ /* @__PURE__ */ jsxDEV21("text", {
6533
7093
  fg: iconInfo.color,
6534
7094
  children: [
6535
7095
  iconInfo.symbol,
6536
7096
  " "
6537
7097
  ]
6538
7098
  }, undefined, true, undefined, this),
6539
- /* @__PURE__ */ jsxDEV19("text", {
7099
+ /* @__PURE__ */ jsxDEV21("text", {
6540
7100
  fg: "#ffffff",
6541
7101
  children: notification.message
6542
7102
  }, undefined, false, undefined, this),
6543
- timeAgo && /* @__PURE__ */ jsxDEV19("text", {
7103
+ timeAgo && /* @__PURE__ */ jsxDEV21("text", {
6544
7104
  fg: colors.dim,
6545
7105
  children: [
6546
7106
  " \xB7 ",
@@ -6549,9 +7109,9 @@ function NotificationItem({
6549
7109
  }, undefined, true, undefined, this)
6550
7110
  ]
6551
7111
  }, undefined, true, undefined, this),
6552
- notification.targetTweet && /* @__PURE__ */ jsxDEV19("box", {
7112
+ notification.targetTweet && /* @__PURE__ */ jsxDEV21("box", {
6553
7113
  style: { paddingLeft: 4, marginTop: 1 },
6554
- children: /* @__PURE__ */ jsxDEV19("text", {
7114
+ children: /* @__PURE__ */ jsxDEV21("text", {
6555
7115
  fg: colors.muted,
6556
7116
  children: [
6557
7117
  '"',
@@ -6560,9 +7120,9 @@ function NotificationItem({
6560
7120
  ]
6561
7121
  }, undefined, true, undefined, this)
6562
7122
  }, undefined, false, undefined, this),
6563
- notification.icon === "person_icon" && notification.fromUsers && notification.fromUsers.length > 0 && /* @__PURE__ */ jsxDEV19("box", {
7123
+ notification.icon === "person_icon" && notification.fromUsers && notification.fromUsers.length > 0 && /* @__PURE__ */ jsxDEV21("box", {
6564
7124
  style: { paddingLeft: 4, marginTop: 1 },
6565
- children: /* @__PURE__ */ jsxDEV19("text", {
7125
+ children: /* @__PURE__ */ jsxDEV21("text", {
6566
7126
  fg: colors.dim,
6567
7127
  children: [
6568
7128
  "@",
@@ -6575,7 +7135,7 @@ function NotificationItem({
6575
7135
  }
6576
7136
 
6577
7137
  // src/components/NotificationList.tsx
6578
- import { jsxDEV as jsxDEV20 } from "@opentui/react/jsx-dev-runtime";
7138
+ import { jsxDEV as jsxDEV22 } from "@opentui/react/jsx-dev-runtime";
6579
7139
  function getNotificationItemId(notificationId) {
6580
7140
  return `notification-${notificationId}`;
6581
7141
  }
@@ -6587,10 +7147,10 @@ function NotificationList({
6587
7147
  loadingMore = false,
6588
7148
  hasMore = true
6589
7149
  }) {
6590
- const scrollRef = useRef9(null);
6591
- const savedScrollTop = useRef9(0);
6592
- const wasFocused = useRef9(focused);
6593
- useEffect14(() => {
7150
+ const scrollRef = useRef10(null);
7151
+ const savedScrollTop = useRef10(0);
7152
+ const wasFocused = useRef10(focused);
7153
+ useEffect16(() => {
6594
7154
  const scrollbox = scrollRef.current;
6595
7155
  if (!scrollbox)
6596
7156
  return;
@@ -6612,7 +7172,7 @@ function NotificationList({
6612
7172
  }
6613
7173
  }
6614
7174
  });
6615
- useEffect14(() => {
7175
+ useEffect16(() => {
6616
7176
  const scrollbox = scrollRef.current;
6617
7177
  if (!scrollbox || notifications.length === 0)
6618
7178
  return;
@@ -6641,7 +7201,7 @@ function NotificationList({
6641
7201
  scrollbox.scrollBy(relativeY - topMargin);
6642
7202
  }
6643
7203
  }, [selectedIndex, notifications.length]);
6644
- useEffect14(() => {
7204
+ useEffect16(() => {
6645
7205
  if (!onLoadMore || loadingMore || !hasMore || notifications.length === 0)
6646
7206
  return;
6647
7207
  const threshold = 5;
@@ -6650,15 +7210,15 @@ function NotificationList({
6650
7210
  }
6651
7211
  }, [selectedIndex, notifications.length, onLoadMore, loadingMore, hasMore]);
6652
7212
  if (notifications.length === 0) {
6653
- return /* @__PURE__ */ jsxDEV20("box", {
7213
+ return /* @__PURE__ */ jsxDEV22("box", {
6654
7214
  style: { padding: 2 },
6655
- children: /* @__PURE__ */ jsxDEV20("text", {
7215
+ children: /* @__PURE__ */ jsxDEV22("text", {
6656
7216
  fg: colors.muted,
6657
7217
  children: "No notifications"
6658
7218
  }, undefined, false, undefined, this)
6659
7219
  }, undefined, false, undefined, this);
6660
7220
  }
6661
- return /* @__PURE__ */ jsxDEV20("scrollbox", {
7221
+ return /* @__PURE__ */ jsxDEV22("scrollbox", {
6662
7222
  ref: scrollRef,
6663
7223
  focused,
6664
7224
  style: {
@@ -6666,21 +7226,21 @@ function NotificationList({
6666
7226
  height: "100%"
6667
7227
  },
6668
7228
  children: [
6669
- notifications.map((notification, index) => /* @__PURE__ */ jsxDEV20(NotificationItem, {
7229
+ notifications.map((notification, index) => /* @__PURE__ */ jsxDEV22(NotificationItem, {
6670
7230
  id: getNotificationItemId(notification.id),
6671
7231
  notification,
6672
7232
  isSelected: index === selectedIndex
6673
7233
  }, notification.id, false, undefined, this)),
6674
- loadingMore ? /* @__PURE__ */ jsxDEV20("box", {
7234
+ loadingMore ? /* @__PURE__ */ jsxDEV22("box", {
6675
7235
  style: { padding: 1, paddingLeft: 2 },
6676
- children: /* @__PURE__ */ jsxDEV20("text", {
7236
+ children: /* @__PURE__ */ jsxDEV22("text", {
6677
7237
  fg: colors.muted,
6678
7238
  children: "Loading more..."
6679
7239
  }, undefined, false, undefined, this)
6680
7240
  }, undefined, false, undefined, this) : null,
6681
- !hasMore && notifications.length > 0 ? /* @__PURE__ */ jsxDEV20("box", {
7241
+ !hasMore && notifications.length > 0 ? /* @__PURE__ */ jsxDEV22("box", {
6682
7242
  style: { padding: 1, paddingLeft: 2 },
6683
- children: /* @__PURE__ */ jsxDEV20("text", {
7243
+ children: /* @__PURE__ */ jsxDEV22("text", {
6684
7244
  fg: colors.dim,
6685
7245
  children: "No more notifications"
6686
7246
  }, undefined, false, undefined, this)
@@ -6692,10 +7252,10 @@ function NotificationList({
6692
7252
  // src/experiments/use-notifications-query.ts
6693
7253
  import { useInfiniteQuery as useInfiniteQuery4 } from "@tanstack/react-query";
6694
7254
  import { appendFileSync } from "fs";
6695
- import { homedir as homedir2 } from "os";
7255
+ import { homedir as homedir3 } from "os";
6696
7256
  import { join } from "path";
6697
- import { useCallback as useCallback12, useEffect as useEffect15, useMemo as useMemo7, useRef as useRef10, useState as useState19 } from "react";
6698
- var LOG_FILE = join(homedir2(), ".xfeed-notifications.log");
7257
+ import { useCallback as useCallback13, useEffect as useEffect17, useMemo as useMemo7, useRef as useRef11, useState as useState24 } from "react";
7258
+ var LOG_FILE = join(homedir3(), ".xfeed-notifications.log");
6699
7259
  function log(message, data) {
6700
7260
  const timestamp = new Date().toISOString();
6701
7261
  const line = data ? `[${timestamp}] ${message}: ${JSON.stringify(data)}
@@ -6777,8 +7337,8 @@ function useNotificationsQuery({
6777
7337
  client,
6778
7338
  pollingInterval = DEFAULT_POLLING_INTERVAL
6779
7339
  }) {
6780
- const lastSeenNewestIdRef = useRef10(null);
6781
- const [newNotificationsCount, setNewNotificationsCount] = useState19(0);
7340
+ const lastSeenNewestIdRef = useRef11(null);
7341
+ const [newNotificationsCount, setNewNotificationsCount] = useState24(0);
6782
7342
  log("useNotificationsQuery render", {
6783
7343
  lastSeenNewestId: lastSeenNewestIdRef.current,
6784
7344
  newNotificationsCount
@@ -6821,22 +7381,22 @@ function useNotificationsQuery({
6821
7381
  });
6822
7382
  return count;
6823
7383
  }, [data?.pages, notifications]);
6824
- useEffect15(() => {
7384
+ useEffect17(() => {
6825
7385
  if (lastSeenNewestIdRef.current === null && notifications.length > 0) {
6826
7386
  const newestId = notifications[0]?.id;
6827
7387
  log("Initializing lastSeenNewestId", { newestId });
6828
7388
  lastSeenNewestIdRef.current = newestId ?? null;
6829
7389
  }
6830
7390
  }, [notifications]);
6831
- const lastUnreadSortIndexRef = useRef10(null);
6832
- useEffect15(() => {
7391
+ const lastUnreadSortIndexRef = useRef11(null);
7392
+ useEffect17(() => {
6833
7393
  if (lastUnreadSortIndexRef.current === null && data?.pages?.[0]) {
6834
7394
  const sortIndex = data.pages[0].unreadSortIndex;
6835
7395
  log("Initializing lastUnreadSortIndex", { sortIndex });
6836
7396
  lastUnreadSortIndexRef.current = sortIndex ?? null;
6837
7397
  }
6838
7398
  }, [data?.pages]);
6839
- useEffect15(() => {
7399
+ useEffect17(() => {
6840
7400
  if (isLoading || lastSeenNewestIdRef.current === null) {
6841
7401
  log("Polling not started - waiting for initial load", {
6842
7402
  isLoading,
@@ -6896,7 +7456,7 @@ function useNotificationsQuery({
6896
7456
  clearInterval(intervalId);
6897
7457
  };
6898
7458
  }, [client, isLoading, pollingInterval, refetch]);
6899
- const refresh = useCallback12(() => {
7459
+ const refresh = useCallback13(() => {
6900
7460
  log("refresh called");
6901
7461
  setNewNotificationsCount(0);
6902
7462
  lastSeenNewestIdRef.current = null;
@@ -6917,9 +7477,9 @@ function useNotificationsQuery({
6917
7477
  }
6918
7478
 
6919
7479
  // src/screens/NotificationsScreen.tsx
6920
- import { jsxDEV as jsxDEV21 } from "@opentui/react/jsx-dev-runtime";
7480
+ import { jsxDEV as jsxDEV23 } from "@opentui/react/jsx-dev-runtime";
6921
7481
  function NewNotificationsBanner({ count }) {
6922
- return /* @__PURE__ */ jsxDEV21("box", {
7482
+ return /* @__PURE__ */ jsxDEV23("box", {
6923
7483
  style: {
6924
7484
  flexShrink: 0,
6925
7485
  paddingLeft: 1,
@@ -6927,15 +7487,15 @@ function NewNotificationsBanner({ count }) {
6927
7487
  paddingTop: 0,
6928
7488
  paddingBottom: 1
6929
7489
  },
6930
- children: /* @__PURE__ */ jsxDEV21("box", {
7490
+ children: /* @__PURE__ */ jsxDEV23("box", {
6931
7491
  style: {
6932
7492
  backgroundColor: colors.primary,
6933
7493
  paddingLeft: 2,
6934
7494
  paddingRight: 2
6935
7495
  },
6936
- children: /* @__PURE__ */ jsxDEV21("text", {
7496
+ children: /* @__PURE__ */ jsxDEV23("text", {
6937
7497
  fg: "#000000",
6938
- children: /* @__PURE__ */ jsxDEV21("b", {
7498
+ children: /* @__PURE__ */ jsxDEV23("b", {
6939
7499
  children: [
6940
7500
  count,
6941
7501
  " new notification",
@@ -6965,10 +7525,10 @@ function NotificationsScreen({
6965
7525
  refresh,
6966
7526
  newNotificationsCount
6967
7527
  } = useNotificationsQuery({ client });
6968
- useEffect16(() => {
7528
+ useEffect18(() => {
6969
7529
  onNotificationCountChange?.(notifications.length);
6970
7530
  }, [notifications.length, onNotificationCountChange]);
6971
- useEffect16(() => {
7531
+ useEffect18(() => {
6972
7532
  onUnreadCountChange?.(unreadCount);
6973
7533
  }, [unreadCount, onUnreadCountChange]);
6974
7534
  useKeyboard7((key) => {
@@ -6979,11 +7539,11 @@ function NotificationsScreen({
6979
7539
  }
6980
7540
  });
6981
7541
  if (isLoading) {
6982
- return /* @__PURE__ */ jsxDEV21("box", {
7542
+ return /* @__PURE__ */ jsxDEV23("box", {
6983
7543
  style: { flexDirection: "column", height: "100%" },
6984
- children: /* @__PURE__ */ jsxDEV21("box", {
7544
+ children: /* @__PURE__ */ jsxDEV23("box", {
6985
7545
  style: { padding: 2, flexGrow: 1 },
6986
- children: /* @__PURE__ */ jsxDEV21("text", {
7546
+ children: /* @__PURE__ */ jsxDEV23("text", {
6987
7547
  fg: colors.muted,
6988
7548
  children: "Loading notifications..."
6989
7549
  }, undefined, false, undefined, this)
@@ -6991,9 +7551,9 @@ function NotificationsScreen({
6991
7551
  }, undefined, false, undefined, this);
6992
7552
  }
6993
7553
  if (error) {
6994
- return /* @__PURE__ */ jsxDEV21("box", {
7554
+ return /* @__PURE__ */ jsxDEV23("box", {
6995
7555
  style: { flexDirection: "column", height: "100%" },
6996
- children: /* @__PURE__ */ jsxDEV21(ErrorBanner, {
7556
+ children: /* @__PURE__ */ jsxDEV23(ErrorBanner, {
6997
7557
  error,
6998
7558
  onRetry: refresh,
6999
7559
  retryDisabled: false
@@ -7001,24 +7561,24 @@ function NotificationsScreen({
7001
7561
  }, undefined, false, undefined, this);
7002
7562
  }
7003
7563
  if (notifications.length === 0) {
7004
- return /* @__PURE__ */ jsxDEV21("box", {
7564
+ return /* @__PURE__ */ jsxDEV23("box", {
7005
7565
  style: { flexDirection: "column", height: "100%" },
7006
- children: /* @__PURE__ */ jsxDEV21("box", {
7566
+ children: /* @__PURE__ */ jsxDEV23("box", {
7007
7567
  style: { padding: 2, flexGrow: 1 },
7008
- children: /* @__PURE__ */ jsxDEV21("text", {
7568
+ children: /* @__PURE__ */ jsxDEV23("text", {
7009
7569
  fg: colors.muted,
7010
7570
  children: "No notifications yet. Press r to refresh."
7011
7571
  }, undefined, false, undefined, this)
7012
7572
  }, undefined, false, undefined, this)
7013
7573
  }, undefined, false, undefined, this);
7014
7574
  }
7015
- return /* @__PURE__ */ jsxDEV21("box", {
7575
+ return /* @__PURE__ */ jsxDEV23("box", {
7016
7576
  style: { flexDirection: "column", height: "100%" },
7017
7577
  children: [
7018
- newNotificationsCount > 0 && /* @__PURE__ */ jsxDEV21(NewNotificationsBanner, {
7578
+ newNotificationsCount > 0 && /* @__PURE__ */ jsxDEV23(NewNotificationsBanner, {
7019
7579
  count: newNotificationsCount
7020
7580
  }, undefined, false, undefined, this),
7021
- /* @__PURE__ */ jsxDEV21(NotificationList, {
7581
+ /* @__PURE__ */ jsxDEV23(NotificationList, {
7022
7582
  notifications,
7023
7583
  focused,
7024
7584
  onNotificationSelect,
@@ -7032,11 +7592,11 @@ function NotificationsScreen({
7032
7592
 
7033
7593
  // src/screens/PostDetailScreen.tsx
7034
7594
  import { useKeyboard as useKeyboard8 } from "@opentui/react";
7035
- import { useState as useState20, useRef as useRef11, useEffect as useEffect17, useCallback as useCallback13 } from "react";
7595
+ import { useState as useState25, useRef as useRef12, useEffect as useEffect19, useCallback as useCallback14 } from "react";
7036
7596
  init_media();
7037
7597
 
7038
7598
  // src/lib/text.tsx
7039
- import { jsxDEV as jsxDEV22 } from "@opentui/react/jsx-dev-runtime";
7599
+ import { jsxDEV as jsxDEV24 } from "@opentui/react/jsx-dev-runtime";
7040
7600
  function extractMentions(text) {
7041
7601
  const mentionRegex = /@(\w+)/g;
7042
7602
  const mentions = [];
@@ -7057,32 +7617,32 @@ function renderTextWithMentions(text, mentionColor, textColor) {
7057
7617
  let keyIdx = 0;
7058
7618
  while ((match = mentionRegex.exec(text)) !== null) {
7059
7619
  if (match.index > lastIndex) {
7060
- parts.push(/* @__PURE__ */ jsxDEV22("span", {
7620
+ parts.push(/* @__PURE__ */ jsxDEV24("span", {
7061
7621
  fg: textColor,
7062
7622
  children: text.slice(lastIndex, match.index)
7063
7623
  }, `text-${keyIdx++}`, false, undefined, this));
7064
7624
  }
7065
- parts.push(/* @__PURE__ */ jsxDEV22("span", {
7625
+ parts.push(/* @__PURE__ */ jsxDEV24("span", {
7066
7626
  fg: mentionColor,
7067
7627
  children: match[0]
7068
7628
  }, `mention-${keyIdx++}`, false, undefined, this));
7069
7629
  lastIndex = match.index + match[0].length;
7070
7630
  }
7071
7631
  if (lastIndex < text.length) {
7072
- parts.push(/* @__PURE__ */ jsxDEV22("span", {
7632
+ parts.push(/* @__PURE__ */ jsxDEV24("span", {
7073
7633
  fg: textColor,
7074
7634
  children: text.slice(lastIndex)
7075
7635
  }, `text-${keyIdx++}`, false, undefined, this));
7076
7636
  }
7077
7637
  if (parts.length === 0) {
7078
- return /* @__PURE__ */ jsxDEV22("text", {
7638
+ return /* @__PURE__ */ jsxDEV24("text", {
7079
7639
  fg: textColor,
7080
7640
  selectable: true,
7081
7641
  selectionBg: "#264F78",
7082
7642
  children: text
7083
7643
  }, undefined, false, undefined, this);
7084
7644
  }
7085
- return /* @__PURE__ */ jsxDEV22("text", {
7645
+ return /* @__PURE__ */ jsxDEV24("text", {
7086
7646
  selectable: true,
7087
7647
  selectionBg: "#264F78",
7088
7648
  children: parts
@@ -7090,7 +7650,7 @@ function renderTextWithMentions(text, mentionColor, textColor) {
7090
7650
  }
7091
7651
 
7092
7652
  // src/screens/PostDetailScreen.tsx
7093
- import { jsxDEV as jsxDEV23, Fragment } from "@opentui/react/jsx-dev-runtime";
7653
+ import { jsxDEV as jsxDEV25, Fragment as Fragment2 } from "@opentui/react/jsx-dev-runtime";
7094
7654
  var HEART_EMPTY2 = "\u2661";
7095
7655
  var HEART_FILLED2 = "\u2665";
7096
7656
  var FLAG_EMPTY2 = "\u2690";
@@ -7138,6 +7698,8 @@ function PostDetailScreen({
7138
7698
  onLike,
7139
7699
  onBookmark,
7140
7700
  onMoveToFolder,
7701
+ onAnnotate,
7702
+ annotationText,
7141
7703
  isLiked = false,
7142
7704
  isBookmarked = false,
7143
7705
  isJustLiked = false,
@@ -7160,17 +7722,17 @@ function PostDetailScreen({
7160
7722
  hasMoreReplies,
7161
7723
  loadMoreReplies
7162
7724
  } = usePostDetailQuery({ client, tweet });
7163
- const [isExpanded, setIsExpanded] = useState20(false);
7164
- const [statusMessage, setStatusMessage] = useState20(null);
7165
- const [linkIndex, setLinkIndex] = useState20(0);
7166
- const [mentionIndex, setMentionIndex] = useState20(0);
7167
- const [linkMetadata, setLinkMetadata] = useState20(null);
7168
- const [isLoadingMetadata, setIsLoadingMetadata] = useState20(false);
7169
- const [repliesMode, setRepliesMode] = useState20(false);
7170
- const [mentionsMode, setMentionsMode] = useState20(false);
7171
- const [linkMode, setLinkMode] = useState20(false);
7172
- const scrollRef = useRef11(null);
7173
- useEffect17(() => {
7725
+ const [isExpanded, setIsExpanded] = useState25(false);
7726
+ const [statusMessage, setStatusMessage] = useState25(null);
7727
+ const [linkIndex, setLinkIndex] = useState25(0);
7728
+ const [mentionIndex, setMentionIndex] = useState25(0);
7729
+ const [linkMetadata, setLinkMetadata] = useState25(null);
7730
+ const [isLoadingMetadata, setIsLoadingMetadata] = useState25(false);
7731
+ const [repliesMode, setRepliesMode] = useState25(false);
7732
+ const [mentionsMode, setMentionsMode] = useState25(false);
7733
+ const [linkMode, setLinkMode] = useState25(false);
7734
+ const scrollRef = useRef12(null);
7735
+ useEffect19(() => {
7174
7736
  setRepliesMode(false);
7175
7737
  setMentionsMode(false);
7176
7738
  setLinkMode(false);
@@ -7210,7 +7772,7 @@ function PostDetailScreen({
7210
7772
  }
7211
7773
  }
7212
7774
  });
7213
- useEffect17(() => {
7775
+ useEffect19(() => {
7214
7776
  const scrollbox = scrollRef.current;
7215
7777
  if (!scrollbox || !repliesMode || replies.length === 0)
7216
7778
  return;
@@ -7232,7 +7794,7 @@ function PostDetailScreen({
7232
7794
  scrollbox.scrollBy(relativeY - topMargin);
7233
7795
  }
7234
7796
  }, [selectedReplyIndex, repliesMode, replies]);
7235
- useEffect17(() => {
7797
+ useEffect19(() => {
7236
7798
  if (!repliesMode || loadingMoreReplies || !hasMoreReplies || replies.length === 0)
7237
7799
  return;
7238
7800
  const threshold = 3;
@@ -7247,18 +7809,18 @@ function PostDetailScreen({
7247
7809
  repliesMode,
7248
7810
  loadMoreReplies
7249
7811
  ]);
7250
- useEffect17(() => {
7812
+ useEffect19(() => {
7251
7813
  if (isExpanded && scrollRef.current) {
7252
7814
  scrollRef.current.scrollTo(0);
7253
7815
  }
7254
7816
  }, [isExpanded]);
7255
- useEffect17(() => {
7817
+ useEffect19(() => {
7256
7818
  if (statusMessage) {
7257
7819
  const timer = setTimeout(() => setStatusMessage(null), 3000);
7258
7820
  return () => clearTimeout(timer);
7259
7821
  }
7260
7822
  }, [statusMessage]);
7261
- useEffect17(() => {
7823
+ useEffect19(() => {
7262
7824
  if (!currentLink) {
7263
7825
  setLinkMetadata(null);
7264
7826
  return;
@@ -7275,27 +7837,27 @@ function PostDetailScreen({
7275
7837
  cancelled = true;
7276
7838
  };
7277
7839
  }, [currentLink]);
7278
- const handlePreview = useCallback13(async () => {
7840
+ const handlePreview = useCallback14(async () => {
7279
7841
  if (!hasMedia || !tweet.media)
7280
7842
  return;
7281
7843
  setStatusMessage("Opening...");
7282
7844
  const result = await previewAllMedia(tweet.media, tweet.id);
7283
7845
  setStatusMessage(result.success ? result.message : result.error);
7284
7846
  }, [hasMedia, tweet.media, tweet.id]);
7285
- const handleDownload = useCallback13(async () => {
7847
+ const handleDownload = useCallback14(async () => {
7286
7848
  if (!tweet.media || tweet.media.length === 0)
7287
7849
  return;
7288
7850
  setStatusMessage("Downloading...");
7289
7851
  const result = await downloadAllMedia(tweet.media, tweet.id);
7290
7852
  setStatusMessage(result.success ? result.message : result.error);
7291
7853
  }, [tweet.media, tweet.id]);
7292
- const handleMentionProfile = useCallback13(() => {
7854
+ const handleMentionProfile = useCallback14(() => {
7293
7855
  if (!currentMention)
7294
7856
  return;
7295
7857
  setStatusMessage(`Opening @${currentMention.username}...`);
7296
7858
  onProfileOpen?.(currentMention.username);
7297
7859
  }, [currentMention, onProfileOpen]);
7298
- const handleOpenTweet = useCallback13(async () => {
7860
+ const handleOpenTweet = useCallback14(async () => {
7299
7861
  const urlToOpen = `https://x.com/${tweet.author.username}/status/${tweet.id}`;
7300
7862
  setStatusMessage("Opening on x.com...");
7301
7863
  try {
@@ -7305,7 +7867,7 @@ function PostDetailScreen({
7305
7867
  setStatusMessage("Failed to open browser");
7306
7868
  }
7307
7869
  }, [tweet.author.username, tweet.id]);
7308
- const handleOpenLink = useCallback13(async () => {
7870
+ const handleOpenLink = useCallback14(async () => {
7309
7871
  if (!currentLink) {
7310
7872
  setStatusMessage("No external link selected");
7311
7873
  return;
@@ -7433,6 +7995,11 @@ function PostDetailScreen({
7433
7995
  onMoveToFolder?.();
7434
7996
  }
7435
7997
  break;
7998
+ case "a":
7999
+ if (isBookmarked) {
8000
+ onAnnotate?.();
8001
+ }
8002
+ break;
7436
8003
  case "p":
7437
8004
  onProfileOpen?.(tweet.author.username);
7438
8005
  break;
@@ -7473,7 +8040,7 @@ function PostDetailScreen({
7473
8040
  }
7474
8041
  });
7475
8042
  const isInNavigationMode = repliesMode || mentionsMode || linkMode;
7476
- const headerContent = /* @__PURE__ */ jsxDEV23("box", {
8043
+ const headerContent = /* @__PURE__ */ jsxDEV25("box", {
7477
8044
  style: {
7478
8045
  flexShrink: 0,
7479
8046
  paddingLeft: 1,
@@ -7482,19 +8049,19 @@ function PostDetailScreen({
7482
8049
  flexDirection: "row"
7483
8050
  },
7484
8051
  children: [
7485
- /* @__PURE__ */ jsxDEV23("text", {
8052
+ /* @__PURE__ */ jsxDEV25("text", {
7486
8053
  fg: colors.muted,
7487
8054
  children: isInNavigationMode ? "<- Back (Esc) | " : "<- Back (Esc)"
7488
8055
  }, undefined, false, undefined, this),
7489
- repliesMode && /* @__PURE__ */ jsxDEV23("text", {
8056
+ repliesMode && /* @__PURE__ */ jsxDEV25("text", {
7490
8057
  fg: colors.primary,
7491
8058
  children: "Navigating replies"
7492
8059
  }, undefined, false, undefined, this),
7493
- mentionsMode && /* @__PURE__ */ jsxDEV23("text", {
8060
+ mentionsMode && /* @__PURE__ */ jsxDEV25("text", {
7494
8061
  fg: colors.primary,
7495
8062
  children: "Navigating mentions"
7496
8063
  }, undefined, false, undefined, this),
7497
- linkMode && /* @__PURE__ */ jsxDEV23("text", {
8064
+ linkMode && /* @__PURE__ */ jsxDEV25("text", {
7498
8065
  fg: colors.primary,
7499
8066
  children: [
7500
8067
  "Navigating links (",
@@ -7506,7 +8073,7 @@ function PostDetailScreen({
7506
8073
  }, undefined, true, undefined, this)
7507
8074
  ]
7508
8075
  }, undefined, true, undefined, this);
7509
- const parentContent = isReply && (loadingParent || parentTweet) ? /* @__PURE__ */ jsxDEV23("box", {
8076
+ const parentContent = isReply && (loadingParent || parentTweet) ? /* @__PURE__ */ jsxDEV25("box", {
7510
8077
  style: {
7511
8078
  marginBottom: 1,
7512
8079
  paddingLeft: 1,
@@ -7514,24 +8081,24 @@ function PostDetailScreen({
7514
8081
  borderStyle: "single",
7515
8082
  borderColor: "#444444"
7516
8083
  },
7517
- children: loadingParent ? /* @__PURE__ */ jsxDEV23("text", {
8084
+ children: loadingParent ? /* @__PURE__ */ jsxDEV25("text", {
7518
8085
  fg: colors.dim,
7519
8086
  children: "Loading parent tweet..."
7520
- }, undefined, false, undefined, this) : parentTweet ? /* @__PURE__ */ jsxDEV23("box", {
8087
+ }, undefined, false, undefined, this) : parentTweet ? /* @__PURE__ */ jsxDEV25("box", {
7521
8088
  style: { flexDirection: "column" },
7522
8089
  children: [
7523
- /* @__PURE__ */ jsxDEV23("box", {
8090
+ /* @__PURE__ */ jsxDEV25("box", {
7524
8091
  style: { flexDirection: "row" },
7525
8092
  children: [
7526
- /* @__PURE__ */ jsxDEV23("text", {
8093
+ /* @__PURE__ */ jsxDEV25("text", {
7527
8094
  fg: colors.dim,
7528
8095
  children: "Replying to "
7529
8096
  }, undefined, false, undefined, this),
7530
- /* @__PURE__ */ jsxDEV23("text", {
8097
+ /* @__PURE__ */ jsxDEV25("text", {
7531
8098
  fg: colors.muted,
7532
8099
  children: parentTweet.author.name
7533
8100
  }, undefined, false, undefined, this),
7534
- /* @__PURE__ */ jsxDEV23("text", {
8101
+ /* @__PURE__ */ jsxDEV25("text", {
7535
8102
  fg: colors.reply,
7536
8103
  children: [
7537
8104
  " @",
@@ -7540,9 +8107,9 @@ function PostDetailScreen({
7540
8107
  }, undefined, true, undefined, this)
7541
8108
  ]
7542
8109
  }, undefined, true, undefined, this),
7543
- /* @__PURE__ */ jsxDEV23("box", {
8110
+ /* @__PURE__ */ jsxDEV25("box", {
7544
8111
  style: { marginTop: 1 },
7545
- children: /* @__PURE__ */ jsxDEV23("text", {
8112
+ children: /* @__PURE__ */ jsxDEV25("text", {
7546
8113
  fg: "#aaaaaa",
7547
8114
  selectable: true,
7548
8115
  selectionBg: "#264F78",
@@ -7552,19 +8119,49 @@ function PostDetailScreen({
7552
8119
  ]
7553
8120
  }, undefined, true, undefined, this) : null
7554
8121
  }, undefined, false, undefined, this) : null;
7555
- const authorContent = /* @__PURE__ */ jsxDEV23("box", {
8122
+ const annotationContent = isBookmarked && annotationText ? /* @__PURE__ */ jsxDEV25("box", {
8123
+ style: {
8124
+ marginBottom: 1,
8125
+ paddingLeft: 1,
8126
+ paddingRight: 1,
8127
+ borderStyle: "single",
8128
+ borderColor: colors.warning
8129
+ },
8130
+ children: /* @__PURE__ */ jsxDEV25("box", {
8131
+ style: { flexDirection: "column" },
8132
+ children: [
8133
+ /* @__PURE__ */ jsxDEV25("box", {
8134
+ style: { flexDirection: "row" },
8135
+ children: /* @__PURE__ */ jsxDEV25("text", {
8136
+ fg: colors.warning,
8137
+ children: "+ Your note:"
8138
+ }, undefined, false, undefined, this)
8139
+ }, undefined, false, undefined, this),
8140
+ /* @__PURE__ */ jsxDEV25("box", {
8141
+ style: { marginTop: 1 },
8142
+ children: /* @__PURE__ */ jsxDEV25("text", {
8143
+ fg: "#cccccc",
8144
+ selectable: true,
8145
+ selectionBg: "#264F78",
8146
+ children: annotationText
8147
+ }, undefined, false, undefined, this)
8148
+ }, undefined, false, undefined, this)
8149
+ ]
8150
+ }, undefined, true, undefined, this)
8151
+ }, undefined, false, undefined, this) : null;
8152
+ const authorContent = /* @__PURE__ */ jsxDEV25("box", {
7556
8153
  style: { flexDirection: "column", paddingLeft: 1, paddingRight: 1 },
7557
8154
  children: [
7558
- /* @__PURE__ */ jsxDEV23("box", {
8155
+ /* @__PURE__ */ jsxDEV25("box", {
7559
8156
  style: { flexDirection: "row" },
7560
8157
  children: [
7561
- /* @__PURE__ */ jsxDEV23("text", {
7562
- children: /* @__PURE__ */ jsxDEV23("b", {
8158
+ /* @__PURE__ */ jsxDEV25("text", {
8159
+ children: /* @__PURE__ */ jsxDEV25("b", {
7563
8160
  fg: colors.primary,
7564
8161
  children: tweet.author.name
7565
8162
  }, undefined, false, undefined, this)
7566
8163
  }, undefined, false, undefined, this),
7567
- /* @__PURE__ */ jsxDEV23("text", {
8164
+ /* @__PURE__ */ jsxDEV25("text", {
7568
8165
  fg: colors.handle,
7569
8166
  children: [
7570
8167
  " @",
@@ -7573,49 +8170,49 @@ function PostDetailScreen({
7573
8170
  }, undefined, true, undefined, this)
7574
8171
  ]
7575
8172
  }, undefined, true, undefined, this),
7576
- fullTimestamp && /* @__PURE__ */ jsxDEV23("box", {
8173
+ fullTimestamp && /* @__PURE__ */ jsxDEV25("box", {
7577
8174
  style: { marginTop: 0 },
7578
- children: /* @__PURE__ */ jsxDEV23("text", {
8175
+ children: /* @__PURE__ */ jsxDEV25("text", {
7579
8176
  fg: colors.dim,
7580
8177
  children: fullTimestamp
7581
8178
  }, undefined, false, undefined, this)
7582
8179
  }, undefined, false, undefined, this)
7583
8180
  ]
7584
8181
  }, undefined, true, undefined, this);
7585
- const postContent = /* @__PURE__ */ jsxDEV23("box", {
8182
+ const postContent = /* @__PURE__ */ jsxDEV25("box", {
7586
8183
  style: { marginTop: 1, paddingLeft: 1, paddingRight: 1 },
7587
- children: hasMentions ? renderTextWithMentions(displayText, colors.mention, "#ffffff") : /* @__PURE__ */ jsxDEV23("text", {
8184
+ children: hasMentions ? renderTextWithMentions(displayText, colors.mention, "#ffffff") : /* @__PURE__ */ jsxDEV25("text", {
7588
8185
  fg: "#ffffff",
7589
8186
  selectable: true,
7590
8187
  selectionBg: "#264F78",
7591
8188
  children: displayText
7592
8189
  }, undefined, false, undefined, this)
7593
8190
  }, undefined, false, undefined, this);
7594
- const truncationIndicator = showTruncated ? /* @__PURE__ */ jsxDEV23("box", {
8191
+ const truncationIndicator = showTruncated ? /* @__PURE__ */ jsxDEV25("box", {
7595
8192
  style: { paddingLeft: 1, marginTop: 1 },
7596
8193
  children: [
7597
- /* @__PURE__ */ jsxDEV23("text", {
8194
+ /* @__PURE__ */ jsxDEV25("text", {
7598
8195
  fg: colors.primary,
7599
8196
  children: "[Show more]"
7600
8197
  }, undefined, false, undefined, this),
7601
- /* @__PURE__ */ jsxDEV23("text", {
8198
+ /* @__PURE__ */ jsxDEV25("text", {
7602
8199
  fg: colors.dim,
7603
8200
  children: " (e)"
7604
8201
  }, undefined, false, undefined, this)
7605
8202
  ]
7606
8203
  }, undefined, true, undefined, this) : null;
7607
- const quotedContent = tweet.quotedTweet ? /* @__PURE__ */ jsxDEV23("box", {
8204
+ const quotedContent = tweet.quotedTweet ? /* @__PURE__ */ jsxDEV25("box", {
7608
8205
  style: { paddingLeft: 1, paddingRight: 1, marginTop: 1 },
7609
- children: /* @__PURE__ */ jsxDEV23(QuotedPostCard, {
8206
+ children: /* @__PURE__ */ jsxDEV25(QuotedPostCard, {
7610
8207
  post: tweet.quotedTweet,
7611
8208
  showNavigationHint: true
7612
8209
  }, undefined, false, undefined, this)
7613
8210
  }, undefined, false, undefined, this) : null;
7614
- const statsContent = /* @__PURE__ */ jsxDEV23("box", {
8211
+ const statsContent = /* @__PURE__ */ jsxDEV25("box", {
7615
8212
  style: { marginTop: 1, paddingLeft: 1, paddingRight: 1 },
7616
- children: /* @__PURE__ */ jsxDEV23("box", {
8213
+ children: /* @__PURE__ */ jsxDEV25("box", {
7617
8214
  style: { flexDirection: "row" },
7618
- children: /* @__PURE__ */ jsxDEV23("text", {
8215
+ children: /* @__PURE__ */ jsxDEV25("text", {
7619
8216
  fg: colors.muted,
7620
8217
  children: [
7621
8218
  formatCount(tweet.replyCount),
@@ -7630,16 +8227,16 @@ function PostDetailScreen({
7630
8227
  }, undefined, true, undefined, this)
7631
8228
  }, undefined, false, undefined, this)
7632
8229
  }, undefined, false, undefined, this);
7633
- const mediaContent = hasMedia ? /* @__PURE__ */ jsxDEV23("box", {
8230
+ const mediaContent = hasMedia ? /* @__PURE__ */ jsxDEV25("box", {
7634
8231
  style: { marginTop: 1, paddingLeft: 1, paddingRight: 1 },
7635
- children: /* @__PURE__ */ jsxDEV23("box", {
8232
+ children: /* @__PURE__ */ jsxDEV25("box", {
7636
8233
  style: { flexDirection: "row", flexWrap: "wrap" },
7637
8234
  children: [
7638
8235
  tweet.media?.map((item, idx) => {
7639
8236
  const dims = item.width && item.height ? ` (${item.width}x${item.height})` : "";
7640
8237
  const typeLabel = item.type === "photo" ? "Image" : item.type === "video" ? "Video" : "GIF";
7641
8238
  const typeColor = item.type === "photo" ? colors.warning : item.type === "video" ? colors.warning : colors.success;
7642
- return /* @__PURE__ */ jsxDEV23("text", {
8239
+ return /* @__PURE__ */ jsxDEV25("text", {
7643
8240
  fg: typeColor,
7644
8241
  children: [
7645
8242
  "\u2022 ",
@@ -7650,74 +8247,74 @@ function PostDetailScreen({
7650
8247
  ]
7651
8248
  }, item.id, true, undefined, this);
7652
8249
  }),
7653
- /* @__PURE__ */ jsxDEV23("text", {
8250
+ /* @__PURE__ */ jsxDEV25("text", {
7654
8251
  fg: colors.dim,
7655
8252
  children: "("
7656
8253
  }, undefined, false, undefined, this),
7657
- /* @__PURE__ */ jsxDEV23("text", {
8254
+ /* @__PURE__ */ jsxDEV25("text", {
7658
8255
  fg: colors.primary,
7659
8256
  children: "i"
7660
8257
  }, undefined, false, undefined, this),
7661
- /* @__PURE__ */ jsxDEV23("text", {
8258
+ /* @__PURE__ */ jsxDEV25("text", {
7662
8259
  fg: colors.dim,
7663
8260
  children: " view, "
7664
8261
  }, undefined, false, undefined, this),
7665
- /* @__PURE__ */ jsxDEV23("text", {
8262
+ /* @__PURE__ */ jsxDEV25("text", {
7666
8263
  fg: colors.primary,
7667
8264
  children: "d"
7668
8265
  }, undefined, false, undefined, this),
7669
- /* @__PURE__ */ jsxDEV23("text", {
8266
+ /* @__PURE__ */ jsxDEV25("text", {
7670
8267
  fg: colors.dim,
7671
8268
  children: " download)"
7672
8269
  }, undefined, false, undefined, this)
7673
8270
  ]
7674
8271
  }, undefined, true, undefined, this)
7675
8272
  }, undefined, false, undefined, this) : null;
7676
- const linksContent = hasLinks ? /* @__PURE__ */ jsxDEV23("box", {
8273
+ const linksContent = hasLinks ? /* @__PURE__ */ jsxDEV25("box", {
7677
8274
  style: { marginTop: 1, paddingLeft: 1, paddingRight: 1 },
7678
- children: /* @__PURE__ */ jsxDEV23("box", {
8275
+ children: /* @__PURE__ */ jsxDEV25("box", {
7679
8276
  style: { flexDirection: "column" },
7680
- children: linkCount === 1 ? /* @__PURE__ */ jsxDEV23("box", {
8277
+ children: linkCount === 1 ? /* @__PURE__ */ jsxDEV25("box", {
7681
8278
  style: { flexDirection: "row" },
7682
8279
  children: [
7683
- /* @__PURE__ */ jsxDEV23("text", {
8280
+ /* @__PURE__ */ jsxDEV25("text", {
7684
8281
  fg: colors.dim,
7685
8282
  children: "Links: "
7686
8283
  }, undefined, false, undefined, this),
7687
- /* @__PURE__ */ jsxDEV23("text", {
8284
+ /* @__PURE__ */ jsxDEV25("text", {
7688
8285
  fg: colors.primary,
7689
8286
  children: [
7690
8287
  "> ",
7691
8288
  tweet.urls?.[0]?.displayUrl
7692
8289
  ]
7693
8290
  }, undefined, true, undefined, this),
7694
- /* @__PURE__ */ jsxDEV23("text", {
8291
+ /* @__PURE__ */ jsxDEV25("text", {
7695
8292
  fg: colors.dim,
7696
8293
  children: " ("
7697
8294
  }, undefined, false, undefined, this),
7698
- /* @__PURE__ */ jsxDEV23("text", {
8295
+ /* @__PURE__ */ jsxDEV25("text", {
7699
8296
  fg: colors.primary,
7700
8297
  children: "o"
7701
8298
  }, undefined, false, undefined, this),
7702
- /* @__PURE__ */ jsxDEV23("text", {
8299
+ /* @__PURE__ */ jsxDEV25("text", {
7703
8300
  fg: colors.dim,
7704
8301
  children: " open)"
7705
8302
  }, undefined, false, undefined, this)
7706
8303
  ]
7707
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV23(Fragment, {
8304
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV25(Fragment2, {
7708
8305
  children: [
7709
- /* @__PURE__ */ jsxDEV23("box", {
8306
+ /* @__PURE__ */ jsxDEV25("box", {
7710
8307
  style: { flexDirection: "row" },
7711
8308
  children: [
7712
- /* @__PURE__ */ jsxDEV23("text", {
8309
+ /* @__PURE__ */ jsxDEV25("text", {
7713
8310
  fg: colors.dim,
7714
8311
  children: "Links: "
7715
8312
  }, undefined, false, undefined, this),
7716
- /* @__PURE__ */ jsxDEV23("text", {
8313
+ /* @__PURE__ */ jsxDEV25("text", {
7717
8314
  fg: colors.primary,
7718
8315
  children: "o"
7719
8316
  }, undefined, false, undefined, this),
7720
- /* @__PURE__ */ jsxDEV23("text", {
8317
+ /* @__PURE__ */ jsxDEV25("text", {
7721
8318
  fg: colors.dim,
7722
8319
  children: linkMode ? " open" : " select"
7723
8320
  }, undefined, false, undefined, this)
@@ -7726,15 +8323,15 @@ function PostDetailScreen({
7726
8323
  tweet.urls?.map((link, idx) => {
7727
8324
  const isSelected = linkMode && idx === linkIndex;
7728
8325
  const showMetadata = isSelected && linkMetadata;
7729
- return /* @__PURE__ */ jsxDEV23("box", {
8326
+ return /* @__PURE__ */ jsxDEV25("box", {
7730
8327
  style: {
7731
8328
  flexDirection: "column",
7732
8329
  marginTop: idx === 0 ? 1 : 0
7733
8330
  },
7734
8331
  children: [
7735
- /* @__PURE__ */ jsxDEV23("box", {
8332
+ /* @__PURE__ */ jsxDEV25("box", {
7736
8333
  style: { flexDirection: "row" },
7737
- children: /* @__PURE__ */ jsxDEV23("text", {
8334
+ children: /* @__PURE__ */ jsxDEV25("text", {
7738
8335
  fg: isSelected ? colors.primary : colors.muted,
7739
8336
  children: [
7740
8337
  isSelected ? ">" : "\u2022",
@@ -7743,9 +8340,9 @@ function PostDetailScreen({
7743
8340
  ]
7744
8341
  }, undefined, true, undefined, this)
7745
8342
  }, undefined, false, undefined, this),
7746
- showMetadata && linkMetadata.title && /* @__PURE__ */ jsxDEV23("box", {
8343
+ showMetadata && linkMetadata.title && /* @__PURE__ */ jsxDEV25("box", {
7747
8344
  style: { paddingLeft: 2 },
7748
- children: /* @__PURE__ */ jsxDEV23("text", {
8345
+ children: /* @__PURE__ */ jsxDEV25("text", {
7749
8346
  fg: colors.dim,
7750
8347
  children: [
7751
8348
  ' "',
@@ -7754,9 +8351,9 @@ function PostDetailScreen({
7754
8351
  ]
7755
8352
  }, undefined, true, undefined, this)
7756
8353
  }, undefined, false, undefined, this),
7757
- isSelected && isLoadingMetadata && /* @__PURE__ */ jsxDEV23("box", {
8354
+ isSelected && isLoadingMetadata && /* @__PURE__ */ jsxDEV25("box", {
7758
8355
  style: { paddingLeft: 2 },
7759
- children: /* @__PURE__ */ jsxDEV23("text", {
8356
+ children: /* @__PURE__ */ jsxDEV25("text", {
7760
8357
  fg: colors.dim,
7761
8358
  children: " Loading..."
7762
8359
  }, undefined, false, undefined, this)
@@ -7768,57 +8365,57 @@ function PostDetailScreen({
7768
8365
  }, undefined, true, undefined, this)
7769
8366
  }, undefined, false, undefined, this)
7770
8367
  }, undefined, false, undefined, this) : null;
7771
- const handleMentionRowClick = useCallback13((username) => (event) => {
8368
+ const handleMentionRowClick = useCallback14((username) => (event) => {
7772
8369
  if (event.type === "up" && event.button === 0) {
7773
8370
  onProfileOpen?.(username);
7774
8371
  }
7775
8372
  }, [onProfileOpen]);
7776
8373
  const firstMention = tweet.mentions?.[0];
7777
- const mentionsContent = hasMentions ? /* @__PURE__ */ jsxDEV23("box", {
8374
+ const mentionsContent = hasMentions ? /* @__PURE__ */ jsxDEV25("box", {
7778
8375
  style: { marginTop: 1, paddingLeft: 1, paddingRight: 1 },
7779
- children: /* @__PURE__ */ jsxDEV23("box", {
8376
+ children: /* @__PURE__ */ jsxDEV25("box", {
7780
8377
  style: { flexDirection: "column" },
7781
- children: mentionCount === 1 ? /* @__PURE__ */ jsxDEV23("box", {
8378
+ children: mentionCount === 1 ? /* @__PURE__ */ jsxDEV25("box", {
7782
8379
  style: { flexDirection: "row" },
7783
8380
  onMouse: firstMention ? handleMentionRowClick(firstMention.username) : undefined,
7784
8381
  children: [
7785
- /* @__PURE__ */ jsxDEV23("text", {
8382
+ /* @__PURE__ */ jsxDEV25("text", {
7786
8383
  fg: colors.dim,
7787
8384
  children: "Mentions: "
7788
8385
  }, undefined, false, undefined, this),
7789
- /* @__PURE__ */ jsxDEV23("text", {
8386
+ /* @__PURE__ */ jsxDEV25("text", {
7790
8387
  fg: colors.mention,
7791
8388
  children: [
7792
8389
  "@",
7793
8390
  firstMention?.username
7794
8391
  ]
7795
8392
  }, undefined, true, undefined, this),
7796
- firstMention?.name && /* @__PURE__ */ jsxDEV23("text", {
8393
+ firstMention?.name && /* @__PURE__ */ jsxDEV25("text", {
7797
8394
  fg: colors.dim,
7798
8395
  children: [
7799
8396
  " \xB7 ",
7800
8397
  firstMention.name
7801
8398
  ]
7802
8399
  }, undefined, true, undefined, this),
7803
- /* @__PURE__ */ jsxDEV23("text", {
8400
+ /* @__PURE__ */ jsxDEV25("text", {
7804
8401
  fg: colors.dim,
7805
8402
  children: " ("
7806
8403
  }, undefined, false, undefined, this),
7807
- /* @__PURE__ */ jsxDEV23("text", {
8404
+ /* @__PURE__ */ jsxDEV25("text", {
7808
8405
  fg: colors.primary,
7809
8406
  children: "m"
7810
8407
  }, undefined, false, undefined, this),
7811
- /* @__PURE__ */ jsxDEV23("text", {
8408
+ /* @__PURE__ */ jsxDEV25("text", {
7812
8409
  fg: colors.dim,
7813
8410
  children: "/click)"
7814
8411
  }, undefined, false, undefined, this)
7815
8412
  ]
7816
- }, undefined, true, undefined, this) : mentionsMode ? /* @__PURE__ */ jsxDEV23(Fragment, {
8413
+ }, undefined, true, undefined, this) : mentionsMode ? /* @__PURE__ */ jsxDEV25(Fragment2, {
7817
8414
  children: [
7818
- /* @__PURE__ */ jsxDEV23("box", {
8415
+ /* @__PURE__ */ jsxDEV25("box", {
7819
8416
  style: { flexDirection: "row" },
7820
8417
  children: [
7821
- /* @__PURE__ */ jsxDEV23("text", {
8418
+ /* @__PURE__ */ jsxDEV25("text", {
7822
8419
  fg: colors.dim,
7823
8420
  children: [
7824
8421
  "Mentions (",
@@ -7826,19 +8423,19 @@ function PostDetailScreen({
7826
8423
  "): "
7827
8424
  ]
7828
8425
  }, undefined, true, undefined, this),
7829
- /* @__PURE__ */ jsxDEV23("text", {
8426
+ /* @__PURE__ */ jsxDEV25("text", {
7830
8427
  fg: colors.primary,
7831
8428
  children: "j/k"
7832
8429
  }, undefined, false, undefined, this),
7833
- /* @__PURE__ */ jsxDEV23("text", {
8430
+ /* @__PURE__ */ jsxDEV25("text", {
7834
8431
  fg: colors.dim,
7835
8432
  children: " navigate "
7836
8433
  }, undefined, false, undefined, this),
7837
- /* @__PURE__ */ jsxDEV23("text", {
8434
+ /* @__PURE__ */ jsxDEV25("text", {
7838
8435
  fg: colors.primary,
7839
8436
  children: "Enter"
7840
8437
  }, undefined, false, undefined, this),
7841
- /* @__PURE__ */ jsxDEV23("text", {
8438
+ /* @__PURE__ */ jsxDEV25("text", {
7842
8439
  fg: colors.dim,
7843
8440
  children: "/click profile"
7844
8441
  }, undefined, false, undefined, this)
@@ -7846,11 +8443,11 @@ function PostDetailScreen({
7846
8443
  }, undefined, true, undefined, this),
7847
8444
  tweet.mentions?.map((mention, idx) => {
7848
8445
  const isSelected = idx === mentionIndex;
7849
- return /* @__PURE__ */ jsxDEV23("box", {
8446
+ return /* @__PURE__ */ jsxDEV25("box", {
7850
8447
  style: { flexDirection: "row", marginTop: idx === 0 ? 1 : 0 },
7851
8448
  onMouse: handleMentionRowClick(mention.username),
7852
8449
  children: [
7853
- /* @__PURE__ */ jsxDEV23("text", {
8450
+ /* @__PURE__ */ jsxDEV25("text", {
7854
8451
  fg: isSelected ? colors.mention : colors.muted,
7855
8452
  children: [
7856
8453
  isSelected ? ">" : " ",
@@ -7858,7 +8455,7 @@ function PostDetailScreen({
7858
8455
  mention.username
7859
8456
  ]
7860
8457
  }, undefined, true, undefined, this),
7861
- mention.name && /* @__PURE__ */ jsxDEV23("text", {
8458
+ mention.name && /* @__PURE__ */ jsxDEV25("text", {
7862
8459
  fg: colors.dim,
7863
8460
  children: [
7864
8461
  " \xB7 ",
@@ -7869,7 +8466,7 @@ function PostDetailScreen({
7869
8466
  }, mention.username, true, undefined, this);
7870
8467
  })
7871
8468
  ]
7872
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV23("box", {
8469
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV25("box", {
7873
8470
  style: { flexDirection: "row" },
7874
8471
  onMouse: (event) => {
7875
8472
  if (event.type === "up" && event.button === 0) {
@@ -7878,18 +8475,18 @@ function PostDetailScreen({
7878
8475
  }
7879
8476
  },
7880
8477
  children: [
7881
- /* @__PURE__ */ jsxDEV23("text", {
8478
+ /* @__PURE__ */ jsxDEV25("text", {
7882
8479
  fg: colors.dim,
7883
8480
  children: "Mentions: "
7884
8481
  }, undefined, false, undefined, this),
7885
- /* @__PURE__ */ jsxDEV23("text", {
8482
+ /* @__PURE__ */ jsxDEV25("text", {
7886
8483
  fg: colors.mention,
7887
8484
  children: [
7888
8485
  "@",
7889
8486
  firstMention?.username
7890
8487
  ]
7891
8488
  }, undefined, true, undefined, this),
7892
- /* @__PURE__ */ jsxDEV23("text", {
8489
+ /* @__PURE__ */ jsxDEV25("text", {
7893
8490
  fg: colors.dim,
7894
8491
  children: [
7895
8492
  " +",
@@ -7897,11 +8494,11 @@ function PostDetailScreen({
7897
8494
  " more ("
7898
8495
  ]
7899
8496
  }, undefined, true, undefined, this),
7900
- /* @__PURE__ */ jsxDEV23("text", {
8497
+ /* @__PURE__ */ jsxDEV25("text", {
7901
8498
  fg: colors.primary,
7902
8499
  children: "m"
7903
8500
  }, undefined, false, undefined, this),
7904
- /* @__PURE__ */ jsxDEV23("text", {
8501
+ /* @__PURE__ */ jsxDEV25("text", {
7905
8502
  fg: colors.dim,
7906
8503
  children: "/click)"
7907
8504
  }, undefined, false, undefined, this)
@@ -7909,21 +8506,21 @@ function PostDetailScreen({
7909
8506
  }, undefined, true, undefined, this)
7910
8507
  }, undefined, false, undefined, this)
7911
8508
  }, undefined, false, undefined, this) : null;
7912
- const repliesContent = /* @__PURE__ */ jsxDEV23("box", {
8509
+ const repliesContent = /* @__PURE__ */ jsxDEV25("box", {
7913
8510
  style: { marginTop: 1, paddingLeft: 1, paddingRight: 1 },
7914
- children: /* @__PURE__ */ jsxDEV23("box", {
8511
+ children: /* @__PURE__ */ jsxDEV25("box", {
7915
8512
  style: { flexDirection: "column" },
7916
8513
  children: [
7917
- /* @__PURE__ */ jsxDEV23("box", {
8514
+ /* @__PURE__ */ jsxDEV25("box", {
7918
8515
  style: { flexDirection: "row" },
7919
8516
  children: [
7920
- /* @__PURE__ */ jsxDEV23("text", {
8517
+ /* @__PURE__ */ jsxDEV25("text", {
7921
8518
  fg: "#ffffff",
7922
8519
  children: "Replies"
7923
8520
  }, undefined, false, undefined, this),
7924
- hasReplies && /* @__PURE__ */ jsxDEV23(Fragment, {
8521
+ hasReplies && /* @__PURE__ */ jsxDEV25(Fragment2, {
7925
8522
  children: [
7926
- /* @__PURE__ */ jsxDEV23("text", {
8523
+ /* @__PURE__ */ jsxDEV25("text", {
7927
8524
  fg: colors.dim,
7928
8525
  children: [
7929
8526
  " ",
@@ -7934,13 +8531,13 @@ function PostDetailScreen({
7934
8531
  " "
7935
8532
  ]
7936
8533
  }, undefined, true, undefined, this),
7937
- !repliesMode && /* @__PURE__ */ jsxDEV23(Fragment, {
8534
+ !repliesMode && /* @__PURE__ */ jsxDEV25(Fragment2, {
7938
8535
  children: [
7939
- /* @__PURE__ */ jsxDEV23("text", {
8536
+ /* @__PURE__ */ jsxDEV25("text", {
7940
8537
  fg: colors.primary,
7941
8538
  children: "r"
7942
8539
  }, undefined, false, undefined, this),
7943
- /* @__PURE__ */ jsxDEV23("text", {
8540
+ /* @__PURE__ */ jsxDEV25("text", {
7944
8541
  fg: colors.dim,
7945
8542
  children: " to navigate"
7946
8543
  }, undefined, false, undefined, this)
@@ -7950,17 +8547,17 @@ function PostDetailScreen({
7950
8547
  }, undefined, true, undefined, this)
7951
8548
  ]
7952
8549
  }, undefined, true, undefined, this),
7953
- loadingReplies ? /* @__PURE__ */ jsxDEV23("box", {
7954
- children: /* @__PURE__ */ jsxDEV23("text", {
8550
+ loadingReplies ? /* @__PURE__ */ jsxDEV25("box", {
8551
+ children: /* @__PURE__ */ jsxDEV25("text", {
7955
8552
  fg: colors.dim,
7956
8553
  children: "Loading replies..."
7957
8554
  }, undefined, false, undefined, this)
7958
- }, undefined, false, undefined, this) : hasReplies ? /* @__PURE__ */ jsxDEV23("box", {
8555
+ }, undefined, false, undefined, this) : hasReplies ? /* @__PURE__ */ jsxDEV25("box", {
7959
8556
  style: { flexDirection: "column" },
7960
8557
  children: [
7961
8558
  replies.map((reply, idx) => {
7962
8559
  const state = getActionState?.(reply.id);
7963
- return /* @__PURE__ */ jsxDEV23(PostCard, {
8560
+ return /* @__PURE__ */ jsxDEV25(PostCard, {
7964
8561
  id: getReplyCardId(reply.id),
7965
8562
  post: reply,
7966
8563
  isSelected: repliesMode && idx === selectedReplyIndex,
@@ -7970,16 +8567,16 @@ function PostDetailScreen({
7970
8567
  mainPostAuthorUsername: tweet.author.username
7971
8568
  }, reply.id, false, undefined, this);
7972
8569
  }),
7973
- loadingMoreReplies && /* @__PURE__ */ jsxDEV23("box", {
8570
+ loadingMoreReplies && /* @__PURE__ */ jsxDEV25("box", {
7974
8571
  style: { paddingTop: 1 },
7975
- children: /* @__PURE__ */ jsxDEV23("text", {
8572
+ children: /* @__PURE__ */ jsxDEV25("text", {
7976
8573
  fg: colors.dim,
7977
8574
  children: "Loading more replies..."
7978
8575
  }, undefined, false, undefined, this)
7979
8576
  }, undefined, false, undefined, this)
7980
8577
  ]
7981
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV23("box", {
7982
- children: /* @__PURE__ */ jsxDEV23("text", {
8578
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV25("box", {
8579
+ children: /* @__PURE__ */ jsxDEV25("text", {
7983
8580
  fg: colors.dim,
7984
8581
  children: "No replies yet"
7985
8582
  }, undefined, false, undefined, this)
@@ -7989,9 +8586,9 @@ function PostDetailScreen({
7989
8586
  }, undefined, false, undefined, this);
7990
8587
  const displayMessage = statusMessage;
7991
8588
  const isError = displayMessage?.startsWith("Error:");
7992
- const statusContent = displayMessage ? /* @__PURE__ */ jsxDEV23("box", {
8589
+ const statusContent = displayMessage ? /* @__PURE__ */ jsxDEV25("box", {
7993
8590
  style: { marginTop: 1, paddingLeft: 1, paddingRight: 1 },
7994
- children: /* @__PURE__ */ jsxDEV23("text", {
8591
+ children: /* @__PURE__ */ jsxDEV25("text", {
7995
8592
  fg: isError ? colors.error : colors.success,
7996
8593
  children: displayMessage
7997
8594
  }, undefined, false, undefined, this)
@@ -8043,18 +8640,24 @@ function PostDetailScreen({
8043
8640
  activeColor: isLoadingQuote ? colors.primary : undefined,
8044
8641
  show: hasQuote
8045
8642
  },
8046
- { key: "f", label: "folder", show: isBookmarked }
8643
+ { key: "f", label: "folder", show: isBookmarked },
8644
+ {
8645
+ key: "a",
8646
+ label: annotationText ? "edit note" : "annotate",
8647
+ show: isBookmarked
8648
+ }
8047
8649
  ];
8048
- return /* @__PURE__ */ jsxDEV23("box", {
8650
+ return /* @__PURE__ */ jsxDEV25("box", {
8049
8651
  style: { flexDirection: "column", height: "100%" },
8050
8652
  children: [
8051
8653
  headerContent,
8052
- /* @__PURE__ */ jsxDEV23("scrollbox", {
8654
+ /* @__PURE__ */ jsxDEV25("scrollbox", {
8053
8655
  ref: scrollRef,
8054
8656
  focused: focused && !repliesMode,
8055
8657
  style: { flexGrow: 1, height: "100%" },
8056
8658
  children: [
8057
8659
  parentContent,
8660
+ annotationContent,
8058
8661
  authorContent,
8059
8662
  postContent,
8060
8663
  truncationIndicator,
@@ -8067,7 +8670,7 @@ function PostDetailScreen({
8067
8670
  ]
8068
8671
  }, undefined, true, undefined, this),
8069
8672
  statusContent,
8070
- /* @__PURE__ */ jsxDEV23(Footer, {
8673
+ /* @__PURE__ */ jsxDEV25(Footer, {
8071
8674
  bindings: footerBindings,
8072
8675
  visible: showFooter
8073
8676
  }, undefined, false, undefined, this)
@@ -8077,9 +8680,9 @@ function PostDetailScreen({
8077
8680
 
8078
8681
  // src/screens/ProfileScreen.tsx
8079
8682
  import { useKeyboard as useKeyboard9 } from "@opentui/react";
8080
- import { useState as useState21, useCallback as useCallback14, useEffect as useEffect18, useMemo as useMemo8 } from "react";
8683
+ import { useState as useState26, useCallback as useCallback15, useEffect as useEffect20, useMemo as useMemo8 } from "react";
8081
8684
  init_media();
8082
- import { jsxDEV as jsxDEV24, Fragment as Fragment2 } from "@opentui/react/jsx-dev-runtime";
8685
+ import { jsxDEV as jsxDEV26, Fragment as Fragment3 } from "@opentui/react/jsx-dev-runtime";
8083
8686
  var PROFILE_TABS = [
8084
8687
  { key: "tweets", label: "Tweets" },
8085
8688
  { key: "highlights", label: "Highlights" },
@@ -8160,9 +8763,9 @@ function ProfileScreen({
8160
8763
  client,
8161
8764
  username
8162
8765
  });
8163
- const [isFollowing, setIsFollowing] = useState21(false);
8164
- const [isMuting, setIsMuting] = useState21(false);
8165
- useEffect18(() => {
8766
+ const [isFollowing, setIsFollowing] = useState26(false);
8767
+ const [isMuting, setIsMuting] = useState26(false);
8768
+ useEffect20(() => {
8166
8769
  if (user) {
8167
8770
  setIsFollowing(user.following ?? false);
8168
8771
  setIsMuting(user.muting ?? false);
@@ -8171,12 +8774,13 @@ function ProfileScreen({
8171
8774
  const availableTabs = useMemo8(() => {
8172
8775
  return PROFILE_TABS.filter((tab) => tab.key !== "likes" || isSelf);
8173
8776
  }, [isSelf]);
8174
- const [activeTab, setActiveTab] = useState21("tweets");
8777
+ const [activeTab, setActiveTab] = useState26("tweets");
8778
+ const [refreshKey, setRefreshKey] = useState26(0);
8175
8779
  const activeTabIndex = useMemo8(() => availableTabs.findIndex((t) => t.key === activeTab), [availableTabs, activeTab]);
8176
- const [isCollapsed, setIsCollapsed] = useState21(false);
8177
- const [mentionsMode, setMentionsMode] = useState21(false);
8178
- const [mentionIndex, setMentionIndex] = useState21(0);
8179
- useEffect18(() => {
8780
+ const [isCollapsed, setIsCollapsed] = useState26(false);
8781
+ const [mentionsMode, setMentionsMode] = useState26(false);
8782
+ const [mentionIndex, setMentionIndex] = useState26(0);
8783
+ useEffect20(() => {
8180
8784
  switch (activeTab) {
8181
8785
  case "replies":
8182
8786
  if (!repliesFetched && !isRepliesLoading) {
@@ -8215,7 +8819,7 @@ function ProfileScreen({
8215
8819
  isLikesLoading,
8216
8820
  fetchLikes
8217
8821
  ]);
8218
- useEffect18(() => {
8822
+ useEffect20(() => {
8219
8823
  setIsCollapsed(false);
8220
8824
  setActiveTab("tweets");
8221
8825
  setMentionsMode(false);
@@ -8225,7 +8829,7 @@ function ProfileScreen({
8225
8829
  const hasMentions = bioMentions.length > 0;
8226
8830
  const mentionCount = bioMentions.length;
8227
8831
  const currentMention = hasMentions ? bioMentions[mentionIndex] : undefined;
8228
- const handleSelectedIndexChange = useCallback14((index) => {
8832
+ const handleSelectedIndexChange = useCallback15((index) => {
8229
8833
  setIsCollapsed(index > 0);
8230
8834
  }, []);
8231
8835
  useKeyboard9((key) => {
@@ -8263,6 +8867,7 @@ function ProfileScreen({
8263
8867
  break;
8264
8868
  case "r":
8265
8869
  refresh();
8870
+ setRefreshKey((k) => k + 1);
8266
8871
  break;
8267
8872
  case "a":
8268
8873
  if (user?.profileImageUrl) {
@@ -8344,7 +8949,7 @@ function ProfileScreen({
8344
8949
  break;
8345
8950
  }
8346
8951
  });
8347
- const compactHeader = user && /* @__PURE__ */ jsxDEV24("box", {
8952
+ const compactHeader = user && /* @__PURE__ */ jsxDEV26("box", {
8348
8953
  style: {
8349
8954
  flexShrink: 0,
8350
8955
  paddingLeft: 1,
@@ -8352,55 +8957,55 @@ function ProfileScreen({
8352
8957
  flexDirection: "row"
8353
8958
  },
8354
8959
  children: [
8355
- /* @__PURE__ */ jsxDEV24("text", {
8960
+ /* @__PURE__ */ jsxDEV26("text", {
8356
8961
  fg: colors.dim,
8357
8962
  children: mentionsMode ? "<- Back (Esc) | " : "<- "
8358
8963
  }, undefined, false, undefined, this),
8359
- mentionsMode && /* @__PURE__ */ jsxDEV24("text", {
8964
+ mentionsMode && /* @__PURE__ */ jsxDEV26("text", {
8360
8965
  fg: colors.primary,
8361
8966
  children: "Navigating mentions "
8362
8967
  }, undefined, false, undefined, this),
8363
- isSelf && /* @__PURE__ */ jsxDEV24("text", {
8968
+ isSelf && /* @__PURE__ */ jsxDEV26("text", {
8364
8969
  fg: colors.primary,
8365
8970
  children: "My Profile "
8366
8971
  }, undefined, false, undefined, this),
8367
- /* @__PURE__ */ jsxDEV24("text", {
8972
+ /* @__PURE__ */ jsxDEV26("text", {
8368
8973
  fg: "#ffffff",
8369
- children: /* @__PURE__ */ jsxDEV24("b", {
8974
+ children: /* @__PURE__ */ jsxDEV26("b", {
8370
8975
  children: user.name
8371
8976
  }, undefined, false, undefined, this)
8372
8977
  }, undefined, false, undefined, this),
8373
- user.isBlueVerified && /* @__PURE__ */ jsxDEV24("text", {
8978
+ user.isBlueVerified && /* @__PURE__ */ jsxDEV26("text", {
8374
8979
  fg: colors.primary,
8375
8980
  children: [
8376
8981
  " ",
8377
8982
  "\u2713"
8378
8983
  ]
8379
8984
  }, undefined, true, undefined, this),
8380
- /* @__PURE__ */ jsxDEV24("text", {
8985
+ /* @__PURE__ */ jsxDEV26("text", {
8381
8986
  fg: colors.muted,
8382
8987
  children: [
8383
8988
  " @",
8384
8989
  user.username
8385
8990
  ]
8386
8991
  }, undefined, true, undefined, this),
8387
- !isSelf && /* @__PURE__ */ jsxDEV24(Fragment2, {
8992
+ !isSelf && /* @__PURE__ */ jsxDEV26(Fragment3, {
8388
8993
  children: [
8389
- /* @__PURE__ */ jsxDEV24("text", {
8994
+ /* @__PURE__ */ jsxDEV26("text", {
8390
8995
  fg: colors.dim,
8391
8996
  children: " | "
8392
8997
  }, undefined, false, undefined, this),
8393
- /* @__PURE__ */ jsxDEV24("text", {
8998
+ /* @__PURE__ */ jsxDEV26("text", {
8394
8999
  fg: isFollowing ? colors.primary : colors.muted,
8395
9000
  children: userActions.isFollowPending ? "..." : isFollowing ? "Following" : "Follow"
8396
9001
  }, undefined, false, undefined, this),
8397
- isMuting && /* @__PURE__ */ jsxDEV24(Fragment2, {
9002
+ isMuting && /* @__PURE__ */ jsxDEV26(Fragment3, {
8398
9003
  children: [
8399
- /* @__PURE__ */ jsxDEV24("text", {
9004
+ /* @__PURE__ */ jsxDEV26("text", {
8400
9005
  fg: colors.dim,
8401
9006
  children: " \xB7 "
8402
9007
  }, undefined, false, undefined, this),
8403
- /* @__PURE__ */ jsxDEV24("text", {
9008
+ /* @__PURE__ */ jsxDEV26("text", {
8404
9009
  fg: colors.muted,
8405
9010
  children: "Muted"
8406
9011
  }, undefined, false, undefined, this)
@@ -8412,7 +9017,7 @@ function ProfileScreen({
8412
9017
  }, undefined, true, undefined, this);
8413
9018
  const joinDate = formatJoinDate(user?.createdAt);
8414
9019
  const websiteDomain = extractDomain2(user?.websiteUrl);
8415
- const fullHeader = user && /* @__PURE__ */ jsxDEV24("box", {
9020
+ const fullHeader = user && /* @__PURE__ */ jsxDEV26("box", {
8416
9021
  style: {
8417
9022
  flexShrink: 0,
8418
9023
  flexDirection: "column",
@@ -8421,58 +9026,58 @@ function ProfileScreen({
8421
9026
  paddingBottom: 0
8422
9027
  },
8423
9028
  children: [
8424
- /* @__PURE__ */ jsxDEV24("box", {
9029
+ /* @__PURE__ */ jsxDEV26("box", {
8425
9030
  style: { paddingLeft: 1, paddingRight: 1, flexDirection: "row" },
8426
9031
  children: [
8427
- /* @__PURE__ */ jsxDEV24("text", {
9032
+ /* @__PURE__ */ jsxDEV26("text", {
8428
9033
  fg: colors.dim,
8429
9034
  children: mentionsMode ? "<- Back (Esc) | " : "<- "
8430
9035
  }, undefined, false, undefined, this),
8431
- mentionsMode && /* @__PURE__ */ jsxDEV24("text", {
9036
+ mentionsMode && /* @__PURE__ */ jsxDEV26("text", {
8432
9037
  fg: colors.primary,
8433
9038
  children: "Navigating mentions "
8434
9039
  }, undefined, false, undefined, this),
8435
- isSelf && /* @__PURE__ */ jsxDEV24("text", {
9040
+ isSelf && /* @__PURE__ */ jsxDEV26("text", {
8436
9041
  fg: colors.primary,
8437
9042
  children: "My Profile "
8438
9043
  }, undefined, false, undefined, this),
8439
- /* @__PURE__ */ jsxDEV24("text", {
9044
+ /* @__PURE__ */ jsxDEV26("text", {
8440
9045
  fg: "#ffffff",
8441
- children: /* @__PURE__ */ jsxDEV24("b", {
9046
+ children: /* @__PURE__ */ jsxDEV26("b", {
8442
9047
  children: user.name
8443
9048
  }, undefined, false, undefined, this)
8444
9049
  }, undefined, false, undefined, this),
8445
- user.isBlueVerified && /* @__PURE__ */ jsxDEV24("text", {
9050
+ user.isBlueVerified && /* @__PURE__ */ jsxDEV26("text", {
8446
9051
  fg: colors.primary,
8447
9052
  children: [
8448
9053
  " ",
8449
9054
  "\u2713"
8450
9055
  ]
8451
9056
  }, undefined, true, undefined, this),
8452
- /* @__PURE__ */ jsxDEV24("text", {
9057
+ /* @__PURE__ */ jsxDEV26("text", {
8453
9058
  fg: colors.muted,
8454
9059
  children: [
8455
9060
  " @",
8456
9061
  user.username
8457
9062
  ]
8458
9063
  }, undefined, true, undefined, this),
8459
- !isSelf && /* @__PURE__ */ jsxDEV24(Fragment2, {
9064
+ !isSelf && /* @__PURE__ */ jsxDEV26(Fragment3, {
8460
9065
  children: [
8461
- /* @__PURE__ */ jsxDEV24("text", {
9066
+ /* @__PURE__ */ jsxDEV26("text", {
8462
9067
  fg: colors.dim,
8463
9068
  children: " | "
8464
9069
  }, undefined, false, undefined, this),
8465
- /* @__PURE__ */ jsxDEV24("text", {
9070
+ /* @__PURE__ */ jsxDEV26("text", {
8466
9071
  fg: isFollowing ? colors.primary : colors.muted,
8467
9072
  children: userActions.isFollowPending ? "..." : isFollowing ? "Following" : "Follow"
8468
9073
  }, undefined, false, undefined, this),
8469
- isMuting && /* @__PURE__ */ jsxDEV24(Fragment2, {
9074
+ isMuting && /* @__PURE__ */ jsxDEV26(Fragment3, {
8470
9075
  children: [
8471
- /* @__PURE__ */ jsxDEV24("text", {
9076
+ /* @__PURE__ */ jsxDEV26("text", {
8472
9077
  fg: colors.dim,
8473
9078
  children: " \xB7 "
8474
9079
  }, undefined, false, undefined, this),
8475
- /* @__PURE__ */ jsxDEV24("text", {
9080
+ /* @__PURE__ */ jsxDEV26("text", {
8476
9081
  fg: colors.muted,
8477
9082
  children: "Muted"
8478
9083
  }, undefined, false, undefined, this)
@@ -8482,32 +9087,32 @@ function ProfileScreen({
8482
9087
  }, undefined, true, undefined, this)
8483
9088
  ]
8484
9089
  }, undefined, true, undefined, this),
8485
- user.description && /* @__PURE__ */ jsxDEV24("box", {
9090
+ user.description && /* @__PURE__ */ jsxDEV26("box", {
8486
9091
  style: { paddingLeft: 1, paddingRight: 1 },
8487
- children: hasMentions ? renderTextWithMentions(user.description.trim(), colors.primary, "#cccccc") : /* @__PURE__ */ jsxDEV24("text", {
9092
+ children: hasMentions ? renderTextWithMentions(user.description.trim(), colors.primary, "#cccccc") : /* @__PURE__ */ jsxDEV26("text", {
8488
9093
  fg: "#cccccc",
8489
9094
  children: user.description.trim()
8490
9095
  }, undefined, false, undefined, this)
8491
9096
  }, undefined, false, undefined, this),
8492
- (user.location || websiteDomain || joinDate) && /* @__PURE__ */ jsxDEV24("box", {
9097
+ (user.location || websiteDomain || joinDate) && /* @__PURE__ */ jsxDEV26("box", {
8493
9098
  style: { paddingLeft: 1, paddingRight: 1, flexDirection: "row" },
8494
9099
  children: [
8495
- user.location && /* @__PURE__ */ jsxDEV24(Fragment2, {
9100
+ user.location && /* @__PURE__ */ jsxDEV26(Fragment3, {
8496
9101
  children: [
8497
- /* @__PURE__ */ jsxDEV24("text", {
9102
+ /* @__PURE__ */ jsxDEV26("text", {
8498
9103
  fg: colors.muted,
8499
9104
  children: [
8500
9105
  "\uD83D\uDCCD",
8501
9106
  " "
8502
9107
  ]
8503
9108
  }, undefined, true, undefined, this),
8504
- /* @__PURE__ */ jsxDEV24("text", {
9109
+ /* @__PURE__ */ jsxDEV26("text", {
8505
9110
  fg: "#aaaaaa",
8506
9111
  children: user.location
8507
9112
  }, undefined, false, undefined, this)
8508
9113
  ]
8509
9114
  }, undefined, true, undefined, this),
8510
- user.location && websiteDomain && /* @__PURE__ */ jsxDEV24("text", {
9115
+ user.location && websiteDomain && /* @__PURE__ */ jsxDEV26("text", {
8511
9116
  fg: colors.dim,
8512
9117
  children: [
8513
9118
  " ",
@@ -8515,22 +9120,22 @@ function ProfileScreen({
8515
9120
  " "
8516
9121
  ]
8517
9122
  }, undefined, true, undefined, this),
8518
- websiteDomain && /* @__PURE__ */ jsxDEV24(Fragment2, {
9123
+ websiteDomain && /* @__PURE__ */ jsxDEV26(Fragment3, {
8519
9124
  children: [
8520
- /* @__PURE__ */ jsxDEV24("text", {
9125
+ /* @__PURE__ */ jsxDEV26("text", {
8521
9126
  fg: colors.muted,
8522
9127
  children: [
8523
9128
  "\uD83D\uDD17",
8524
9129
  " "
8525
9130
  ]
8526
9131
  }, undefined, true, undefined, this),
8527
- /* @__PURE__ */ jsxDEV24("text", {
9132
+ /* @__PURE__ */ jsxDEV26("text", {
8528
9133
  fg: colors.primary,
8529
9134
  children: websiteDomain
8530
9135
  }, undefined, false, undefined, this)
8531
9136
  ]
8532
9137
  }, undefined, true, undefined, this),
8533
- (user.location || websiteDomain) && joinDate && /* @__PURE__ */ jsxDEV24("text", {
9138
+ (user.location || websiteDomain) && joinDate && /* @__PURE__ */ jsxDEV26("text", {
8534
9139
  fg: colors.dim,
8535
9140
  children: [
8536
9141
  " ",
@@ -8538,16 +9143,16 @@ function ProfileScreen({
8538
9143
  " "
8539
9144
  ]
8540
9145
  }, undefined, true, undefined, this),
8541
- joinDate && /* @__PURE__ */ jsxDEV24(Fragment2, {
9146
+ joinDate && /* @__PURE__ */ jsxDEV26(Fragment3, {
8542
9147
  children: [
8543
- /* @__PURE__ */ jsxDEV24("text", {
9148
+ /* @__PURE__ */ jsxDEV26("text", {
8544
9149
  fg: colors.muted,
8545
9150
  children: [
8546
9151
  "\uD83D\uDCC5",
8547
9152
  " "
8548
9153
  ]
8549
9154
  }, undefined, true, undefined, this),
8550
- /* @__PURE__ */ jsxDEV24("text", {
9155
+ /* @__PURE__ */ jsxDEV26("text", {
8551
9156
  fg: "#aaaaaa",
8552
9157
  children: joinDate
8553
9158
  }, undefined, false, undefined, this)
@@ -8555,69 +9160,69 @@ function ProfileScreen({
8555
9160
  }, undefined, true, undefined, this)
8556
9161
  ]
8557
9162
  }, undefined, true, undefined, this),
8558
- /* @__PURE__ */ jsxDEV24("box", {
9163
+ /* @__PURE__ */ jsxDEV26("box", {
8559
9164
  style: { paddingLeft: 1, paddingRight: 1, flexDirection: "row" },
8560
9165
  children: [
8561
- /* @__PURE__ */ jsxDEV24("text", {
9166
+ /* @__PURE__ */ jsxDEV26("text", {
8562
9167
  fg: "#ffffff",
8563
9168
  children: formatCount(user.followersCount)
8564
9169
  }, undefined, false, undefined, this),
8565
- /* @__PURE__ */ jsxDEV24("text", {
9170
+ /* @__PURE__ */ jsxDEV26("text", {
8566
9171
  fg: colors.muted,
8567
9172
  children: " Followers "
8568
9173
  }, undefined, false, undefined, this),
8569
- /* @__PURE__ */ jsxDEV24("text", {
9174
+ /* @__PURE__ */ jsxDEV26("text", {
8570
9175
  fg: colors.dim,
8571
9176
  children: [
8572
9177
  "\xB7",
8573
9178
  " "
8574
9179
  ]
8575
9180
  }, undefined, true, undefined, this),
8576
- /* @__PURE__ */ jsxDEV24("text", {
9181
+ /* @__PURE__ */ jsxDEV26("text", {
8577
9182
  fg: "#ffffff",
8578
9183
  children: formatCount(user.followingCount)
8579
9184
  }, undefined, false, undefined, this),
8580
- /* @__PURE__ */ jsxDEV24("text", {
9185
+ /* @__PURE__ */ jsxDEV26("text", {
8581
9186
  fg: colors.muted,
8582
9187
  children: " Following"
8583
9188
  }, undefined, false, undefined, this)
8584
9189
  ]
8585
9190
  }, undefined, true, undefined, this),
8586
- hasMentions && /* @__PURE__ */ jsxDEV24("box", {
9191
+ hasMentions && /* @__PURE__ */ jsxDEV26("box", {
8587
9192
  style: { paddingLeft: 1, paddingRight: 1, flexDirection: "column" },
8588
- children: mentionCount === 1 ? /* @__PURE__ */ jsxDEV24("box", {
9193
+ children: mentionCount === 1 ? /* @__PURE__ */ jsxDEV26("box", {
8589
9194
  style: { flexDirection: "row" },
8590
9195
  children: [
8591
- /* @__PURE__ */ jsxDEV24("text", {
9196
+ /* @__PURE__ */ jsxDEV26("text", {
8592
9197
  fg: colors.dim,
8593
9198
  children: "Mentions: "
8594
9199
  }, undefined, false, undefined, this),
8595
- /* @__PURE__ */ jsxDEV24("text", {
9200
+ /* @__PURE__ */ jsxDEV26("text", {
8596
9201
  fg: colors.primary,
8597
9202
  children: [
8598
9203
  "@",
8599
9204
  bioMentions[0]
8600
9205
  ]
8601
9206
  }, undefined, true, undefined, this),
8602
- /* @__PURE__ */ jsxDEV24("text", {
9207
+ /* @__PURE__ */ jsxDEV26("text", {
8603
9208
  fg: colors.dim,
8604
9209
  children: " ("
8605
9210
  }, undefined, false, undefined, this),
8606
- /* @__PURE__ */ jsxDEV24("text", {
9211
+ /* @__PURE__ */ jsxDEV26("text", {
8607
9212
  fg: colors.primary,
8608
9213
  children: "p"
8609
9214
  }, undefined, false, undefined, this),
8610
- /* @__PURE__ */ jsxDEV24("text", {
9215
+ /* @__PURE__ */ jsxDEV26("text", {
8611
9216
  fg: colors.dim,
8612
9217
  children: " profile)"
8613
9218
  }, undefined, false, undefined, this)
8614
9219
  ]
8615
- }, undefined, true, undefined, this) : mentionsMode ? /* @__PURE__ */ jsxDEV24(Fragment2, {
9220
+ }, undefined, true, undefined, this) : mentionsMode ? /* @__PURE__ */ jsxDEV26(Fragment3, {
8616
9221
  children: [
8617
- /* @__PURE__ */ jsxDEV24("box", {
9222
+ /* @__PURE__ */ jsxDEV26("box", {
8618
9223
  style: { flexDirection: "row" },
8619
9224
  children: [
8620
- /* @__PURE__ */ jsxDEV24("text", {
9225
+ /* @__PURE__ */ jsxDEV26("text", {
8621
9226
  fg: colors.dim,
8622
9227
  children: [
8623
9228
  "Mentions (",
@@ -8625,19 +9230,19 @@ function ProfileScreen({
8625
9230
  "): "
8626
9231
  ]
8627
9232
  }, undefined, true, undefined, this),
8628
- /* @__PURE__ */ jsxDEV24("text", {
9233
+ /* @__PURE__ */ jsxDEV26("text", {
8629
9234
  fg: colors.primary,
8630
9235
  children: "j/k"
8631
9236
  }, undefined, false, undefined, this),
8632
- /* @__PURE__ */ jsxDEV24("text", {
9237
+ /* @__PURE__ */ jsxDEV26("text", {
8633
9238
  fg: colors.dim,
8634
9239
  children: " navigate "
8635
9240
  }, undefined, false, undefined, this),
8636
- /* @__PURE__ */ jsxDEV24("text", {
9241
+ /* @__PURE__ */ jsxDEV26("text", {
8637
9242
  fg: colors.primary,
8638
9243
  children: "Enter"
8639
9244
  }, undefined, false, undefined, this),
8640
- /* @__PURE__ */ jsxDEV24("text", {
9245
+ /* @__PURE__ */ jsxDEV26("text", {
8641
9246
  fg: colors.dim,
8642
9247
  children: " profile"
8643
9248
  }, undefined, false, undefined, this)
@@ -8645,9 +9250,9 @@ function ProfileScreen({
8645
9250
  }, undefined, true, undefined, this),
8646
9251
  bioMentions.map((mention, idx) => {
8647
9252
  const isSelected = idx === mentionIndex;
8648
- return /* @__PURE__ */ jsxDEV24("box", {
9253
+ return /* @__PURE__ */ jsxDEV26("box", {
8649
9254
  style: { flexDirection: "row" },
8650
- children: /* @__PURE__ */ jsxDEV24("text", {
9255
+ children: /* @__PURE__ */ jsxDEV26("text", {
8651
9256
  fg: isSelected ? colors.primary : colors.muted,
8652
9257
  children: [
8653
9258
  isSelected ? ">" : " ",
@@ -8658,21 +9263,21 @@ function ProfileScreen({
8658
9263
  }, mention, false, undefined, this);
8659
9264
  })
8660
9265
  ]
8661
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV24("box", {
9266
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV26("box", {
8662
9267
  style: { flexDirection: "row" },
8663
9268
  children: [
8664
- /* @__PURE__ */ jsxDEV24("text", {
9269
+ /* @__PURE__ */ jsxDEV26("text", {
8665
9270
  fg: colors.dim,
8666
9271
  children: "Mentions: "
8667
9272
  }, undefined, false, undefined, this),
8668
- /* @__PURE__ */ jsxDEV24("text", {
9273
+ /* @__PURE__ */ jsxDEV26("text", {
8669
9274
  fg: colors.primary,
8670
9275
  children: [
8671
9276
  "@",
8672
9277
  bioMentions[0]
8673
9278
  ]
8674
9279
  }, undefined, true, undefined, this),
8675
- /* @__PURE__ */ jsxDEV24("text", {
9280
+ /* @__PURE__ */ jsxDEV26("text", {
8676
9281
  fg: colors.dim,
8677
9282
  children: [
8678
9283
  " +",
@@ -8680,11 +9285,11 @@ function ProfileScreen({
8680
9285
  " more ("
8681
9286
  ]
8682
9287
  }, undefined, true, undefined, this),
8683
- /* @__PURE__ */ jsxDEV24("text", {
9288
+ /* @__PURE__ */ jsxDEV26("text", {
8684
9289
  fg: colors.primary,
8685
9290
  children: "p"
8686
9291
  }, undefined, false, undefined, this),
8687
- /* @__PURE__ */ jsxDEV24("text", {
9292
+ /* @__PURE__ */ jsxDEV26("text", {
8688
9293
  fg: colors.dim,
8689
9294
  children: " to navigate)"
8690
9295
  }, undefined, false, undefined, this)
@@ -8707,7 +9312,7 @@ function ProfileScreen({
8707
9312
  return false;
8708
9313
  }
8709
9314
  })();
8710
- const tabBar = /* @__PURE__ */ jsxDEV24("box", {
9315
+ const tabBar = /* @__PURE__ */ jsxDEV26("box", {
8711
9316
  style: {
8712
9317
  paddingLeft: 1,
8713
9318
  paddingRight: 1,
@@ -8715,12 +9320,12 @@ function ProfileScreen({
8715
9320
  flexDirection: "row"
8716
9321
  },
8717
9322
  children: [
8718
- availableTabs.map((tab, idx) => /* @__PURE__ */ jsxDEV24("box", {
9323
+ availableTabs.map((tab, idx) => /* @__PURE__ */ jsxDEV26("box", {
8719
9324
  style: { flexDirection: "row" },
8720
9325
  children: [
8721
- /* @__PURE__ */ jsxDEV24("text", {
9326
+ /* @__PURE__ */ jsxDEV26("text", {
8722
9327
  fg: activeTab === tab.key ? colors.primary : colors.dim,
8723
- children: activeTab === tab.key ? /* @__PURE__ */ jsxDEV24("b", {
9328
+ children: activeTab === tab.key ? /* @__PURE__ */ jsxDEV26("b", {
8724
9329
  children: [
8725
9330
  "[",
8726
9331
  idx + 1,
@@ -8729,19 +9334,19 @@ function ProfileScreen({
8729
9334
  ]
8730
9335
  }, undefined, true, undefined, this) : ` ${idx + 1} ${tab.label}`
8731
9336
  }, undefined, false, undefined, this),
8732
- idx < availableTabs.length - 1 && /* @__PURE__ */ jsxDEV24("text", {
9337
+ idx < availableTabs.length - 1 && /* @__PURE__ */ jsxDEV26("text", {
8733
9338
  fg: colors.dim,
8734
9339
  children: " | "
8735
9340
  }, undefined, false, undefined, this)
8736
9341
  ]
8737
9342
  }, tab.key, true, undefined, this)),
8738
- isCurrentTabLoading && /* @__PURE__ */ jsxDEV24("text", {
9343
+ isCurrentTabLoading && /* @__PURE__ */ jsxDEV26("text", {
8739
9344
  fg: colors.muted,
8740
9345
  children: " (loading...)"
8741
9346
  }, undefined, false, undefined, this)
8742
9347
  ]
8743
9348
  }, undefined, true, undefined, this);
8744
- const separator = /* @__PURE__ */ jsxDEV24("box", {
9349
+ const separator = /* @__PURE__ */ jsxDEV26("box", {
8745
9350
  style: {
8746
9351
  paddingLeft: 1,
8747
9352
  paddingRight: 1,
@@ -8751,7 +9356,7 @@ function ProfileScreen({
8751
9356
  paddingTop: 0,
8752
9357
  paddingBottom: 0
8753
9358
  },
8754
- children: /* @__PURE__ */ jsxDEV24("text", {
9359
+ children: /* @__PURE__ */ jsxDEV26("text", {
8755
9360
  fg: "#444444",
8756
9361
  children: "\u2500".repeat(50)
8757
9362
  }, undefined, false, undefined, this)
@@ -8814,16 +9419,16 @@ function ProfileScreen({
8814
9419
  { key: "r", label: "refresh" }
8815
9420
  ];
8816
9421
  if (isLoading) {
8817
- return /* @__PURE__ */ jsxDEV24("box", {
9422
+ return /* @__PURE__ */ jsxDEV26("box", {
8818
9423
  style: { flexDirection: "column", height: "100%" },
8819
- children: /* @__PURE__ */ jsxDEV24("box", {
9424
+ children: /* @__PURE__ */ jsxDEV26("box", {
8820
9425
  style: { padding: 1, flexDirection: "row" },
8821
9426
  children: [
8822
- /* @__PURE__ */ jsxDEV24("text", {
9427
+ /* @__PURE__ */ jsxDEV26("text", {
8823
9428
  fg: colors.dim,
8824
9429
  children: "<- "
8825
9430
  }, undefined, false, undefined, this),
8826
- /* @__PURE__ */ jsxDEV24("text", {
9431
+ /* @__PURE__ */ jsxDEV26("text", {
8827
9432
  fg: colors.muted,
8828
9433
  children: "Loading profile..."
8829
9434
  }, undefined, false, undefined, this)
@@ -8832,16 +9437,16 @@ function ProfileScreen({
8832
9437
  }, undefined, false, undefined, this);
8833
9438
  }
8834
9439
  if (error) {
8835
- return /* @__PURE__ */ jsxDEV24("box", {
9440
+ return /* @__PURE__ */ jsxDEV26("box", {
8836
9441
  style: { flexDirection: "column", height: "100%" },
8837
- children: /* @__PURE__ */ jsxDEV24("box", {
9442
+ children: /* @__PURE__ */ jsxDEV26("box", {
8838
9443
  style: { padding: 1, flexDirection: "row" },
8839
9444
  children: [
8840
- /* @__PURE__ */ jsxDEV24("text", {
9445
+ /* @__PURE__ */ jsxDEV26("text", {
8841
9446
  fg: colors.dim,
8842
9447
  children: "<- "
8843
9448
  }, undefined, false, undefined, this),
8844
- /* @__PURE__ */ jsxDEV24("text", {
9449
+ /* @__PURE__ */ jsxDEV26("text", {
8845
9450
  fg: "#ff6666",
8846
9451
  children: [
8847
9452
  "Error: ",
@@ -8853,16 +9458,16 @@ function ProfileScreen({
8853
9458
  }, undefined, false, undefined, this);
8854
9459
  }
8855
9460
  if (!user) {
8856
- return /* @__PURE__ */ jsxDEV24("box", {
9461
+ return /* @__PURE__ */ jsxDEV26("box", {
8857
9462
  style: { flexDirection: "column", height: "100%" },
8858
- children: /* @__PURE__ */ jsxDEV24("box", {
9463
+ children: /* @__PURE__ */ jsxDEV26("box", {
8859
9464
  style: { padding: 1, flexDirection: "row" },
8860
9465
  children: [
8861
- /* @__PURE__ */ jsxDEV24("text", {
9466
+ /* @__PURE__ */ jsxDEV26("text", {
8862
9467
  fg: colors.dim,
8863
9468
  children: "<- "
8864
9469
  }, undefined, false, undefined, this),
8865
- /* @__PURE__ */ jsxDEV24("text", {
9470
+ /* @__PURE__ */ jsxDEV26("text", {
8866
9471
  fg: colors.muted,
8867
9472
  children: "User not found"
8868
9473
  }, undefined, false, undefined, this)
@@ -8886,22 +9491,22 @@ function ProfileScreen({
8886
9491
  return "No content to display";
8887
9492
  }
8888
9493
  })();
8889
- return /* @__PURE__ */ jsxDEV24("box", {
9494
+ return /* @__PURE__ */ jsxDEV26("box", {
8890
9495
  style: { flexDirection: "column", height: "100%" },
8891
9496
  children: [
8892
9497
  isCollapsed ? compactHeader : fullHeader,
8893
9498
  tabBar,
8894
9499
  separator,
8895
- displayError ? /* @__PURE__ */ jsxDEV24("box", {
9500
+ displayError ? /* @__PURE__ */ jsxDEV26("box", {
8896
9501
  style: { padding: 1, flexGrow: 1 },
8897
- children: /* @__PURE__ */ jsxDEV24("text", {
9502
+ children: /* @__PURE__ */ jsxDEV26("text", {
8898
9503
  fg: "#ff6666",
8899
9504
  children: [
8900
9505
  "Error: ",
8901
9506
  displayError
8902
9507
  ]
8903
9508
  }, undefined, true, undefined, this)
8904
- }, undefined, false, undefined, this) : displayPosts.length > 0 ? /* @__PURE__ */ jsxDEV24(PostList, {
9509
+ }, undefined, false, undefined, this) : displayPosts.length > 0 ? /* @__PURE__ */ jsxDEV26(PostList, {
8905
9510
  posts: displayPosts,
8906
9511
  focused,
8907
9512
  onPostSelect,
@@ -8909,15 +9514,16 @@ function ProfileScreen({
8909
9514
  onLike,
8910
9515
  onBookmark,
8911
9516
  getActionState,
8912
- initActionState
8913
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV24("box", {
9517
+ initActionState,
9518
+ refreshKey
9519
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV26("box", {
8914
9520
  style: { padding: 1, flexGrow: 1 },
8915
- children: /* @__PURE__ */ jsxDEV24("text", {
9521
+ children: /* @__PURE__ */ jsxDEV26("text", {
8916
9522
  fg: colors.muted,
8917
9523
  children: emptyMessage
8918
9524
  }, undefined, false, undefined, this)
8919
9525
  }, undefined, false, undefined, this),
8920
- /* @__PURE__ */ jsxDEV24(Footer, {
9526
+ /* @__PURE__ */ jsxDEV26(Footer, {
8921
9527
  bindings: footerBindings,
8922
9528
  visible: showFooter
8923
9529
  }, undefined, false, undefined, this)
@@ -8926,8 +9532,8 @@ function ProfileScreen({
8926
9532
  }
8927
9533
 
8928
9534
  // src/screens/SplashScreen.tsx
8929
- import { useEffect as useEffect19, useState as useState22 } from "react";
8930
- import { jsxDEV as jsxDEV25 } from "@opentui/react/jsx-dev-runtime";
9535
+ import { useEffect as useEffect21, useState as useState27 } from "react";
9536
+ import { jsxDEV as jsxDEV27 } from "@opentui/react/jsx-dev-runtime";
8931
9537
  var LOGO = [
8932
9538
  " \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 ",
8933
9539
  " \u255A\u2588\u2588\u2557\u2588\u2588\u2554\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557",
@@ -8939,14 +9545,14 @@ var LOGO = [
8939
9545
  var SPINNER_FRAMES = ["\u25E2", "\u25E3", "\u25E4", "\u25E5"];
8940
9546
  var SPINNER_INTERVAL_MS = 100;
8941
9547
  function SplashScreen() {
8942
- const [spinnerIndex, setSpinnerIndex] = useState22(0);
8943
- useEffect19(() => {
9548
+ const [spinnerIndex, setSpinnerIndex] = useState27(0);
9549
+ useEffect21(() => {
8944
9550
  const interval = setInterval(() => {
8945
9551
  setSpinnerIndex((prev) => (prev + 1) % SPINNER_FRAMES.length);
8946
9552
  }, SPINNER_INTERVAL_MS);
8947
9553
  return () => clearInterval(interval);
8948
9554
  }, []);
8949
- return /* @__PURE__ */ jsxDEV25("box", {
9555
+ return /* @__PURE__ */ jsxDEV27("box", {
8950
9556
  style: {
8951
9557
  flexDirection: "column",
8952
9558
  height: "100%",
@@ -8954,39 +9560,39 @@ function SplashScreen() {
8954
9560
  alignItems: "center"
8955
9561
  },
8956
9562
  children: [
8957
- /* @__PURE__ */ jsxDEV25("text", {
9563
+ /* @__PURE__ */ jsxDEV27("text", {
8958
9564
  fg: colors.dim,
8959
9565
  children: "\u2500".repeat(52)
8960
9566
  }, undefined, false, undefined, this),
8961
- /* @__PURE__ */ jsxDEV25("box", {
9567
+ /* @__PURE__ */ jsxDEV27("box", {
8962
9568
  style: { marginTop: 1 }
8963
9569
  }, undefined, false, undefined, this),
8964
- LOGO.map((line, i) => /* @__PURE__ */ jsxDEV25("text", {
9570
+ LOGO.map((line, i) => /* @__PURE__ */ jsxDEV27("text", {
8965
9571
  fg: "#ffffff",
8966
9572
  children: line
8967
9573
  }, i, false, undefined, this)),
8968
- /* @__PURE__ */ jsxDEV25("box", {
9574
+ /* @__PURE__ */ jsxDEV27("box", {
8969
9575
  style: { marginTop: 1 }
8970
9576
  }, undefined, false, undefined, this),
8971
- /* @__PURE__ */ jsxDEV25("text", {
9577
+ /* @__PURE__ */ jsxDEV27("text", {
8972
9578
  fg: colors.dim,
8973
9579
  children: "[terminal client for X, everything app]"
8974
9580
  }, undefined, false, undefined, this),
8975
- /* @__PURE__ */ jsxDEV25("box", {
9581
+ /* @__PURE__ */ jsxDEV27("box", {
8976
9582
  style: { marginTop: 1 }
8977
9583
  }, undefined, false, undefined, this),
8978
- /* @__PURE__ */ jsxDEV25("text", {
9584
+ /* @__PURE__ */ jsxDEV27("text", {
8979
9585
  fg: colors.dim,
8980
9586
  children: "\u2500".repeat(52)
8981
9587
  }, undefined, false, undefined, this),
8982
- /* @__PURE__ */ jsxDEV25("box", {
9588
+ /* @__PURE__ */ jsxDEV27("box", {
8983
9589
  style: { marginTop: 2, flexDirection: "row" },
8984
9590
  children: [
8985
- /* @__PURE__ */ jsxDEV25("text", {
9591
+ /* @__PURE__ */ jsxDEV27("text", {
8986
9592
  fg: "#ffffff",
8987
9593
  children: SPINNER_FRAMES[spinnerIndex]
8988
9594
  }, undefined, false, undefined, this),
8989
- /* @__PURE__ */ jsxDEV25("text", {
9595
+ /* @__PURE__ */ jsxDEV27("text", {
8990
9596
  fg: colors.dim,
8991
9597
  children: " initializing..."
8992
9598
  }, undefined, false, undefined, this)
@@ -8997,7 +9603,7 @@ function SplashScreen() {
8997
9603
  }
8998
9604
 
8999
9605
  // src/screens/ThreadScreen.tsx
9000
- import { jsxDEV as jsxDEV26 } from "@opentui/react/jsx-dev-runtime";
9606
+ import { jsxDEV as jsxDEV28 } from "@opentui/react/jsx-dev-runtime";
9001
9607
  function ThreadScreen({
9002
9608
  client,
9003
9609
  tweet,
@@ -9012,11 +9618,11 @@ function ThreadScreen({
9012
9618
  maxAncestorDepth: 10
9013
9619
  });
9014
9620
  if (loadingAncestors || loadingReplies) {
9015
- return /* @__PURE__ */ jsxDEV26("box", {
9621
+ return /* @__PURE__ */ jsxDEV28("box", {
9016
9622
  style: { flexDirection: "column", height: "100%" },
9017
- children: /* @__PURE__ */ jsxDEV26("box", {
9623
+ children: /* @__PURE__ */ jsxDEV28("box", {
9018
9624
  style: { paddingLeft: 1, paddingTop: 1 },
9019
- children: /* @__PURE__ */ jsxDEV26("text", {
9625
+ children: /* @__PURE__ */ jsxDEV28("text", {
9020
9626
  fg: colors.muted,
9021
9627
  children: [
9022
9628
  "Loading thread...",
@@ -9028,12 +9634,12 @@ function ThreadScreen({
9028
9634
  }, undefined, false, undefined, this);
9029
9635
  }
9030
9636
  if (error) {
9031
- return /* @__PURE__ */ jsxDEV26("box", {
9637
+ return /* @__PURE__ */ jsxDEV28("box", {
9032
9638
  style: { flexDirection: "column", height: "100%" },
9033
9639
  children: [
9034
- /* @__PURE__ */ jsxDEV26("box", {
9640
+ /* @__PURE__ */ jsxDEV28("box", {
9035
9641
  style: { paddingLeft: 1, paddingTop: 1 },
9036
- children: /* @__PURE__ */ jsxDEV26("text", {
9642
+ children: /* @__PURE__ */ jsxDEV28("text", {
9037
9643
  fg: colors.error,
9038
9644
  children: [
9039
9645
  "Error: ",
@@ -9041,9 +9647,9 @@ function ThreadScreen({
9041
9647
  ]
9042
9648
  }, undefined, true, undefined, this)
9043
9649
  }, undefined, false, undefined, this),
9044
- /* @__PURE__ */ jsxDEV26("box", {
9650
+ /* @__PURE__ */ jsxDEV28("box", {
9045
9651
  style: { paddingLeft: 1, paddingTop: 1 },
9046
- children: /* @__PURE__ */ jsxDEV26("text", {
9652
+ children: /* @__PURE__ */ jsxDEV28("text", {
9047
9653
  fg: colors.dim,
9048
9654
  children: "Press h or Esc to go back"
9049
9655
  }, undefined, false, undefined, this)
@@ -9051,7 +9657,7 @@ function ThreadScreen({
9051
9657
  ]
9052
9658
  }, undefined, true, undefined, this);
9053
9659
  }
9054
- return /* @__PURE__ */ jsxDEV26(ThreadViewPrototype, {
9660
+ return /* @__PURE__ */ jsxDEV28(ThreadViewPrototype, {
9055
9661
  ancestors,
9056
9662
  focusedTweet: tweet,
9057
9663
  replyTree,
@@ -9063,12 +9669,12 @@ function ThreadScreen({
9063
9669
  }
9064
9670
 
9065
9671
  // src/app.tsx
9066
- import { jsxDEV as jsxDEV27 } from "@opentui/react/jsx-dev-runtime";
9672
+ import { jsxDEV as jsxDEV29 } from "@opentui/react/jsx-dev-runtime";
9067
9673
  var SPLASH_MIN_DISPLAY_MS = 500;
9068
9674
  var MAIN_VIEWS = ["timeline", "bookmarks", "notifications"];
9069
9675
  function App({ client, user }) {
9070
- return /* @__PURE__ */ jsxDEV27(QueryProvider, {
9071
- children: /* @__PURE__ */ jsxDEV27(AppContent, {
9676
+ return /* @__PURE__ */ jsxDEV29(QueryProvider, {
9677
+ children: /* @__PURE__ */ jsxDEV29(AppContent, {
9072
9678
  client,
9073
9679
  user
9074
9680
  }, undefined, false, undefined, this)
@@ -9080,15 +9686,15 @@ function AppContent({ client, user }) {
9080
9686
  initialView: "timeline",
9081
9687
  mainViews: MAIN_VIEWS
9082
9688
  });
9083
- const [postCount, setPostCount] = useState23(0);
9084
- const [bookmarkCount, setBookmarkCount] = useState23(0);
9085
- const [bookmarkHasMore, setBookmarkHasMore] = useState23(false);
9086
- const [notificationCount, setNotificationCount] = useState23(0);
9087
- const [unreadNotificationCount, setUnreadNotificationCount] = useState23(0);
9088
- const [showFooter, setShowFooter] = useState23(true);
9689
+ const [postCount, setPostCount] = useState28(0);
9690
+ const [bookmarkCount, setBookmarkCount] = useState28(0);
9691
+ const [bookmarkHasMore, setBookmarkHasMore] = useState28(false);
9692
+ const [notificationCount, setNotificationCount] = useState28(0);
9693
+ const [unreadNotificationCount, setUnreadNotificationCount] = useState28(0);
9694
+ const [showFooter, setShowFooter] = useState28(true);
9089
9695
  const dialog = useDialog();
9090
9696
  const isDialogOpen = useDialogState((s) => s.isOpen);
9091
- useEffect20(() => {
9697
+ useEffect22(() => {
9092
9698
  const toaster = new ToasterRenderable(renderer, {
9093
9699
  position: "top-right",
9094
9700
  stackingMode: "stack",
@@ -9109,10 +9715,10 @@ function AppContent({ client, user }) {
9109
9715
  renderer.root.add(toaster);
9110
9716
  return () => toaster.destroy();
9111
9717
  }, [renderer]);
9112
- useEffect20(() => {
9718
+ useEffect22(() => {
9113
9719
  client.setOnSessionExpired(() => {
9114
9720
  dialog.alert({
9115
- content: (ctx) => /* @__PURE__ */ jsxDEV27(SessionExpiredContent, {
9721
+ content: (ctx) => /* @__PURE__ */ jsxDEV29(SessionExpiredContent, {
9116
9722
  dismiss: ctx.dismiss,
9117
9723
  dialogId: ctx.dialogId
9118
9724
  }, undefined, false, undefined, this),
@@ -9120,7 +9726,7 @@ function AppContent({ client, user }) {
9120
9726
  });
9121
9727
  });
9122
9728
  }, [client, dialog]);
9123
- const [selectedBookmarkFolder, setSelectedBookmarkFolder] = useState23(null);
9729
+ const [selectedBookmarkFolder, setSelectedBookmarkFolder] = useState28(null);
9124
9730
  const bookmarkMutation = useBookmarkMutation({
9125
9731
  client,
9126
9732
  onSuccess: (message) => toast.success(message),
@@ -9133,24 +9739,25 @@ function AppContent({ client, user }) {
9133
9739
  bookmarkMutation,
9134
9740
  currentFolderId: selectedBookmarkFolder?.id
9135
9741
  });
9136
- const [showSplash, setShowSplash] = useState23(true);
9137
- const [minTimeElapsed, setMinTimeElapsed] = useState23(false);
9138
- const initialLoadComplete = useRef12(false);
9139
- useEffect20(() => {
9742
+ const { getAnnotation, hasAnnotation, setAnnotation, deleteAnnotation } = useAnnotations();
9743
+ const [showSplash, setShowSplash] = useState28(true);
9744
+ const [minTimeElapsed, setMinTimeElapsed] = useState28(false);
9745
+ const initialLoadComplete = useRef13(false);
9746
+ useEffect22(() => {
9140
9747
  const timer = setTimeout(() => {
9141
9748
  setMinTimeElapsed(true);
9142
9749
  }, SPLASH_MIN_DISPLAY_MS);
9143
9750
  return () => clearTimeout(timer);
9144
9751
  }, []);
9145
- useEffect20(() => {
9752
+ useEffect22(() => {
9146
9753
  if (minTimeElapsed && initialLoadComplete.current) {
9147
9754
  setShowSplash(false);
9148
9755
  }
9149
9756
  }, [minTimeElapsed]);
9150
- const handlePostCountChange = useCallback15((count) => {
9757
+ const handlePostCountChange = useCallback16((count) => {
9151
9758
  setPostCount(count);
9152
9759
  }, []);
9153
- const handleInitialLoadComplete = useCallback15(() => {
9760
+ const handleInitialLoadComplete = useCallback16(() => {
9154
9761
  if (!initialLoadComplete.current) {
9155
9762
  initialLoadComplete.current = true;
9156
9763
  if (minTimeElapsed) {
@@ -9158,34 +9765,34 @@ function AppContent({ client, user }) {
9158
9765
  }
9159
9766
  }
9160
9767
  }, [minTimeElapsed]);
9161
- const handleBookmarkCountChange = useCallback15((count) => {
9768
+ const handleBookmarkCountChange = useCallback16((count) => {
9162
9769
  setBookmarkCount(count);
9163
9770
  }, []);
9164
- const handleBookmarkHasMoreChange = useCallback15((hasMore) => {
9771
+ const handleBookmarkHasMoreChange = useCallback16((hasMore) => {
9165
9772
  setBookmarkHasMore(hasMore);
9166
9773
  }, []);
9167
- const handleNotificationCountChange = useCallback15((count) => {
9774
+ const handleNotificationCountChange = useCallback16((count) => {
9168
9775
  setNotificationCount(count);
9169
9776
  }, []);
9170
- const handleUnreadCountChange = useCallback15((count) => {
9777
+ const handleUnreadCountChange = useCallback16((count) => {
9171
9778
  setUnreadNotificationCount(count);
9172
9779
  }, []);
9173
- const [postStack, setPostStack] = useState23([]);
9780
+ const [postStack, setPostStack] = useState28([]);
9174
9781
  const selectedPost = postStack[postStack.length - 1] ?? null;
9175
- const [isLoadingQuote, setIsLoadingQuote] = useState23(false);
9176
- const [isLoadingParent, setIsLoadingParent] = useState23(false);
9177
- const [threadRootTweet, setThreadRootTweet] = useState23(null);
9178
- const handlePostSelect = useCallback15((post) => {
9782
+ const [isLoadingQuote, setIsLoadingQuote] = useState28(false);
9783
+ const [isLoadingParent, setIsLoadingParent] = useState28(false);
9784
+ const [threadRootTweet, setThreadRootTweet] = useState28(null);
9785
+ const handlePostSelect = useCallback16((post) => {
9179
9786
  setPostStack((prev) => [...prev, post]);
9180
9787
  initState(post.id, post.favorited ?? false, post.bookmarked ?? false);
9181
9788
  navigate("post-detail");
9182
9789
  }, [navigate, initState]);
9183
- const handlePostSelectFromThread = useCallback15((post) => {
9790
+ const handlePostSelectFromThread = useCallback16((post) => {
9184
9791
  setPostStack((prev) => [...prev, post]);
9185
9792
  initState(post.id, post.favorited ?? false, post.bookmarked ?? false);
9186
9793
  navigate("post-detail");
9187
9794
  }, [navigate, initState]);
9188
- const handleQuoteSelect = useCallback15(async (quotedTweet) => {
9795
+ const handleQuoteSelect = useCallback16(async (quotedTweet) => {
9189
9796
  if (isLoadingQuote)
9190
9797
  return;
9191
9798
  if (postStack.some((p) => p.id === quotedTweet.id)) {
@@ -9206,7 +9813,7 @@ function AppContent({ client, user }) {
9206
9813
  setIsLoadingQuote(false);
9207
9814
  }
9208
9815
  }, [client, initState, isLoadingQuote, navigate, postStack]);
9209
- const handleParentSelect = useCallback15(async (parentTweet) => {
9816
+ const handleParentSelect = useCallback16(async (parentTweet) => {
9210
9817
  if (isLoadingParent)
9211
9818
  return;
9212
9819
  const parentIndex = postStack.findIndex((p) => p.id === parentTweet.id);
@@ -9232,40 +9839,40 @@ function AppContent({ client, user }) {
9232
9839
  setIsLoadingParent(false);
9233
9840
  }
9234
9841
  }, [client, goBack, initState, isLoadingParent, navigate, postStack]);
9235
- const handleBackFromDetail = useCallback15(() => {
9842
+ const handleBackFromDetail = useCallback16(() => {
9236
9843
  goBack();
9237
9844
  setPostStack((prev) => prev.slice(0, -1));
9238
9845
  }, [goBack]);
9239
- const [profileStack, setProfileStack] = useState23([]);
9846
+ const [profileStack, setProfileStack] = useState28([]);
9240
9847
  const profileUsername = profileStack[profileStack.length - 1] ?? null;
9241
- const handleProfileOpen = useCallback15((username) => {
9848
+ const handleProfileOpen = useCallback16((username) => {
9242
9849
  setProfileStack((prev) => [...prev, username]);
9243
9850
  navigate("profile");
9244
9851
  }, [navigate]);
9245
- const handleThreadView = useCallback15(() => {
9852
+ const handleThreadView = useCallback16(() => {
9246
9853
  if (selectedPost) {
9247
9854
  setThreadRootTweet(selectedPost);
9248
9855
  navigate("thread");
9249
9856
  }
9250
9857
  }, [navigate, selectedPost]);
9251
- const handleBackFromThread = useCallback15(() => {
9858
+ const handleBackFromThread = useCallback16(() => {
9252
9859
  goBack();
9253
9860
  setThreadRootTweet(null);
9254
9861
  }, [goBack]);
9255
- const handleBackFromProfile = useCallback15(() => {
9862
+ const handleBackFromProfile = useCallback16(() => {
9256
9863
  goBack();
9257
9864
  setProfileStack((prev) => prev.slice(0, -1));
9258
9865
  }, [goBack]);
9259
- const handlePostSelectFromProfile = useCallback15((post) => {
9866
+ const handlePostSelectFromProfile = useCallback16((post) => {
9260
9867
  setPostStack((prev) => [...prev, post]);
9261
9868
  initState(post.id, post.favorited ?? false, post.bookmarked ?? false);
9262
9869
  navigate("post-detail");
9263
9870
  }, [navigate, initState]);
9264
- const handleMoveToFolder = useCallback15(async () => {
9871
+ const handleMoveToFolder = useCallback16(async () => {
9265
9872
  if (!selectedPost)
9266
9873
  return;
9267
9874
  const result = await dialog.choice({
9268
- content: (ctx) => /* @__PURE__ */ jsxDEV27(FolderPickerContent, {
9875
+ content: (ctx) => /* @__PURE__ */ jsxDEV29(FolderPickerContent, {
9269
9876
  client,
9270
9877
  resolve: ctx.resolve,
9271
9878
  dismiss: ctx.dismiss,
@@ -9282,9 +9889,39 @@ function AppContent({ client, user }) {
9282
9889
  toast.error(moveResult.error);
9283
9890
  }
9284
9891
  }, [client, selectedPost, dialog]);
9285
- const handleBookmarkFolderSelectorOpen = useCallback15(async () => {
9892
+ const handleAnnotate = useCallback16(async (tweetId) => {
9893
+ const existingAnnotation = getAnnotation(tweetId);
9894
+ const result = await dialog.prompt({
9895
+ content: (ctx) => /* @__PURE__ */ jsxDEV29(AnnotationEditorContent, {
9896
+ initialText: existingAnnotation ?? "",
9897
+ hasExisting: !!existingAnnotation,
9898
+ resolve: ctx.resolve,
9899
+ dismiss: ctx.dismiss,
9900
+ dialogId: ctx.dialogId
9901
+ }, undefined, false, undefined, this),
9902
+ unstyled: true
9903
+ });
9904
+ if (!result)
9905
+ return;
9906
+ if (result.action === "delete") {
9907
+ deleteAnnotation(tweetId);
9908
+ toast.success("Annotation deleted");
9909
+ } else if (result.action === "save" && result.text) {
9910
+ setAnnotation(tweetId, result.text);
9911
+ toast.success(existingAnnotation ? "Annotation updated" : "Annotation saved");
9912
+ }
9913
+ }, [dialog, getAnnotation, setAnnotation, deleteAnnotation]);
9914
+ const handleAnnotateSelectedPost = useCallback16(() => {
9915
+ if (selectedPost) {
9916
+ handleAnnotate(selectedPost.id);
9917
+ }
9918
+ }, [selectedPost, handleAnnotate]);
9919
+ const handleAnnotateFromList = useCallback16((post) => {
9920
+ handleAnnotate(post.id);
9921
+ }, [handleAnnotate]);
9922
+ const handleBookmarkFolderSelectorOpen = useCallback16(async () => {
9286
9923
  const folder = await dialog.choice({
9287
- content: (ctx) => /* @__PURE__ */ jsxDEV27(BookmarkFolderSelectorContent, {
9924
+ content: (ctx) => /* @__PURE__ */ jsxDEV29(BookmarkFolderSelectorContent, {
9288
9925
  client,
9289
9926
  currentFolder: selectedBookmarkFolder,
9290
9927
  resolve: ctx.resolve,
@@ -9297,9 +9934,9 @@ function AppContent({ client, user }) {
9297
9934
  setSelectedBookmarkFolder(folder);
9298
9935
  }
9299
9936
  }, [client, selectedBookmarkFolder, dialog]);
9300
- const handleCreateBookmarkFolder = useCallback15(async () => {
9937
+ const handleCreateBookmarkFolder = useCallback16(async () => {
9301
9938
  const name = await dialog.prompt({
9302
- content: (ctx) => /* @__PURE__ */ jsxDEV27(FolderNameInputContent, {
9939
+ content: (ctx) => /* @__PURE__ */ jsxDEV29(FolderNameInputContent, {
9303
9940
  mode: "create",
9304
9941
  onSubmit: async (folderName) => {
9305
9942
  const result = await client.createBookmarkFolder(folderName);
@@ -9317,11 +9954,11 @@ function AppContent({ client, user }) {
9317
9954
  toast.success(`Created folder "${name}"`);
9318
9955
  }
9319
9956
  }, [client, dialog]);
9320
- const handleEditBookmarkFolder = useCallback15(async () => {
9957
+ const handleEditBookmarkFolder = useCallback16(async () => {
9321
9958
  if (!selectedBookmarkFolder)
9322
9959
  return;
9323
9960
  const name = await dialog.prompt({
9324
- content: (ctx) => /* @__PURE__ */ jsxDEV27(FolderNameInputContent, {
9961
+ content: (ctx) => /* @__PURE__ */ jsxDEV29(FolderNameInputContent, {
9325
9962
  mode: "edit",
9326
9963
  initialName: selectedBookmarkFolder.name,
9327
9964
  onSubmit: async (folderName) => {
@@ -9342,11 +9979,11 @@ function AppContent({ client, user }) {
9342
9979
  toast.success(`Renamed folder to "${name}"`);
9343
9980
  }
9344
9981
  }, [client, selectedBookmarkFolder, dialog]);
9345
- const handleDeleteBookmarkFolder = useCallback15(async () => {
9982
+ const handleDeleteBookmarkFolder = useCallback16(async () => {
9346
9983
  if (!selectedBookmarkFolder)
9347
9984
  return;
9348
9985
  const confirmed = await dialog.confirm({
9349
- content: (ctx) => /* @__PURE__ */ jsxDEV27(DeleteFolderConfirmContent, {
9986
+ content: (ctx) => /* @__PURE__ */ jsxDEV29(DeleteFolderConfirmContent, {
9350
9987
  folderName: selectedBookmarkFolder.name,
9351
9988
  onConfirm: async () => {
9352
9989
  const result = await client.deleteBookmarkFolder(selectedBookmarkFolder.id);
@@ -9366,7 +10003,7 @@ function AppContent({ client, user }) {
9366
10003
  if (!confirmed)
9367
10004
  return;
9368
10005
  }, [client, selectedBookmarkFolder, dialog]);
9369
- const handleNotificationSelect = useCallback15((notification) => {
10006
+ const handleNotificationSelect = useCallback16((notification) => {
9370
10007
  if (notification.targetTweet) {
9371
10008
  setPostStack((prev) => [...prev, notification.targetTweet]);
9372
10009
  initState(notification.targetTweet.id, notification.targetTweet.favorited ?? false, notification.targetTweet.bookmarked ?? false);
@@ -9387,9 +10024,9 @@ function AppContent({ client, user }) {
9387
10024
  });
9388
10025
  }
9389
10026
  }, [navigate, initState]);
9390
- const showExitConfirmation = useCallback15(() => {
10027
+ const showExitConfirmation = useCallback16(() => {
9391
10028
  dialog.choice({
9392
- content: (ctx) => /* @__PURE__ */ jsxDEV27(ExitConfirmationContent, {
10029
+ content: (ctx) => /* @__PURE__ */ jsxDEV29(ExitConfirmationContent, {
9393
10030
  resolve: ctx.resolve,
9394
10031
  dismiss: ctx.dismiss,
9395
10032
  dialogId: ctx.dialogId
@@ -9404,6 +10041,35 @@ function AppContent({ client, user }) {
9404
10041
  }
9405
10042
  });
9406
10043
  }, [dialog, renderer]);
10044
+ const handleUrlNavigationOpen = useCallback16(async () => {
10045
+ const result = await dialog.prompt({
10046
+ content: (ctx) => /* @__PURE__ */ jsxDEV29(UrlInputContent, {
10047
+ onNavigateToTweet: async (tweetId) => {
10048
+ const tweetResult = await client.getTweet(tweetId);
10049
+ if (tweetResult.success && tweetResult.tweet) {
10050
+ setPostStack((prev) => [...prev, tweetResult.tweet]);
10051
+ initState(tweetResult.tweet.id, tweetResult.tweet.favorited ?? false, tweetResult.tweet.bookmarked ?? false);
10052
+ navigate("post-detail");
10053
+ return { success: true };
10054
+ }
10055
+ return {
10056
+ success: false,
10057
+ error: tweetResult.error ?? "Tweet not found"
10058
+ };
10059
+ },
10060
+ onNavigateToProfile: async (username) => {
10061
+ setProfileStack((prev) => [...prev, username]);
10062
+ navigate("profile");
10063
+ return { success: true };
10064
+ },
10065
+ resolve: ctx.resolve,
10066
+ dismiss: ctx.dismiss,
10067
+ dialogId: ctx.dialogId
10068
+ }, undefined, false, undefined, this)
10069
+ });
10070
+ if (!result)
10071
+ return;
10072
+ }, [client, dialog, initState, navigate]);
9407
10073
  useKeyboard10((key) => {
9408
10074
  if (key.name === "c") {
9409
10075
  const selection = renderer.getSelection();
@@ -9476,33 +10142,36 @@ function AppContent({ client, user }) {
9476
10142
  setProfileStack((prev) => [...prev, user.username]);
9477
10143
  navigate("profile");
9478
10144
  }
10145
+ if (key.name === "g") {
10146
+ handleUrlNavigationOpen();
10147
+ }
9479
10148
  });
9480
- return /* @__PURE__ */ jsxDEV27("box", {
10149
+ return /* @__PURE__ */ jsxDEV29("box", {
9481
10150
  style: {
9482
10151
  flexDirection: "column",
9483
10152
  height: "100%"
9484
10153
  },
9485
10154
  children: [
9486
- showSplash ? /* @__PURE__ */ jsxDEV27(SplashScreen, {}, undefined, false, undefined, this) : isMainView ? /* @__PURE__ */ jsxDEV27(Header, {
10155
+ showSplash ? /* @__PURE__ */ jsxDEV29(SplashScreen, {}, undefined, false, undefined, this) : isMainView ? /* @__PURE__ */ jsxDEV29(Header, {
9487
10156
  currentView,
9488
10157
  postCount: currentView === "bookmarks" ? bookmarkCount : currentView === "notifications" ? notificationCount : postCount,
9489
10158
  hasMore: currentView === "bookmarks" ? bookmarkHasMore : false,
9490
10159
  unreadNotificationCount
9491
10160
  }, undefined, false, undefined, this) : null,
9492
- /* @__PURE__ */ jsxDEV27("box", {
10161
+ /* @__PURE__ */ jsxDEV29("box", {
9493
10162
  style: {
9494
10163
  flexGrow: 1,
9495
10164
  height: showSplash ? 0 : undefined,
9496
10165
  overflow: showSplash ? "hidden" : undefined
9497
10166
  },
9498
10167
  children: [
9499
- /* @__PURE__ */ jsxDEV27("box", {
10168
+ /* @__PURE__ */ jsxDEV29("box", {
9500
10169
  visible: currentView === "timeline",
9501
10170
  style: {
9502
10171
  flexGrow: 1,
9503
10172
  height: "100%"
9504
10173
  },
9505
- children: /* @__PURE__ */ jsxDEV27(TimelineScreenExperimental, {
10174
+ children: /* @__PURE__ */ jsxDEV29(TimelineScreenExperimental, {
9506
10175
  client,
9507
10176
  focused: currentView === "timeline" && !showSplash && !isDialogOpen,
9508
10177
  onPostCountChange: handlePostCountChange,
@@ -9514,7 +10183,7 @@ function AppContent({ client, user }) {
9514
10183
  initActionState: initState
9515
10184
  }, undefined, false, undefined, this)
9516
10185
  }, undefined, false, undefined, this),
9517
- currentView === "post-detail" && selectedPost && /* @__PURE__ */ jsxDEV27(PostDetailScreen, {
10186
+ currentView === "post-detail" && selectedPost && /* @__PURE__ */ jsxDEV29(PostDetailScreen, {
9518
10187
  client,
9519
10188
  tweet: selectedPost,
9520
10189
  focused: !isDialogOpen,
@@ -9523,6 +10192,8 @@ function AppContent({ client, user }) {
9523
10192
  onLike: () => toggleLike(selectedPost),
9524
10193
  onBookmark: () => toggleBookmark(selectedPost),
9525
10194
  onMoveToFolder: handleMoveToFolder,
10195
+ onAnnotate: handleAnnotateSelectedPost,
10196
+ annotationText: getAnnotation(selectedPost.id),
9526
10197
  isLiked: getState(selectedPost.id).liked,
9527
10198
  isBookmarked: getState(selectedPost.id).bookmarked,
9528
10199
  isJustLiked: getState(selectedPost.id).justLiked,
@@ -9536,13 +10207,13 @@ function AppContent({ client, user }) {
9536
10207
  isLoadingParent,
9537
10208
  showFooter
9538
10209
  }, undefined, false, undefined, this),
9539
- /* @__PURE__ */ jsxDEV27("box", {
10210
+ /* @__PURE__ */ jsxDEV29("box", {
9540
10211
  visible: currentView === "thread",
9541
10212
  style: {
9542
10213
  flexGrow: 1,
9543
10214
  height: "100%"
9544
10215
  },
9545
- children: threadRootTweet && /* @__PURE__ */ jsxDEV27(ThreadScreen, {
10216
+ children: threadRootTweet && /* @__PURE__ */ jsxDEV29(ThreadScreen, {
9546
10217
  client,
9547
10218
  tweet: threadRootTweet,
9548
10219
  focused: currentView === "thread",
@@ -9551,13 +10222,13 @@ function AppContent({ client, user }) {
9551
10222
  showFooter
9552
10223
  }, undefined, false, undefined, this)
9553
10224
  }, undefined, false, undefined, this),
9554
- /* @__PURE__ */ jsxDEV27("box", {
10225
+ /* @__PURE__ */ jsxDEV29("box", {
9555
10226
  visible: currentView === "profile",
9556
10227
  style: {
9557
10228
  flexGrow: 1,
9558
10229
  height: "100%"
9559
10230
  },
9560
- children: profileUsername && /* @__PURE__ */ jsxDEV27(ProfileScreen, {
10231
+ children: profileUsername && /* @__PURE__ */ jsxDEV29(ProfileScreen, {
9561
10232
  client,
9562
10233
  username: profileUsername,
9563
10234
  currentUser: user,
@@ -9572,13 +10243,13 @@ function AppContent({ client, user }) {
9572
10243
  showFooter
9573
10244
  }, undefined, false, undefined, this)
9574
10245
  }, undefined, false, undefined, this),
9575
- /* @__PURE__ */ jsxDEV27("box", {
10246
+ /* @__PURE__ */ jsxDEV29("box", {
9576
10247
  visible: currentView === "bookmarks",
9577
10248
  style: {
9578
10249
  flexGrow: 1,
9579
10250
  height: "100%"
9580
10251
  },
9581
- children: /* @__PURE__ */ jsxDEV27(BookmarksScreen, {
10252
+ children: /* @__PURE__ */ jsxDEV29(BookmarksScreen, {
9582
10253
  client,
9583
10254
  focused: currentView === "bookmarks" && !showSplash && !isDialogOpen,
9584
10255
  selectedFolder: selectedBookmarkFolder,
@@ -9588,20 +10259,22 @@ function AppContent({ client, user }) {
9588
10259
  onPostSelect: handlePostSelect,
9589
10260
  onLike: toggleLike,
9590
10261
  onBookmark: toggleBookmark,
10262
+ onAnnotate: handleAnnotateFromList,
9591
10263
  getActionState: getState,
9592
10264
  initActionState: initState,
10265
+ hasAnnotation,
9593
10266
  onCreateFolder: handleCreateBookmarkFolder,
9594
10267
  onEditFolder: handleEditBookmarkFolder,
9595
10268
  onDeleteFolder: handleDeleteBookmarkFolder
9596
10269
  }, undefined, false, undefined, this)
9597
10270
  }, undefined, false, undefined, this),
9598
- /* @__PURE__ */ jsxDEV27("box", {
10271
+ /* @__PURE__ */ jsxDEV29("box", {
9599
10272
  visible: currentView === "notifications",
9600
10273
  style: {
9601
10274
  flexGrow: 1,
9602
10275
  height: "100%"
9603
10276
  },
9604
- children: /* @__PURE__ */ jsxDEV27(NotificationsScreen, {
10277
+ children: /* @__PURE__ */ jsxDEV29(NotificationsScreen, {
9605
10278
  client,
9606
10279
  focused: currentView === "notifications" && !showSplash && !isDialogOpen,
9607
10280
  onNotificationCountChange: handleNotificationCountChange,
@@ -9611,7 +10284,7 @@ function AppContent({ client, user }) {
9611
10284
  }, undefined, false, undefined, this)
9612
10285
  ]
9613
10286
  }, undefined, true, undefined, this),
9614
- !showSplash && isMainView && /* @__PURE__ */ jsxDEV27(Footer, {
10287
+ !showSplash && isMainView && /* @__PURE__ */ jsxDEV29(Footer, {
9615
10288
  visible: showFooter
9616
10289
  }, undefined, false, undefined, this)
9617
10290
  ]
@@ -9619,46 +10292,46 @@ function AppContent({ client, user }) {
9619
10292
  }
9620
10293
 
9621
10294
  // src/auth/browser-detect.ts
9622
- import { existsSync as existsSync2, readdirSync } from "fs";
9623
- import { homedir as homedir4 } from "os";
9624
- import path2 from "path";
9625
- var home = homedir4();
10295
+ import { existsSync as existsSync3, readdirSync } from "fs";
10296
+ import { homedir as homedir5 } from "os";
10297
+ import path3 from "path";
10298
+ var home = homedir5();
9626
10299
  var BROWSER_CONFIGS = [
9627
10300
  {
9628
10301
  id: "safari",
9629
10302
  name: "Safari",
9630
- check: () => existsSync2(path2.join(home, "Library/Containers/com.apple.Safari/Data/Library/Cookies/Cookies.binarycookies")) || existsSync2(path2.join(home, "Library/Cookies/Cookies.binarycookies"))
10303
+ check: () => existsSync3(path3.join(home, "Library/Containers/com.apple.Safari/Data/Library/Cookies/Cookies.binarycookies")) || existsSync3(path3.join(home, "Library/Cookies/Cookies.binarycookies"))
9631
10304
  },
9632
10305
  {
9633
10306
  id: "chrome",
9634
10307
  name: "Chrome",
9635
- check: () => existsSync2(path2.join(home, "Library/Application Support/Google/Chrome/Default/Cookies")) || existsSync2(path2.join(home, "Library/Application Support/Google/Chrome/Default/Network/Cookies"))
10308
+ check: () => existsSync3(path3.join(home, "Library/Application Support/Google/Chrome/Default/Cookies")) || existsSync3(path3.join(home, "Library/Application Support/Google/Chrome/Default/Network/Cookies"))
9636
10309
  },
9637
10310
  {
9638
10311
  id: "brave",
9639
10312
  name: "Brave",
9640
- check: () => existsSync2(path2.join(home, "Library/Application Support/BraveSoftware/Brave-Browser/Default/Cookies")) || existsSync2(path2.join(home, "Library/Application Support/BraveSoftware/Brave-Browser/Default/Network/Cookies"))
10313
+ check: () => existsSync3(path3.join(home, "Library/Application Support/BraveSoftware/Brave-Browser/Default/Cookies")) || existsSync3(path3.join(home, "Library/Application Support/BraveSoftware/Brave-Browser/Default/Network/Cookies"))
9641
10314
  },
9642
10315
  {
9643
10316
  id: "arc",
9644
10317
  name: "Arc",
9645
- check: () => existsSync2(path2.join(home, "Library/Application Support/Arc/User Data/Default/Cookies")) || existsSync2(path2.join(home, "Library/Application Support/Arc/User Data/Default/Network/Cookies"))
10318
+ check: () => existsSync3(path3.join(home, "Library/Application Support/Arc/User Data/Default/Cookies")) || existsSync3(path3.join(home, "Library/Application Support/Arc/User Data/Default/Network/Cookies"))
9646
10319
  },
9647
10320
  {
9648
10321
  id: "opera",
9649
10322
  name: "Opera",
9650
- check: () => existsSync2(path2.join(home, "Library/Application Support/com.operasoftware.Opera/Cookies")) || existsSync2(path2.join(home, "Library/Application Support/com.operasoftware.Opera/Network/Cookies"))
10323
+ check: () => existsSync3(path3.join(home, "Library/Application Support/com.operasoftware.Opera/Cookies")) || existsSync3(path3.join(home, "Library/Application Support/com.operasoftware.Opera/Network/Cookies"))
9651
10324
  },
9652
10325
  {
9653
10326
  id: "firefox",
9654
10327
  name: "Firefox",
9655
10328
  check: () => {
9656
- const profilesDir = path2.join(home, "Library/Application Support/Firefox/Profiles");
9657
- if (!existsSync2(profilesDir))
10329
+ const profilesDir = path3.join(home, "Library/Application Support/Firefox/Profiles");
10330
+ if (!existsSync3(profilesDir))
9658
10331
  return false;
9659
10332
  try {
9660
10333
  const profiles = readdirSync(profilesDir);
9661
- return profiles.some((profile) => existsSync2(path2.join(profilesDir, profile, "cookies.sqlite")));
10334
+ return profiles.some((profile) => existsSync3(path3.join(profilesDir, profile, "cookies.sqlite")));
9662
10335
  } catch {
9663
10336
  return false;
9664
10337
  }
@@ -9766,8 +10439,8 @@ var query_ids_default = {
9766
10439
 
9767
10440
  // src/api/runtime-query-ids.ts
9768
10441
  import { mkdir as mkdir2, readFile, writeFile as writeFile2 } from "fs/promises";
9769
- import { homedir as homedir5 } from "os";
9770
- import path3 from "path";
10442
+ import { homedir as homedir6 } from "os";
10443
+ import path4 from "path";
9771
10444
  var DEFAULT_CACHE_FILENAME = "query-ids-cache.json";
9772
10445
  var DEFAULT_TTL_MS = 24 * 60 * 60 * 1000;
9773
10446
  var DISCOVERY_PAGES = [
@@ -9816,9 +10489,9 @@ async function fetchText(fetchImpl, url) {
9816
10489
  function resolveDefaultCachePath() {
9817
10490
  const override = process.env.XFEED_QUERY_IDS_CACHE;
9818
10491
  if (override && override.trim().length > 0) {
9819
- return path3.resolve(override.trim());
10492
+ return path4.resolve(override.trim());
9820
10493
  }
9821
- return path3.join(homedir5(), ".config", "xfeed", DEFAULT_CACHE_FILENAME);
10494
+ return path4.join(homedir6(), ".config", "xfeed", DEFAULT_CACHE_FILENAME);
9822
10495
  }
9823
10496
  function parseSnapshot(raw) {
9824
10497
  if (!raw || typeof raw !== "object") {
@@ -9862,7 +10535,7 @@ async function readSnapshotFromDisk(cachePath) {
9862
10535
  }
9863
10536
  }
9864
10537
  async function writeSnapshotToDisk(cachePath, snapshot) {
9865
- await mkdir2(path3.dirname(cachePath), { recursive: true });
10538
+ await mkdir2(path4.dirname(cachePath), { recursive: true });
9866
10539
  await writeFile2(cachePath, `${JSON.stringify(snapshot, null, 2)}
9867
10540
  `, "utf8");
9868
10541
  }
@@ -9935,7 +10608,7 @@ async function fetchAndExtract(fetchImpl, bundleUrls, targets) {
9935
10608
  function createRuntimeQueryIdStore(options = {}) {
9936
10609
  const fetchImpl = options.fetchImpl ?? fetch;
9937
10610
  const ttlMs = options.ttlMs ?? DEFAULT_TTL_MS;
9938
- const cachePath = options.cachePath ? path3.resolve(options.cachePath) : resolveDefaultCachePath();
10611
+ const cachePath = options.cachePath ? path4.resolve(options.cachePath) : resolveDefaultCachePath();
9939
10612
  let memorySnapshot = null;
9940
10613
  let loadOnce = null;
9941
10614
  let refreshInFlight = null;
@@ -10190,11 +10863,11 @@ class XClient {
10190
10863
  }
10191
10864
  await this.transactionInitPromise;
10192
10865
  }
10193
- async generateTransactionId(method, path4) {
10866
+ async generateTransactionId(method, path5) {
10194
10867
  await this.ensureClientTransaction();
10195
10868
  if (this.clientTransaction) {
10196
10869
  try {
10197
- return await this.clientTransaction.generateTransactionId(method, path4);
10870
+ return await this.clientTransaction.generateTransactionId(method, path5);
10198
10871
  } catch (error) {
10199
10872
  console.error("[xfeed] Failed to generate transaction ID:", error);
10200
10873
  }
@@ -10761,6 +11434,7 @@ ${body}`;
10761
11434
  responsive_web_grok_analyze_button_fetch_trends_enabled: false,
10762
11435
  responsive_web_grok_analyze_post_followups_enabled: false,
10763
11436
  responsive_web_jetfuel_frame: true,
11437
+ post_ctas_fetch_enabled: true,
10764
11438
  responsive_web_grok_share_attachment_enabled: true,
10765
11439
  articles_preview_enabled: true,
10766
11440
  responsive_web_edit_tweet_api_enabled: true,
@@ -10826,6 +11500,7 @@ ${body}`;
10826
11500
  responsive_web_grok_analyze_button_fetch_trends_enabled: false,
10827
11501
  responsive_web_grok_analyze_post_followups_enabled: true,
10828
11502
  responsive_web_jetfuel_frame: true,
11503
+ post_ctas_fetch_enabled: true,
10829
11504
  responsive_web_grok_share_attachment_enabled: true,
10830
11505
  responsive_web_grok_annotations_enabled: false,
10831
11506
  articles_preview_enabled: true,
@@ -12955,9 +13630,9 @@ ${fallback.plainText}` : fallback.plainText;
12955
13630
  };
12956
13631
  const tryOnce = async () => {
12957
13632
  const queryId = await this.getQueryId("bookmarkTweetToFolder");
12958
- const path4 = `/i/api/graphql/${queryId}/bookmarkTweetToFolder`;
12959
- const url = `https://x.com${path4}`;
12960
- const transactionId = await this.generateTransactionId("POST", path4);
13633
+ const path5 = `/i/api/graphql/${queryId}/bookmarkTweetToFolder`;
13634
+ const url = `https://x.com${path5}`;
13635
+ const transactionId = await this.generateTransactionId("POST", path5);
12961
13636
  try {
12962
13637
  const headers = {
12963
13638
  ...this.getHeaders(),
@@ -13012,9 +13687,9 @@ ${fallback.plainText}` : fallback.plainText;
13012
13687
  const variables = { name };
13013
13688
  const tryOnce = async () => {
13014
13689
  const queryId = await this.getQueryId("createBookmarkFolder");
13015
- const path4 = `/i/api/graphql/${queryId}/createBookmarkFolder`;
13016
- const url = `https://x.com${path4}`;
13017
- const transactionId = await this.generateTransactionId("POST", path4);
13690
+ const path5 = `/i/api/graphql/${queryId}/createBookmarkFolder`;
13691
+ const url = `https://x.com${path5}`;
13692
+ const transactionId = await this.generateTransactionId("POST", path5);
13018
13693
  try {
13019
13694
  const headers = {
13020
13695
  ...this.getHeaders(),
@@ -13076,9 +13751,9 @@ ${fallback.plainText}` : fallback.plainText;
13076
13751
  const variables = { bookmark_collection_id: folderId };
13077
13752
  const tryOnce = async () => {
13078
13753
  const queryId = await this.getQueryId("DeleteBookmarkFolder");
13079
- const path4 = `/i/api/graphql/${queryId}/DeleteBookmarkFolder`;
13080
- const url = `https://x.com${path4}`;
13081
- const transactionId = await this.generateTransactionId("POST", path4);
13754
+ const path5 = `/i/api/graphql/${queryId}/DeleteBookmarkFolder`;
13755
+ const url = `https://x.com${path5}`;
13756
+ const transactionId = await this.generateTransactionId("POST", path5);
13082
13757
  try {
13083
13758
  const headers = {
13084
13759
  ...this.getHeaders(),
@@ -13136,9 +13811,9 @@ ${fallback.plainText}` : fallback.plainText;
13136
13811
  const variables = { bookmark_collection_id: folderId, name };
13137
13812
  const tryOnce = async () => {
13138
13813
  const queryId = await this.getQueryId("EditBookmarkFolder");
13139
- const path4 = `/i/api/graphql/${queryId}/EditBookmarkFolder`;
13140
- const url = `https://x.com${path4}`;
13141
- const transactionId = await this.generateTransactionId("POST", path4);
13814
+ const path5 = `/i/api/graphql/${queryId}/EditBookmarkFolder`;
13815
+ const url = `https://x.com${path5}`;
13816
+ const transactionId = await this.generateTransactionId("POST", path5);
13142
13817
  try {
13143
13818
  const headers = {
13144
13819
  ...this.getHeaders(),
@@ -13200,9 +13875,9 @@ ${fallback.plainText}` : fallback.plainText;
13200
13875
  const variables = { tweet_id: tweetId };
13201
13876
  const tryOnce = async () => {
13202
13877
  const queryId = await this.getQueryId(operationName);
13203
- const path4 = `/i/api/graphql/${queryId}/${operationName}`;
13204
- const url = `https://x.com${path4}`;
13205
- const transactionId = await this.generateTransactionId("POST", path4);
13878
+ const path5 = `/i/api/graphql/${queryId}/${operationName}`;
13879
+ const url = `https://x.com${path5}`;
13880
+ const transactionId = await this.generateTransactionId("POST", path5);
13206
13881
  try {
13207
13882
  const headers = {
13208
13883
  ...this.getHeaders(),
@@ -13597,9 +14272,9 @@ Invalid tokens: ${result.error}
13597
14272
  }
13598
14273
 
13599
14274
  // src/config/preferences.ts
13600
- import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
13601
- import { homedir as homedir6 } from "os";
13602
- import path4 from "path";
14275
+ import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
14276
+ import { homedir as homedir7 } from "os";
14277
+ import path5 from "path";
13603
14278
 
13604
14279
  // src/config/preferences-types.ts
13605
14280
  var DEFAULT_PREFERENCES = {
@@ -13641,8 +14316,8 @@ function parseToml(content) {
13641
14316
  }
13642
14317
 
13643
14318
  // src/config/preferences.ts
13644
- var CONFIG_DIR2 = path4.join(homedir6(), ".config", "xfeed");
13645
- var PREFERENCES_PATH = path4.join(CONFIG_DIR2, "preferences.toml");
14319
+ var CONFIG_DIR3 = path5.join(homedir7(), ".config", "xfeed");
14320
+ var PREFERENCES_PATH = path5.join(CONFIG_DIR3, "preferences.toml");
13646
14321
  function validateTimelineTab(value) {
13647
14322
  if (typeof value === "string") {
13648
14323
  if (VALID_TIMELINE_TABS.includes(value)) {
@@ -13654,12 +14329,12 @@ function validateTimelineTab(value) {
13654
14329
  function loadPreferences() {
13655
14330
  const warnings = [];
13656
14331
  const preferences = structuredClone(DEFAULT_PREFERENCES);
13657
- if (!existsSync3(PREFERENCES_PATH)) {
14332
+ if (!existsSync4(PREFERENCES_PATH)) {
13658
14333
  return { preferences, warnings };
13659
14334
  }
13660
14335
  let content;
13661
14336
  try {
13662
- content = readFileSync2(PREFERENCES_PATH, "utf-8");
14337
+ content = readFileSync3(PREFERENCES_PATH, "utf-8");
13663
14338
  } catch (error) {
13664
14339
  const message = error instanceof Error ? error.message : String(error);
13665
14340
  warnings.push(`Could not read preferences file: ${message}`);
@@ -13687,7 +14362,7 @@ function getPreferencesPath() {
13687
14362
  }
13688
14363
 
13689
14364
  // src/index.tsx
13690
- import { jsxDEV as jsxDEV28 } from "@opentui/react/jsx-dev-runtime";
14365
+ import { jsxDEV as jsxDEV30 } from "@opentui/react/jsx-dev-runtime";
13691
14366
  function checkTerminalCompatibility() {
13692
14367
  const termProgram = process.env.TERM_PROGRAM;
13693
14368
  const colorterm = process.env.COLORTERM;
@@ -13874,14 +14549,14 @@ Details:
13874
14549
  const renderer = await createCliRenderer({
13875
14550
  exitOnCtrlC: true
13876
14551
  });
13877
- createRoot(renderer).render(/* @__PURE__ */ jsxDEV28(PreferencesProvider, {
14552
+ createRoot(renderer).render(/* @__PURE__ */ jsxDEV30(PreferencesProvider, {
13878
14553
  preferences,
13879
- children: /* @__PURE__ */ jsxDEV28(DialogProvider, {
14554
+ children: /* @__PURE__ */ jsxDEV30(DialogProvider, {
13880
14555
  backdropColor: "#000000",
13881
14556
  backdropOpacity: 0.8,
13882
14557
  size: "small",
13883
14558
  unstyled: true,
13884
- children: /* @__PURE__ */ jsxDEV28(App, {
14559
+ children: /* @__PURE__ */ jsxDEV30(App, {
13885
14560
  client: authResult.client,
13886
14561
  user: authResult.user
13887
14562
  }, undefined, false, undefined, this)