Source code for the WriteFreely SwiftUI app for iOS, iPadOS, and macOS
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 

140 linhas
4.6 KiB

  1. import SwiftUI
  2. struct PostListView: View {
  3. @EnvironmentObject var model: WriteFreelyModel
  4. @State var selectedCollection: PostCollection
  5. #if os(iOS)
  6. @State private var isPresentingSettings = false
  7. #endif
  8. var body: some View {
  9. #if os(iOS)
  10. GeometryReader { geometry in
  11. List {
  12. ForEach(showPosts(for: selectedCollection)) { post in
  13. NavigationLink(
  14. destination: PostEditorView(post: post)
  15. ) {
  16. PostCellView(
  17. post: post
  18. )
  19. }
  20. }
  21. }
  22. .environmentObject(model)
  23. .navigationTitle(selectedCollection.title)
  24. .toolbar {
  25. ToolbarItem(placement: .primaryAction) {
  26. Button(action: {
  27. let post = Post()
  28. model.store.add(post)
  29. }, label: {
  30. Image(systemName: "square.and.pencil")
  31. })
  32. }
  33. ToolbarItem(placement: .bottomBar) {
  34. HStack {
  35. Button(action: {
  36. isPresentingSettings = true
  37. }, label: {
  38. Image(systemName: "gear")
  39. }).sheet(
  40. isPresented: $isPresentingSettings,
  41. onDismiss: {
  42. isPresentingSettings = false
  43. },
  44. content: {
  45. SettingsView(isPresented: $isPresentingSettings)
  46. }
  47. )
  48. .padding(.leading)
  49. Spacer()
  50. Text(pluralizedPostCount(for: showPosts(for: selectedCollection)))
  51. .foregroundColor(.secondary)
  52. Spacer()
  53. Button(action: {
  54. reloadFromServer()
  55. }, label: {
  56. Image(systemName: "arrow.clockwise")
  57. })
  58. .disabled(!model.account.isLoggedIn)
  59. }
  60. .padding()
  61. .frame(width: geometry.size.width)
  62. }
  63. }
  64. }
  65. #else //if os(macOS)
  66. List {
  67. ForEach(showPosts(for: selectedCollection)) { post in
  68. NavigationLink(
  69. destination: PostEditorView(post: post)
  70. ) {
  71. PostCellView(
  72. post: post
  73. )
  74. }
  75. }
  76. }
  77. .navigationTitle(selectedCollection.title)
  78. .navigationSubtitle(pluralizedPostCount(for: showPosts(for: selectedCollection)))
  79. .toolbar {
  80. Button(action: {
  81. let post = Post()
  82. model.store.add(post)
  83. }, label: {
  84. Image(systemName: "square.and.pencil")
  85. })
  86. Button(action: {
  87. reloadFromServer()
  88. }, label: {
  89. Image(systemName: "arrow.clockwise")
  90. })
  91. .disabled(!model.account.isLoggedIn)
  92. }
  93. #endif
  94. }
  95. private func pluralizedPostCount(for posts: [Post]) -> String {
  96. if posts.count == 1 {
  97. return "1 post"
  98. } else {
  99. return "\(posts.count) posts"
  100. }
  101. }
  102. private func showPosts(for collection: PostCollection) -> [Post] {
  103. var posts: [Post]
  104. if collection == CollectionListModel.allPostsCollection {
  105. posts = model.store.posts
  106. } else if collection == CollectionListModel.draftsCollection {
  107. posts = model.store.posts.filter { $0.collection == nil }
  108. } else {
  109. posts = model.store.posts.filter { $0.collection?.title == collection.title }
  110. }
  111. return posts
  112. }
  113. private func reloadFromServer() {
  114. DispatchQueue.main.async {
  115. model.collections.clearUserCollection()
  116. model.fetchUserCollections()
  117. model.fetchUserPosts()
  118. }
  119. }
  120. }
  121. struct PostList_Previews: PreviewProvider {
  122. static var previews: some View {
  123. let model = WriteFreelyModel()
  124. for post in testPostData {
  125. model.store.add(post)
  126. }
  127. return Group {
  128. PostListView(selectedCollection: CollectionListModel.allPostsCollection)
  129. .environmentObject(model)
  130. }
  131. }
  132. }