u
This commit is contained in:
1 parent
cf23acdabc
commit
2efeb7cee2
13 files changed
+271
-49
No files matched your search
@@ -0,0 +1,96 @@
|
||||
import * as Clipboard from 'expo-clipboard'
|
||||
import { useLocalSearchParams } from 'expo-router'
|
||||
import { useEffect, useState } from 'react'
|
||||
import {
|
||||
Modal,
|
||||
Pressable,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from 'react-native'
|
||||
import QRCode from 'react-native-qrcode-svg'
|
||||
import { toast } from 'sonner-native'
|
||||
import { AButton, ADivider, LucideIcon } from '@/components/common/ao'
|
||||
import CustomHeader from '@/components/custom/Header'
|
||||
|
||||
export default function Invite() {
|
||||
const params = useLocalSearchParams<{ invite_code: string }>()
|
||||
const { invite_code } = params
|
||||
|
||||
const [qrcode, setQrcode] = useState('space:')
|
||||
|
||||
const [previewVisible, setPreviewVisible] = useState(false)
|
||||
|
||||
async function copyInviteCode() {
|
||||
await Clipboard.setStringAsync(invite_code)
|
||||
toast.success('邀请码已复制')
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setQrcode(`space:${invite_code}`)
|
||||
console.log(`space:${invite_code}`)
|
||||
}, [invite_code])
|
||||
|
||||
return (
|
||||
<View className="flex-1 bg-[#f5f6f8]">
|
||||
<CustomHeader title="分享空间" />
|
||||
|
||||
<View className="px-5 pt-6">
|
||||
|
||||
{/* 邀请码卡片 */}
|
||||
<View className="bg-white rounded-2xl p-6 items-center">
|
||||
<Text className="text-gray-500 text-sm mb-3">
|
||||
复制邀请码邀请家庭成员加入
|
||||
</Text>
|
||||
|
||||
<Text className="text-4xl font-bold tracking-[8px] text-gray-900 mb-4">
|
||||
{invite_code}
|
||||
</Text>
|
||||
|
||||
<AButton
|
||||
onPress={copyInviteCode}
|
||||
className="rounded-full"
|
||||
leftIcon={
|
||||
<LucideIcon icon="Copy" size={16} color="#fff" clickable={false} />
|
||||
}
|
||||
>
|
||||
复制邀请码
|
||||
</AButton>
|
||||
</View>
|
||||
|
||||
<View className="my-8">
|
||||
<ADivider direction="horizontal" text="或扫描二维码" />
|
||||
</View>
|
||||
|
||||
{/* 二维码卡片 */}
|
||||
<TouchableOpacity
|
||||
activeOpacity={0.9}
|
||||
onPress={() => setPreviewVisible(true)}
|
||||
className="bg-white rounded-2xl py-8 items-center"
|
||||
>
|
||||
<QRCode
|
||||
size={160}
|
||||
value={qrcode || ''}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
|
||||
</View>
|
||||
|
||||
{/* 全屏预览(无动画) */}
|
||||
<Modal
|
||||
visible={previewVisible}
|
||||
transparent={false}
|
||||
>
|
||||
<Pressable
|
||||
onPress={() => setPreviewVisible(false)}
|
||||
className="flex-1 bg-white items-center justify-center"
|
||||
>
|
||||
<QRCode
|
||||
size={280}
|
||||
value={qrcode || ''}
|
||||
/>
|
||||
</Pressable>
|
||||
</Modal>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { View } from 'react-native'
|
||||
import CustomHeader from '@/components/custom/Header'
|
||||
|
||||
export default function () {
|
||||
return (
|
||||
<View className="flex-1">
|
||||
<CustomHeader title="成员管理" />
|
||||
</View>
|
||||
)
|
||||
}
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
ActionsheetDragIndicator,
|
||||
ActionsheetDragIndicatorWrapper,
|
||||
} from '@/components/ui/actionsheet'
|
||||
import { dissolveSpaceApi, getSpaceSettingsApi, updateSpaceDefaultApi, updateSpaceMemberNameApi, updateSpaceNameApi } from '@/request/api/space'
|
||||
import { dissolveSpaceApi, exitSpaceApi, getSpaceSettingsApi, updateSpaceDefaultApi, updateSpaceMemberNameApi, updateSpaceNameApi } from '@/request/api/space'
|
||||
import { useUserStore } from '@/store/user'
|
||||
|
||||
interface ItemProps {
|
||||
@@ -65,6 +65,8 @@ export default function Settings() {
|
||||
const { spaceId } = params
|
||||
|
||||
const [space, setSpace] = useState<UserSpace | null>(null)
|
||||
// 是否自己的空间
|
||||
const [isOwner, setIsOwner] = useState(false)
|
||||
|
||||
// 空间名称
|
||||
const [showName, setShowName] = useState(false)
|
||||
@@ -114,6 +116,15 @@ export default function Settings() {
|
||||
}
|
||||
}, [spaceId])
|
||||
|
||||
useEffect(() => {
|
||||
if (space) {
|
||||
setIsOwner(space.owner_id === userStore.userInfo.id)
|
||||
}
|
||||
else {
|
||||
setIsOwner(false)
|
||||
}
|
||||
}, [space])
|
||||
|
||||
return (
|
||||
<View className="flex-1 bg-[#f5f6f8]">
|
||||
<CustomHeader title="空间设置" />
|
||||
@@ -124,13 +135,14 @@ export default function Settings() {
|
||||
)
|
||||
: (
|
||||
<View className="flex-1 px-4 pt-4">
|
||||
|
||||
<Text className="text-sm font-semibold text-gray-400 mb-2 tracking-wider">
|
||||
常用设置
|
||||
</Text>
|
||||
|
||||
<View className="bg-white rounded-xl overflow-hidden mb-6">
|
||||
{
|
||||
space?.owner_id === userStore.userInfo.id && (
|
||||
isOwner && (
|
||||
<Item
|
||||
icon="Earth"
|
||||
title="空间名称"
|
||||
@@ -205,19 +217,42 @@ export default function Settings() {
|
||||
/>
|
||||
</View>
|
||||
|
||||
<Text className="text-sm font-semibold text-gray-400 mb-2 tracking-wider">
|
||||
分享
|
||||
</Text>
|
||||
|
||||
<View className="bg-white rounded-xl overflow-hidden mb-6">
|
||||
<Item
|
||||
icon="Share2"
|
||||
title="邀请"
|
||||
onPress={() => {
|
||||
router.navigate({
|
||||
pathname: '/space/manage/sub-page/invite',
|
||||
params: {
|
||||
invite_code: space.invite_code,
|
||||
},
|
||||
})
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<Text className="text-sm font-semibold text-gray-400 mb-2 tracking-wider">
|
||||
其它操作
|
||||
</Text>
|
||||
|
||||
<View className="bg-white rounded-xl overflow-hidden">
|
||||
<Item
|
||||
icon="Users"
|
||||
title="成员管理"
|
||||
/>
|
||||
{
|
||||
isOwner && (
|
||||
<Item
|
||||
icon="Users"
|
||||
title="成员管理"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
<Item
|
||||
icon="LogOut"
|
||||
title={userStore.userInfo.id === space.owner_id ? '解散空间' : '退出空间'}
|
||||
title={isOwner ? '解散空间' : '退出空间'}
|
||||
isLast
|
||||
onPress={() => {
|
||||
setShowDissolve(true)
|
||||
@@ -397,7 +432,7 @@ export default function Settings() {
|
||||
{/* 解散 */}
|
||||
<AModal
|
||||
title="提示"
|
||||
body="确认解散该空间么?"
|
||||
body={isOwner ? '确认解散该空间么?' : '确定解散空间么?'}
|
||||
isOpen={showDissolve}
|
||||
onClose={() => {
|
||||
setShowDissolve(false)
|
||||
@@ -411,18 +446,34 @@ export default function Settings() {
|
||||
return
|
||||
}
|
||||
|
||||
await dissolveSpaceApi({
|
||||
space_id: space.space_id,
|
||||
}).then((res) => {
|
||||
if (res.isSuccess) {
|
||||
setShowDissolve(false)
|
||||
toast.success('解散成功')
|
||||
if (isOwner) {
|
||||
await dissolveSpaceApi({
|
||||
space_id: space.space_id,
|
||||
}).then((res) => {
|
||||
if (res.isSuccess) {
|
||||
setShowDissolve(false)
|
||||
toast.success('已解散该空间')
|
||||
|
||||
setTimeout(() => {
|
||||
router.back()
|
||||
}, 300)
|
||||
}
|
||||
})
|
||||
setTimeout(() => {
|
||||
router.back()
|
||||
}, 300)
|
||||
}
|
||||
})
|
||||
}
|
||||
else {
|
||||
await exitSpaceApi({
|
||||
space_id: space.space_id,
|
||||
}).then((res) => {
|
||||
if (res.isSuccess) {
|
||||
setShowDissolve(false)
|
||||
toast.success('已退出该空间')
|
||||
|
||||
setTimeout(() => {
|
||||
router.back()
|
||||
}, 300)
|
||||
}
|
||||
})
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
|
||||
@@ -2,9 +2,7 @@ import type {
|
||||
CreateSpaceParams,
|
||||
CreateSpaceResult,
|
||||
DissolveSpaceParams,
|
||||
DissolveSpaceResult,
|
||||
ExitSpaceParams,
|
||||
ExitSpaceResult,
|
||||
GetSpaceSettingsParams,
|
||||
JoinSpaceParams,
|
||||
JoinSpaceResult,
|
||||
@@ -60,21 +58,21 @@ export function getSpaceSettingsApi(params: GetSpaceSettingsParams) {
|
||||
return alovaInstance.Post<ResponseData<UserSpace>>(`${API_PREFIX}/settings`, params)
|
||||
}
|
||||
|
||||
// 解散空间
|
||||
export function dissolveSpaceApi(params: DissolveSpaceParams) {
|
||||
return alovaInstance.Post<ResponseData<void>>(`${API_PREFIX}/dissolve`, params)
|
||||
}
|
||||
|
||||
// 退出空间
|
||||
export function exitSpaceApi(params: ExitSpaceParams) {
|
||||
return alovaInstance.Post<ResponseData<void>>(`${API_PREFIX}/member/exit`, params)
|
||||
}
|
||||
|
||||
// Join Space API
|
||||
export function joinSpaceApi(params: JoinSpaceParams) {
|
||||
return alovaInstance.Post<ResponseData<JoinSpaceResult>>(`${API_PREFIX}/join`, params)
|
||||
}
|
||||
|
||||
// Dissolve Space API
|
||||
export function dissolveSpaceApi(params: DissolveSpaceParams) {
|
||||
return alovaInstance.Post<ResponseData<DissolveSpaceResult>>(`${API_PREFIX}/dissolve`, params)
|
||||
}
|
||||
|
||||
// Exit Space API
|
||||
export function exitSpaceApi(params: ExitSpaceParams) {
|
||||
return alovaInstance.Post<ResponseData<ExitSpaceResult>>(`${API_PREFIX}/exit`, params)
|
||||
}
|
||||
|
||||
// Remove Space User API
|
||||
export function removeSpaceMemberApi(params: RemoveSpaceMemberParams) {
|
||||
return alovaInstance.Post<ResponseData<RemoveSpaceMemberResult>>(`${API_PREFIX}/remove`, params)
|
||||
|
||||
@@ -28,8 +28,8 @@ function isWhiteListed(url: string) {
|
||||
}
|
||||
|
||||
const alovaInstance = createAlova({
|
||||
// baseURL: 'http://192.168.5.6:8086/app',
|
||||
baseURL: 'http://192.168.1.137:8086/app',
|
||||
baseURL: 'http://192.168.5.6:8086/app',
|
||||
// baseURL: 'http://192.168.1.137:8086/app',
|
||||
requestAdapter: axiosRequestAdapter(),
|
||||
timeout: 5000,
|
||||
cacheFor: null,
|
||||
|
||||
@@ -8,6 +8,8 @@ export interface UserSpace {
|
||||
|
||||
member_name: string
|
||||
sort_number: number
|
||||
|
||||
invite_code: string
|
||||
}
|
||||
|
||||
// 创建空间
|
||||
@@ -31,9 +33,11 @@ export interface ListUserSpacesResult {
|
||||
export interface DissolveSpaceParams {
|
||||
space_id: number
|
||||
}
|
||||
export interface DissolveSpaceResult {
|
||||
}
|
||||
|
||||
// 退出空间
|
||||
export interface ExitSpaceParams {
|
||||
space_id: number
|
||||
}
|
||||
// 更新空间名称
|
||||
export interface UpdateSpaceNameParams {
|
||||
space_id: number
|
||||
@@ -74,13 +78,6 @@ export interface JoinSpaceResult {
|
||||
space_name: string
|
||||
}
|
||||
|
||||
// 退出空间
|
||||
export interface ExitSpaceParams {
|
||||
space_id: number
|
||||
}
|
||||
export interface ExitSpaceResult {
|
||||
}
|
||||
|
||||
// 踢出用户
|
||||
export interface RemoveSpaceMemberParams {
|
||||
space_id: number
|
||||
|
||||
Reference in new issue
Block a user