From 909fa4b8f868fa05aa3a6fd90c883091f1c86213 Mon Sep 17 00:00:00 2001 From: Gray Zhang Date: Wed, 24 Sep 2025 22:25:16 +0800 Subject: [PATCH] fix: prevent crash when clicking Ignore/Report without login MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added login checks for all user actions in FeedDetail: - Star/Unstar topic - Thanks author - Ignore topic - Report topic - Reply to topic These actions now: 1. Check if user is logged in before executing 2. Show login prompt if not authenticated 3. Properly handle nil values with guard statements 4. Show error messages if required data is missing This fixes the crash reported in issue #4 when non-logged-in users click Ignore or Report buttons. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../DataFlow/Actions/FeedDetailActions.swift | 77 ++++++++++++++++--- 1 file changed, 67 insertions(+), 10 deletions(-) diff --git a/V2er/State/DataFlow/Actions/FeedDetailActions.swift b/V2er/State/DataFlow/Actions/FeedDetailActions.swift index 4ef2020..5f590d7 100644 --- a/V2er/State/DataFlow/Actions/FeedDetailActions.swift +++ b/V2er/State/DataFlow/Actions/FeedDetailActions.swift @@ -59,15 +59,25 @@ struct FeedDetailActions { var id: String func execute(in store: Store) async { + // Check if user is logged in + guard AccountState.hasSignIn() else { + Toast.show("请先登录") + dispatch(LoginActions.ShowLoginPageAction(reason: "需要登录才能收藏主题")) + return + } + let state = store.appState.feedDetailStates[id] let hadStared = state?.model.headerInfo?.hadStared ?? false Toast.show(hadStared ? "取消收藏" : "收藏中") - let once = state?.model.once + guard let once = state?.model.once else { + Toast.show("操作失败,请刷新页面") + return + } let headers: Params = Headers.topicReferer(id) let result: APIResult = await APIService.shared .htmlGet(endpoint: hadStared ? .unStarTopic(id: id): .starTopic(id: id), - ["once": once!], + ["once": once], requestHeaders: headers) dispatch(StarTopicDone(id: id, hadStared: hadStared, result: result)) } @@ -86,12 +96,22 @@ struct FeedDetailActions { var id: String func execute(in store: Store) async { + // Check if user is logged in + guard AccountState.hasSignIn() else { + Toast.show("请先登录") + dispatch(LoginActions.ShowLoginPageAction(reason: "需要登录才能感谢作者")) + return + } + Toast.show("发送中") let state = store.appState.feedDetailStates[id] - let once = state?.model.once + guard let once = state?.model.once else { + Toast.show("操作失败,请刷新页面") + return + } let step1Result: APIResult = await APIService.shared - .post(endpoint: .thanksAuthor(id: id), ["once": once!]) + .post(endpoint: .thanksAuthor(id: id), ["once": once]) var success: Bool = false var toast = "感谢发送失败" @@ -116,11 +136,21 @@ struct FeedDetailActions { var id: String func execute(in store: Store) async { + // Check if user is logged in + guard AccountState.hasSignIn() else { + Toast.show("请先登录") + dispatch(LoginActions.ShowLoginPageAction(reason: "需要登录才能忽略主题")) + return + } + Toast.show("忽略中") let state = store.appState.feedDetailStates[id] - let once = state?.model.once + guard let once = state?.model.once else { + Toast.show("操作失败,请刷新页面") + return + } let result: APIResult = await APIService.shared - .htmlGet(endpoint: .ignoreTopic(id: id), ["once": once!]) + .htmlGet(endpoint: .ignoreTopic(id: id), ["once": once]) var ignored = false if case let .success(result) = result { ignored = result?.isValid() ?? false @@ -141,11 +171,22 @@ struct FeedDetailActions { var id: String func execute(in store: Store) async { + // Check if user is logged in + guard AccountState.hasSignIn() else { + Toast.show("请先登录") + dispatch(LoginActions.ShowLoginPageAction(reason: "需要登录才能举报主题")) + return + } + Toast.show("举报中") - let state = store.appState.feedDetailStates[id]! + guard let state = store.appState.feedDetailStates[id], + let reportLink = state.model.reportLink else { + Toast.show("操作失败,请刷新页面") + return + } let result: APIResult = await APIService.shared - .htmlGet(endpoint: .general(url: state.model.reportLink!), + .htmlGet(endpoint: .general(url: reportLink), requestHeaders: Headers.TINY_REFERER) var reported = false if case let .success(result) = result { @@ -166,10 +207,26 @@ struct FeedDetailActions { var id: String func execute(in store: Store) async { + // Check if user is logged in + guard AccountState.hasSignIn() else { + Toast.show("请先登录") + dispatch(LoginActions.ShowLoginPageAction(reason: "需要登录才能回复主题")) + return + } + Toast.show("回复中") - let state = store.appState.feedDetailStates[id]! + guard let state = store.appState.feedDetailStates[id] else { + Toast.show("操作失败,请刷新页面") + return + } + + guard let once = state.model.once else { + Toast.show("操作失败,请刷新页面") + return + } + var params: Params = Params() - params["once"] = state.model.once + params["once"] = once params["content"] = state.replyContent let result: APIResult = await APIService.shared