feat: 更新CreateFeedFeature和FeedListFeature以增强发布和关闭功能

- 修改CreateFeedFeature中的发布逻辑,确保在发布成功时同时发送关闭通知。
- 更新FeedListFeature以在创建Feed成功时触发刷新并关闭编辑页面。
- 优化CreateFeedView中的键盘管理和通知处理,提升用户体验。
This commit is contained in:
edwinQQQ
2025-07-31 16:44:49 +08:00
parent 65c74db837
commit 57a8b833eb
4 changed files with 121 additions and 103 deletions

View File

@@ -83,9 +83,7 @@ struct CreateFeedFeature {
newImages.append(image) newImages.append(image)
} }
} }
await MainActor.run { await send(.updateProcessedImages(newImages))
send(.updateProcessedImages(newImages))
}
} }
case .updateProcessedImages(let images): case .updateProcessedImages(let images):
@@ -239,17 +237,26 @@ struct CreateFeedFeature {
return .none return .none
case .dismissView: case .dismissView:
guard isPresented else { //
return .none
}
return .run { _ in return .run { _ in
await dismiss() await MainActor.run {
NotificationCenter.default.post(name: .init("CreateFeedDismiss"), object: nil)
}
} }
case .publishSuccess: case .publishSuccess:
// //
return .run { _ in return .merge(
NotificationCenter.default.post(name: .init("CreateFeedPublishSuccess"), object: nil) .run { _ in
} await MainActor.run {
NotificationCenter.default.post(name: .init("CreateFeedPublishSuccess"), object: nil)
}
},
.run { _ in
await MainActor.run {
NotificationCenter.default.post(name: .init("CreateFeedDismiss"), object: nil)
}
}
)
} }
} }
} }

View File

@@ -145,8 +145,11 @@ struct FeedListFeature {
state.isEditFeedPresented = false state.isEditFeedPresented = false
return .none return .none
case .createFeedPublishSuccess: case .createFeedPublishSuccess:
// CreateFeed // CreateFeed
return .send(.reload) return .merge(
.send(.reload),
.send(.editFeedDismissed)
)
case .testButtonTapped: case .testButtonTapped:
debugInfoSync("[LOG] FeedListFeature testButtonTapped") debugInfoSync("[LOG] FeedListFeature testButtonTapped")
return .none return .none

View File

@@ -8,106 +8,111 @@ struct CreateFeedView: View {
@FocusState private var isTextEditorFocused: Bool @FocusState private var isTextEditorFocused: Bool
var body: some View { var body: some View {
WithPerceptionTracking { NavigationStack {
NavigationStack { GeometryReader { geometry in
GeometryReader { geometry in VStack(spacing: 0) {
VStack(spacing: 0) { ZStack {
ZStack { //
// Color(hex: 0x0C0527)
Color(hex: 0x0C0527) .ignoresSafeArea()
.ignoresSafeArea()
// //
VStack(spacing: 20) { VStack(spacing: 20) {
ContentInputSection(store: store, isFocused: $isTextEditorFocused) ContentInputSection(store: store, isFocused: $isTextEditorFocused)
ImageSelectionSection(store: store) ImageSelectionSection(store: store)
LoadingAndErrorSection(store: store) LoadingAndErrorSection(store: store)
Spacer() Spacer()
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
.ignoresSafeArea(.keyboard, edges: .bottom)
.background(Color(hex: 0x0C0527))
}
// -
if !isKeyboardVisible {
PublishButtonSection(store: store, geometry: geometry, isFocused: $isTextEditorFocused)
} }
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
.ignoresSafeArea(.keyboard, edges: .bottom)
.background(Color(hex: 0x0C0527))
} }
.onTapGesture {
isTextEditorFocused = false // // -
if !isKeyboardVisible {
PublishButtonSection(store: store, geometry: geometry, isFocused: $isTextEditorFocused)
} }
} }
.navigationTitle(NSLocalizedString("createFeed.title", comment: "Image & Text Publish")) .onTapGesture {
.navigationBarTitleDisplayMode(.inline) isTextEditorFocused = false //
.toolbarBackground(.hidden, for: .navigationBar) }
.navigationBarBackButtonHidden(true) }
.toolbar { .navigationTitle(NSLocalizedString("createFeed.title", comment: "Image & Text Publish"))
ToolbarItem(placement: .navigationBarLeading) { .navigationBarTitleDisplayMode(.inline)
Button(action: { .toolbarBackground(.hidden, for: .navigationBar)
store.send(.dismissView) .navigationBarBackButtonHidden(true)
}) { .toolbar {
Image(systemName: "xmark") ToolbarItem(placement: .navigationBarLeading) {
.font(.system(size: 18, weight: .medium)) Button(action: {
.foregroundColor(.white) store.send(.dismissView)
} }) {
} Image(systemName: "xmark")
ToolbarItem(placement: .principal) {
Text(NSLocalizedString("createFeed.title", comment: "Image & Text Publish"))
.font(.system(size: 18, weight: .medium)) .font(.system(size: 18, weight: .medium))
.foregroundColor(.white) .foregroundColor(.white)
} }
}
// - ToolbarItem(placement: .principal) {
ToolbarItem(placement: .navigationBarTrailing) { Text(NSLocalizedString("createFeed.title", comment: "Image & Text Publish"))
if isKeyboardVisible { .font(.system(size: 18, weight: .medium))
Button(action: { .foregroundColor(.white)
isTextEditorFocused = false // }
store.send(.publishButtonTapped)
}) { // -
HStack(spacing: 4) { ToolbarItem(placement: .navigationBarTrailing) {
if store.isLoading || store.isUploadingImages { if isKeyboardVisible {
ProgressView() Button(action: {
.progressViewStyle(CircularProgressViewStyle(tint: .white)) isTextEditorFocused = false //
.scaleEffect(0.7) store.send(.publishButtonTapped)
} }) {
Text(toolbarButtonText) HStack(spacing: 4) {
.font(.system(size: 14, weight: .medium)) if store.isLoading || store.isUploadingImages {
.foregroundColor(.white) ProgressView()
.progressViewStyle(CircularProgressViewStyle(tint: .white))
.scaleEffect(0.7)
} }
.padding(.horizontal, 12) Text(toolbarButtonText)
.padding(.vertical, 8) .font(.system(size: 14, weight: .medium))
.background( .foregroundColor(.white)
LinearGradient(
gradient: Gradient(colors: [
Color(hex: 0xF854FC),
Color(hex: 0x500FFF)
]),
startPoint: .leading,
endPoint: .trailing
)
)
.cornerRadius(16)
} }
.disabled(store.isLoading || store.isUploadingImages || !store.canPublish) .padding(.horizontal, 12)
.opacity(toolbarButtonOpacity) .padding(.vertical, 8)
.background(
LinearGradient(
gradient: Gradient(colors: [
Color(hex: 0xF854FC),
Color(hex: 0x500FFF)
]),
startPoint: .leading,
endPoint: .trailing
)
)
.cornerRadius(16)
} }
.disabled(store.isLoading || store.isUploadingImages || !store.canPublish)
.opacity(toolbarButtonOpacity)
} }
} }
} }
.onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillShowNotification)) { notification in }
if let _ = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect { .onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillShowNotification)) { notification in
if let _ = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect {
DispatchQueue.main.async {
isKeyboardVisible = true isKeyboardVisible = true
} }
} }
.onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillHideNotification)) { _ in }
isKeyboardVisible = false .onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillHideNotification)) { _ in
} DispatchQueue.main.async {
.onDisappear {
isKeyboardVisible = false isKeyboardVisible = false
} }
} }
.onReceive(NotificationCenter.default.publisher(for: .init("CreateFeedDismiss"))) { _ in
store.send(.dismissView)
}
.onDisappear {
isKeyboardVisible = false
}
} }
// MARK: - // MARK: -

View File

@@ -255,16 +255,19 @@ struct FeedListView: View {
} }
// //
.sheet(isPresented: viewStore.binding(get: \.isEditFeedPresented, send: { _ in .editFeedDismissed })) { .sheet(isPresented: viewStore.binding(get: \.isEditFeedPresented, send: { _ in .editFeedDismissed })) {
CreateFeedView( let createFeedStore = Store(
store: Store( initialState: CreateFeedFeature.State()
initialState: CreateFeedFeature.State() ) {
) { CreateFeedFeature()
CreateFeedFeature()
}
)
.onReceive(NotificationCenter.default.publisher(for: .init("CreateFeedPublishSuccess"))) { _ in
store.send(.createFeedPublishSuccess)
} }
CreateFeedView(store: createFeedStore)
.onReceive(NotificationCenter.default.publisher(for: .init("CreateFeedPublishSuccess"))) { _ in
store.send(.createFeedPublishSuccess)
}
.onReceive(NotificationCenter.default.publisher(for: .init("CreateFeedDismiss"))) { _ in
store.send(.editFeedDismissed)
}
} }
// //
.navigationDestination(isPresented: viewStore.binding(get: \.showDetail, send: { _ in .detailDismissed })) { .navigationDestination(isPresented: viewStore.binding(get: \.showDetail, send: { _ in .detailDismissed })) {