diff --git a/Localizable.xcstrings b/Localizable.xcstrings index 4aa7397..d3fd111 100644 --- a/Localizable.xcstrings +++ b/Localizable.xcstrings @@ -70,6 +70,9 @@ }, "Archive bookmark" : { + }, + "Are you sure you want to delete this bookmark? This action cannot be undone." : { + }, "Are you sure you want to log out? This will delete all your login credentials and return you to setup." : { @@ -100,6 +103,9 @@ }, "Delete" : { + }, + "Delete Bookmark" : { + }, "Developer: Ilyas Hallak" : { diff --git a/readeck/UI/BookmarkDetail/BookmarkDetailView.swift b/readeck/UI/BookmarkDetail/BookmarkDetailView.swift index 26e370f..92d6a34 100644 --- a/readeck/UI/BookmarkDetail/BookmarkDetailView.swift +++ b/readeck/UI/BookmarkDetail/BookmarkDetailView.swift @@ -48,7 +48,7 @@ struct BookmarkDetailView: View { .frame(height: 0) ZStack(alignment: .top) { headerView(geometry: outerGeo) - VStack(alignment: .center, spacing: 16) { + VStack(alignment: .leading, spacing: 16) { Color.clear.frame(height: viewModel.bookmarkDetail.imageUrl.isEmpty ? 84 : headerHeight) titleSection Divider().padding(.horizontal) @@ -57,7 +57,9 @@ struct BookmarkDetailView: View { } if let settings = viewModel.settings, !viewModel.articleContent.isEmpty { WebView(htmlContent: viewModel.articleContent, settings: settings, onHeightChange: { height in - webViewHeight = height + if webViewHeight != height { + webViewHeight = height + } }) .frame(height: webViewHeight) .cornerRadius(14) @@ -82,11 +84,14 @@ struct BookmarkDetailView: View { .padding(.horizontal) .padding(.top, 0) } - Spacer(minLength: 40) + if viewModel.isLoadingArticle == false && viewModel.isLoading == false { - archiveSection - .transition(.opacity.combined(with: .move(edge: .bottom))) - .animation(.easeInOut, value: viewModel.articleContent) + VStack(alignment: .center) { + archiveSection + .transition(.opacity.combined(with: .move(edge: .bottom))) + .animation(.easeInOut, value: viewModel.articleContent) + } + .frame(maxWidth: .infinity) } } } @@ -358,7 +363,7 @@ struct BookmarkDetailView: View { let displayFormatter = DateFormatter() displayFormatter.dateStyle = .medium displayFormatter.timeStyle = .short - displayFormatter.locale = Locale(identifier: "de_DE") + displayFormatter.locale = .autoupdatingCurrent return displayFormatter.string(from: date) } return dateString @@ -417,13 +422,11 @@ struct BookmarkDetailView: View { @ViewBuilder func JumpButton() -> some View { Button(action: { - if #available(iOS 17.0, *) { - let maxOffset = webViewHeight - scrollViewHeight - let offset = maxOffset * (Double(viewModel.readProgress) / 100.0) - DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { - scrollPosition = ScrollPosition(y: offset) - showJumpToProgressButton = false - } + let maxOffset = webViewHeight - scrollViewHeight + let offset = maxOffset * (Double(viewModel.readProgress) / 100.0) + DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { + scrollPosition = ScrollPosition(y: offset) + showJumpToProgressButton = false } }) { Text("Jump to last read position (\(viewModel.readProgress)%)") diff --git a/readeck/UI/Bookmarks/BookmarkCardView.swift b/readeck/UI/Bookmarks/BookmarkCardView.swift index 0fbc9d3..e098191 100644 --- a/readeck/UI/Bookmarks/BookmarkCardView.swift +++ b/readeck/UI/Bookmarks/BookmarkCardView.swift @@ -28,7 +28,7 @@ struct BookmarkCardView: View { } .clipShape(RoundedRectangle(cornerRadius: 8)) - if bookmark.readProgress > 0 { + if bookmark.readProgress > 0 && bookmark.isArchived == false && bookmark.isMarked == false { ZStack { Circle() .fill(Color(.systemBackground)) diff --git a/readeck/UI/Bookmarks/BookmarksView.swift b/readeck/UI/Bookmarks/BookmarksView.swift index db42e96..23b348b 100644 --- a/readeck/UI/Bookmarks/BookmarksView.swift +++ b/readeck/UI/Bookmarks/BookmarksView.swift @@ -12,6 +12,7 @@ struct BookmarksView: View { @State private var showingAddBookmarkFromShare = false @State private var shareURL = "" @State private var shareTitle = "" + @State private var bookmarkToDelete: Bookmark? = nil let state: BookmarkState let type: [BookmarkType] @@ -19,7 +20,6 @@ struct BookmarksView: View { @EnvironmentObject var playerUIState: PlayerUIState let tag: String? - // MARK: Environments @Environment(\.horizontalSizeClass) var horizontalSizeClass @@ -65,9 +65,7 @@ struct BookmarksView: View { } }, onDelete: { bookmark in - Task { - await viewModel.deleteBookmark(bookmark: bookmark) - } + bookmarkToDelete = bookmark }, onToggleFavorite: { bookmark in Task { @@ -150,6 +148,18 @@ struct BookmarksView: View { AddBookmarkView(prefilledURL: shareURL, prefilledTitle: shareTitle) } ) + .alert(item: $bookmarkToDelete) { bookmark in + Alert( + title: Text("Delete Bookmark"), + message: Text("Are you sure you want to delete this bookmark? This action cannot be undone."), + primaryButton: .destructive(Text("Delete")) { + Task { + await viewModel.deleteBookmark(bookmark: bookmark) + } + }, + secondaryButton: .cancel() + ) + } .onAppear { Task { await viewModel.loadBookmarks(state: state, type: type, tag: tag) diff --git a/readeck/UI/Components/WebView.swift b/readeck/UI/Components/WebView.swift index f667a5a..ef96687 100644 --- a/readeck/UI/Components/WebView.swift +++ b/readeck/UI/Components/WebView.swift @@ -11,7 +11,7 @@ struct WebView: UIViewRepresentable { func makeUIView(context: Context) -> WKWebView { let webView = WKWebView() webView.navigationDelegate = context.coordinator - webView.scrollView.isScrollEnabled = true + webView.scrollView.isScrollEnabled = false webView.isOpaque = false webView.backgroundColor = UIColor.clear @@ -214,17 +214,13 @@ struct WebView: UIViewRepresentable { \(htmlContent) @@ -290,7 +285,10 @@ class WebViewCoordinator: NSObject, WKNavigationDelegate, WKScriptMessageHandler func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { if message.name == "heightUpdate", let height = message.body as? CGFloat { DispatchQueue.main.async { - self.onHeightChange?(height) + if self.hasHeightUpdate == false { + self.onHeightChange?(height) + self.hasHeightUpdate = true + } } } if message.name == "scrollProgress", let progress = message.body as? Double { @@ -299,4 +297,6 @@ class WebViewCoordinator: NSObject, WKNavigationDelegate, WKScriptMessageHandler } } } + + var hasHeightUpdate: Bool = false }