feat(marketplace): Add suggested packs feature to marketplace

- Introduced new SuggestedPacks component to display trending quote and photo packs.
- Implemented useSuggestedPacks hook for fetching and caching suggested packs from the marketplace.
- Updated localization files for multiple languages to include new strings for suggested packs.
- Added explore all button to navigate to the marketplace category page.
This commit is contained in:
alexsparkes
2026-02-07 11:02:29 +00:00
parent 5cbcee522b
commit 474b4ae237
41 changed files with 405 additions and 6 deletions

View File

@@ -162,10 +162,14 @@ function MainModal({ modalClose, deepLinkData }) {
const handleSectionChange = (section, sectionName) => {
setCurrentSection(section);
setCurrentSectionName(sectionName);
setCurrentSubSection(null);
const entry = { section, sectionName, subSection: null };
// Only reset subsection if we're actually changing to a different section
// Don't reset on initial section set (when currentSectionName is empty)
if (currentSectionName !== '' && currentSectionName !== sectionName) {
setCurrentSubSection(null);
}
const entry = { section, sectionName, subSection: (currentSectionName === '' || currentSectionName === sectionName) ? currentSubSection : null };
const current = historyRef.current[historyIndexRef.current];
if (!current || current.sectionName !== sectionName || current.subSection !== null) {
if (!current || current.sectionName !== sectionName || current.subSection !== entry.subSection) {
historyRef.current = historyRef.current.slice(0, historyIndexRef.current + 1).concat(entry);
historyIndexRef.current = historyRef.current.length - 1;
updateNavButtons();
@@ -183,7 +187,11 @@ function MainModal({ modalClose, deepLinkData }) {
updateHash(`#${currentTab}/${sectionKey}`);
}
} else if (currentTab === TAB_TYPES.SETTINGS && sectionName) {
updateHash(`#${currentTab}/${sectionName}`, false);
// Include subsection in hash if it exists and we're not changing sections
const hash = currentSubSection && (currentSectionName === '' || currentSectionName === sectionName)
? `#${currentTab}/${sectionName}/${currentSubSection}`
: `#${currentTab}/${sectionName}`;
updateHash(hash, false);
}
};

View File

@@ -13,10 +13,11 @@
// height: 100%;
overflow-y: auto;
margin-bottom: 0;
padding-bottom: 2rem;
@include themed {
background: t($modal-background);
margin: 0;
border-radius: t($borderRadius);
}

View File

@@ -4,6 +4,7 @@ import { Dropdown } from 'components/Form/Settings';
import { Row, Content, Action } from 'components/Layout/Settings/Item';
import { Button } from 'components/Elements';
import Items from 'features/marketplace/components/Items/Items';
import SuggestedPacks from 'features/marketplace/components/SuggestedPacks';
import { getBackgroundOptionItems } from '../optionTypes';
const SourceSection = ({
@@ -70,6 +71,7 @@ const SourceSection = ({
viewType="grid"
showChips={false}
/>
<SuggestedPacks category="photo_packs" />
</>
)}
</>

View File

@@ -278,6 +278,7 @@ function Items({
onTogglePack,
viewType = 'grid',
showChips = true,
style,
}) {
const [selectedCategory, setSelectedCategory] = useState('all');
const [sortType, setSortType] = useState(localStorage.getItem('sortMarketplace') || 'a-z');
@@ -329,7 +330,7 @@ function Items({
/>
</div>
)}
<div className={`items ${viewType === 'list' ? 'items-list' : 'items-grid'}`}>
<div className={`items ${viewType === 'list' ? 'items-list' : 'items-grid'}`} style={style}>
{items
?.filter((item) => filterItems(item, filter, filterOptions ? selectedCategory : 'all'))
.map((item, index) => (

View File

@@ -0,0 +1,74 @@
import React from 'react';
import { MdExplore } from 'react-icons/md';
import { useT } from 'contexts';
import { Row, Content, Action } from 'components/Layout/Settings';
import { Button } from 'components/Elements';
import Items from 'features/marketplace/components/Items/Items';
import { updateHash } from 'utils/deepLinking';
import { useSuggestedPacks } from './useSuggestedPacks';
/**
* Component that displays suggested packs from the marketplace
* @param {Object} props
* @param {string} props.category - 'quote_packs' or 'photo_packs'
* @param {number} props.limit - Number of suggestions to display (default: 4)
* @param {number} props.minToShow - Minimum suggestions to show, hide if fewer (default: 2)
*/
const SuggestedPacks = ({ category, limit = 4, minToShow = 2 }) => {
const t = useT();
const { suggestions, loading, error } = useSuggestedPacks(category, limit, minToShow);
// Don't render anything while loading, on error, or if no suggestions
if (loading || error || !suggestions || suggestions.length === 0) {
return null;
}
// Determine the section key based on category
const sectionKey = category === 'quote_packs' ? 'quote' : 'background';
// Navigate to marketplace category page
const goToMarketplace = () => {
updateHash(`#discover/${category}`);
const event = new window.Event('popstate');
window.dispatchEvent(event);
};
// Navigate to specific item detail page
const navigateToItem = (item) => {
const itemId = item.id || item.name;
updateHash(`#discover/${category}/${itemId}`);
const event = new window.Event('popstate');
window.dispatchEvent(event);
};
return (
<>
<Row final={false}>
<Content
title={t(`modals.main.settings.sections.${sectionKey}.suggested_packs_title`)}
subtitle={t(`modals.main.settings.sections.${sectionKey}.suggested_packs_subtitle`)}
/>
<Action>
<Button
type="settings"
onClick={goToMarketplace}
icon={<MdExplore />}
label={t(`modals.main.settings.sections.${sectionKey}.explore_all`)}
/>
</Action>
</Row>
<Items
items={suggestions}
isAdded={false}
filter=""
toggleFunction={navigateToItem}
showCreateYourOwn={false}
viewType="grid"
showChips={false}
style={{ paddingBottom: '3rem' }}
/>
</>
);
};
export default SuggestedPacks;

View File

@@ -0,0 +1,2 @@
export { default } from './SuggestedPacks';
export { useSuggestedPacks } from './useSuggestedPacks';

View File

@@ -0,0 +1,111 @@
import { useState, useEffect, useCallback } from 'react';
import { API_URL } from 'config/constants';
import { safeParseJSON } from 'utils/jsonStorage';
/**
* Custom hook for fetching and caching suggested packs from the marketplace
* @param {string} category - 'quote_packs' or 'photo_packs'
* @param {number} limit - Number of suggestions to display (default: 4)
* @param {number} minToShow - Minimum number of suggestions to show, hide if fewer (default: 2)
* @returns {Object} - { suggestions, loading, error, refresh }
*/
export function useSuggestedPacks(category, limit = 4, minToShow = 2) {
const [suggestions, setSuggestions] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const cacheKey = `suggested_${category}`;
const timestampKey = `${cacheKey}_timestamp`;
const cacheExpiryMs = 24 * 60 * 60 * 1000; // 24 hours
const getInstalledPackIds = useCallback(() => {
const installed = safeParseJSON('installed', []);
// Create a Set of installed pack IDs for O(1) lookup
return new Set(installed.map((item) => item.id));
}, []);
const isCacheValid = useCallback(() => {
const timestamp = localStorage.getItem(timestampKey);
if (!timestamp) return false;
return Date.now() - Number(timestamp) < cacheExpiryMs;
}, [timestampKey, cacheExpiryMs]);
const fetchSuggestions = useCallback(async () => {
try {
setLoading(true);
setError(null);
// Check cache first
if (isCacheValid()) {
const cached = safeParseJSON(cacheKey, null);
if (cached && Array.isArray(cached)) {
const installedIds = getInstalledPackIds();
const filtered = cached.filter((item) => !installedIds.has(item.id));
// Only show if we have at least minToShow suggestions
if (filtered.length >= minToShow) {
setSuggestions(filtered.slice(0, limit));
} else {
setSuggestions(null);
}
setLoading(false);
return;
}
}
// Fetch from API - request more than we need to account for filtering
const response = await fetch(`${API_URL}/marketplace/trending?limit=${limit + 4}&category=${category}`);
if (!response.ok) {
throw new Error(`API responded with status ${response.status}`);
}
const data = await response.json();
const trendingItems = data.data || [];
// Cache the raw trending results
try {
localStorage.setItem(cacheKey, JSON.stringify(trendingItems));
localStorage.setItem(timestampKey, Date.now().toString());
} catch (cacheError) {
console.warn('Failed to cache suggestions:', cacheError);
}
// Filter out installed packs
const installedIds = getInstalledPackIds();
const filtered = trendingItems.filter((item) => !installedIds.has(item.id));
// Only show if we have at least minToShow suggestions
if (filtered.length >= minToShow) {
setSuggestions(filtered.slice(0, limit));
} else {
setSuggestions(null);
}
setLoading(false);
} catch (err) {
console.error('Failed to fetch suggested packs:', err);
setError(err);
setSuggestions(null);
setLoading(false);
}
}, [category, limit, minToShow, cacheKey, timestampKey, isCacheValid, getInstalledPackIds]);
const refresh = useCallback(() => {
// Clear cache and refetch
localStorage.removeItem(cacheKey);
localStorage.removeItem(timestampKey);
fetchSuggestions();
}, [cacheKey, timestampKey, fetchSuggestions]);
useEffect(() => {
fetchSuggestions();
}, [fetchSuggestions]);
return {
suggestions,
loading,
error,
refresh,
};
}

View File

@@ -26,6 +26,7 @@ import { Checkbox, ColourPicker, Dropdown, Textarea } from 'components/Form/Sett
import { Button } from 'components/Elements';
import { FREQUENCY_OPTIONS } from 'utils/frequencyManager';
import Items from 'features/marketplace/components/Items/Items';
import SuggestedPacks from 'features/marketplace/components/SuggestedPacks';
import { uninstall } from 'utils/marketplace';
import { updateHash } from 'utils/deepLinking';
import './QuoteOptions.scss';
@@ -461,6 +462,7 @@ const QuoteOptions = ({ currentSubSection, onSubSectionChange, sectionName }) =>
viewType="grid"
showChips={false}
/>
<SuggestedPacks category="quote_packs" />
</>
);
} else {

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "قم بتعيين اقتباساتك المخصصة",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "لا توجد اقتباسات",
"author": "المؤلف",
"custom_buttons": "الأزرار",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Set your own custom quotes",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "No quotes",
"author": "Author",
"custom_buttons": "Buttons",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Öz xüsusi sitatlarınızı təyin edin",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "Sitat yoxdur",
"author": "Müəllif",
"custom_buttons": "Düymələr",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Öz xüsusi sitatlarınızı təyin edin",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "Sitat yoxdur",
"author": "Müəllif",
"custom_buttons": "Düymələr",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Set your own custom quotes",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "No quotes",
"author": "লেখক",
"custom_buttons": "Buttons",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Legen Sie Ihre eigenen Zitate fest",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "Keine Zitate",
"author": "Autor",
"custom_buttons": "Schaltflächen",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Set your own custom quotes",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "No quotes",
"author": "Author",
"custom_buttons": "Buttons",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Set your own custom quotes",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "No quotes",
"author": "Author",
"custom_buttons": "Buttons",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Set your own custom quotes",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "No quotes",
"author": "Author",
"custom_buttons": "Buttons",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Establece tus propias cotizaciones personalizados",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "Sin comillas",
"author": "Autor",
"custom_buttons": "Botones",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Set your own custom quotes",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "No quotes",
"author": "Author",
"custom_buttons": "Buttons",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Määra oma kohandatud tsitaadid",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "Tsitaate pole",
"author": "Autor",
"custom_buttons": "Nupud",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Set your own custom quotes",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "No quotes",
"author": "Author",
"custom_buttons": "Buttons",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Définir vos propres citations",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "Pas de citations",
"author": "Auteur",
"custom_buttons": "Boutons",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Set your own custom quotes",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "No quotes",
"author": "Author",
"custom_buttons": "Buttons",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Tetapkan kutipan khusus Anda sendiri",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "Tidak ada kutipan",
"author": "Kreator",
"custom_buttons": "Tombol",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Set your own custom quotes",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "No quotes",
"author": "Author",
"custom_buttons": "Buttons",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Nustatykite savo pasirinktines citatas",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "Nėra citatų",
"author": "Autorius",
"custom_buttons": "Mygtukai",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Iestatiet savus pielāgotos citātus",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "Nav citātu",
"author": "Autors",
"custom_buttons": "Pogas",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Schrijf je eigen citaten",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "Geen citaten",
"author": "Auteur",
"custom_buttons": "Knoppen",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Set your own custom quotes",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "No quotes",
"author": "Author",
"custom_buttons": "Buttons",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Set your own custom quotes",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "No quotes",
"author": "Author",
"custom_buttons": "Buttons",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Define as suas próprias citações personalizadas",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "sem aspas",
"author": "Autor",
"custom_buttons": "Botões",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Defina suas próprias citações personalizadas",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "sem aspas",
"author": "Autor",
"custom_buttons": "Botões",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Установите свои собственные пользовательские цитаты",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "Без кавычек",
"author": "Автор",
"custom_buttons": "Кнопки",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Nastavite svoje lastne citate",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "Brez citatov",
"author": "Avtor",
"custom_buttons": "Gumbi",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Set your own custom quotes",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "No quotes",
"author": "Author",
"custom_buttons": "Buttons",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "உங்கள் சொந்த தனிப்பயன் மேற்கோள்களை அமைக்கவும்",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "மேற்கோள்கள் இல்லை",
"author": "நூலாசிரியர்",
"custom_buttons": "பொத்தான்கள்",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Kendi özel alıntınızı belirleyin, ekleyin.",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "Alıntı yok",
"author": "Yazar",
"custom_buttons": "Butonlar",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Встановіть свої власні користувацьки цитати",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "Без лапок",
"author": "Автор",
"custom_buttons": "Кнопки",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Set your own custom quotes",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "No quotes",
"author": "Author",
"custom_buttons": "Buttons",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "自定义名言",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "没有名言",
"author": "作者",
"custom_buttons": "按钮",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"

View File

@@ -218,6 +218,9 @@
"custom_subtitle": "Set your own custom quotes",
"installed_packs_title": "Installed Quote Packs",
"get_more": "Get More",
"suggested_packs_title": "Suggested Quote Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"no_quotes": "No quotes",
"author": "Author",
"custom_buttons": "Buttons",
@@ -437,6 +440,9 @@
"day": "Once a day"
},
"installed_packs_title": "Installed Photo Packs",
"suggested_packs_title": "Suggested Photo Packs",
"suggested_packs_subtitle": "Trending packs you might like",
"explore_all": "Explore All",
"photo_pack_settings": {
"title": "{name} Settings",
"refresh_photos": "Refresh Photos"