Source code for the WriteFreely SwiftUI app for iOS, iPadOS, and macOS
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 

150 Zeilen
6.4 KiB

  1. import SwiftUI
  2. import Combine
  3. struct PostListView: View {
  4. @EnvironmentObject var model: WriteFreelyModel
  5. @Environment(\.managedObjectContext) var managedObjectContext
  6. @State private var postCount: Int = 0
  7. #if os(iOS)
  8. private var frameHeight: CGFloat {
  9. var height: CGFloat = 50
  10. let bottom = UIApplication.shared.windows.first?.safeAreaInsets.bottom ?? 0
  11. height += bottom
  12. return height
  13. }
  14. #endif
  15. var body: some View {
  16. #if os(iOS)
  17. ZStack(alignment: .bottom) {
  18. PostListFilteredView(
  19. collection: model.selectedCollection,
  20. showAllPosts: model.showAllPosts,
  21. postCount: $postCount
  22. )
  23. .navigationTitle(
  24. model.showAllPosts ? "All Posts" : model.selectedCollection?.title ?? (
  25. model.account.server == "https://write.as" ? "Anonymous" : "Drafts"
  26. )
  27. )
  28. .toolbar {
  29. ToolbarItem(placement: .primaryAction) {
  30. // We have to add a Spacer as a sibling view to the Button in some kind of Stack, so that any
  31. // a11y modifiers are applied as expected: bug report filed as FB8956392.
  32. ZStack {
  33. Spacer()
  34. Button(action: {
  35. let managedPost = model.editor.generateNewLocalPost(withFont: model.preferences.font)
  36. withAnimation {
  37. self.model.showAllPosts = false
  38. self.model.selectedPost = managedPost
  39. }
  40. }, label: {
  41. ZStack {
  42. Image("does.not.exist")
  43. .accessibilityHidden(true)
  44. Image(systemName: "square.and.pencil")
  45. .accessibilityHidden(true)
  46. .imageScale(.large) // These modifiers compensate for the resizing
  47. .padding(.vertical, 12) // done to the Image (and the button tap target)
  48. .padding(.leading, 12) // by the SwiftUI layout system from adding a
  49. .padding(.trailing, 8) // Spacer in this ZStack (FB8956392).
  50. }
  51. .frame(maxWidth: .infinity, maxHeight: .infinity)
  52. })
  53. .accessibilityLabel(Text("Compose"))
  54. .accessibilityHint(Text("Compose a new local draft"))
  55. }
  56. }
  57. }
  58. VStack {
  59. HStack(spacing: 0) {
  60. Button(action: {
  61. model.isPresentingSettingsView = true
  62. }, label: {
  63. Image(systemName: "gear")
  64. .padding(.vertical, 4)
  65. .padding(.horizontal, 8)
  66. })
  67. .accessibilityLabel(Text("Settings"))
  68. .accessibilityHint(Text("Open the Settings sheet"))
  69. Spacer()
  70. Text(postCount == 1 ? "\(postCount) post" : "\(postCount) posts")
  71. .foregroundColor(.secondary)
  72. Spacer()
  73. if model.isProcessingRequest {
  74. ProgressView()
  75. .padding(.vertical, 4)
  76. .padding(.horizontal, 8)
  77. } else {
  78. Button(action: {
  79. DispatchQueue.main.async {
  80. model.fetchUserCollections()
  81. model.fetchUserPosts()
  82. }
  83. }, label: {
  84. Image(systemName: "arrow.clockwise")
  85. .padding(.vertical, 4)
  86. .padding(.horizontal, 8)
  87. })
  88. .accessibilityLabel(Text("Refresh Posts"))
  89. .accessibilityHint(Text("Fetch changes from the server"))
  90. .disabled(!model.account.isLoggedIn)
  91. }
  92. }
  93. .padding(.top, 8)
  94. .padding(.horizontal, 8)
  95. Spacer()
  96. }
  97. .frame(height: frameHeight)
  98. .background(Color(UIColor.systemGray5))
  99. .overlay(Divider(), alignment: .top)
  100. }
  101. .ignoresSafeArea()
  102. #else
  103. PostListFilteredView(
  104. collection: model.selectedCollection,
  105. showAllPosts: model.showAllPosts,
  106. postCount: $postCount
  107. )
  108. .toolbar {
  109. ToolbarItemGroup(placement: .primaryAction) {
  110. if model.selectedPost != nil {
  111. ActivePostToolbarView(activePost: model.selectedPost!)
  112. .alert(isPresented: $model.isPresentingNetworkErrorAlert, content: {
  113. Alert(
  114. title: Text("Connection Error"),
  115. message: Text("""
  116. There is no internet connection at the moment. \
  117. Please reconnect or try again later.
  118. """),
  119. dismissButton: .default(Text("OK"), action: {
  120. model.isPresentingNetworkErrorAlert = false
  121. })
  122. )
  123. })
  124. }
  125. }
  126. }
  127. .navigationTitle(
  128. model.showAllPosts ? "All Posts" : model.selectedCollection?.title ?? (
  129. model.account.server == "https://write.as" ? "Anonymous" : "Drafts"
  130. )
  131. )
  132. #endif
  133. }
  134. }
  135. struct PostListView_Previews: PreviewProvider {
  136. static var previews: some View {
  137. let context = LocalStorageManager.persistentContainer.viewContext
  138. let model = WriteFreelyModel()
  139. return PostListView()
  140. .environment(\.managedObjectContext, context)
  141. .environmentObject(model)
  142. }
  143. }