Skip to content

Commit 00a5572

Browse files
authored
feat:mobileAdaptation (#2186)
* feat:mobileAdaptation * fix:problem * format
1 parent e1befa2 commit 00a5572

File tree

16 files changed

+456
-39
lines changed

16 files changed

+456
-39
lines changed

spx-gui/src/components/community/CenteredWrapper.vue

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,25 @@ withDefaults(
2828
2929
&.size-medium {
3030
width: 988px;
31+
3132
@include responsive(desktop-large) {
3233
width: 1240px;
3334
}
3435
}
3536
3637
&.size-large {
3738
width: 1240px;
39+
3840
@include responsive(desktop-large) {
3941
width: 1492px;
4042
}
4143
}
44+
45+
&.size-medium,
46+
&.size-large {
47+
@include responsive(mobile) {
48+
width: 95%;
49+
}
50+
}
4251
}
4352
</style>

spx-gui/src/components/community/CommunityNavbar.vue

Lines changed: 93 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,47 @@
1414
</NavbarDropdown>
1515
</template>
1616
<template #right>
17-
<div class="search">
17+
<div class="search mobile-hide">
1818
<UITextInput
1919
v-model:value="searchInput"
2020
v-radar="{ name: 'Search input', desc: 'Input and press enter to search projects' }"
2121
:placeholder="$t({ en: 'Search project', zh: '搜索项目' })"
2222
@keypress.enter="handleSearch"
2323
>
24-
<template #prefix><UIIcon class="search-icon" type="search" /></template>
24+
<template #prefix>
25+
<UIIcon class="search-icon" type="search" />
26+
</template>
2527
</UITextInput>
2628
</div>
29+
<!-- mobile -->
30+
<div class="mobile-search-btn" @click="expandSearch">
31+
<UIIcon type="search" />
32+
</div>
33+
34+
<div v-if="isSearchExpanded" class="mobile-search-expanded">
35+
<div class="search-input-wrapper">
36+
<UITextInput
37+
ref="mobileSearchInput"
38+
v-model:value="searchInput"
39+
v-radar="{ name: 'Mobile search input', desc: 'Mobile search input' }"
40+
:placeholder="$t({ en: 'Search project', zh: '搜索项目' })"
41+
:autofocus="true"
42+
@blur="collapseSearch"
43+
>
44+
<template #prefix>
45+
<UIIcon
46+
class="search-icon"
47+
type="search"
48+
@mousedown.prevent="handleSearch"
49+
@touchstart.prevent="handleSearch"
50+
/>
51+
</template>
52+
</UITextInput>
53+
</div>
54+
<UIButton @click="collapseSearch">
55+
{{ $t({ en: 'Cancel', zh: '取消' }) }}
56+
</UIButton>
57+
</div>
2758
</template>
2859
</NavbarWrapper>
2960
</template>
@@ -32,7 +63,7 @@
3263
import { ref, watch } from 'vue'
3364
import { useRouter } from 'vue-router'
3465
import { getStringParam } from '@/utils/route'
35-
import { UIMenu, UITextInput, UIIcon } from '@/components/ui'
66+
import { UIMenu, UITextInput, UIIcon, UIButton } from '@/components/ui'
3667
import NavbarWrapper from '@/components/navbar/NavbarWrapper.vue'
3768
import NavbarDropdown from '../navbar/NavbarDropdown.vue'
3869
import NavbarNewProjectItem from '@/components/navbar/NavbarNewProjectItem.vue'
@@ -42,6 +73,16 @@ import { getSearchRoute } from '@/router'
4273
4374
const router = useRouter()
4475
const searchInput = ref('')
76+
// mobile search
77+
const isSearchExpanded = ref(false)
78+
const mobileSearchInput = ref<InstanceType<typeof UITextInput> | null>(null)
79+
function expandSearch() {
80+
isSearchExpanded.value = true
81+
}
82+
function collapseSearch() {
83+
isSearchExpanded.value = false
84+
searchInput.value = ''
85+
}
4586
4687
function handleSearch() {
4788
router.push(getSearchRoute(searchInput.value))
@@ -71,10 +112,59 @@ watch(
71112
</script>
72113

73114
<style lang="scss" scoped>
115+
@import '@/components/ui/responsive.scss';
116+
74117
.search {
75118
margin-right: 8px;
76119
width: 340px;
77120
display: flex;
78121
align-items: center;
79122
}
123+
124+
// mobile
125+
.mobile-search-btn {
126+
display: none;
127+
align-items: center;
128+
justify-content: center;
129+
width: 50px;
130+
height: auto;
131+
cursor: pointer;
132+
133+
&:hover {
134+
background-color: rgba(255, 255, 255, 0.2);
135+
}
136+
137+
@include responsive(mobile) {
138+
display: flex;
139+
}
140+
}
141+
142+
.mobile-search-expanded {
143+
position: fixed;
144+
top: 0;
145+
left: 0;
146+
right: 0;
147+
height: 50px;
148+
background-color: var(--ui-color-primary-main);
149+
display: flex;
150+
align-items: center;
151+
padding: 0 12px;
152+
gap: 12px;
153+
z-index: 1000;
154+
155+
.search-input-wrapper {
156+
flex: 1;
157+
158+
:deep(.ui-text-input) {
159+
width: 100%;
160+
}
161+
}
162+
}
163+
164+
// mobile-hide
165+
@include responsive(mobile) {
166+
.mobile-hide {
167+
display: none !important;
168+
}
169+
}
80170
</style>

spx-gui/src/components/community/ProjectsSection.vue

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,28 +55,38 @@ const slots = useSlots()
5555
</script>
5656

5757
<style lang="scss" scoped>
58+
@import '@/components/ui/responsive.scss';
59+
60+
section {
61+
font-size: 16px;
62+
63+
@include responsive(mobile) {
64+
font-size: 12px;
65+
}
66+
}
67+
5868
.header {
59-
height: 52px;
69+
height: 3.25em;
6070
display: flex;
6171
justify-content: space-between;
6272
align-items: center;
6373
6474
.title {
65-
line-height: 28px;
66-
font-size: 20px;
75+
line-height: 1.75em;
76+
font-size: 1.25em;
6777
color: var(--ui-color-title);
6878
}
6979
7080
.link {
7181
display: flex;
7282
align-items: center;
73-
font-size: 15px;
83+
font-size: 0.94em;
7484
}
7585
7686
.link-icon {
77-
margin-left: 8px;
78-
width: 20px;
79-
height: 20px;
87+
margin-left: 0.5em;
88+
width: 1.25em;
89+
height: 1.25em;
8090
}
8191
}
8292
@@ -93,21 +103,24 @@ const slots = useSlots()
93103
.projects {
94104
display: grid;
95105
grid-template-columns: repeat(var(--project-num-in-row), 1fr);
96-
gap: 20px;
106+
gap: 1.25em;
97107
}
98108
99109
.context-user {
100110
.header {
101111
height: 60px;
102112
padding: 20px 0 8px;
103113
}
114+
104115
.title {
105116
font-size: 16px;
106117
line-height: 26px;
107118
}
119+
108120
.projects-wrapper {
109121
margin: 8px 0 16px;
110122
}
123+
111124
.projects {
112125
gap: 16px;
113126
}

spx-gui/src/components/community/home/banner/GuestBanner.vue

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,16 @@ function handleJoin() {
3131
</template>
3232

3333
<style lang="scss" scoped>
34+
@import '@/components/ui/responsive.scss';
35+
3436
.guest-banner {
3537
padding: 12px;
38+
font-size: 24px;
39+
40+
@include responsive(mobile) {
41+
padding: 8px;
42+
font-size: 18px;
43+
}
3644
}
3745
3846
.main {
@@ -45,15 +53,21 @@ function handleJoin() {
4553
background-image: url('./bg.svg');
4654
background-repeat: no-repeat;
4755
background-position: center right 54px;
56+
57+
@include responsive(mobile) {
58+
padding: 32px 24px 36px;
59+
background-position: center right 20px;
60+
background-size: auto 80%;
61+
}
4862
}
4963
5064
.title {
51-
font-size: 24px;
65+
font-size: 1em;
5266
line-height: 1.5;
5367
}
5468
5569
.sub-title {
56-
font-size: 13px;
70+
font-size: 0.5em;
5771
line-height: 20px;
5872
margin-top: 8px;
5973
}

spx-gui/src/components/community/user/UserHeader.vue

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ import FollowButton from './FollowButton.vue'
1111
import UserJoinedAt from './UserJoinedAt.vue'
1212
import EditProfileModal from './EditProfileModal.vue'
1313
import { getCoverImgUrl } from './cover'
14-
14+
import { useResponsive } from '@/components/ui/responsive'
1515
const props = defineProps<{
1616
user: User
1717
}>()
18-
18+
const isMobile = useResponsive('mobile')
1919
const isSignedInUser = computed(() => props.user.username === getSignedInUsername())
2020
const avatarUrl = useExternalUrl(() => props.user.avatar)
2121
const coverImgUrl = computed(() => getCoverImgUrl(props.user.username))
@@ -38,23 +38,25 @@ const handleEditProfile = useMessageHandle(async () => invokeEditProfileModal({
3838
{{ user.displayName }}
3939
<UserJoinedAt class="joined-at" :time="user.createdAt" />
4040
</h2>
41-
<TextView style="max-height: 66px" :text="user.description" />
41+
<TextView v-if="!isMobile" style="max-height: 66px" :text="user.description" />
4242
</div>
4343
<div class="op">
4444
<UIButton
45-
v-if="isSignedInUser"
45+
v-if="isSignedInUser && !isMobile"
4646
v-radar="{ name: 'Edit profile button', desc: 'Click to edit user profile' }"
4747
@click="handleEditProfile"
4848
>
4949
{{ $t({ en: 'Edit profile', zh: '编辑' }) }}
5050
</UIButton>
51-
<FollowButton v-else :name="user.username" />
51+
<FollowButton v-if="!isSignedInUser" :name="user.username" />
5252
</div>
5353
</div>
5454
</CommunityCard>
5555
</template>
5656

5757
<style lang="scss" scoped>
58+
@import '@/components/ui/responsive.scss';
59+
5860
.user-header {
5961
position: relative;
6062
}
@@ -66,6 +68,11 @@ const handleEditProfile = useMessageHandle(async () => invokeEditProfileModal({
6668
background-position: center;
6769
background-size: cover;
6870
background-repeat: no-repeat;
71+
72+
@include responsive(mobile) {
73+
height: 15vh;
74+
max-height: 120px;
75+
}
6976
}
7077
7178
.avatar {
@@ -77,13 +84,27 @@ const handleEditProfile = useMessageHandle(async () => invokeEditProfileModal({
7784
border: 2px solid var(--ui-color-grey-100);
7885
border-radius: 50%;
7986
background-color: var(--ui-color-grey-100);
87+
88+
@include responsive(mobile) {
89+
left: 16px;
90+
bottom: 16px;
91+
width: 80px;
92+
height: 80px;
93+
}
8094
}
8195
8296
.content {
8397
padding: 20px 20px 20px 192px;
8498
display: flex;
8599
align-items: end;
86100
gap: 100px;
101+
102+
@include responsive(mobile) {
103+
padding: 16px 16px 16px 112px;
104+
gap: 20px;
105+
justify-content: center;
106+
align-items: flex-start;
107+
}
87108
}
88109
89110
.info {
@@ -99,6 +120,14 @@ const handleEditProfile = useMessageHandle(async () => invokeEditProfileModal({
99120
font-size: 20px;
100121
line-height: 28px;
101122
color: var(--ui-color-title);
123+
124+
@include responsive(mobile) {
125+
font-size: 16px;
126+
line-height: 22px;
127+
align-items: flex-start;
128+
flex-direction: column;
129+
gap: 4px;
130+
}
102131
}
103132
104133
.joined-at {
@@ -116,5 +145,9 @@ const handleEditProfile = useMessageHandle(async () => invokeEditProfileModal({
116145
flex: 0 0 110px;
117146
display: flex;
118147
justify-content: flex-end;
148+
149+
@include responsive(mobile) {
150+
flex: 0 0 auto;
151+
}
119152
}
120153
</style>

spx-gui/src/components/community/user/sidebar/UserSidebar.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ const isMobile = useResponsive('mobile')
132132
position: relative;
133133
134134
width: 212px;
135+
135136
@include responsive(desktop-large) {
136137
width: 216px;
137138
}

0 commit comments

Comments
 (0)