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
2 changes: 2 additions & 0 deletions docs/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ paths:
$ref: "#/components/schemas/User/properties/username"
displayName:
$ref: "#/components/schemas/User/properties/displayName"
avatar:
$ref: "#/components/schemas/User/properties/avatar"
description:
$ref: "#/components/schemas/User/properties/description"
responses:
Expand Down
166 changes: 134 additions & 32 deletions spx-gui/package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions spx-gui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"browserslist": "^4.28.0",
"browserslist-to-esbuild": "^2.1.1",
"casdoor-js-sdk": "^0.16.0",
"cropperjs": "^2.1.0",
"csv-stringify": "^6.5.2",
"dayjs": "^1.11.10",
"eslint": "^9.39.1",
Expand Down
2 changes: 1 addition & 1 deletion spx-gui/src/apis/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export function getSignedInUser(): Promise<SignedInUser> {
return client.get(`/user`) as Promise<SignedInUser>
}

export type UpdateSignedInUserParams = Partial<Pick<User, 'username' | 'displayName' | 'description'>>
export type UpdateSignedInUserParams = Partial<Pick<User, 'username' | 'displayName' | 'avatar' | 'description'>>

export function updateSignedInUser(params: UpdateSignedInUserParams) {
return client.patch(`/user`, params) as Promise<SignedInUser>
Expand Down
129 changes: 129 additions & 0 deletions spx-gui/src/components/community/user/AvatarZoomSlider.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<script setup lang="ts">
import { UIIcon, UISlider } from '@/components/ui'

const props = withDefaults(
defineProps<{
value: number
disabled?: boolean
min?: number
max?: number
step?: number
buttonStep?: number
}>(),
{
disabled: false,
min: 1,
max: 3,
step: 0.01,
buttonStep: 0.1
}
)

const emit = defineEmits<{
'update:value': [number]
}>()

function handleValueUpdate(value: number) {
const nextValue = Number(Math.min(props.max, Math.max(props.min, value)).toFixed(2))
if (nextValue === props.value) return
emit('update:value', nextValue)
}
</script>

<template>
<div class="avatar-zoom-slider">
<button
v-radar="{ name: 'Zoom out avatar button', desc: 'Click to zoom out the avatar image' }"
class="zoom-button"
type="button"
:disabled="props.disabled || props.value <= props.min"
@click="handleValueUpdate(props.value - props.buttonStep)"
>
<UIIcon class="zoom-icon" type="minus" />
</button>

<UISlider
class="slider"
update-on="input"
:min="props.min"
:max="props.max"
:step="props.step"
:value="props.value"
:disabled="props.disabled"
:tooltip="false"
@update:value="handleValueUpdate"
/>

<button
v-radar="{ name: 'Zoom in avatar button', desc: 'Click to zoom in the avatar image' }"
class="zoom-button"
type="button"
:disabled="props.disabled || props.value >= props.max"
@click="handleValueUpdate(props.value + props.buttonStep)"
>
<UIIcon class="zoom-icon" type="plus" />
</button>
</div>
</template>

<style scoped lang="scss">
.avatar-zoom-slider {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
width: 366px;
height: 48px;
}

.slider {
flex: 1 1 auto;
min-width: 0;

&:deep(.n-slider-handle) {
background: transparent;
box-shadow: none;
}

&:deep(.n-slider-rail),
&:deep(.n-slider-rail__fill) {
height: 6px;
border-radius: 999px;
}
}

.slider:deep(.thumb) {
box-sizing: border-box;
box-shadow:
inset 0 0 0 2px var(--ui-color-primary-400),
0 1px 2px rgb(36 41 47 / 10%);
}

.zoom-button {
display: flex;
align-items: center;
justify-content: center;
flex: 0 0 auto;
width: 24px;
height: 24px;
padding: 0;
border: none;
background: none;
color: var(--ui-color-grey-900);
cursor: pointer;

&:not(:disabled):hover {
color: var(--ui-color-grey-1000);
}

&:disabled {
color: var(--ui-color-grey-700);
cursor: not-allowed;
}
}

.zoom-icon {
width: 20px;
height: 20px;
}
</style>
Loading