web: the reel is curated, not crowd-sourced — no CONTRIBUTE button

This commit is contained in:
2026-09-18 21:02:30 +07:00
parent d25649a26b
commit d3c5c47973
3 changed files with 1 additions and 50 deletions
+1 -44
View File
@@ -175,8 +175,6 @@ export function Landing() {
const asked = new URLSearchParams(window.location.search).get('auth');
return asked === 'signup' ? 'signup' : asked ? 'login' : null;
});
const [uploading, setUploading] = useState(false);
const filePick = useRef<HTMLInputElement>(null);
const toastTimer = useRef<ReturnType<typeof setTimeout>>();
// Marketing copy, picked by the workspace's language switch.
@@ -206,19 +204,6 @@ export function Landing() {
reload();
}, [reload]);
const contribute = useCallback(async (file: File) => {
setUploading(true);
try {
const { photo } = await api.uploadPhoto(file);
setPhotos((prev) => [photo, ...prev]);
showToast(t('photo.thanks'));
} catch (err) {
showToast(t('photo.failed', { msg: err instanceof Error ? err.message : String(err) }));
} finally {
setUploading(false);
}
}, [showToast, t]);
// One vote. The visitor may change their mind: the API upserts under the same
// address hash, so a second click replaces the first rather than stacking. A
// vote that never lands is silently dropped — it is not worth a toast.
@@ -561,36 +546,8 @@ export function Landing() {
<div>
<span className="lp-eyebrow">{c({ en: 'Community film strip', vi: 'Dải phim cộng đồng' })}</span>
<h2>{c({ en: 'Shoot it, grade it, hang it on the reel', vi: 'Chụp, chỉnh màu, rồi treo lên dải phim' })}</h2>
<p>{c({ en: 'Signed-in members can add a still of their own to the strip below, seen by everyone who lands here.', vi: 'Thành viên đã đăng nhập có thể thêm một khung ảnh của mình vào dải phim bên dưới, ai ghé trang cũng thấy.' })}</p>
<p>{c({ en: 'Every still here is picked and placed by the studio — this reel is curated, not crowd-sourced.', vi: 'Mọi khung ảnh ở đây đều do studio chọn và đặt — dải phim này được tuyển chọn, không phải ai cũng tự thêm được.' })}</p>
</div>
{user ? (
<button
type="button"
className="lp-btn lp-primary"
data-key="contribute"
disabled={uploading}
onClick={() => filePick.current?.click()}
>
{uploading ? t('photo.uploading') : t('photo.contribute')}
</button>
) : (
/* A guest gets the same button; it opens the sign-in dialog. */
<button type="button" className="lp-btn lp-primary" data-key="contribute" onClick={() => setAuth('login')}>
{t('photo.contribute')}
</button>
)}
<input
ref={filePick}
type="file"
hidden
accept="image/jpeg,image/png,image/webp"
data-key="contribute-input"
onChange={(e) => {
const file = e.target.files?.[0];
e.target.value = '';
if (file) void contribute(file);
}}
/>
</div>
<div className="lp-track">
{[...reel, ...reel].map((look, i) => {
-3
View File
@@ -143,10 +143,7 @@ export const en: Dict = {
'del.confirm': 'DELETE PHOTO',
'del.cancel': 'CANCEL',
'photo.contribute': 'CONTRIBUTE A PHOTO',
'photo.uploading': 'UPLOADING…',
'photo.thanks': 'Your frame is in the strip.',
'photo.failed': 'Upload failed: {msg}',
'photos.title': 'My photos',
'photos.hint': 'Each account keeps up to {max} photos. What the studio saves lives here and shows up on the community reel.',
-3
View File
@@ -151,10 +151,7 @@ export const vi = {
'del.confirm': 'XOÁ ẢNH',
'del.cancel': 'HUỶ',
'photo.contribute': 'ĐÓNG GÓP ẢNH',
'photo.uploading': 'ĐANG TẢI…',
'photo.thanks': 'Ảnh của bạn đã vào dải phim.',
'photo.failed': 'Không tải được ảnh: {msg}',
'photos.title': 'Ảnh của tôi',
'photos.hint': 'Mỗi tài khoản giữ tối đa {max} ảnh. Ảnh lưu từ studio nằm ở đây và xuất hiện trên dải phim cộng đồng.',