Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions iBox/Sources/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,14 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
}

private func preloadFavoriteWeb() {
let favorite = UserDefaultsManager.favorite
let favoriteUrl = favorite.url
let favoriteId = UserDefaultsManager.favoriteId
var favoriteUrl: URL? = nil
if let favoriteId {
favoriteUrl = CoreDataManager.shared.getBookmarkUrl(favoriteId)
if favoriteUrl == nil {
UserDefaultsManager.favoriteId = nil
}
}
WebViewPreloader.shared.preloadFavoriteView(url: favoriteUrl)
}

Expand Down
23 changes: 20 additions & 3 deletions iBox/Sources/BoxList/BoxListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,17 @@ class BoxListView: UIView {
setupLayout()
configureDataSource()
bindViewModel()
subscribeToNotifications()
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

deinit {
NotificationCenter.default.removeObserver(self)
}

// MARK: - Setup Methods

private func setupProperty() {
Expand Down Expand Up @@ -141,6 +146,14 @@ class BoxListView: UIView {
}.store(in: &cancellables)
}

private func subscribeToNotifications() {
NotificationCenter.default.addObserver(self, selector: #selector(dataDidReset), name: .didResetData, object: nil)
}

@objc func dataDidReset(notification: NSNotification) {
viewModel?.input.send(.viewDidLoad)
}

}

extension BoxListView: UITableViewDelegate {
Expand Down Expand Up @@ -190,12 +203,16 @@ extension BoxListView: UITableViewDelegate {

func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
// ์•ก์…˜ ์ •์˜
let favoriteAction = UIContextualAction(style: .normal, title: "favorite", handler: {(action, view, completionHandler) in
self.viewModel?.input.send(.setFavorite(indexPath: indexPath))
let favoriteAction = UIContextualAction(style: .normal, title: "favorite", handler: { [weak self] (action, view, completionHandler) in
self?.viewModel?.input.send(.toggleFavorite(indexPath: indexPath))
completionHandler(true)
})
favoriteAction.backgroundColor = .box2
favoriteAction.image = UIImage(systemName: "heart")
if viewModel?.isFavoriteBookmark(at: indexPath) == true {
favoriteAction.image = UIImage(systemName: "heart.fill")
} else {
favoriteAction.image = UIImage(systemName: "heart")
}

let shareAction = UIContextualAction(style: .normal, title: "share", handler: {(action, view, completionHandler) in
let cellViewModel = self.viewModel?.viewModel(at: indexPath)
Expand Down
1 change: 1 addition & 0 deletions iBox/Sources/BoxList/BoxListViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ extension BoxListViewController: BoxListViewDelegate {
guard let newName = controller.textFields?.first?.text else { return }
guard let newUrlString = controller.textFields?.last?.text,
let newUrl = URL(string: newUrlString) else { return }
guard let contentView = self?.contentView as? BoxListView else { return }

contentView.viewModel?.editBookmark(at: indexPath, name: newName, url: newUrl)
}
Expand Down
38 changes: 35 additions & 3 deletions iBox/Sources/BoxList/BoxListViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,19 @@ class BoxListViewModel {
var folders: [Folder] {
boxList.map{ $0.folder }
}

var sectionsToReload = Set<BoxListSectionViewModel.ID>()
var isEditing = false
var favoriteId: UUID? = nil


enum Input {
case toggleEditStatus
case viewDidLoad
case viewWillAppear
case folderTapped(section: Int)
case deleteBookmark(indexPath: IndexPath)
case setFavorite(indexPath: IndexPath)
case toggleFavorite(indexPath: IndexPath)
case moveBookmark(from: IndexPath, to: IndexPath)
case openFolderIfNeeded(folderIndex: Int)
}
Expand All @@ -50,6 +53,7 @@ class BoxListViewModel {
case .viewDidLoad:
let folders = CoreDataManager.shared.getFolders()
boxList = folders.map{ BoxListSectionViewModel(folder: $0) }
favoriteId = UserDefaultsManager.favoriteId
case .viewWillAppear:
output.send(.sendBoxList(boxList: boxList))
if !sectionsToReload.isEmpty {
Expand All @@ -61,8 +65,8 @@ class BoxListViewModel {
output.send(.sendBoxList(boxList: boxList))
case let .deleteBookmark(indexPath):
deleteBookmark(at: indexPath)
case let .setFavorite(indexPath):
print("\(viewModel(at: indexPath).name) favorite ํ• ๊ฒŒ์šฉ")
case let .toggleFavorite(indexPath):
toggleFavorite(at: indexPath)
case .moveBookmark(from: let from, to: let to):
reorderBookmark(srcIndexPath: from, destIndexPath: to)
case .openFolderIfNeeded(folderIndex: let folderIndex):
Expand All @@ -76,6 +80,34 @@ class BoxListViewModel {
return boxList[indexPath.section].boxListCellViewModels[indexPath.row]
}

func isFavoriteBookmark(at indexPath: IndexPath) -> Bool {
if let favoriteId {
if favoriteId == bookmark(at: indexPath).id {
return true
} else { return false }
} else {
return false
}
}

private func toggleFavorite(at indexPath: IndexPath) {
let bookmark = boxList[indexPath.section].viewModel(at: indexPath.row)
if let prevId = favoriteId {
if prevId == bookmark.id { // ์ง€๊ธˆ ๋“ค์–ด์˜จ๊ฒŒ ์ฆ๊ฒจ์ฐพ๊ธฐ๋ฉด ์ง€์›Œ์•ผ
WebViewPreloader.shared.setFavoriteUrl(url: nil)
favoriteId = nil
UserDefaultsManager.favoriteId = nil
} else {
WebViewPreloader.shared.setFavoriteUrl(url: bookmark.url)
favoriteId = bookmark.id
}
} else {
WebViewPreloader.shared.setFavoriteUrl(url: bookmark.url)
favoriteId = bookmark.id
}
UserDefaultsManager.favoriteId = favoriteId
}

func bookmark(at indexPath: IndexPath) -> Bookmark {
return boxList[indexPath.section].viewModel(at: indexPath.row).bookmark
}
Expand Down
44 changes: 39 additions & 5 deletions iBox/Sources/Settings/Reset/ResetViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,56 @@ extension ResetViewController: ResetViewDelegate {

func showAlert() {
let alertController = UIAlertController(title: "๊ฒฝ๊ณ ", message: "์ด ์ž‘์—…์€ ๋˜๋Œ๋ฆด ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ณ„์†ํ•˜๋ ค๋ฉด \"iBox\"๋ผ๊ณ  ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.", preferredStyle: .alert)
alertController.addTextField()

let cancelAction = UIAlertAction(title: "์ทจ์†Œ", style: .cancel, handler: nil)
alertController.addAction(cancelAction)

let confirmAction = UIAlertAction(title: "ํ™•์ธ", style: .default) { _ in
let confirmAction = UIAlertAction(title: "ํ™•์ธ", style: .default) { [weak self] _ in
if let textField = alertController.textFields?.first, let text = textField.text, text == "iBox" {
print("์ •๋ง๋กœ ์ดˆ๊ธฐํ™”๋ฅผ ํ•ด๋ฒ„๋ ท๋‹น")
self.navigationController?.popViewController(animated: true)
self?.resetData()
self?.navigationController?.popViewController(animated: true)
} else {
self.showAlert()
self?.showAlert()
}
}
confirmAction.isEnabled = false
alertController.addAction(confirmAction)

alertController.addTextField() { textField in
NotificationCenter.default.addObserver(forName: UITextField.textDidChangeNotification, object: textField, queue: OperationQueue.main, using:
{_ in
let isTextMatch = textField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "iBox"

confirmAction.isEnabled = isTextMatch
})

}

self.present(alertController, animated: true, completion: nil)
}

private func resetData() {
let defaultData = [
Folder(id: UUID(), name: "42 ํด๋”", bookmarks: [
Bookmark(id: UUID(), name: "42 Intra", url: URL(string: "https://profile.intra.42.fr/")!),
Bookmark(id: UUID(), name: "42Where", url: URL(string: "https://www.where42.kr/")! ),
Bookmark(id: UUID(), name: "42Stat", url: URL(string: "https://stat.42seoul.kr/")!),
Bookmark(id: UUID(), name: "์ง‘ํ˜„์ „", url: URL(string: "https://42library.kr/")!),
Bookmark(id: UUID(), name: "Cabi", url: URL(string: "https://cabi.42seoul.io/")!),
Bookmark(id: UUID(), name: "24HANE", url: URL(string: "https://24hoursarenotenough.42seoul.kr/")!)
])
]
CoreDataManager.shared.deleteAllFolders()
CoreDataManager.shared.addInitialFolders(defaultData)
UserDefaultsManager.isDefaultDataInserted = true

UserDefaultsManager.favoriteId = nil
WebViewPreloader.shared.setFavoriteUrl(url: nil)
NotificationCenter.default.post(name: .didResetData, object: nil)
}

}

extension Notification.Name {
static let didResetData = Notification.Name("didResetData")
}
9 changes: 9 additions & 0 deletions iBox/Sources/Shared/CoreDataManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,15 @@ extension CoreDataManager {
// ๋ถ๋งˆํฌ ๊ด€๋ จ
extension CoreDataManager {

func getBookmarkUrl(_ bookmarkId: UUID) -> URL? {
let entity = getBookmarkEntity(id: bookmarkId)
if let entity {
return entity.url
} else {
return nil
}
}

func addBookmark(_ bookmark: Bookmark, folderId: UUID) {
let context = persistentContainer.viewContext

Expand Down
4 changes: 2 additions & 2 deletions iBox/Sources/Shared/UserDefaultsManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ final class UserDefaultsManager {
@UserDefaultsData(key: "theme", defaultValue: Theme.system)
static var theme: Theme

@UserDefaultsData(key: "favorite", defaultValue: Bookmark(id: UUID(), name: "42 Intra", url: URL(string: "https://profile.intra.42.fr/")!))
static var favorite: Bookmark
@UserDefaultsData(key: "favoriteId", defaultValue: nil)
static var favoriteId: UUID?

@UserDefaultsData(key: "homeTabIndex", defaultValue: 0)
static var homeTabIndex: Int
Expand Down
21 changes: 18 additions & 3 deletions iBox/Sources/Shared/WebViewPreloader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class WebViewPreloader {
static let shared = WebViewPreloader()
private var webView: WKWebView?
private var favoriteView: (url: URL, webView: WKWebView)?
private var defaultUrl = URL(string: "https://profile.intra.42.fr/")!

private init() {}

Expand All @@ -22,11 +23,11 @@ class WebViewPreloader {
self.webView = webView
}

func preloadFavoriteView(url: URL) {
func preloadFavoriteView(url: URL?) {
let webView = WKWebView()
webView.isOpaque = false
webView.load(URLRequest(url: url))
favoriteView = (url, webView)
webView.load(URLRequest(url: url ?? defaultUrl))
favoriteView = (url ?? defaultUrl, webView)
}

func getWebView() -> WKWebView? {
Expand All @@ -45,5 +46,19 @@ class WebViewPreloader {
guard let favoriteView else { return }
favoriteView.webView.load(URLRequest(url: favoriteView.url))
}

func setFavoriteUrl(url: URL?) {
if let favoriteView {
if url == favoriteView.url ||
(url == nil && favoriteView.url == defaultUrl ) {
return
} else {
self.favoriteView?.url = url ?? defaultUrl
resetFavoriteView()
}
} else {
preloadFavoriteView(url: url)
}
}

}