Source code for the WriteFreely SwiftUI app for iOS, iPadOS, and macOS
Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 

144 righe
5.5 KiB

  1. import SwiftUI
  2. struct PostListFilteredView: View {
  3. @EnvironmentObject var model: WriteFreelyModel
  4. @Binding var postCount: Int
  5. @FetchRequest(entity: WFACollection.entity(), sortDescriptors: []) var collections: FetchedResults<WFACollection>
  6. var fetchRequest: FetchRequest<WFAPost>
  7. init(collection: WFACollection?, showAllPosts: Bool, postCount: Binding<Int>) {
  8. if showAllPosts {
  9. fetchRequest = FetchRequest<WFAPost>(
  10. entity: WFAPost.entity(),
  11. sortDescriptors: [NSSortDescriptor(key: "createdDate", ascending: false)]
  12. )
  13. } else {
  14. if let collectionAlias = collection?.alias {
  15. fetchRequest = FetchRequest<WFAPost>(
  16. entity: WFAPost.entity(),
  17. sortDescriptors: [NSSortDescriptor(key: "createdDate", ascending: false)],
  18. predicate: NSPredicate(format: "collectionAlias == %@", collectionAlias)
  19. )
  20. } else {
  21. fetchRequest = FetchRequest<WFAPost>(
  22. entity: WFAPost.entity(),
  23. sortDescriptors: [NSSortDescriptor(key: "createdDate", ascending: false)],
  24. predicate: NSPredicate(format: "collectionAlias == nil")
  25. )
  26. }
  27. }
  28. _postCount = postCount
  29. }
  30. var body: some View {
  31. #if os(iOS)
  32. if #available(iOS 15, *) {
  33. SearchablePostListFilteredView(
  34. postCount: $postCount,
  35. collections: collections,
  36. fetchRequest: fetchRequest,
  37. onDelete: delete(_:)
  38. )
  39. .environmentObject(model)
  40. .onAppear(perform: {
  41. self.postCount = fetchRequest.wrappedValue.count
  42. })
  43. .onChange(of: fetchRequest.wrappedValue.count, perform: { value in
  44. self.postCount = value
  45. })
  46. } else {
  47. List(selection: $model.selectedPost) {
  48. ForEach(fetchRequest.wrappedValue, id: \.self) { post in
  49. NavigationLink(
  50. destination: PostEditorView(post: post),
  51. tag: post,
  52. selection: $model.selectedPost,
  53. label: {
  54. if model.showAllPosts {
  55. if let collection = collections.filter({ $0.alias == post.collectionAlias }).first {
  56. PostCellView(post: post, collectionName: collection.title)
  57. } else {
  58. // swiftlint:disable:next line_length
  59. let collectionName = model.account.server == "https://write.as" ? "Anonymous" : "Drafts"
  60. PostCellView(post: post, collectionName: collectionName)
  61. }
  62. } else {
  63. PostCellView(post: post)
  64. }
  65. })
  66. .deleteDisabled(post.status != PostStatus.local.rawValue)
  67. }
  68. .onDelete(perform: { indexSet in
  69. for index in indexSet {
  70. let post = fetchRequest.wrappedValue[index]
  71. delete(post)
  72. }
  73. })
  74. }
  75. .onAppear(perform: {
  76. self.postCount = fetchRequest.wrappedValue.count
  77. })
  78. .onChange(of: fetchRequest.wrappedValue.count, perform: { value in
  79. self.postCount = value
  80. })
  81. }
  82. #else
  83. SearchablePostListFilteredView(
  84. postCount: $postCount,
  85. collections: collections,
  86. fetchRequest: fetchRequest,
  87. onDelete: delete(_:)
  88. )
  89. .environmentObject(model)
  90. .alert(isPresented: $model.isPresentingDeleteAlert) {
  91. Alert(
  92. title: Text("Delete Post?"),
  93. message: Text("This action cannot be undone."),
  94. primaryButton: .cancel {
  95. model.postToDelete = nil
  96. },
  97. secondaryButton: .destructive(Text("Delete"), action: {
  98. if let postToDelete = model.postToDelete {
  99. model.selectedPost = nil
  100. DispatchQueue.main.async {
  101. model.editor.clearLastDraft()
  102. model.posts.remove(postToDelete)
  103. }
  104. model.postToDelete = nil
  105. }
  106. })
  107. )
  108. }
  109. .onDeleteCommand(perform: {
  110. guard let selectedPost = model.selectedPost else { return }
  111. if selectedPost.status == PostStatus.local.rawValue {
  112. model.postToDelete = selectedPost
  113. model.isPresentingDeleteAlert = true
  114. }
  115. })
  116. #endif
  117. }
  118. func delete(_ post: WFAPost) {
  119. DispatchQueue.main.async {
  120. if post == model.selectedPost {
  121. model.selectedPost = nil
  122. model.editor.clearLastDraft()
  123. }
  124. model.posts.remove(post)
  125. }
  126. }
  127. }
  128. struct PostListFilteredView_Previews: PreviewProvider {
  129. static var previews: some View {
  130. return PostListFilteredView(
  131. collection: nil,
  132. showAllPosts: false,
  133. postCount: .constant(999)
  134. )
  135. .environmentObject(WriteFreelyModel())
  136. }
  137. }