Skip to content

Commit

Permalink
Add base structure
Browse files Browse the repository at this point in the history
  • Loading branch information
kadiryazici committed Oct 22, 2023
1 parent 27f1a01 commit ab73ee6
Show file tree
Hide file tree
Showing 10 changed files with 270 additions and 9 deletions.
2 changes: 2 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ module.exports = {
'vue/v-on-event-hyphenation': 'off',
'@typescript-eslint/no-unused-vars': 'error',
'vue/custom-event-name-casing': 'off',
// Breaks vue's multiple script tags
'import/first': 'off',
'vue/max-attributes-per-line': ['error', {
singleline: {
max: 1,
Expand Down
85 changes: 85 additions & 0 deletions src/components/Dialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<script lang="ts">
function transitionHandle(bg: HTMLElement, done: () => void, enter = true) {
const content = bg.querySelector('.dialog-body') as HTMLElement
bg.animate([
{ backgroundColor: 'rgba(0, 0, 0, 0)' },
{ backgroundColor: bg.style.backgroundColor },
], {
duration: 250,
fill: 'forwards',
direction: enter ? 'normal' : 'reverse',
})
content.animate([
{ transform: 'scale(0.9)', opacity: 0 },
{ transform: 'scale(1)', opacity: 1 },
], {
duration: 250,
fill: 'forwards',
direction: enter ? 'normal' : 'reverse',
}).onfinish = done
}
</script>

<script lang="ts" setup>
interface Props {
title: string
visible: boolean
}
interface Emits {
(name: 'update:visible', value: boolean): void
}
const props = defineProps<Props>()
const emit = defineEmits<Emits>()
</script>

<template>
<Teleport to="body">
<Transition
appear
@enter="(el, done) => transitionHandle(el as HTMLElement, done, true)"

Check failure on line 43 in src/components/Dialog.vue

View workflow job for this annotation

GitHub Actions / Type Check

Parameter 'el' implicitly has an 'any' type.

Check failure on line 43 in src/components/Dialog.vue

View workflow job for this annotation

GitHub Actions / Type Check

Parameter 'done' implicitly has an 'any' type.
@leave="(el, done) => transitionHandle(el as HTMLElement, done, false)"

Check failure on line 44 in src/components/Dialog.vue

View workflow job for this annotation

GitHub Actions / Type Check

Parameter 'el' implicitly has an 'any' type.

Check failure on line 44 in src/components/Dialog.vue

View workflow job for this annotation

GitHub Actions / Type Check

Parameter 'done' implicitly has an 'any' type.
>
<div
v-if="props.visible"
class="dialog-bg"
@click.self="emit('update:visible', false)"
>
<div class="dialog-body">
<div class="dialog-title">
{{ props.title }}
</div>
<div class="dialog-content">
<slot />
</div>
</div>
</div>
</Transition>
</Teleport>
</template>

<style lang="scss" scoped>
.dialog-bg {
position: fixed;
inset: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
padding: 25px;
.dialog-content {
background-color: var(--content-bg);
border-radius: 8px;
min-width: 33%;
overflow: hidden;
display: flex;
flex-direction: column;
box-shadow: 0px 3px 8px -5px rgba(0, 0, 0, 0.3);
}
}
</style>
30 changes: 30 additions & 0 deletions src/components/PageHeader.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
<script lang="ts" setup>
import { Icons } from './Icons'
import SlotRef from './SlotRef.vue'
import Tooltip from './Tooltip.vue'
interface Props {
inline?: boolean
dot?: boolean
info?: string
}
withDefaults(defineProps<Props>(), {
Expand All @@ -20,6 +25,23 @@ withDefaults(defineProps<Props>(), {
/>

<slot />

<SlotRef v-if="info != null">
<template #default>
<div class="header-info">
<Icons.Question />
</div>
</template>

<template #ref="{ el }">
<Tooltip
style="width: 275px; text-align: left"
:text="info"
:target="el"
position="top"
/>
</template>
</SlotRef>
</header>
</template>

Expand All @@ -43,5 +65,13 @@ withDefaults(defineProps<Props>(), {
&-inline {
display: inline-block;
}
&-info {
margin-left: 5px;
color: var(--accent-color);
font-size: 14px;
vertical-align: middle;
display: inline-flex;
}
}
</style>
2 changes: 1 addition & 1 deletion src/components/SettingItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ defineProps<Props>()
</div>
</template>

<style lang="scss">
<style lang="scss" scoped>
.setting-item {
display: flex;
flex-direction: row;
Expand Down
76 changes: 76 additions & 0 deletions src/components/SettingsSilentHours.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<script lang="ts">
export const SilentHourDays = {
Monday: 1,
Tuesday: 2,
Wednesday: 3,
Thursday: 4,
Friday: 5,
Saturday: 6,
Sunday: 0,
}
export interface SilentHourContext {
repoName: string
start: string
end: string
days: number[]
}
interface Props {
context?: SilentHourContext[]
}
const mockListData = [
{
repoName: 'test',
start: '10:00',
end: '12:00',
days: [SilentHourDays.Monday, SilentHourDays.Tuesday],
},
{
repoName: 'test2',
start: '10:00',
end: '12:00',
days: [SilentHourDays.Monday, SilentHourDays.Tuesday],
},
]
</script>

<script lang="ts" setup>
import { ref } from 'vue'
import Dialog from './Dialog.vue'
import PageHeader from './PageHeader.vue'
import SettingsSilentHoursAddButton from './SettingsSilentHoursAddButton.vue'
import SettingsSilentHoursItem from './SettingsSilentHoursItem.vue'
withDefaults(defineProps<Props>(), {
context: () => [],
})
const dialogVisible = ref(false)
</script>

<template>
<PageHeader
dot
style="margin: 20px 0px;"
info="You can select specific hours not to receive any system notification and not to play sound for a spesific repository."
>
Silent Hours
</PageHeader>

<SettingsSilentHoursItem
v-for="item in mockListData"
:key="item.repoName"
:context="item"
/>

<SettingsSilentHoursAddButton @click="dialogVisible = true" />

<Dialog
v-model:visible="dialogVisible"
title="Add Silent Hour"
>
Bruh
</Dialog>
</template>
37 changes: 37 additions & 0 deletions src/components/SettingsSilentHoursAddButton.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<script lang="ts" setup>
import { Icons } from './Icons'
import SlotRef from './SlotRef.vue'
import Tooltip from './Tooltip.vue'
</script>

<template>
<SlotRef>
<template #default>
<button class="settings-silent-hours-add-button">
<Icons.Plus16 />
</button>
</template>

<template #ref="{ el }">
<Tooltip
text="Create new silent hour"
:target="el"
/>
</template>
</SlotRef>
</template>

<style lang="scss" scoped>
.settings-silent-hours-add-button {
width: 100%;
background-color: var(--item-bg);
padding: 10px;
font-size: 16px;
border-radius: 8px;
color: var(--text);
&:hover {
background-color: var(--item-hover-bg);
}
}
</style>
17 changes: 17 additions & 0 deletions src/components/SettingsSilentHoursItem.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<script lang="ts">
import { type SilentHourContext } from './SettingsSilentHours.vue'
interface Props {
context: SilentHourContext
}
</script>

<script lang="ts" setup>
defineProps<Props>()
</script>

<template>
<div>
Testo
</div>
</template>
5 changes: 3 additions & 2 deletions src/composables/useI18n.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { createSharedComposable, reactiveComputed } from '@vueuse/core'
import { reactiveComputed } from '@vueuse/core'
import { Fragment, customRef, h } from 'vue'
import { AppStorage } from '../storage'
import { type NotificationReason } from '../constants'
import { singleton } from '../utils/common'

export type Locale = 'en' | 'tr'

Expand Down Expand Up @@ -141,7 +142,7 @@ const tr: typeof en = {

const localeMap: Record<Locale, typeof en> = { en, tr }

export const useI18n = createSharedComposable(() => {
export const useI18n = singleton(() => {
const currentLanguage = customRef<Locale>((track, trigger) => {
let locale: Locale = AppStorage.get('language')

Expand Down
4 changes: 3 additions & 1 deletion src/pages/SettingsPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import Switch from '../components/Switch.vue'
import SettingItem from '../components/SettingItem.vue'
import { Page, useRoute } from '../stores/route'
import { useI18n } from '../composables/useI18n'
import SettingsSilentHours from '../components/SettingsSilentHours.vue'
const route = useRoute()
const { t, currentLanguage } = useI18n()
Expand Down Expand Up @@ -303,6 +304,8 @@ function handleScroll(e: Event) {
>
<Switch v-model="markAsReadOnOpen" />
</SettingItem>

<SettingsSilentHours />
</div>
</div>
</template>
Expand All @@ -313,7 +316,6 @@ function handleScroll(e: Event) {
left: 0;
top: 0;
width: 100%;
height: 100%;
display: flex;
flex-flow: column nowrap;
Expand Down
21 changes: 16 additions & 5 deletions src/utils/common.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
import { type Ref, type UnwrapRef } from 'vue'

/**
* Just returns value of passed ref, used for reactivity tracking.
* Used for singleton composable functions
*
* @example
* ```ts
* const fn = singletonFn(() => {
* const state = reactive({ count: 0 })
* const increment = () => state.count++
* const decrement = () => state.count--
* return { state, increment, decrement }
* })
*
* const { state, increment, decrement } = fn()
* ```
*/
export function trackRef<T extends Ref<any>>(ref: T): UnwrapRef<T> {
return ref.value
export function singleton<T>(fn: () => T): () => T {
const context = fn()
return () => context
}

0 comments on commit ab73ee6

Please sign in to comment.