Skip to content
Open
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
5 changes: 4 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ dependencies {
implementation Deps.kotlin_coroutines

implementation Deps.androidx_appcompat
implementation Deps.androidx_core
implementation Deps.androidx_core_ktx
implementation Deps.androidx_paging
implementation Deps.androidx_navigation_fragment
Expand Down Expand Up @@ -330,7 +331,9 @@ dependencies {
testImplementation Deps.kotlin_coroutines_test

// Must be in debug implementation
debugImplementation Deps.androidx_fragment_testing
debugImplementation(Deps.androidx_fragment_testing) {
exclude group: 'androidx.test', module : 'core'
}
}

// -------------------------------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ package org.mozilla.reference.browser
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import org.mozilla.reference.browser.library.bookmarks.ui.BookmarkViewModel
import org.mozilla.reference.browser.library.bookmarks.ui.addfolder.AddBookmarkFolderViewModel
import org.mozilla.reference.browser.library.bookmarks.ui.edit.EditBookmarkViewModel
import org.mozilla.reference.browser.library.bookmarks.ui.selectfolder.SelectBookmarkViewModel
import org.mozilla.reference.browser.library.history.ui.HistoryViewModel
import java.lang.IllegalArgumentException

Expand All @@ -15,17 +18,28 @@ import java.lang.IllegalArgumentException
*/
class ViewModelFactory(private val applicationContext: BrowserApplication) : ViewModelProvider.Factory {

@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T =
when (modelClass) {
HistoryViewModel::class.java -> with(applicationContext.components.useCases) {
@Suppress("UNCHECKED_CAST", "ComplexMethod")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
val useCases = applicationContext.components.useCases
return when (modelClass) {
HistoryViewModel::class.java -> with(useCases) {
HistoryViewModel(historyUseCases) as T
}
BookmarkViewModel::class.java -> with(applicationContext.components.useCases) {
BookmarkViewModel::class.java -> with(useCases) {
BookmarkViewModel(bookmarkUseCases) as T
}
AddBookmarkFolderViewModel::class.java -> with(useCases) {
AddBookmarkFolderViewModel(bookmarkUseCases) as T
}
SelectBookmarkViewModel::class.java -> with(useCases) {
SelectBookmarkViewModel(bookmarkUseCases) as T
}
EditBookmarkViewModel::class.java -> with(useCases) {
EditBookmarkViewModel(bookmarkUseCases) as T
}
else -> throw IllegalArgumentException("Unknown model class $modelClass")
}
}

companion object {
private var INSTANCE: ViewModelFactory? = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import org.mozilla.reference.browser.ext.nav
import org.mozilla.reference.browser.ext.share
import org.mozilla.reference.browser.settings.SettingsActivity
import org.mozilla.reference.browser.settings.deletebrowsingdata.DeleteBrowsingData
import org.mozilla.reference.browser.storage.HistoryDatabase.Companion.bookmarksRootFolder
import org.mozilla.reference.browser.view.DaisySnackbar

@Suppress("TooManyFunctions")
Expand Down Expand Up @@ -337,34 +338,36 @@ class ToolbarIntegration(
}
}

private suspend fun bookmarkTapped(session: Session) = withContext(Dispatchers.IO) {
val existing =
private suspend fun bookmarkTapped(session: Session) {
withContext(Dispatchers.IO) {
val existing =
bookmarksStorage.getBookmarksWithUrl(session.url).firstOrNull { it.url == session.url }
if (existing != null) {
bookmarksStorage.deleteNode(existing.guid)
} else {
// Save bookmark
bookmarksStorage.addItem(
parentGuid = 0.toString(),
url = session.url,
title = session.title,
position = null
)

withContext(Dispatchers.Main) {
showBookmarkAddedSnackbar()
if (existing != null) {
bookmarksStorage.deleteNode(existing.guid)
} else {
// Save bookmark
val guid = bookmarksStorage.addItem(
parentGuid = 0.toString(),
url = session.url,
title = session.title,
position = null
)

withContext(Dispatchers.Main) {
showBookmarkAddedSnackbar(guid)
}
}
}
}

private fun showBookmarkAddedSnackbar() {
private fun showBookmarkAddedSnackbar(guid: String) {
DaisySnackbar.make(
view = parentView,
duration = DaisySnackbar.LENGTH_LONG
)
.setText(context.getString(R.string.bookmark_added_snackbar_text))
.setAction(context.getString(R.string.bookmark_added_snackbar_edit_action)) {
openBookmarkEditFragment()
openBookmarkEditFragment(guid)
}
.show()
}
Expand All @@ -374,8 +377,9 @@ class ToolbarIntegration(
context.startActivity(intent)
}

private fun openBookmarkEditFragment() {
// to-do go to bookmark edit fragment
private fun openBookmarkEditFragment(guid: String) {
val direction = BrowserFragmentDirections.actionBrowserFragmentToEditBookmarkFragment(guid)
navController.nav(R.id.browserFragment, direction)
}

private fun openHistoryFragment() {
Expand All @@ -384,7 +388,7 @@ class ToolbarIntegration(
}

private fun openBookmarkFragment() {
val direction = BrowserFragmentDirections.actionBrowserFragmentToBookmarkFragment()
val direction = BrowserFragmentDirections.actionBrowserFragmentToBookmarkFragment(bookmarksRootFolder)
navController.nav(R.id.browserFragment, direction)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package org.mozilla.reference.browser.ext

import androidx.annotation.IdRes
import androidx.fragment.app.Fragment
import androidx.navigation.NavController
import androidx.navigation.NavDirections
import androidx.navigation.NavOptions
import androidx.navigation.Navigator
Expand All @@ -20,6 +21,10 @@ import org.mozilla.reference.browser.Components
val Fragment.requireComponents: Components
get() = requireContext().components

fun Fragment.navController(): NavController {
return NavHostFragment.findNavController(this)
}

fun Fragment.nav(@IdRes id: Int?, directions: NavDirections) {
NavHostFragment.findNavController(this).nav(id, directions)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import org.mozilla.reference.browser.ext.nav
import org.mozilla.reference.browser.ext.openToBrowserAndLoad
import org.mozilla.reference.browser.settings.SettingsActivity
import org.mozilla.reference.browser.settings.deletebrowsingdata.DeleteBrowsingData
import org.mozilla.reference.browser.storage.HistoryDatabase.Companion.bookmarksRootFolder

@Suppress("TooManyFunctions")
interface FreshTabController {
Expand Down Expand Up @@ -91,7 +92,7 @@ class DefaultFreshTabController(
}

override fun handleBookmarksClicked() {
val direction = FreshTabFragmentDirections.actionFreshTabFragmentToBookmarkFragment()
val direction = FreshTabFragmentDirections.actionFreshTabFragmentToBookmarkFragment(bookmarksRootFolder)
navController.nav(R.id.freshTabFragment, direction)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ class LibraryItemView @JvmOverloads constructor(
val urlView: TextView
val actionButton: ImageButton

private val iconView: ViewSwitcher
val iconView: ViewSwitcher

private val favicon: ImageView

init {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ class LibraryToolbar @JvmOverloads constructor(
fun searchClosed()

fun searchQueryChanged(query: String)

fun add()

fun confirm()
}

var title: CharSequence
Expand Down Expand Up @@ -107,6 +111,14 @@ class LibraryToolbar @JvmOverloads constructor(
notifyObservers { openAll(newTab = true, private = true) }
true
}
R.id.add_folder -> {
notifyObservers { add() }
true
}
R.id.confirm -> {
notifyObservers { confirm() }
true
}
else -> throw IllegalArgumentException("Invalid menu item")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import androidx.navigation.fragment.findNavController
Expand All @@ -22,7 +23,9 @@ import org.mozilla.reference.browser.BrowserDirection
import org.mozilla.reference.browser.R
import org.mozilla.reference.browser.ViewModelFactory
import org.mozilla.reference.browser.ext.application
import org.mozilla.reference.browser.ext.nav
import org.mozilla.reference.browser.ext.openToBrowserAndLoad
import org.mozilla.reference.browser.storage.HistoryDatabase.Companion.bookmarksRootFolder

class BookmarkFragment @JvmOverloads constructor(
private val initialBookmarkViewModel: BookmarkViewModel? = null
Expand All @@ -33,6 +36,8 @@ class BookmarkFragment @JvmOverloads constructor(
private lateinit var bookmarkView: BookmarkView
private lateinit var bookmarkInteractor: BookmarkViewInteractor

private val sharedViewModel: BookmarksSharedViewModel by activityViewModels()

override fun onAttach(context: Context) {
super.onAttach(context)

Expand All @@ -42,7 +47,10 @@ class BookmarkFragment @JvmOverloads constructor(
bookmarkInteractor = BookmarkViewInteractor(
bookmarkViewModel,
::openBookmarkItem,
::onBackPressed
::expandBookmarkFolder,
::onBackPressed,
::navigateToAddFolder,
::navigateToEditBookmark
)
}

Expand All @@ -54,6 +62,7 @@ class BookmarkFragment @JvmOverloads constructor(
newViewMode = bookmarkViewModel.viewMode,
newBookmarkNode = tree,
newSelectedItems = bookmarkViewModel.selectedItems.value!!)
sharedViewModel.selectedFolder = tree
})

bookmarkViewModel.selectedItems.observe(this, Observer { selectedItems ->
Expand All @@ -67,6 +76,15 @@ class BookmarkFragment @JvmOverloads constructor(
newSelectedItems = selectedItems,
newBookmarkNode = bookmarkViewModel.tree.value)
})

val currentGuid = BookmarkFragmentArgs.fromBundle(requireArguments()).currentRoot.ifEmpty {
bookmarksRootFolder
}
loadRootFolder(currentGuid)
}

private fun loadRootFolder(currentGuid: String) {
bookmarkViewModel.fetchBookmarks(currentGuid)
}

override fun onCreateView(
Expand All @@ -90,6 +108,21 @@ class BookmarkFragment @JvmOverloads constructor(
}
}

private fun expandBookmarkFolder(folder: BookmarkNode) {
findNavController().nav(R.id.bookmarkFragment,
BookmarkFragmentDirections.actionBookmarkFragmentSelf(folder.guid))
}

private fun navigateToAddFolder() {
findNavController().nav(R.id.bookmarkFragment,
BookmarkFragmentDirections.actionBookmarkFragmentToAddBookmarkFolderFragment())
}

fun navigateToEditBookmark(bookmarkNode: BookmarkNode) {
findNavController().nav(R.id.bookmarkFragment,
BookmarkFragmentDirections.actionBookmarkFragmentToEditBookmarkFragment(bookmarkNode.guid))
}

override fun onBackPressed(): Boolean {
if (bookmarkView.onBackPressed()) {
return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ class BookmarkView(
view.bookmark_search_list.visibility = View.VISIBLE
bookmarkViewModel.searchBookmarks(query)
}

override fun confirm() {
// no-op
}

override fun add() {
interactor.navigateToAddFolder()
}
})
bookmarkViewModel.bookmarkSearchList.observe(lifecycleOwner, Observer { bookmarkList ->
bookmarkSearchAdapter.setData(bookmarkList)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,29 @@
package org.mozilla.reference.browser.library.bookmarks.ui

import mozilla.components.concept.storage.BookmarkNode
import mozilla.components.concept.storage.BookmarkNodeType
import org.mozilla.reference.browser.library.MultiSelectionInteractor

@Suppress("TooManyFunctions")
class BookmarkViewInteractor(
private val bookmarkViewModel: BookmarkViewModel,
private val openToBrowser: (items: Set<BookmarkNode>, private: Boolean) -> Unit,
private val onBackPressed: () -> Boolean
private val expandBookmarkFolder: (item: BookmarkNode) -> Unit,
private val onBackPressed: () -> Boolean,
private val navigateToAddFolder: () -> Unit,
private val navigateToEditBookmark: (item: BookmarkNode) -> Unit
) : MultiSelectionInteractor<BookmarkNode> {

override fun open(items: Set<BookmarkNode>, newTab: Boolean, private: Boolean) {
openToBrowser.invoke(items, private)
when (items.first().type) {
BookmarkNodeType.ITEM -> {
openToBrowser.invoke(items, private)
}
BookmarkNodeType.FOLDER -> {
expandBookmarkFolder.invoke(items.first())
}
BookmarkNodeType.SEPARATOR -> throw IllegalStateException("Cannot open separators")
}
}

override fun select(item: BookmarkNode) {
Expand All @@ -39,6 +52,14 @@ class BookmarkViewInteractor(
return false
}

fun navigateToAddFolder() {
navigateToAddFolder.invoke()
}

fun onEdit(item: BookmarkNode) {
navigateToEditBookmark.invoke(item)
}

fun onOpenInNormalTab(item: BookmarkNode) {
open(setOf(item), false)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,9 @@ class BookmarkViewModel(private val bookmarkUseCases: BookmarkUseCases) : ViewMo
init {
_selectedItems.value = mutableSetOf()
_bookmarkSearchList.value = listOf()
fetchBookmarks("0")
}

private fun fetchBookmarks(id: String) {
fun fetchBookmarks(id: String) {
viewModelScope.launch(Dispatchers.IO) {
val tree = bookmarkUseCases.getBookmarks.invoke(id)
withContext(Dispatchers.Main) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

package org.mozilla.reference.browser.library.bookmarks.ui

import androidx.lifecycle.ViewModel
import mozilla.components.concept.storage.BookmarkNode

/**
* [ViewModel] that shares data between various bookmarks fragments.
*/
class BookmarksSharedViewModel : ViewModel() {
/**
* The currently selected bookmark root.
*/
var selectedFolder: BookmarkNode? = null
}
Loading