Source code for the WriteFreely SwiftUI app for iOS, iPadOS, and macOS
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 

127 行
4.4 KiB

  1. import SwiftUI
  2. struct PostListView: View {
  3. @EnvironmentObject var model: WriteFreelyModel
  4. @Environment(\.managedObjectContext) var moc
  5. @State var selectedCollection: WFACollection?
  6. @State var showAllPosts: Bool = false
  7. var body: some View {
  8. #if os(iOS)
  9. GeometryReader { geometry in
  10. PostListFilteredView(filter: selectedCollection?.alias, showAllPosts: showAllPosts)
  11. .navigationTitle(
  12. showAllPosts ? "All Posts" : selectedCollection?.title ?? (
  13. model.account.server == "https://write.as" ? "Anonymous" : "Drafts"
  14. )
  15. )
  16. .toolbar {
  17. ToolbarItem(placement: .primaryAction) {
  18. Button(action: {
  19. createNewLocalDraft()
  20. }, label: {
  21. Image(systemName: "square.and.pencil")
  22. })
  23. }
  24. ToolbarItem(placement: .bottomBar) {
  25. HStack {
  26. Button(action: {
  27. model.isPresentingSettingsView = true
  28. }, label: {
  29. Image(systemName: "gear")
  30. })
  31. .padding(.leading)
  32. Spacer()
  33. Text(pluralizedPostCount(for: showPosts(for: selectedCollection)))
  34. .foregroundColor(.secondary)
  35. Spacer()
  36. Button(action: {
  37. reloadFromServer()
  38. }, label: {
  39. Image(systemName: "arrow.clockwise")
  40. })
  41. .disabled(!model.account.isLoggedIn)
  42. }
  43. .padding()
  44. .frame(width: geometry.size.width)
  45. }
  46. }
  47. }
  48. #else //if os(macOS)
  49. PostListFilteredView(filter: selectedCollection?.alias, showAllPosts: showAllPosts)
  50. .navigationTitle(
  51. showAllPosts ? "All Posts" : selectedCollection?.title ?? (
  52. model.account.server == "https://write.as" ? "Anonymous" : "Drafts"
  53. )
  54. )
  55. .navigationSubtitle(pluralizedPostCount(for: showPosts(for: selectedCollection)))
  56. .toolbar {
  57. Button(action: {
  58. createNewLocalDraft()
  59. }, label: {
  60. Image(systemName: "square.and.pencil")
  61. })
  62. Button(action: {
  63. reloadFromServer()
  64. }, label: {
  65. Image(systemName: "arrow.clockwise")
  66. })
  67. .disabled(!model.account.isLoggedIn)
  68. }
  69. #endif
  70. }
  71. private func pluralizedPostCount(for posts: [WFAPost]) -> String {
  72. if posts.count == 1 {
  73. return "1 post"
  74. } else {
  75. return "\(posts.count) posts"
  76. }
  77. }
  78. private func showPosts(for collection: WFACollection?) -> [WFAPost] {
  79. if showAllPosts {
  80. return model.posts.userPosts
  81. } else {
  82. if let selectedCollection = collection {
  83. return model.posts.userPosts.filter { $0.collectionAlias == selectedCollection.alias }
  84. } else {
  85. return model.posts.userPosts.filter { $0.collectionAlias == nil }
  86. }
  87. }
  88. }
  89. private func reloadFromServer() {
  90. DispatchQueue.main.async {
  91. model.fetchUserCollections()
  92. model.fetchUserPosts()
  93. }
  94. }
  95. private func createNewLocalDraft() {
  96. let managedPost = WFAPost(context: LocalStorageManager.persistentContainer.viewContext)
  97. managedPost.createdDate = Date()
  98. managedPost.title = ""
  99. managedPost.body = ""
  100. managedPost.status = PostStatus.local.rawValue
  101. if let selectedCollectionAlias = selectedCollection?.alias {
  102. managedPost.collectionAlias = selectedCollectionAlias
  103. }
  104. DispatchQueue.main.async {
  105. LocalStorageManager().saveContext()
  106. }
  107. }
  108. }
  109. struct PostListView_Previews: PreviewProvider {
  110. static var previews: some View {
  111. let context = LocalStorageManager.persistentContainer.viewContext
  112. let model = WriteFreelyModel()
  113. return PostListView()
  114. .environment(\.managedObjectContext, context)
  115. .environmentObject(model)
  116. }
  117. }