Skip to content

Commit

Permalink
Merge pull request #4141 from traPtitech/feat/settings_stamp
Browse files Browse the repository at this point in the history
設定画面スタンプタブの改修
  • Loading branch information
nokhnaton authored Oct 21, 2024
2 parents c3aaaeb + bae8de0 commit 697a1a9
Show file tree
Hide file tree
Showing 22 changed files with 1,218 additions and 475 deletions.
6 changes: 4 additions & 2 deletions src/assets/mdi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ import {
mdiCrown,
mdiFormatTitle,
mdiCloseCircle,
mdiNotebook
mdiNotebook,
mdiDelete
} from '@mdi/js'

interface MdiIconsMapping {
Expand Down Expand Up @@ -167,7 +168,8 @@ const mdi: MdiIconsMapping = {
'music-note': mdiMusicNote,
stop: mdiStop,
crown: mdiCrown,
'format-title': mdiFormatTitle
'format-title': mdiFormatTitle,
delete: mdiDelete
}

export default mdi
2 changes: 1 addition & 1 deletion src/components/Modal/Common/ModalFrame.vue
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const { clearModal } = useModalStore()
}
.body {
width: 100%;
padding: 16px 24px;
padding: 16px;
overflow: {
x: hidden;
y: auto;
Expand Down
19 changes: 18 additions & 1 deletion src/components/Modal/ModalContainer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
currentState.type === 'file' ||
currentState.type === 'channel-manage' ||
currentState.type === 'group-admin-add' ||
currentState.type === 'group-member-add'
currentState.type === 'group-member-add' ||
currentState.type === 'settings-stamp-edit' ||
currentState.type === 'settings-stamp-image-edit'
? currentState.id
: undefined
"
Expand Down Expand Up @@ -41,6 +43,13 @@
? currentState.userId
: undefined
"
:file="
currentState.type === 'settings-stamp-create' ||
currentState.type === 'settings-stamp-image-edit' ||
currentState.type === 'settings-profile-icon-edit'
? currentState.file
: undefined
"
/>
</div>
</transition>
Expand All @@ -63,6 +72,10 @@ import GroupCreateModal from './GroupCreateModal/GroupCreateModal.vue'
import GroupMemberEditModal from './GroupMemberEditModal/GroupMemberEditModal.vue'
import GroupAdminAddModal from './GroupAdminAddModal/GroupAdminAddModal.vue'
import GroupMemberAddModal from './GroupMemberAddModal/GroupMemberAddModal.vue'
import StampCreateModal from './StampCreateModal/StampCreateModal.vue'
import StampEditModal from './StampEditModal/StampEditModal.vue'
import StampImageEditModal from './StampImageEditModal/StampImageEditModal.vue'
import ProfileIconEditModal from './ProfileIconEditModal/ProfileIconEditModal.vue'
import SettingsCacheClearModal from './SettingsCacheClearModal/SettingsCacheClearModal.vue'
import SettingsThemeEditModal from './SettingsThemeEditModal/SettingsThemeEditModal.vue'
import type { ModalStateType } from '/@/store/ui/modal/states'
Expand All @@ -84,6 +97,10 @@ const components: Record<ModalStateType, Component> = {
'group-member-edit': GroupMemberEditModal,
'group-admin-add': GroupAdminAddModal,
'group-member-add': GroupMemberAddModal,
'settings-stamp-create': StampCreateModal,
'settings-stamp-edit': StampEditModal,
'settings-stamp-image-edit': StampImageEditModal,
'settings-profile-icon-edit': ProfileIconEditModal,
'settings-cache-clear': SettingsCacheClearModal,
'settings-theme-edit': SettingsThemeEditModal
}
Expand Down
79 changes: 79 additions & 0 deletions src/components/Modal/ProfileIconEditModal/ProfileIconEditModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<template>
<modal-frame
title="アイコンの編集"
subtitle="画像の位置・サイズを編集できます"
>
<div :class="$style.container">
<image-upload v-model="iconImage" />
</div>
<div :class="$style.buttonContainer">
<form-button label="キャンセル" type="tertiary" @click="cancel" />
<form-button
label="更新する"
:loading="isEditing"
@click="editIconImage"
/>
</div>
</modal-frame>
</template>

<script lang="ts" setup>
import { ref, type Ref } from 'vue'
import apis, { formatResizeError } from '/@/lib/apis'
import { useToastStore } from '/@/store/ui/toast'
import FormButton from '/@/components/UI/FormButton.vue'
import ModalFrame from '../Common/ModalFrame.vue'
import { useModalStore } from '/@/store/ui/modal'
import ImageUpload from '/@/components/Settings/ImageUpload.vue'
const props = defineProps<{
file: File
}>()
const { clearModal } = useModalStore()
const iconImage = ref<File>(props.file)
const useIconImageEdit = (iconImage: Ref<File>) => {
const { addSuccessToast, addErrorToast } = useToastStore()
const isEditing = ref(false)
const editIconImage = async () => {
if (!iconImage.value) return
isEditing.value = true
try {
await apis.changeMyIcon(iconImage.value)
addSuccessToast('アイコン画像を変更しました')
} catch (e) {
// eslint-disable-next-line no-console
console.error('アイコン画像の変更に失敗しました', e)
addErrorToast(formatResizeError(e, 'アイコン画像の変更に失敗しました'))
}
clearModal()
isEditing.value = false
}
return { isEditing, editIconImage }
}
const { isEditing, editIconImage } = useIconImageEdit(iconImage)
const cancel = () => {
clearModal()
}
</script>

<style lang="scss" module>
.container {
display: flex;
justify-content: center;
}
.buttonContainer {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 16px;
margin-top: 16px;
}
</style>
86 changes: 86 additions & 0 deletions src/components/Modal/StampCreateModal/StampCreateModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<template>
<modal-frame title="新規スタンプ登録" :subtitle="subtitle">
<stamp-image-edit
v-if="step === 'image'"
:file="file"
@update-file="updateFile"
/>
<stamp-info-edit v-else :stamp-image="stampImage" @back="backToImageEdit" />
</modal-frame>
</template>

<script lang="ts" setup>
import ModalFrame from '/@/components/Modal/Common/ModalFrame.vue'
import { ref, computed } from 'vue'
import StampImageEdit from './StampImageEdit.vue'
import StampInfoEdit from './StampInfoEdit.vue'
const props = defineProps<{
file: File
}>()
const stampImage = ref<File>(props.file)
const step = ref<'image' | 'info'>('image')
const subtitle = computed(() =>
step.value === 'image'
? '画像の位置・サイズを編集できます'
: 'スタンプの名前を入力してください'
)
const updateFile = (file: File) => {
stampImage.value = file
step.value = 'info'
}
const backToImageEdit = () => {
step.value = 'image'
}
</script>

<style lang="scss" module>
.form {
margin: 8px 0;
}
.container {
display: flex;
justify-content: space-between;
gap: 16px;
}
.leftContainer {
min-width: 136px;
width: 136px;
height: 136px;
margin: 8px 0;
flex-grow: 1;
}
.imgButton {
width: 100%;
height: 100%;
border: 2px solid $theme-ui-secondary-default;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
.label {
@include color-ui-secondary;
margin-bottom: 16px;
}
.creator {
@include color-ui-primary;
}
.note {
@include color-ui-secondary;
margin-bottom: 12px;
font-size: 12px;
}
.buttonContainer {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 16px;
}
</style>
81 changes: 81 additions & 0 deletions src/components/Modal/StampCreateModal/StampImageEdit.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<template>
<div>
<div :class="$style.container">
<image-upload v-model="stampImage" />
</div>
<div :class="$style.buttonContainer">
<form-button label="キャンセル" type="tertiary" @click="cancel" />
<form-button
label="次へ"
:loading="isChecking"
@click="checkStampImage"
/>
</div>
</div>
</template>

<script lang="ts" setup>
import { ref, type Ref } from 'vue'
import { formatResizeError } from '/@/lib/apis'
import { useToastStore } from '/@/store/ui/toast'
import { imageSize } from '/@/components/Settings/StampTab/imageSize'
import FormButton from '/@/components/UI/FormButton.vue'
import { useModalStore } from '/@/store/ui/modal'
import ImageUpload from '/@/components/Settings/ImageUpload.vue'
const props = defineProps<{
file: File
}>()
const emit = defineEmits<{
(e: 'updateFile', file: File): void
}>()
const { popModal } = useModalStore()
const stampImage = ref<File>(props.file)
const useCheckStamp = (stampImage: Ref<File>) => {
const { addErrorToast } = useToastStore()
const isChecking = ref(false)
const checkStampImage = async () => {
if (!stampImage.value) return
isChecking.value = true
try {
const size = await imageSize(stampImage.value)
if (size.height !== size.width) {
addErrorToast('画像が正方形ではありません。編集してください')
return
}
} catch (e) {
// eslint-disable-next-line no-console
console.error('画像の整形に失敗しました', e)
addErrorToast(formatResizeError(e, '画像の整形に失敗しました'))
}
emit('updateFile', stampImage.value)
isChecking.value = false
}
return { isChecking, checkStampImage }
}
const { isChecking, checkStampImage } = useCheckStamp(stampImage)
const cancel = () => {
popModal()
}
</script>

<style lang="scss" module>
.container {
display: flex;
justify-content: center;
}
.buttonContainer {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 16px;
margin-top: 16px;
}
</style>
Loading

0 comments on commit 697a1a9

Please sign in to comment.