From f5a802d651db90cc414dd23eab741e2e55d15074 Mon Sep 17 00:00:00 2001 From: Lu Wilson Date: Tue, 9 Jun 2026 18:07:55 +0100 Subject: [PATCH 01/11] interest picker --- .../InterestsSettingsPage.vue | 302 +++++++++++ .../template-homepage/InterestsToggleChip.vue | 68 +++ .../template-homepage/SuggestedEditsView.vue | 62 ++- .../suggested-edits/data/interestsFixtures.ts | 187 +++++++ .../suggested-edits/data/interestsSearch.ts | 133 +++++ .../data/useInterestsSettings.ts | 471 ++++++++++++++++++ .../suggested-edits/index.vue | 20 +- 7 files changed, 1234 insertions(+), 9 deletions(-) create mode 100644 src/prototypes/template-homepage/InterestsSettingsPage.vue create mode 100644 src/prototypes/template-homepage/InterestsToggleChip.vue create mode 100644 src/prototypes/template-homepage/suggested-edits/data/interestsFixtures.ts create mode 100644 src/prototypes/template-homepage/suggested-edits/data/interestsSearch.ts create mode 100644 src/prototypes/template-homepage/suggested-edits/data/useInterestsSettings.ts diff --git a/src/prototypes/template-homepage/InterestsSettingsPage.vue b/src/prototypes/template-homepage/InterestsSettingsPage.vue new file mode 100644 index 0000000..d3ea020 --- /dev/null +++ b/src/prototypes/template-homepage/InterestsSettingsPage.vue @@ -0,0 +1,302 @@ + + + + + diff --git a/src/prototypes/template-homepage/InterestsToggleChip.vue b/src/prototypes/template-homepage/InterestsToggleChip.vue new file mode 100644 index 0000000..a9113ae --- /dev/null +++ b/src/prototypes/template-homepage/InterestsToggleChip.vue @@ -0,0 +1,68 @@ + + + + + diff --git a/src/prototypes/template-homepage/SuggestedEditsView.vue b/src/prototypes/template-homepage/SuggestedEditsView.vue index c545b2b..9e0c95c 100644 --- a/src/prototypes/template-homepage/SuggestedEditsView.vue +++ b/src/prototypes/template-homepage/SuggestedEditsView.vue @@ -52,7 +52,7 @@ interface Props { const props = withDefaults(defineProps(), { showFilterBar: false, - topicFilter: 'Music', + topicFilter: 'Interests', difficultyFilter: 'Easy, Medium', currentIndex: 0, totalCount: 1, @@ -82,9 +82,9 @@ const emit = defineEmits<{ load: [] refresh: [] navigate: [delta: number] + 'open-interests': [] }>() -const topicMenuItems = computed(() => [{ value: 'music', label: props.topicFilter }]) const difficultyMenuItems = computed(() => [{ value: 'mixed', label: props.difficultyFilter }]) const displayIndex = computed(() => (props.currentIndex ?? 0) + 1) @@ -122,6 +122,10 @@ function onRefreshClick(): void { function onNavigate(delta: number): void { emit('navigate', delta) } + +function onOpenInterests(): void { + emit('open-interests') +} diff --git a/src/prototypes/no-distractions/screens/AllSuggestionsScreen.vue b/src/prototypes/no-distractions/screens/AllSuggestionsScreen.vue index def8764..06eafe1 100644 --- a/src/prototypes/no-distractions/screens/AllSuggestionsScreen.vue +++ b/src/prototypes/no-distractions/screens/AllSuggestionsScreen.vue @@ -1,17 +1,31 @@ + + + + diff --git a/src/prototypes/no-distractions/screens/InterestsScreen.vue b/src/prototypes/no-distractions/screens/InterestsScreen.vue index 3ce89e9..7596acd 100644 --- a/src/prototypes/no-distractions/screens/InterestsScreen.vue +++ b/src/prototypes/no-distractions/screens/InterestsScreen.vue @@ -1,15 +1,21 @@ @@ -49,6 +51,8 @@ function onBookmark(): void {
+ + diff --git a/src/prototypes/no-distractions/screens/TrendingScreen.vue b/src/prototypes/no-distractions/screens/TrendingScreen.vue new file mode 100644 index 0000000..e2d17ad --- /dev/null +++ b/src/prototypes/no-distractions/screens/TrendingScreen.vue @@ -0,0 +1,141 @@ + + + + + diff --git a/src/prototypes/template-homepage/impact/data/fetchUserImpact.ts b/src/prototypes/template-homepage/impact/data/fetchUserImpact.ts index 5b5311c..e1a00c6 100644 --- a/src/prototypes/template-homepage/impact/data/fetchUserImpact.ts +++ b/src/prototypes/template-homepage/impact/data/fetchUserImpact.ts @@ -11,6 +11,7 @@ * - "Most viewed" rows: top 3 articles by those view counts (not merely the 3 most recent edits). */ import { normalizeWikiUsername, wikimediaApiFetchHeaders, wikiHostFromLang } from '@/config' +import { formatRelativeTime, parseMediaWikiTimestamp } from '@/lib/mediaWikiTime' import type { ImpactData, ImpactMostViewedArticle } from './impactTypes' const METRICS_HOST = 'wikimedia.org' @@ -67,16 +68,6 @@ function actionUrl(wikiHost: string, params: Record): string { return `https://${wikiHost}/w/api.php?${search.toString()}` } -/** Parse Action API timestamps (`2026-02-23T09:12:59Z` or `2013-07-31 11:54:03`). */ -function parseMediaWikiTimestamp(timestamp: string): Date { - const trimmed = timestamp.trim() - if (!trimmed.length) return new Date(Number.NaN) - if (trimmed.includes('T')) { - return new Date(trimmed.endsWith('Z') ? trimmed : `${trimmed}Z`) - } - return new Date(trimmed.replace(' ', 'T') + 'Z') -} - function toPageviewDateParam(date: Date): string { const y = date.getUTCFullYear() const m = String(date.getUTCMonth() + 1).padStart(2, '0') @@ -95,26 +86,6 @@ function pageviewsArticleSlug(title: string): string { return encodeURIComponent(title.replace(/ /g, '_')) } -function formatRelativeTime(isoTimestamp: string): string { - const then = parseMediaWikiTimestamp(isoTimestamp).getTime() - if (Number.isNaN(then)) return '—' - const diffMs = Date.now() - then - if (diffMs < 0) return 'just now' - - const minutes = Math.floor(diffMs / (1000 * 60)) - const hours = Math.floor(diffMs / (1000 * 60 * 60)) - const days = Math.floor(diffMs / (1000 * 60 * 60 * 24)) - - if (minutes < 1) return 'just now' - if (minutes < 60) return minutes === 1 ? '1 minute ago' : `${minutes} minutes ago` - if (hours < 24) return hours === 1 ? '1 hour ago' : `${hours} hours ago` - if (days === 1) return '1 day ago' - if (days < 30) return `${days} days ago` - const months = Math.floor(days / 30) - if (months === 1) return '1 month ago' - return `${months} months ago` -} - function formatShortDate(date: Date): string { return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }) }