diff --git a/V2er.xcodeproj/project.pbxproj b/V2er.xcodeproj/project.pbxproj index 07f9f2f..d3fe54f 100644 --- a/V2er.xcodeproj/project.pbxproj +++ b/V2er.xcodeproj/project.pbxproj @@ -13,7 +13,6 @@ 4EC32AF229D818FC003A3BD4 /* WebBrowserView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EC32AF129D818FC003A3BD4 /* WebBrowserView.swift */; }; 5D02BD5F26909146007B6A1B /* LoadmoreIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D02BD5E26909146007B6A1B /* LoadmoreIndicatorView.swift */; }; 5D04BF9726C9FB6E0005F7E3 /* FeedInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D04BF9626C9FB6E0005F7E3 /* FeedInfo.swift */; }; - 5D096A08247ABF5E00EF3E47 /* TabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D096A07247ABF5E00EF3E47 /* TabBar.swift */; }; 5D0A513726E0CBFC006F3D9B /* ExploreActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D0A513626E0CBFC006F3D9B /* ExploreActions.swift */; }; 5D0A513926E26473006F3D9B /* FeedDetailReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D0A513826E26473006F3D9B /* FeedDetailReducer.swift */; }; 5D0A513B26E26505006F3D9B /* FeedDetailInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D0A513A26E26505006F3D9B /* FeedDetailInfo.swift */; }; @@ -173,7 +172,6 @@ 4EC32AF129D818FC003A3BD4 /* WebBrowserView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebBrowserView.swift; sourceTree = ""; }; 5D02BD5E26909146007B6A1B /* LoadmoreIndicatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadmoreIndicatorView.swift; sourceTree = ""; }; 5D04BF9626C9FB6E0005F7E3 /* FeedInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedInfo.swift; sourceTree = ""; }; - 5D096A07247ABF5E00EF3E47 /* TabBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBar.swift; sourceTree = ""; }; 5D0A513626E0CBFC006F3D9B /* ExploreActions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExploreActions.swift; sourceTree = ""; }; 5D0A513826E26473006F3D9B /* FeedDetailReducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedDetailReducer.swift; sourceTree = ""; }; 5D0A513A26E26505006F3D9B /* FeedDetailInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedDetailInfo.swift; sourceTree = ""; }; @@ -350,7 +348,6 @@ children = ( 5D73FBD827284ACA004558E9 /* RichText */, 5DE5B4CB268466AF00569684 /* Updatable */, - 5D096A07247ABF5E00EF3E47 /* TabBar.swift */, 5D1F4264249713640043F604 /* VEBlur.swift */, 5DE5B4C92684601A00569684 /* TopBar.swift */, 5D4E43FB2699E20400650714 /* AvatarView.swift */, @@ -985,7 +982,6 @@ 5D1D7B8726FC9B61008E0C08 /* LoginReducer.swift in Sources */, 5DA2AD4826C18232007FB1EF /* MessageState.swift in Sources */, 5D0CFA8226B9935B001A8A7F /* UserFeedPage.swift in Sources */, - 5D096A08247ABF5E00EF3E47 /* TabBar.swift in Sources */, 5D91F8D926F22CEC0089D72E /* TagDetailReducer.swift in Sources */, 5D45FC2B26CD3FCF0055C336 /* SwiftSoupExtention.swift in Sources */, ); diff --git a/V2er/Assets.xcassets/explore_tab.imageset/Contents.json b/V2er/Assets.xcassets/explore_tab.imageset/Contents.json deleted file mode 100644 index fe661a8..0000000 --- a/V2er/Assets.xcassets/explore_tab.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "filename" : "explore_tab.png", - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "explore_tab@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "explore_tab@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/V2er/Assets.xcassets/explore_tab.imageset/explore_tab.png b/V2er/Assets.xcassets/explore_tab.imageset/explore_tab.png deleted file mode 100644 index c9a59f6..0000000 Binary files a/V2er/Assets.xcassets/explore_tab.imageset/explore_tab.png and /dev/null differ diff --git a/V2er/Assets.xcassets/explore_tab.imageset/explore_tab@2x.png b/V2er/Assets.xcassets/explore_tab.imageset/explore_tab@2x.png deleted file mode 100644 index d202940..0000000 Binary files a/V2er/Assets.xcassets/explore_tab.imageset/explore_tab@2x.png and /dev/null differ diff --git a/V2er/Assets.xcassets/explore_tab.imageset/explore_tab@3x.png b/V2er/Assets.xcassets/explore_tab.imageset/explore_tab@3x.png deleted file mode 100644 index 9c8a6ea..0000000 Binary files a/V2er/Assets.xcassets/explore_tab.imageset/explore_tab@3x.png and /dev/null differ diff --git a/V2er/Assets.xcassets/feed_tab.imageset/Contents.json b/V2er/Assets.xcassets/feed_tab.imageset/Contents.json deleted file mode 100644 index c16fc32..0000000 --- a/V2er/Assets.xcassets/feed_tab.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "filename" : "feed_tab.png", - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "feed_tab@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "feed_tab@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/V2er/Assets.xcassets/feed_tab.imageset/feed_tab.png b/V2er/Assets.xcassets/feed_tab.imageset/feed_tab.png deleted file mode 100644 index a516669..0000000 Binary files a/V2er/Assets.xcassets/feed_tab.imageset/feed_tab.png and /dev/null differ diff --git a/V2er/Assets.xcassets/feed_tab.imageset/feed_tab@2x.png b/V2er/Assets.xcassets/feed_tab.imageset/feed_tab@2x.png deleted file mode 100644 index d438419..0000000 Binary files a/V2er/Assets.xcassets/feed_tab.imageset/feed_tab@2x.png and /dev/null differ diff --git a/V2er/Assets.xcassets/feed_tab.imageset/feed_tab@3x.png b/V2er/Assets.xcassets/feed_tab.imageset/feed_tab@3x.png deleted file mode 100644 index b0b8e30..0000000 Binary files a/V2er/Assets.xcassets/feed_tab.imageset/feed_tab@3x.png and /dev/null differ diff --git a/V2er/Assets.xcassets/me_tab.imageset/Contents.json b/V2er/Assets.xcassets/me_tab.imageset/Contents.json deleted file mode 100644 index 5501ecd..0000000 --- a/V2er/Assets.xcassets/me_tab.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "filename" : "me_tab.png", - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "me_tab@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "me_tab@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/V2er/Assets.xcassets/me_tab.imageset/me_tab.png b/V2er/Assets.xcassets/me_tab.imageset/me_tab.png deleted file mode 100644 index b5342a8..0000000 Binary files a/V2er/Assets.xcassets/me_tab.imageset/me_tab.png and /dev/null differ diff --git a/V2er/Assets.xcassets/me_tab.imageset/me_tab@2x.png b/V2er/Assets.xcassets/me_tab.imageset/me_tab@2x.png deleted file mode 100644 index 523de7a..0000000 Binary files a/V2er/Assets.xcassets/me_tab.imageset/me_tab@2x.png and /dev/null differ diff --git a/V2er/Assets.xcassets/me_tab.imageset/me_tab@3x.png b/V2er/Assets.xcassets/me_tab.imageset/me_tab@3x.png deleted file mode 100644 index ce49ed0..0000000 Binary files a/V2er/Assets.xcassets/me_tab.imageset/me_tab@3x.png and /dev/null differ diff --git a/V2er/Assets.xcassets/message_tab.imageset/Contents.json b/V2er/Assets.xcassets/message_tab.imageset/Contents.json deleted file mode 100644 index 2757778..0000000 --- a/V2er/Assets.xcassets/message_tab.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "filename" : "message_tab.png", - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "message_tab@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "message_tab@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/V2er/Assets.xcassets/message_tab.imageset/message_tab.png b/V2er/Assets.xcassets/message_tab.imageset/message_tab.png deleted file mode 100644 index 35a6bcb..0000000 Binary files a/V2er/Assets.xcassets/message_tab.imageset/message_tab.png and /dev/null differ diff --git a/V2er/Assets.xcassets/message_tab.imageset/message_tab@2x.png b/V2er/Assets.xcassets/message_tab.imageset/message_tab@2x.png deleted file mode 100644 index 97ae815..0000000 Binary files a/V2er/Assets.xcassets/message_tab.imageset/message_tab@2x.png and /dev/null differ diff --git a/V2er/Assets.xcassets/message_tab.imageset/message_tab@3x.png b/V2er/Assets.xcassets/message_tab.imageset/message_tab@3x.png deleted file mode 100644 index c954fda..0000000 Binary files a/V2er/Assets.xcassets/message_tab.imageset/message_tab@3x.png and /dev/null differ diff --git a/V2er/State/DataFlow/State/GlobalState.swift b/V2er/State/DataFlow/State/GlobalState.swift index 05924c2..95901a1 100644 --- a/V2er/State/DataFlow/State/GlobalState.swift +++ b/V2er/State/DataFlow/State/GlobalState.swift @@ -9,6 +9,11 @@ import Foundation import SwiftUI +enum TabId: String { + case none + case feed, explore, message, me +} + struct GlobalState: FluxState { var selectedTab: TabId = .feed var lastSelectedTab: TabId = .none @@ -18,7 +23,7 @@ struct GlobalState: FluxState { static var account: AccountInfo? { AccountState.getAccount() } - + static var hasSignIn: Bool { AccountState.hasSignIn() } diff --git a/V2er/View/Explore/ExplorePage.swift b/V2er/View/Explore/ExplorePage.swift index b47343d..a47f6ae 100644 --- a/V2er/View/Explore/ExplorePage.swift +++ b/V2er/View/Explore/ExplorePage.swift @@ -90,7 +90,11 @@ struct ExplorePage: BaseHomePageView { await run(action: ExploreActions.FetchData.Start()) } .background(Color.bgColor) - .hide(!isSelected) + .onAppear { + if !state.hasLoadedOnce { + dispatch(ExploreActions.FetchData.Start(autoLoad: true)) + } + } } } diff --git a/V2er/View/Feed/FeedPage.swift b/V2er/View/Feed/FeedPage.swift index 58736ea..dc3babe 100644 --- a/V2er/View/Feed/FeedPage.swift +++ b/V2er/View/Feed/FeedPage.swift @@ -25,9 +25,11 @@ struct FeedPage: BaseHomePageView { var body: some View { contentView - .hide(!isSelected) .onAppear { log("FeedPage.onAppear") + if !state.hasLoadedOnce { + dispatch(FeedActions.FetchData.Start(autoLoad: true)) + } } } diff --git a/V2er/View/MainPage.swift b/V2er/View/MainPage.swift index 68082c9..453ddf1 100644 --- a/V2er/View/MainPage.swift +++ b/V2er/View/MainPage.swift @@ -25,12 +25,47 @@ struct MainPage: StateView { var body: some View { NavigationView { ZStack { - // Main content pages - ZStack { - FeedPage(selecedTab: state.selectedTab) - ExplorePage(selecedTab: state.selectedTab) - MessagePage(selecedTab: state.selectedTab) - MePage(selecedTab: state.selectedTab) + TabView(selection: selectedTab) { + // Feed Tab + pageWithTopBar( + FeedPage(selecedTab: state.selectedTab) + ) + .tabItem { + Label("最新", systemImage: "newspaper") + } + .tag(TabId.feed) + + // Explore Tab + pageWithTopBar( + ExplorePage(selecedTab: state.selectedTab) + ) + .tabItem { + Label("发现", systemImage: "safari") + } + .tag(TabId.explore) + + // Message Tab + pageWithTopBar( + MessagePage(selecedTab: state.selectedTab) + ) + .tabItem { + if unReadNums > 0 { + Label("通知", systemImage: "bell") + .badge(unReadNums) + } else { + Label("通知", systemImage: "bell") + } + } + .tag(TabId.message) + + // Me Tab + pageWithTopBar( + MePage(selecedTab: state.selectedTab) + ) + .tabItem { + Label("我", systemImage: "person") + } + .tag(TabId.me) } // Filter menu overlay - only render when needed @@ -48,17 +83,19 @@ struct MainPage: StateView { .zIndex(1000) } } - .safeAreaInset(edge: .top, spacing: 0) { - TopBar(selectedTab: state.selectedTab) - } - .safeAreaInset(edge: .bottom, spacing: 0) { - TabBar(unReadNums) - } - .ignoresSafeArea(.container) .navigationBarHidden(true) } } - + + @ViewBuilder + private func pageWithTopBar(_ content: Content) -> some View { + VStack(spacing: 0) { + TopBar(selectedTab: state.selectedTab) + content + } + .ignoresSafeArea(.container, edges: .top) + } + } diff --git a/V2er/View/Me/MePage.swift b/V2er/View/Me/MePage.swift index 336f01a..3668c79 100644 --- a/V2er/View/Me/MePage.swift +++ b/V2er/View/Me/MePage.swift @@ -49,7 +49,6 @@ struct MePage: BaseHomePageView { .background(Color.dim) } } - .hide(selecedTab != .me) } @ViewBuilder diff --git a/V2er/View/Message/MessagePage.swift b/V2er/View/Message/MessagePage.swift index 4a7c579..ee66cd4 100644 --- a/V2er/View/Message/MessagePage.swift +++ b/V2er/View/Message/MessagePage.swift @@ -28,7 +28,11 @@ struct MessagePage: BaseHomePageView { var body: some View { contentView .background(Color.bgColor) - .hide(!isSelected) + .onAppear { + if !state.hasLoadedOnce { + dispatch(MessageActions.FetchStart(autoLoad: true)) + } + } } @ViewBuilder diff --git a/V2er/View/Widget/TabBar.swift b/V2er/View/Widget/TabBar.swift deleted file mode 100644 index fa4d84e..0000000 --- a/V2er/View/Widget/TabBar.swift +++ /dev/null @@ -1,146 +0,0 @@ -// -// TabBar.swift -// V2er -// -// Created by Seth on 2020/5/24. -// Copyright © 2020 lessmore.io. All rights reserved. -// - -import SwiftUI - -struct TabBar: View { - @EnvironmentObject private var store: Store - var selectedTab : TabId { - store.appState.globalState.selectedTab - } - var unReadMsg: Int = 0 - var tabs: [TabItem] - - init(_ unReadMsg: Int = 0) { - self.tabs = [TabItem(id: TabId.feed, text: "最新", icon: "feed_tab"), - TabItem(id: TabId.explore, text: "发现", icon: "explore_tab"), - TabItem(id: TabId.message, text: "通知", icon: "message_tab", badge: unReadMsg), - TabItem(id: TabId.me, text: "我", icon: "me_tab")] - } - - - var body: some View { - VStack(spacing: 0) { - Divider().frame(height: 0.1) - HStack(spacing: 0) { - ForEach (self.tabs, id: \.self) { tab in - let isSelected: Bool = self.selectedTab == tab.id - Button { - dispatch(TabbarClickAction(selectedTab: tab.id)) - } label: { - VStack (spacing: 0) { - Color(self.selectedTab == tab.id ? "indictor" : "clear") - .frame(height: 3) - .cornerRadius(0) - Image(tab.icon) - .renderingMode(.template) - .resizable() - .scaledToFit() - .frame(height: 18) - .padding(.bottom, 2.5) - .padding(.top, 8) - .padding(.horizontal, 8) - .overlay { - // badge - Group { - if tab.badge > 0 { - badgeView(num: tab.badge) - } - } - } - Text(tab.text) - .font(.caption) - .fontWeight(isSelected ? .semibold : .regular) - .padding(.bottom, 8) - } - .foregroundColor(isSelected ? Color.tintColor : Color.tintColor.opacity(0.6)) - .background(self.bg(isSelected: isSelected)) - .padding(.horizontal, 16) - .background(Color.almostClear) - - } - } - } - } - .padding(.bottom, topSafeAreaInset().bottom) - .background(VEBlur()) - } - - private func badgeView(num: Int) -> some View { - HStack(alignment: .top) { - Spacer() - VStack { - Text(num.string) - .font(.system(size: 10)) - .foregroundColor(.white) - .padding(4) - .background { - Circle() - .fill(Color.red) - } - Spacer() - } - } - } - - func bg(isSelected : Bool) -> some View { - return LinearGradient( - gradient:Gradient(colors: isSelected ? - [Color.hex(0xBFBFBF, alpha: 0.2), Color.hex(0xBFBFBF, alpha: 0.1), Color.hex(0xBFBFBF, alpha: 0.05), Color.hex(0xBFBFBF, alpha: 0.01)] : []) - , startPoint: .top, endPoint: .bottom) - .padding(.top, 3) - } - -} - - - -enum TabId: String { - case none - case feed, explore, message, me -} - -class TabItem : Hashable { - let id : TabId - var text : String - var icon : String - var badge: Int = 0 - - init(id: TabId, text : String, icon : String, badge: Int = 0) { - self.id = id - self.text = text - self.icon = icon - self.badge = badge - } - - static func == (lhs: TabItem, rhs: TabItem) -> Bool { - return lhs.id == rhs.id && - lhs.badge == rhs.badge - } - - func hash(into hasher: inout Hasher) { - hasher.combine(id) - } - -} - -struct TabBar_Previews : PreviewProvider { - // @State static var selected = TabId.feed - - static var previews: some View { - VStack { - Spacer() - TabBar() - .background(VEBlur()) - } - .edgesIgnoringSafeArea(.bottom) - .environmentObject(Store.shared) - } - -} -