Skip to content

Commit

Permalink
Mobileapps 1156 (#68)
Browse files Browse the repository at this point in the history
* Moobileapps 1126 (#102)

* Mobileapps 1146 (#103)

* merged community code
  • Loading branch information
aman-alfresco authored May 9, 2022
1 parent 563f813 commit ed6d797
Show file tree
Hide file tree
Showing 34 changed files with 739 additions and 21 deletions.
1 change: 1 addition & 0 deletions actions/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ dependencies {
implementation libs.androidx.core
implementation libs.androidx.lifecycle.viewmodel
implementation libs.androidx.lifecycle.runtime
implementation libs.androidx.navigation.fragment

implementation libs.google.material
implementation libs.epoxy.core
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.alfresco.content.actions

import android.content.Context
import android.view.View
import com.alfresco.content.data.BrowseRepository
import com.alfresco.content.data.Entry
import kotlin.coroutines.cancellation.CancellationException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

/**
* Mark as ActionMoveFilesFolders
*/
data class ActionMoveFilesFolders(
override var entry: Entry,
override val icon: Int = R.drawable.ic_move,
override val title: Int = R.string.action_move_title
) : Action {

override suspend fun execute(context: Context): Entry {

val result = ActionMoveFragment.moveItem(context)
if (!result.isNullOrEmpty()) {
withContext(Dispatchers.IO) {
BrowseRepository().moveNode(entry.id, result)
}
} else {
throw CancellationException("User Cancellation")
}
return entry
}

override fun copy(_entry: Entry): Action = copy(entry = _entry)

override fun showToast(view: View, anchorView: View?) =
Action.showToast(view, anchorView, R.string.action_move_toast, entry.name)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.alfresco.content.actions

import android.content.Context
import android.os.Bundle
import androidx.activity.result.ActivityResultLauncher
import androidx.fragment.app.Fragment
import com.alfresco.content.withFragment
import kotlinx.coroutines.CancellableContinuation
import kotlinx.coroutines.suspendCancellableCoroutine

/**
* Mark as ActionMoveFragment
*/
class ActionMoveFragment : Fragment() {
private lateinit var requestLauncher: ActivityResultLauncher<Unit>
private var onResult: CancellableContinuation<String?>? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

requestLauncher = registerForActivityResult(MoveResultContract()) {
onResult?.resume(it, null)
}
}

private suspend fun moveItems(): String? =
suspendCancellableCoroutine { continuation ->
onResult = continuation
requestLauncher.launch(Unit)
}

companion object {
private val TAG = ActionMoveFragment::class.java.simpleName

/**
* Generating ActionMoveFragment
*/
suspend fun moveItem(
context: Context
): String? =
withFragment(
context,
TAG,
{ it.moveItems() },
{ ActionMoveFragment() }
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ internal class ContextualActionsViewModel(
buildModel()

// Update the model if necessary
viewModelScope.on<ActionAddFavorite> (block = ::updateState)
viewModelScope.on<ActionRemoveFavorite> (block = ::updateState)
viewModelScope.on<ActionAddOffline> (block = ::updateState)
viewModelScope.on<ActionRemoveOffline> (block = ::updateState)
viewModelScope.on<ActionAddFavorite>(block = ::updateState)
viewModelScope.on<ActionRemoveFavorite>(block = ::updateState)
viewModelScope.on<ActionAddOffline>(block = ::updateState)
viewModelScope.on<ActionRemoveOffline>(block = ::updateState)
viewModelScope.on<ActionMoveFilesFolders>(block = ::updateState)
}

private fun buildModel() = withState { state ->
Expand Down Expand Up @@ -93,7 +94,8 @@ internal class ContextualActionsViewModel(
offlineActionFor(entry),
favoriteActionFor(entry),
externalActionsFor(entry),
deleteActionFor(entry)
deleteActionFor(entry),
moveActionFor(entry)
).flatten()

private fun actionsForTrashed(entry: Entry): List<Action> =
Expand Down Expand Up @@ -127,6 +129,9 @@ internal class ContextualActionsViewModel(
private fun deleteActionFor(entry: Entry) =
if (entry.canDelete) listOf(ActionDelete(entry)) else listOf()

private fun moveActionFor(entry: Entry) =
if (entry.canDelete) listOf(ActionMoveFilesFolders(entry)) else listOf()

private fun makeTopActions(entry: Entry): List<Action> {
val actions = mutableListOf<Action>()
if (!entry.hasOfflineStatus) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ internal class ActionCreateViewModel(
actions.add(ActionCaptureMedia(parent, title = R.string.action_capture_media_title_multiple))
else actions.add(ActionCaptureMedia(parent, title = R.string.action_capture_media_title_single))
actions.add(ActionUploadFiles(parent))
actions.add(ActionUploadFiles(parent))

return actions
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.alfresco.content.actions

import android.app.Activity
import android.content.Context
import android.content.Intent
import androidx.activity.result.contract.ActivityResultContract
import androidx.annotation.CallSuper

/**
* Mark as MoveResultContract
*/
class MoveResultContract : ActivityResultContract<Unit, String?>() {
@CallSuper
override fun createIntent(context: Context, input: Unit): Intent {
return intent
}

override fun parseResult(resultCode: Int, intent: Intent?): String? {
return if (intent == null || resultCode != Activity.RESULT_OK) null
else intent.extras?.getString(OUTPUT_KEY)
}

companion object {
const val OUTPUT_KEY = "targetParentId"
lateinit var intent: Intent

/**
* adding intent for MoveActivity
*/
fun addMoveIntent(moveIntent: Intent) {
intent = moveIntent
}
}
}
9 changes: 9 additions & 0 deletions actions/src/main/res/drawable/ic_move.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M20,6h-8l-2,-2H4C2.9,4 2,4.9 2,6v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V8C22,6.9 21.1,6 20,6zM20,18H4V6h5.17l1.41,1.41L11.17,8H20V18zM12.16,12H8v2h4.16l-1.59,1.59L11.99,17L16,13.01L11.99,9l-1.41,1.41L12.16,12z"
android:fillColor="?attr/colorControlNormal"/>
</vector>
3 changes: 1 addition & 2 deletions actions/src/main/res/values-de/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@
<string name="action_remove_offline_toast">%s ist offline nicht mehr verfügbar.</string>

<string name="action_upload_photo_title">Bilder oder Videos hochladen</string>
<string name="action_capture_media_title_multiple">Fotos oder Videos aufnehmen</string>
<string name="action_capture_media_title_single">Foto oder Video aufnehmen</string>
<string name="action_capture_media_title_multiple">Bilder oder Videos aufnehmen</string>
<string name="action_capture_failed_permissions">@string/capture_failure_permissions</string>

<string name="action_upload_media_toast">Zum Hochladen vorgesehene Medien.</string>
Expand Down
3 changes: 1 addition & 2 deletions actions/src/main/res/values-es/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@
<string name="action_remove_offline_toast">%s ya no estará disponible sin conexión.</string>

<string name="action_upload_photo_title">Cargar fotos o vídeos</string>

<string name="action_capture_media_title">Tomar una foto o un vídeo</string>
<string name="action_capture_media_title_multiple">Tomar una foto o un vídeo</string>
<string name="action_capture_failed_permissions">@string/capture_failure_permissions</string>

<string name="action_upload_media_toast">Contenido multimedia programado para cargar.</string>
Expand Down
5 changes: 4 additions & 1 deletion actions/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
<string name="action_add_offline_toast">%s will be made available offline.</string>
<string name="action_remove_offline_toast">%s will no longer be available offline.</string>

<string name="action_upload_photo_title">Upload photos or videos</string>2
<string name="action_upload_photo_title">Upload photos or videos</string>
<string name="action_capture_media_title_multiple">Take photos or videos</string>
<string name="action_capture_media_title_single">Take a photo or video</string>
<string name="action_capture_failed_permissions">@string/capture_failure_permissions</string>
Expand All @@ -62,4 +62,7 @@
<string name="share_files_permissions_rationale">@string/share_files_failure_permissions</string>
<string name="share_files_failure_permissions">To share files, turn on read storage permissions.</string>

<string name="action_move_title">Move to folder</string>
<string name="action_move_toast">%s was moved successfully</string>

</resources>
3 changes: 2 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ android {
defaultConfig {
applicationId "com.alfresco.content.app"
versionCode envOrDef('VERSION_CODE', '1') as Integer
versionName "1.2.0"
versionName "1.1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Expand Down Expand Up @@ -84,6 +84,7 @@ dependencies {
implementation project(':search')
implementation project(':viewer')
implementation project(':shareextension')
implementation project(':move')

implementation project(':data')
implementation libs.alfresco.content
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@
<activity
android:name="com.alfresco.content.browse.preview.PreviewActivity"
android:configChanges="orientation|screenSize" />

<activity
android:name=".activity.MoveActivity"
android:windowSoftInputMode="adjustNothing" />

</application>

</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import com.alfresco.auth.DiscoveryService
import com.alfresco.auth.activity.LoginViewModel
import com.alfresco.auth.activity.LoginViewModel.Companion.DISTRIBUTION_VERSION
import com.alfresco.content.actions.Action
import com.alfresco.content.actions.MoveResultContract
import com.alfresco.content.activityViewModel
import com.alfresco.content.app.R
import com.alfresco.content.app.widget.ActionBarController
Expand Down Expand Up @@ -95,6 +96,7 @@ class MainActivity : AppCompatActivity(), MavericksView {
bottomNav.setupWithNavController(navController)

setupActionToasts()
MoveResultContract.addMoveIntent(Intent(this, MoveActivity::class.java))
setupDownloadNotifications()
}

Expand Down Expand Up @@ -138,12 +140,11 @@ class MainActivity : AppCompatActivity(), MavericksView {
startActivity(i)
}

private fun setupActionToasts() =
Action.showActionToasts(
lifecycleScope,
findViewById(android.R.id.content),
bottomNav
)
private fun setupActionToasts() = Action.showActionToasts(
lifecycleScope,
findViewById(android.R.id.content),
bottomNav
)

private fun setupDownloadNotifications() =
DownloadMonitor
Expand Down
105 changes: 105 additions & 0 deletions app/src/main/java/com/alfresco/content/app/activity/MoveActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package com.alfresco.content.app.activity

import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import androidx.navigation.findNavController
import com.airbnb.mvrx.MavericksView
import com.airbnb.mvrx.withState
import com.alfresco.auth.activity.LoginViewModel
import com.alfresco.content.actions.Action
import com.alfresco.content.activityViewModel
import com.alfresco.content.app.R
import com.alfresco.content.app.widget.ActionBarController
import com.alfresco.content.session.SessionManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import java.lang.ref.WeakReference

/**
* Marked as MoveActivity class
*/
class MoveActivity : AppCompatActivity(), MavericksView {

private val viewModel: MainActivityViewModel by activityViewModel()
private val navController by lazy { findNavController(R.id.nav_host_fragment) }
private val bottomView by lazy { findViewById<View>(R.id.bottom_view) }
private lateinit var actionBarController: ActionBarController
private var signedOutDialog = WeakReference<AlertDialog>(null)

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_move)

configure()
}

private fun configure() {
val graph = navController.navInflater.inflate(R.navigation.nav_move_paths)
graph.startDestination = R.id.nav_move
val bundle = Bundle().apply {
}
navController.setGraph(graph, bundle)
setupActionToasts()
actionBarController = ActionBarController(findViewById(R.id.toolbar))
actionBarController.setupActionBar(this, navController)
}

override fun onSupportNavigateUp(): Boolean {
return if (navController.currentDestination?.id == R.id.nav_browse_move) {
finish()
false
} else navController.navigateUp()
}

override fun invalidate() = withState(viewModel) { state ->
if (state.requiresReLogin) {
if (state.isOnline) {
showSignedOutPrompt()
}
} else {
// Only when logged in otherwise triggers re-login prompts
actionBarController.setProfileIcon(viewModel.profileIcon)
}

actionBarController.setOnline(state.isOnline)
}

private fun showSignedOutPrompt() {
val oldDialog = signedOutDialog.get()
if (oldDialog != null && oldDialog.isShowing) return
val dialog = MaterialAlertDialogBuilder(this)
.setTitle(resources.getString(R.string.auth_signed_out_title))
.setMessage(resources.getString(R.string.auth_signed_out_subtitle))
.setNegativeButton(resources.getString(R.string.sign_out_confirmation_negative), null)
.setPositiveButton(resources.getString(R.string.auth_basic_sign_in_button)) { _, _ ->
navigateToReLogin()
}
.show()
signedOutDialog = WeakReference(dialog)
}

private fun navigateToReLogin() {
val i = Intent(this, LoginActivity::class.java)
val acc = SessionManager.requireSession.account
i.putExtra(LoginViewModel.EXTRA_IS_EXTENSION, false)
i.putExtra(LoginViewModel.EXTRA_ENDPOINT, acc.serverUrl)
i.putExtra(LoginViewModel.EXTRA_AUTH_TYPE, acc.authType)
i.putExtra(LoginViewModel.EXTRA_AUTH_CONFIG, acc.authConfig)
i.putExtra(LoginViewModel.EXTRA_AUTH_STATE, acc.authState)
startActivity(i)
}

private fun setupActionToasts() = Action.showActionToasts(
lifecycleScope,
findViewById(android.R.id.content),
bottomView
)

override fun onBackPressed() {
super.onBackPressed()
finish()
}
}
Loading

0 comments on commit ed6d797

Please sign in to comment.