Source code for the WriteFreely SwiftUI app for iOS, iPadOS, and macOS
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 

140 lignes
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. }