feat: 更新AppSettingView以集成图片选择与预览功能
- 将图片选择功能整合到AppSettingView中,使用ImagePickerWithPreviewView提升用户体验。 - 移除冗余的照片选择处理逻辑,简化代码结构。 - 更新昵称编辑功能的实现,确保用户输入限制在15个字符内。 - 优化导航栏和用户协议、隐私政策的展示,增强界面交互性。
This commit is contained in:
@@ -11,27 +11,32 @@ import PhotosUI
|
||||
|
||||
struct AppSettingView: View {
|
||||
let store: StoreOf<AppSettingFeature>
|
||||
@State private var showPhotoPicker = false
|
||||
// 直接let声明pickerStore
|
||||
let pickerStore = Store(
|
||||
initialState: ImagePickerWithPreviewReducer.State(inner: ImagePickerWithPreviewState(selectionMode: .single)),
|
||||
reducer: { ImagePickerWithPreviewReducer() }
|
||||
)
|
||||
@State private var showImagePicker = false
|
||||
@State private var showNicknameAlert = false
|
||||
@State private var nicknameInput = ""
|
||||
@State private var selectedPhotoItem: PhotosPickerItem?
|
||||
|
||||
var body: some View {
|
||||
// WithPerceptionTracking {
|
||||
WithViewStore(store, observe: { $0 }) { viewStore in
|
||||
WithPerceptionTracking{
|
||||
ZStack {
|
||||
mainContent(viewStore: viewStore)
|
||||
.navigationBarHidden(true)
|
||||
.photosPicker(
|
||||
isPresented: $showPhotoPicker,
|
||||
selection: $selectedPhotoItem,
|
||||
matching: .images,
|
||||
photoLibrary: .shared()
|
||||
)
|
||||
.onChange(of: selectedPhotoItem) { item in
|
||||
handlePhotoSelection(item: item, viewStore: viewStore)
|
||||
selectedPhotoItem = nil
|
||||
if showImagePicker {
|
||||
WithPerceptionTracking{
|
||||
ImagePickerWithPreviewView(store: pickerStore) { images in
|
||||
if let image = images.first, let data = image.jpegData(compressionQuality: 0.8) {
|
||||
viewStore.send(.avatarSelected(data))
|
||||
}
|
||||
showImagePicker = false
|
||||
}
|
||||
.zIndex(10)
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationBarHidden(true)
|
||||
.alert("修改昵称", isPresented: $showNicknameAlert) {
|
||||
nicknameAlertContent(viewStore: viewStore)
|
||||
} message: {
|
||||
@@ -43,10 +48,12 @@ struct AppSettingView: View {
|
||||
.sheet(isPresented: privacyPolicyBinding(viewStore: viewStore)) {
|
||||
WebView(url: URL(string: "https://www.yana.com/privacy-policy")!)
|
||||
}
|
||||
.onChange(of: showImagePicker) { newValue in
|
||||
if newValue {
|
||||
pickerStore.send(.inner(.showActionSheet(true)))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
// MARK: - 主要内容
|
||||
@@ -56,16 +63,14 @@ struct AppSettingView: View {
|
||||
VStack(spacing: 0) {
|
||||
topBar
|
||||
ScrollView {
|
||||
WithPerceptionTracking {
|
||||
VStack(spacing: 32) {
|
||||
// 头像区域
|
||||
avatarSection(viewStore: viewStore)
|
||||
|
||||
// 昵称设置项
|
||||
nicknameSection(viewStore: viewStore)
|
||||
|
||||
// 设置项区域
|
||||
settingsSection(viewStore: viewStore)
|
||||
|
||||
// 退出登录按钮
|
||||
logoutButton(viewStore: viewStore)
|
||||
}
|
||||
@@ -73,64 +78,6 @@ struct AppSettingView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - 照片选择处理
|
||||
private func handlePhotoSelection(item: PhotosPickerItem?, viewStore: ViewStoreOf<AppSettingFeature>) {
|
||||
if let item = item {
|
||||
loadAndProcessImage(item: item) { data in
|
||||
if let data = data {
|
||||
viewStore.send(.avatarSelected(data))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - 昵称Alert内容
|
||||
@ViewBuilder
|
||||
private func nicknameAlertContent(viewStore: ViewStoreOf<AppSettingFeature>) -> some View {
|
||||
TextField("请输入昵称", text: $nicknameInput)
|
||||
.onChange(of: nicknameInput) { newValue in
|
||||
if newValue.count > 15 {
|
||||
nicknameInput = String(newValue.prefix(15))
|
||||
}
|
||||
}
|
||||
Button("确定") {
|
||||
let trimmed = nicknameInput.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
if !trimmed.isEmpty && trimmed != viewStore.nickname {
|
||||
viewStore.send(.nicknameEditConfirmed(trimmed))
|
||||
}
|
||||
}
|
||||
Button("取消", role: .cancel) {}
|
||||
}
|
||||
|
||||
// MARK: - 顶部栏
|
||||
private var topBar: some View {
|
||||
HStack {
|
||||
WithViewStore(store, observe: { $0 }) { viewStore in
|
||||
Button(action: {
|
||||
viewStore.send(.dismissTapped)
|
||||
}) {
|
||||
Image(systemName: "chevron.left")
|
||||
.foregroundColor(.white)
|
||||
.font(.system(size: 20, weight: .medium))
|
||||
}
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
Text(NSLocalizedString("appSetting.title", comment: "Settings"))
|
||||
.font(.system(size: 18, weight: .semibold))
|
||||
.foregroundColor(.white)
|
||||
|
||||
Spacer()
|
||||
|
||||
// 占位符,保持标题居中
|
||||
Color.clear
|
||||
.frame(width: 20, height: 20)
|
||||
}
|
||||
.padding(.horizontal, 20)
|
||||
.padding(.top, 8)
|
||||
.padding(.bottom, 16)
|
||||
}
|
||||
|
||||
// MARK: - 头像区域
|
||||
@@ -138,11 +85,11 @@ struct AppSettingView: View {
|
||||
ZStack(alignment: .bottomTrailing) {
|
||||
avatarImageView(viewStore: viewStore)
|
||||
.onTapGesture {
|
||||
showPhotoPicker = true
|
||||
showImagePicker = true
|
||||
}
|
||||
cameraButton
|
||||
.onTapGesture {
|
||||
showPhotoPicker = true
|
||||
showImagePicker = true
|
||||
}
|
||||
}
|
||||
.padding(.top, 24)
|
||||
@@ -340,6 +287,54 @@ struct AppSettingView: View {
|
||||
)
|
||||
}
|
||||
|
||||
// MARK: - 昵称Alert内容
|
||||
@ViewBuilder
|
||||
private func nicknameAlertContent(viewStore: ViewStoreOf<AppSettingFeature>) -> some View {
|
||||
TextField("请输入昵称", text: $nicknameInput)
|
||||
.onChange(of: nicknameInput) { newValue in
|
||||
if newValue.count > 15 {
|
||||
nicknameInput = String(newValue.prefix(15))
|
||||
}
|
||||
}
|
||||
Button("确定") {
|
||||
let trimmed = nicknameInput.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
if !trimmed.isEmpty && trimmed != viewStore.nickname {
|
||||
viewStore.send(.nicknameEditConfirmed(trimmed))
|
||||
}
|
||||
}
|
||||
Button("取消", role: .cancel) {}
|
||||
}
|
||||
|
||||
// MARK: - 顶部栏
|
||||
private var topBar: some View {
|
||||
HStack {
|
||||
WithViewStore(store, observe: { $0 }) { viewStore in
|
||||
Button(action: {
|
||||
viewStore.send(.dismissTapped)
|
||||
}) {
|
||||
Image(systemName: "chevron.left")
|
||||
.foregroundColor(.white)
|
||||
.font(.system(size: 20, weight: .medium))
|
||||
}
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
Text(NSLocalizedString("appSetting.title", comment: "Settings"))
|
||||
.font(.system(size: 18, weight: .semibold))
|
||||
.foregroundColor(.white)
|
||||
|
||||
Spacer()
|
||||
|
||||
// 占位符,保持标题居中
|
||||
Color.clear
|
||||
.frame(width: 20, height: 20)
|
||||
}
|
||||
.padding(.horizontal, 20)
|
||||
.padding(.top, 8)
|
||||
.padding(.bottom, 16)
|
||||
}
|
||||
|
||||
// MARK: - 图片处理
|
||||
private func loadAndProcessImage(item: PhotosPickerItem, completion: @escaping (Data?) -> Void) {
|
||||
item.loadTransferable(type: Data.self) { result in
|
||||
|
Reference in New Issue
Block a user