Skip to content

Commit

Permalink
Add filter option to add widget modal
Browse files Browse the repository at this point in the history
  • Loading branch information
bluecaret committed Oct 22, 2023
1 parent 4de5162 commit 0b8f11a
Show file tree
Hide file tree
Showing 19 changed files with 353 additions and 41 deletions.
50 changes: 40 additions & 10 deletions src/assets/lists.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ export const newFeatureCheckIgnoreList = [
'quotes', // quotes widget's quotes
]

export const widgetTags = [
{ label: 'Premium Access', translation: 'settings.tagPremium' },
{ label: 'Free', translation: 'settings.tagFree' },
{ label: 'Design', translation: 'settings.tagDesign' },
{ label: 'Focus', translation: 'settings.tagFocus' },
{ label: 'Fun', translation: 'settings.tagFun' },
{ label: 'Information', translation: 'settings.tagInformation' },
{ label: 'Inspiration', translation: 'settings.tagInspiration' },
{ label: 'Productivity', translation: 'settings.tagProductivity' },
{ label: 'Time and Date', translation: 'settings.tagTimeDate' },
{ label: 'Utility', translation: 'settings.tagUtility' },
{ label: 'Web', translation: 'settings.tagWeb' },
]

export const widgetTypes = [
{
id: 'dc',
Expand All @@ -15,6 +29,7 @@ export const widgetTypes = [
limit: 9999,
max: 9999,
desc: 'A sleek, modern way to keep track of the time, ensuring you always stay on schedule.',
tags: ['Free', 'Time and Date', 'Utility'],
},
{
id: 'ac',
Expand All @@ -25,6 +40,7 @@ export const widgetTypes = [
limit: 9999,
max: 9999,
desc: 'Embrace the charm of timeless elegance with an analog clock, offering a tasteful reminder of the passing hours and minutes.',
tags: ['Free', 'Time and Date', 'Utility'],
},
{
id: 'bc',
Expand All @@ -35,6 +51,7 @@ export const widgetTypes = [
limit: 5,
max: 9999,
desc: 'The perfect blend of tech and timekeeping, for those who appreciate a unique, coded perspective.',
tags: ['Free', 'Time and Date', 'Utility'],
},
{
id: 'dt',
Expand All @@ -45,6 +62,7 @@ export const widgetTypes = [
limit: 1,
max: 9999,
desc: 'Stay aligned with the rhythm of the year, displaying not only the date but also the day of the year, week of the year, and more.',
tags: ['Free', 'Time and Date', 'Utility'],
},
{
id: 'wr',
Expand All @@ -55,6 +73,7 @@ export const widgetTypes = [
limit: 1,
max: 6,
desc: 'Your personal meteorologist in your browser, offering key weather updates and forecasts at a glance.',
tags: ['Free', 'Information', 'Utility'],
},
{
id: 'td',
Expand All @@ -65,6 +84,7 @@ export const widgetTypes = [
limit: 1,
max: 9999,
desc: 'Your personalized task list at your fingertips, ensuring you stay focused and organized by managing your tasks directly from your new tab.',
tags: ['Free', 'Productivity', 'Utility'],
},
{
id: 'np',
Expand All @@ -75,6 +95,7 @@ export const widgetTypes = [
limit: 1,
max: 9999,
desc: 'Your digital canvas for thoughts, ideas, and reminders, ensuring you never miss a beat.',
tags: ['Free', 'Productivity', 'Utility'],
},
{
id: 'qt',
Expand All @@ -85,6 +106,7 @@ export const widgetTypes = [
limit: 1,
max: 9999,
desc: 'Your personal trove of wisdom and wit, this widget showcases your favorite quotes, handpicked and added by you.',
tags: ['Free', 'Inspiration'],
},
{
id: 'ql',
Expand All @@ -95,6 +117,7 @@ export const widgetTypes = [
limit: 2,
max: 9999,
desc: 'Your personal internet directory, curated by you, providing quick access to your favorite sites and saved bookmarks.',
tags: ['Free', 'Utility', 'Web', 'Productivity'],
},
{
id: 'sb',
Expand All @@ -105,16 +128,7 @@ export const widgetTypes = [
limit: 1,
max: 9999,
desc: 'Your portal to the web, with the freedom to choose your preferred search engine for more tailored results.',
},
{
id: 'if',
type: 'iframe',
store: 'iframes',
name: 'IFrame',
icon: 'fa-window-maximize',
limit: 0,
max: 9999,
desc: 'Seamlessly embed external web pages or content into your new tab. NOTE: Some websites are not compatible with the iframe.',
tags: ['Free', 'Utility', 'Web', 'Productivity'],
},
{
id: 'ls',
Expand All @@ -125,6 +139,18 @@ export const widgetTypes = [
limit: 9999,
max: 9999,
desc: 'Stay ahead of power outages with this informative widget, helping South African residents manage their schedules better.',
tags: ['Free', 'Information'],
},
{
id: 'if',
type: 'iframe',
store: 'iframes',
name: 'IFrame',
icon: 'fa-window-maximize',
limit: 0,
max: 9999,
desc: 'Seamlessly embed external web pages or content into your new tab. NOTE: Some websites are not compatible with the iframe.',
tags: ['Premium Access', 'Utility', 'Web'],
},
{
id: 'fg',
Expand All @@ -135,6 +161,7 @@ export const widgetTypes = [
limit: 0,
max: 9999,
desc: 'An interactive digital fidget toy to soothe ADHD and anxiety symptoms, offering tactile-like sensations for focused relaxation.',
tags: ['Premium Access', 'Fun', 'Focus'],
},
{
id: 'sk',
Expand All @@ -145,6 +172,7 @@ export const widgetTypes = [
limit: 0,
max: 9999,
desc: 'Maneuver a digital snake to collect items, adding a layer of dexterity and strategy to your browsing experience.',
tags: ['Premium Access', 'Fun'],
},
{
id: 'sh',
Expand All @@ -155,6 +183,7 @@ export const widgetTypes = [
limit: 0,
max: 9999,
desc: 'Add a touch of geometry to your browser, letting you personalize your new tab with a variety of shapes.',
tags: ['Premium Access', 'Design'],
},
{
id: 'tx',
Expand All @@ -165,6 +194,7 @@ export const widgetTypes = [
limit: 0,
max: 9999,
desc: 'A customizable text area where you can write your own messages or simply use it to personalize your new tab with your favorite saying.',
tags: ['Premium Access', 'Design'],
},
]

Expand Down
97 changes: 85 additions & 12 deletions src/components/elements/AddWidgetModal.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup>
import { ref, inject } from 'vue'
import { widgetTypes } from '@/assets/lists.js'
import { ref, inject, computed } from 'vue'
import { widgetTypes, widgetTags } from '@/assets/lists.js'
import { useSettingsStore } from '@/store.js'
const user = inject('user')
Expand All @@ -9,6 +9,12 @@ const emit = defineEmits(['selected'])
const show = ref(false)
const addWidgetBtnEl = ref(null)
const modalCloseEl = ref(null)
const currentTag = ref(null)
const filteredWidgets = computed(() => {
if (!currentTag.value) return widgetTypes
return widgetTypes.filter((widget) => widget.tags.includes(currentTag.value))
})
const handleWidgetClick = (type) => {
show.value = false
Expand All @@ -31,10 +37,20 @@ const handleOpenPremiumModal = () => {
store.showPremiumModal = true
store.premiumModalBtnRef = modalCloseEl
}
const filterByTag = (tag) => {
currentTag.value = tag
}
</script>

<template>
<ModalWindow :show="show" :button-ref="addWidgetBtnEl" size="1000px" @close="show = false">
<ModalWindow
window-class="addWidgetModal"
:show="show"
:button-ref="addWidgetBtnEl"
size="1000px"
@close="show = false"
>
<template #button>
<button ref="addWidgetBtnEl" type="button" class="btn btnText addBtn" @click.stop="show = true">
<fa icon="fa-plus"></fa>
Expand All @@ -56,8 +72,32 @@ const handleOpenPremiumModal = () => {
</button>
</header>
<div class="modalContent">
<div class="widgetTags">
<div>
<fa icon="fa-tags" fixed-width :title="$t('settings.filterByTag')" />
</div>
<div>
<button class="btn widgetTag" :class="{ active: !currentTag }" @click="filterByTag(null)">
<fa :icon="!currentTag ? 'fa-check' : 'fa-tag'" fixed-width />
{{ $t('settings.tagAll') }}
</button>
<button
v-for="tag in widgetTags"
:key="tag.translation"
class="btn widgetTag"
:class="{ active: currentTag === tag.label }"
@click="filterByTag(tag.label)"
>
<fa
:icon="currentTag === tag.label ? 'fa-check' : tag.label === 'Premium Access' ? 'fa-gem' : 'fa-tag'"
fixed-width
/>
{{ $t(tag.translation) }}
</button>
</div>
</div>
<ul class="widgetList">
<li v-for="widget in widgetTypes" :key="widget.type">
<li v-for="widget in filteredWidgets" :key="widget.type">
<button v-if="hasReachedMax(widget.type)" type="button" class="widgetItem widgetMax">
<div class="group compact">
<fa class="widgetItemIcon" :icon="widget.icon" fixed-width />
Expand Down Expand Up @@ -88,8 +128,8 @@ const handleOpenPremiumModal = () => {
<div v-if="widget.limit !== 0" class="widgetPremiumDesc">
<fa icon="fa-gem" /><span>{{ $t('settings.goPremiumForUnlimitedWidgetsAndMore') }}</span>
</div>
<div v-if="widget.limit === 0" class="widgetLimitDesc">
<span>{{ $t('settings.onlyAvailableWithPremiumAccess') }}</span>
<div v-if="widget.limit === 0" class="widgetLimitDesc widgetLimitDescTruncate">
<span :title="widget.desc">{{ widget.desc }}</span>
</div>
<div v-if="widget.limit === 0" class="widgetPremiumDesc">
<fa icon="fa-gem" /><span>{{ $t('settings.goPremiumToGetThisWidgetAndMoreCustomization') }}</span>
Expand All @@ -114,6 +154,12 @@ const handleOpenPremiumModal = () => {
</ModalWindow>
</template>

<style lang="scss">
.addWidgetModal {
height: min(90dvh, 1000px);
}
</style>

<style lang="scss" scoped>
.btn.addBtn {
width: 100%;
Expand All @@ -127,12 +173,37 @@ const handleOpenPremiumModal = () => {
background-color: hsl(var(--cBlockH) 0% calc(var(--cBlockL) - 11%));
}
}
.widgetTags {
display: grid;
grid-template-columns: auto 1fr;
align-items: center;
gap: var(--s4);
margin-block-end: var(--s5);
max-width: 950px; // avoid scrollbar changing list
> div {
display: flex;
flex-wrap: wrap;
gap: var(--s4);
}
}
.widgetTag {
padding: var(--s3) var(--s4);
border-radius: var(--s5);
font-size: 1.6rem;
min-height: unset;
.svg-inline--fa {
font-size: 1.2rem;
}
}
.widgetList {
list-style: none;
padding: 0;
margin: 0;
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 1fr;
gap: var(--s4);
li {
Expand All @@ -148,6 +219,7 @@ const handleOpenPremiumModal = () => {
border: 0;
width: 100%;
height: 100%;
min-height: 16.5rem;
display: grid;
grid-template: auto 1fr / 1fr;
gap: var(--s4);
Expand Down Expand Up @@ -193,11 +265,6 @@ const handleOpenPremiumModal = () => {
.widgetMax,
.widgetPremium {
grid-template: auto 1fr / 1fr;
position: absolute;
inset: 0 0 0 0;
height: auto;
z-index: 2;
background-blend-mode: darken;
background-color: hsl(var(--g2H) calc(var(--g2S) - 40%) calc(var(--g2L) - 0.5%));
--iconBg: hsl(var(--g2H) calc(var(--g2S) - 40%) calc(var(--g2L) - 1.5%));
Expand All @@ -219,6 +286,12 @@ const handleOpenPremiumModal = () => {
gap: var(--s4);
color: var(--cTextSubtle);
}
.widgetLimitDescTruncate {
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.widgetPremiumDesc {
font-size: 1.4rem;
display: flex;
Expand Down
18 changes: 16 additions & 2 deletions src/components/elements/ModalWindow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ const props = defineProps({
type: String,
default: '800px',
},
windowClass: {
type: String,
default: '',
},
buttonRef: {
type: Object,
},
Expand Down Expand Up @@ -59,7 +63,12 @@ onBeforeUnmount(() => {
<Transition name="modalTransition">
<div v-if="props.show" class="modalWindowWrapper">
<div class="modalOverlay"></div>
<div ref="modalWindowEl" tabindex="-1" class="modalWindow" :style="modalWidth">
<div
ref="modalWindowEl"
tabindex="-1"
:class="`modalWindow ${props.windowClass ? props.windowClass : ''}`"
:style="modalWidth"
>
<slot name="window"> </slot>
</div>
</div>
Expand All @@ -70,7 +79,12 @@ onBeforeUnmount(() => {
<Transition name="modalTransition">
<div v-if="props.show" class="modalWindowWrapper">
<div class="modalOverlay"></div>
<div ref="modalWindowEl" tabindex="-1" class="modalWindow" :style="modalWidth">
<div
ref="modalWindowEl"
tabindex="-1"
:class="`modalWindow ${props.windowClass ? props.windowClass : ''}`"
:style="modalWidth"
>
<slot name="window"> </slot>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/elements/PremiumModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const handleSubscribe = () => {
<span><fa icon="fa-cubes" /></span>
<div>
{{ $t('settings.premiumWidgets') }}
<div>IFrame, Shapes, Text, Fidget Toy, Snake Game.</div>
<div>IFrame, Fidget Toy, Snake Game, Shapes, Text.</div>
</div>
</li>
<li>
Expand Down
Loading

0 comments on commit 0b8f11a

Please sign in to comment.