Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 87 additions & 15 deletions apps/slax-reader-dweb/layers/core/components/Modal/Feedback.vue
Original file line number Diff line number Diff line change
@@ -1,31 +1,47 @@
<template>
<div class="feedback-modal" :class="{ appear }" @click="closeModal">
<div class="feedback-modal" :class="{ appear }" @click="() => !isLoading && closeModal()">
<Transition name="modal" @after-leave="onAfterLeave">
<div class="modal-content" v-show="appear" @click.stop>
<div class="header">
<span>{{ t('component.feedback.title') }}</span>
<span v-if="title || href">{{ t('component.feedback.title') }}</span>
<span v-else>{{ t('component.feedback.name') }}</span>
<button class="close" @click="closeModal">
<img src="@images/button-dialog-close.png" />
</button>
</div>
<div class="content">
<div class="title" v-if="props.title">{{ props.title }}</div>
<div class="title" v-if="title">{{ title }}</div>
<div class="link" v-if="href">
<span>{{ href }}</span>
</div>
<textarea v-model="feedback" :placeholder="t('component.feedback.placeholder')"></textarea>
</div>
<div class="bottom">
<button :class="{ disabled: feedback.length === 0 }" @click="submitFeedback">{{ t('common.operate.submit') }}</button>
<div class="follow-up" v-show="email" @click="allowFollowUp = !allowFollowUp">
<button :class="{ selected: allowFollowUp }"></button>
<span>{{ t('component.feedback.follow_up', { email }) }}</span>
</div>
<button class="submit" :class="{ disabled: feedback.length === 0 }" @click="submitFeedback">{{ t('common.operate.submit') }}</button>
</div>
<Transition name="opacity">
<div class="loading" v-show="isLoading">
<div class="i-svg-spinners:180-ring-with-bg text-5xl text-emerald"></div>
</div>
</Transition>
</div>
</Transition>
</div>
</template>

<script lang="ts" setup>
import { RESTMethodPath } from '@commons/types/const'
import { UAParser } from 'ua-parser-js'

const props = defineProps({
reportType: String,
title: String,
href: { type: String, required: false },
email: { type: String, required: false },
params: {
type: Object as PropType<Record<string, string | number>>,
required: false
Expand All @@ -34,11 +50,15 @@ const props = defineProps({

const emits = defineEmits(['close', 'dismiss'])

const isLoading = ref(false)
const parser = new UAParser()
const result = parser.getResult()
const config = useRuntimeConfig()
const version = config.public.appVersion
const isLocked = useScrollLock(window)
const appear = ref(false)
const feedback = ref('')
const allowFollowUp = ref(false)

isLocked.value = true

Expand All @@ -59,12 +79,24 @@ const submitFeedback = () => {
reportFeedbackContent()
}
const reportFeedbackContent = async () => {
if (isLoading.value) {
return
}

isLoading.value = true
let environment = ''
try {
environment = `${result.browser.name} ${result.browser.version} | ${result.os.name} ${result.os.version} | ${result.device.model}`
} catch (error) {}

const req = {
...props.params,
type: props.reportType,
content: feedback.value,
source: 'web',
platform: 'web',
environment,
version,
...props.params
allow_follow_up: allowFollowUp.value
}

request()
Expand All @@ -76,14 +108,17 @@ const reportFeedbackContent = async () => {
feedback.value = ''
closeModal()
})
.finally(() => {
isLoading.value = false
})
}
const onAfterLeave = () => {
isLocked.value = false
emits('dismiss')
}

const t = (text: string) => {
return useNuxtApp().$i18n.t(text)
const t = (text: string, params: Record<string, unknown> = {}) => {
return useNuxtApp().$i18n.t(text, params)
}
</script>

Expand All @@ -100,11 +135,10 @@ button {
}

.modal-content {
--style: bg-#f5f5f3 rounded-2 p-24px w-480px select-none mb-10;
position: relative;
--style: relative bg-#f5f5f3 rounded-2 p-24px w-480px select-none overflow-hidden mb-10;

.header {
--style: flex justify-between items-center;
--style: relative z-1 flex justify-between items-center;
span {
--style: text-(13px #999999) line-height-18px;
}
Expand All @@ -123,7 +157,15 @@ button {
--style: w-full text-(14px ellipsis #333333) line-height-21px font-medium overflow-hidden line-clamp-2 break-all;
}

.title + textarea {
.link {
--style: w-full text-(#5490c2 15px) line-height-21px;
}

.title + .link {
--style: mt-8px;
}

* + textarea {
--style: mt-20px;
}

Expand All @@ -138,9 +180,35 @@ button {
}

.bottom {
--style: mt-20px flex justify-end items-center;
button {
--style: flex-center w-100px h-40px bg-#16B998 rounded-2 text-(14px #ffffff) font-semibold line-height-40px transition-all duration-250;
--style: mt-20px flex justify-between items-center gap-20px;

.follow-up {
--style: flex items-center justify-start flex-1 overflow-hidden text-ellipsis whitespace-nowrap cursor-pointer;

button {
--style: shrink-0 border-(1px solid #3333331a) bg-#fcfcfc w-12px h-12px rounded-3px transition-transform duration-250;

&.selected {
--style: 'bg-center bg-[length:7px_6px] border-1';
background-image: url('@images/tiny-tick-outline-icon.png');
}

&:hover {
--style: scale-105;
}

&:active {
--style: scale-110;
}
}

span {
--style: ml-5px text-(#333 14px) line-height-22px overflow-hidden text-ellipsis;
}
}

.submit {
--style: flex-center shrink-0 w-100px h-40px bg-#16B998 rounded-2 text-(14px #ffffff) font-semibold line-height-40px transition-all duration-250;

&.disabled {
--style: 'bg-#ccc cursor-not-allowed hover:(scale-100)';
Expand All @@ -155,6 +223,10 @@ button {
}
}
}

.loading {
--style: absolute inset-0 bg-#ffffff40 flex-center;
}
}

.modal-leave-to,
Expand Down
4 changes: 3 additions & 1 deletion apps/slax-reader-dweb/layers/core/components/Modal/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ import { modalBootloader } from '#layers/core/utils/modal'

import { BookmarkParseStatus } from '@commons/types/interface'

export const showFeedbackModal = (options: { title: string; reportType: string; params?: Record<string, string | number> }) => {
export const showFeedbackModal = (options: { title: string; reportType: string; href?: string; email: string; params?: Record<string, string | number> }) => {
const app = modalBootloader({
ele: Feedback,
props: {
reportType: options.reportType,
title: options.title,
href: options.href,
email: options.email,
params: options.params ?? {},
onDismiss: () => {
app.unmount()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,20 +78,31 @@ export const logAnalyzed = (options: BookmarkTypeOptions, userId: number) => {
}

export const showFeedbackView = (options: BookmarkTypeOptions, type: string) => {
const href = `${window.location.origin}${window.location.pathname}`
const email = useUserStore().userInfo?.email

if (options.type === BookmarkType.Normal) {
showFeedbackModal({
reportType: type,
title: options.title,
href,
email: email || '',
params: {
bookmark_id: options.bmId
bookmark_id: options.bmId,
entry_point: 'bookmark_detail',
target_url: href
}
})
} else if (options.type === BookmarkType.Share) {
showFeedbackModal({
reportType: type,
title: options.title,
href,
email: email || '',
params: {
share_code: options.shareCode
share_code: options.shareCode,
entry_point: 'share',
target_url: href
}
})
}
Expand Down
2 changes: 2 additions & 0 deletions apps/slax-reader-dweb/layers/core/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@
"title": "Edit tag"
},
"feedback": {
"follow_up": "Allow follow-up at {email}",
"name": "Feedback",
"placeholder": "Please describe the problem you are experiencing...",
"title": "Your feedback will help us improve"
},
Expand Down
2 changes: 2 additions & 0 deletions apps/slax-reader-dweb/layers/core/i18n/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@
"title": "修改标签"
},
"feedback": {
"follow_up": "允许通过 {email} 跟进",
"name": "反馈",
"placeholder": "请描述你遇到的问题......",
"title": "你的反馈将帮助我们变得更好"
},
Expand Down
32 changes: 31 additions & 1 deletion apps/slax-reader-dweb/layers/core/pages/bookmarks/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@
<span>{{ $t('page.bookmarks_index.add_url') }}</span>
</button>
</div>
<div class="feedback">
<button @click="feedbackClick">
<img src="@images/button-feedback-icon.png" alt="" />
</button>
</div>
</div>
</template>
<template v-slot:content-header>
Expand Down Expand Up @@ -140,6 +145,7 @@ import type { ChannelMessageData } from '#layers/core/utils/channel'
import { RESTMethodPath } from '@commons/types/const'
import type { BookmarkItem, HighlightItem, UserInfo, UserNotificationMessageItem } from '@commons/types/interface'
import { useInfiniteScroll } from '@vueuse/core'
import { showFeedbackModal } from '#layers/core/components/Modal'
import Toast from '#layers/core/components/Toast'
import useNotification from '#layers/core/composables/useNotification'
import { useUserStore } from '#layers/core/stores/user'
Expand Down Expand Up @@ -545,6 +551,18 @@ const addUrlSuccess = () => {
reloadList()
}

const feedbackClick = () => {
const email = useUserStore().userInfo?.email
showFeedbackModal({
reportType: 'parse_error',
title: '',
email: email || '',
params: {
entry_point: 'inbox'
}
})
}

const showNotificationList = () => {
inboxClick('notifications')
}
Expand Down Expand Up @@ -580,7 +598,7 @@ const notificationBack = () => {
}

.tools-sidebar {
--style: absolute bottom-120px w-full flex flex-col justify-end;
--style: absolute bottom-80px w-full flex flex-col justify-end;
.add-url {
--style: 'mt-24px bg-#fcfcfc border-(1px solid #a8b1cd3d) rounded-8px w-68px h-82px py-5px px-5px';
button {
Expand All @@ -594,6 +612,18 @@ const notificationBack = () => {
}
}
}

.feedback {
--style: mt-35px w-68px flex-center;
button {
--style: 'rounded-full bg-#FCFCFC w-42px h-42px border-(1px solid #a8b1cd14) hover:(bg-#f5f5f3) active:(scale-110) transition-all duration-250';
box-shadow: 0px 15px 30px 0px #00000014;

img {
--style: w-18px h-17px object-contain;
}
}
}
}

.bookmarks {
Expand Down
Loading
Loading