+2
-2
dist/index.html
+2
-2
dist/index.html
···
5
5
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
6
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
<title>ATLast: Sync Your TikTok Follows → ATmosphere (Skylight, Bluesky, etc.)</title>
8
-
<script type="module" crossorigin src="/assets/index-DSaTEsTd.js"></script>
9
-
<link rel="stylesheet" crossorigin href="/assets/index-DiTz01qJ.css">
8
+
<script type="module" crossorigin src="/assets/index-WJfYS828.js"></script>
9
+
<link rel="stylesheet" crossorigin href="/assets/index-Bs4vTtm8.css">
10
10
</head>
11
11
<body>
12
12
<div id="root"></div>
+31
-3
src/components/HistoryTab.tsx
+31
-3
src/components/HistoryTab.tsx
···
1
-
import { Upload, Sparkles } from "lucide-react";
1
+
import { Upload, Sparkles, ChevronRight } from "lucide-react";
2
2
import { ATPROTO_APPS } from "../constants/atprotoApps";
3
3
import type { Upload as UploadType } from "../types";
4
4
import type { UserSettings } from "../types/settings";
5
5
6
6
interface HistoryTabProps {
7
7
uploads: UploadType[];
8
+
wizardCompleted: boolean;
9
+
onShowWizard: () => void;
8
10
isLoading: boolean;
9
11
userSettings: UserSettings;
10
12
onLoadUpload: (uploadId: string) => void;
···
12
14
13
15
export default function HistoryTab({
14
16
uploads,
17
+
wizardCompleted,
18
+
onShowWizard,
15
19
isLoading,
16
20
userSettings,
17
21
onLoadUpload,
···
37
41
};
38
42
39
43
return (
40
-
<div className="p-6">
44
+
<div className="p-6 mb-3">
45
+
{/* Setup Assistant Banner - Only show if wizard not completed */}
46
+
{!wizardCompleted && (
47
+
<div className="bg-firefly-banner-dark dark:bg-firefly-banner-dark rounded-2xl p-6 text-white">
48
+
<div className="flex flex-col md:flex-row items-start md:items-center justify-between gap-4">
49
+
<div className="flex-1">
50
+
<h2 className="text-2xl font-bold mb-2">
51
+
Need help getting started?
52
+
</h2>
53
+
<p className="text-white">
54
+
Run the setup assistant to configure your preferences in
55
+
minutes.
56
+
</p>
57
+
</div>
58
+
<button
59
+
onClick={onShowWizard}
60
+
className="bg-white text-slate-900 px-6 py-3 rounded-xl font-semibold hover:bg-slate-100 transition-all flex items-center space-x-2 whitespace-nowrap shadow-lg"
61
+
>
62
+
<span>Start Setup</span>
63
+
<ChevronRight className="w-4 h-4" />
64
+
</button>
65
+
</div>
66
+
</div>
67
+
)}
68
+
41
69
<div className="flex items-center space-x-3 mb-3">
42
70
<div>
43
71
<h2 className="text-xl font-bold text-purple-950 dark:text-cyan-50">
···
50
78
</div>
51
79
52
80
{isLoading ? (
53
-
<div className="space-y-3">
81
+
<div className="space-y-6">
54
82
{[...Array(3)].map((_, i) => (
55
83
<div
56
84
key={i}
+1
-1
src/components/SetupWizard.tsx
+1
-1
src/components/SetupWizard.tsx
···
75
75
<div className="px-6 py-4 border-b-2 border-cyan-500/30 dark:border-purple-500/30 flex-shrink-0">
76
76
<div className="flex items-center justify-between mb-3">
77
77
<div className="flex items-center space-x-3">
78
-
<div className="w-10 h-10 bg-gradient-to-br from-firefly-amber via-firefly-orange to-firefly-pink rounded-xl flex items-center justify-center shadow-md">
78
+
<div className="w-10 h-10 bg-firefly-banner dark:bg-firefly-banner-dark rounded-xl flex items-center justify-center shadow-md">
79
79
<Heart className="w-5 h-5 text-white" />
80
80
</div>
81
81
<h2 className="text-2xl font-bold text-purple-950 dark:text-cyan-50">
+1
-25
src/components/UploadTab.tsx
+1
-25
src/components/UploadTab.tsx
···
1
-
import { Upload, ChevronRight, Settings } from "lucide-react";
1
+
import { Settings } from "lucide-react";
2
2
import { useRef } from "react";
3
3
import PlatformSelector from "../components/PlatformSelector";
4
4
···
29
29
30
30
return (
31
31
<div className="p-6">
32
-
{/* Setup Assistant Banner - Only show if wizard not completed */}
33
-
{!wizardCompleted && (
34
-
<div className="bg-firefly-banner dark:bg-firefly-banner-dark rounded-2xl p-6 text-white">
35
-
<div className="flex flex-col md:flex-row items-start md:items-center justify-between gap-4">
36
-
<div className="flex-1">
37
-
<h2 className="text-2xl font-bold mb-2">
38
-
Need help getting started?
39
-
</h2>
40
-
<p className="text-white/90">
41
-
Run the setup assistant to configure your preferences in
42
-
minutes.
43
-
</p>
44
-
</div>
45
-
<button
46
-
onClick={onShowWizard}
47
-
className="bg-white text-slate-900 px-6 py-3 rounded-xl font-semibold hover:bg-slate-100 transition-all flex items-center space-x-2 whitespace-nowrap shadow-lg"
48
-
>
49
-
<span>Start Setup</span>
50
-
<ChevronRight className="w-4 h-4" />
51
-
</button>
52
-
</div>
53
-
</div>
54
-
)}
55
-
56
32
{/* Upload Section */}
57
33
<div className="space-y-3">
58
34
<div className="flex items-center justify-between mb-4">
+2
src/pages/Home.tsx
+2
src/pages/Home.tsx
+62
-37
src/pages/Loading.tsx
+62
-37
src/pages/Loading.tsx
···
19
19
interface LoadingPageProps {
20
20
session: atprotoSession | null;
21
21
onLogout: () => void;
22
-
onNavigate: (step: 'home' | 'login') => void;
22
+
onNavigate: (step: "home" | "login") => void;
23
23
searchProgress: SearchProgress;
24
24
currentStep: string;
25
25
sourcePlatform: string;
···
29
29
onToggleMotion?: () => void;
30
30
}
31
31
32
-
export default function LoadingPage({
33
-
session,
34
-
onLogout,
35
-
onNavigate,
36
-
searchProgress,
37
-
currentStep,
32
+
export default function LoadingPage({
33
+
session,
34
+
onLogout,
35
+
onNavigate,
36
+
searchProgress,
37
+
currentStep,
38
38
sourcePlatform,
39
39
isDark = false,
40
40
reducedMotion = false,
41
41
onToggleTheme,
42
-
onToggleMotion
42
+
onToggleMotion,
43
43
}: LoadingPageProps) {
44
44
const platform = PLATFORMS[sourcePlatform] || PLATFORMS.tiktok;
45
45
const PlatformIcon = platform.icon;
46
46
47
47
return (
48
48
<div className="min-h-screen">
49
-
<AppHeader
50
-
session={session}
51
-
onLogout={onLogout}
52
-
onNavigate={onNavigate}
49
+
<AppHeader
50
+
session={session}
51
+
onLogout={onLogout}
52
+
onNavigate={onNavigate}
53
53
currentStep={currentStep}
54
54
isDark={isDark}
55
55
reducedMotion={reducedMotion}
56
56
onToggleTheme={onToggleTheme}
57
57
onToggleMotion={onToggleMotion}
58
58
/>
59
-
59
+
60
60
{/* Platform Banner - Searching State */}
61
-
<div className={`bg-firefly-banner dark:bg-firefly-banner-dark text-white`}>
61
+
<div
62
+
className={`bg-firefly-banner dark:bg-firefly-banner-dark text-white`}
63
+
>
62
64
<div className="max-w-3xl mx-auto px-4 py-6">
63
65
<div className="flex items-center justify-between">
64
66
<div className="flex items-center space-x-4">
65
67
<div className="relative w-14 h-14">
66
68
<PlatformIcon className="w-12 h-12" />
67
-
<div className="absolute -bottom-1 -right-1 w-7 h-7 bg-white dark:bg-slate-800 rounded-full flex items-center justify-center">
68
-
<Search className="w-4 h-4 animate-pulse" aria-hidden="true" />
69
-
</div>
70
69
</div>
71
70
<div>
72
71
<h2 className="text-xl font-bold">Finding Your Fireflies</h2>
73
-
<p className="text-white/90 text-sm">
72
+
<p className="text-white text-sm">
74
73
Searching the ATmosphere for {platform.name} follows...
75
74
</p>
76
75
</div>
···
78
77
{searchProgress.found > 0 && (
79
78
<div className="text-right">
80
79
<div className="text-2xl font-bold">{searchProgress.found}</div>
81
-
<div className="text-xs text-white/80">found</div>
80
+
<div className="text-xs text-white">found</div>
82
81
</div>
83
82
)}
84
83
</div>
···
86
85
</div>
87
86
88
87
{/* Progress Stats */}
89
-
<div className="bg-white/95 dark:bg-slate-800/95 border-b-2 border-slate-200 dark:border-slate-700 backdrop-blur-sm">
88
+
<div className="bg-white/95 dark:bg-slate-900 border-b-2 border-cyan-500/30 dark:border-purple-500/30 backdrop-blur-sm">
90
89
<div className="max-w-3xl mx-auto px-4 py-4">
91
90
<div className="grid grid-cols-3 gap-4 text-center mb-4">
92
91
<div>
93
-
<div className="text-2xl font-bold text-slate-900 dark:text-slate-100" aria-label={`${searchProgress.searched} searched`}>
92
+
<div
93
+
className="text-2xl font-bold text-slate-900 dark:text-slate-100"
94
+
aria-label={`${searchProgress.searched} searched`}
95
+
>
94
96
{searchProgress.searched}
95
97
</div>
96
-
<div className="text-sm text-slate-700 dark:text-slate-300 font-medium">Searched</div>
98
+
<div className="text-sm text-slate-700 dark:text-slate-300 font-medium">
99
+
Searched
100
+
</div>
97
101
</div>
98
102
<div>
99
-
<div className="text-2xl font-bold text-firefly-orange" aria-label={`${searchProgress.found} found`}>
103
+
<div
104
+
className="text-2xl font-bold text-orange-500 dark:text-amber-400"
105
+
aria-label={`${searchProgress.found} found`}
106
+
>
100
107
{searchProgress.found}
101
108
</div>
102
-
<div className="text-sm text-slate-700 dark:text-slate-300 font-medium">Fireflies Found</div>
109
+
<div className="text-sm text-slate-700 dark:text-slate-300 font-medium">
110
+
Fireflies Found
111
+
</div>
103
112
</div>
104
113
<div>
105
-
<div className="text-2xl font-bold text-slate-600 dark:text-slate-400" aria-label={`${searchProgress.total} total`}>
114
+
<div
115
+
className="text-2xl font-bold text-slate-600 dark:text-slate-400"
116
+
aria-label={`${searchProgress.total} total`}
117
+
>
106
118
{searchProgress.total}
107
119
</div>
108
-
<div className="text-sm text-slate-700 dark:text-slate-300 font-medium">Total</div>
120
+
<div className="text-sm text-slate-700 dark:text-slate-300 font-medium">
121
+
Total
122
+
</div>
109
123
</div>
110
124
</div>
111
125
112
-
<div
113
-
className="w-full bg-slate-200 dark:bg-slate-700 rounded-full h-3"
114
-
role="progressbar"
115
-
aria-valuenow={searchProgress.total > 0 ? Math.round((searchProgress.searched / searchProgress.total) * 100) : 0}
116
-
aria-valuemin={0}
126
+
<div
127
+
className="w-full bg-slate-200 dark:bg-slate-700 rounded-full h-3"
128
+
role="progressbar"
129
+
aria-valuenow={
130
+
searchProgress.total > 0
131
+
? Math.round(
132
+
(searchProgress.searched / searchProgress.total) * 100,
133
+
)
134
+
: 0
135
+
}
136
+
aria-valuemin={0}
117
137
aria-valuemax={100}
118
138
>
119
-
<div
120
-
className="bg-gradient-to-r from-firefly-amber via-firefly-orange to-firefly-pink h-full rounded-full transition-all"
121
-
style={{ width: `${searchProgress.total > 0 ? (searchProgress.searched / searchProgress.total) * 100 : 0}%` }}
139
+
<div
140
+
className="bg-firefly-banner dark:bg-firefly-banner-dark h-full rounded-full transition-all"
141
+
style={{
142
+
width: `${searchProgress.total > 0 ? (searchProgress.searched / searchProgress.total) * 100 : 0}%`,
143
+
}}
122
144
/>
123
145
</div>
124
146
</div>
···
127
149
{/* Skeleton Results - Matches layout of Results page */}
128
150
<div className="max-w-3xl mx-auto px-4 py-4 space-y-4">
129
151
{[...Array(8)].map((_, i) => (
130
-
<div key={i} className="bg-white/95 dark:bg-slate-800/95 backdrop-blur-xl rounded-2xl shadow-sm overflow-hidden animate-pulse border-2 border-slate-200 dark:border-slate-700">
152
+
<div
153
+
key={i}
154
+
className="bg-white/95 dark:bg-slate-800/95 backdrop-blur-xl rounded-2xl shadow-sm overflow-hidden animate-pulse border-2 border-slate-200 dark:border-slate-700"
155
+
>
131
156
{/* Source User Skeleton */}
132
157
<div className="p-4 bg-slate-50 dark:bg-slate-900/50 border-b-2 border-slate-200 dark:border-slate-700">
133
158
<div className="flex items-center space-x-3">
···
139
164
<div className="h-5 w-16 bg-slate-300 dark:bg-slate-600 rounded-full" />
140
165
</div>
141
166
</div>
142
-
167
+
143
168
{/* Match Skeleton */}
144
169
<div className="p-4">
145
170
<div className="flex items-start space-x-3 p-3 rounded-xl bg-amber-50 dark:bg-amber-900/10 border-2 border-amber-200 dark:border-amber-800/30">
···
158
183
</div>
159
184
</div>
160
185
);
161
-
}
186
+
}
+1
-5
src/pages/Login.tsx
+1
-5
src/pages/Login.tsx
···
31
31
<div className="text-center md:text-left">
32
32
<div className="justify-center md:justify-start mb-4">
33
33
<div className="logo-glow-container">
34
-
<img
35
-
src="src/assets/at-firefly-logo.svg"
36
-
className="w-50 h-15"
37
-
alt="ATlast logo"
38
-
/>
34
+
<FireflyLogo className="w-50 h-15" />
39
35
</div>
40
36
</div>
41
37
+2
-2
src/pages/Results.tsx
+2
-2
src/pages/Results.tsx
···
128
128
</div>
129
129
130
130
{/* Action Buttons */}
131
-
<div className="bg-white/95 dark:bg-slate-900 border-b-2 border-slate-200 dark:border-purple-500/30 sticky top-0 z-10 backdrop-blur-sm">
131
+
<div className="bg-white/95 dark:bg-slate-900 border-b-2 border-cyan-500/30 dark:border-purple-500/30 sticky top-0 z-10 backdrop-blur-sm">
132
132
<div className="max-w-3xl mx-auto px-4 py-3 flex space-x-2">
133
133
<button
134
134
onClick={onSelectAll}
135
-
className="flex-1 bg-orange-600 hover:bg-orange-500 text-white py-3 rounded-xl text-sm font-semibold transition-all shadow-md hover:shadow-lg"
135
+
className="flex-1 bg-orange-600 hover:bg-orange-400 text-white py-3 rounded-xl text-sm font-semibold transition-all shadow-md hover:shadow-lg"
136
136
type="button"
137
137
>
138
138
Select All
+1
-1
src/pages/Settings.tsx
+1
-1
src/pages/Settings.tsx
···
75
75
onClick={onOpenWizard}
76
76
className="w-full flex items-start space-x-4 p-4 bg-purple-100/20 dark:bg-slate-900/50 hover:bg-purple-100/40 dark:hover:bg-slate-900/70 rounded-xl transition-all text-left border-2 border-orange-650/50 dark:border-amber-400/50 hover:border-orange-500 dark:hover:border-amber-400 shadow-md hover:shadow-lg"
77
77
>
78
-
<div className="w-12 h-12 bg-gradient-to-r from-firefly-amber via-firefly-orange to-firefly-pink rounded-xl flex items-center justify-center flex-shrink-0 shadow-md">
78
+
<div className="w-12 h-12 bg-firefly-banner dark:bg-firefly-banner-dark rounded-xl flex items-center justify-center flex-shrink-0 shadow-md">
79
79
<SettingsIcon className="w-6 h-6 text-white" />
80
80
</div>
81
81
<div className="flex-1 min-w-0">