Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE REQUEST] Select correct user and navigate to the correct file when opening via deep link #4211

Closed
wants to merge 7 commits into from
Closed
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
2 changes: 0 additions & 2 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 23 additions & 22 deletions owncloudApp/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
Notifications are off by default since API 33;
See note in https://developer.android.com/develop/ui/views/notifications/notification-permission
-->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<!--
Next permissions are always approved in installation time,
the apps needs to do nothing special in runtime
Expand Down Expand Up @@ -57,8 +57,10 @@
android:taskAffinity=""
android:theme="@style/Theme.ownCloud.Toolbar">

<meta-data android:name="android.content.APP_RESTRICTIONS"
<meta-data
android:name="android.content.APP_RESTRICTIONS"
android:resource="@xml/managed_configurations" />

<activity
android:name=".presentation.releasenotes.ReleaseNotesActivity"
android:exported="false" />
Expand All @@ -67,12 +69,22 @@
<activity android:name=".presentation.migration.StorageMigrationActivity" />
<activity
android:name=".ui.activity.SplashActivity"
android:theme="@style/Theme.ownCloud.Splash"
android:exported="true">
android:exported="true"
android:theme="@style/Theme.ownCloud.Splash">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data
android:host="@string/oauth2_redirect_uri_path"
android:scheme="@string/oauth2_redirect_uri_scheme" />
</intent-filter>
</activity>
<activity
android:name=".ui.activity.FileDisplayActivity"
Expand All @@ -83,8 +95,8 @@
android:name=".ui.activity.ReceiveExternalFilesActivity"
android:configChanges="orientation|screenSize"
android:excludeFromRecents="true"
android:taskAffinity=""
android:exported="true">
android:exported="true"
android:taskAffinity="">
<intent-filter>
<action android:name="android.intent.action.SEND" />

Expand Down Expand Up @@ -168,8 +180,8 @@

<activity
android:name=".presentation.security.passcode.PassCodeActivity"
android:theme="@style/Theme.ownCloud"
android:screenOrientation="portrait"/>
android:screenOrientation="portrait"
android:theme="@style/Theme.ownCloud" />
<activity
android:name=".presentation.conflicts.ConflictsResolveActivity"
android:theme="@style/Theme.ownCloud" />
Expand All @@ -191,11 +203,11 @@
<activity android:name=".ui.activity.UploadPathActivity" />
<activity
android:name=".presentation.sharing.ShareActivity"
android:exported="false"
android:label="@string/share_dialog_title"
android:launchMode="singleTop"
android:theme="@style/Theme.ownCloud"
android:windowSoftInputMode="adjustResize"
android:exported="false">
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
Expand All @@ -221,17 +233,6 @@
android:name=".presentation.authentication.LoginActivity"
android:exported="true"
android:launchMode="singleTask"
android:theme="@style/Theme.ownCloud.Toolbar">
<intent-filter>
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data
android:host="@string/oauth2_redirect_uri_path"
android:scheme="@string/oauth2_redirect_uri_scheme" />
</intent-filter>
</activity>
android:theme="@style/Theme.ownCloud.Toolbar" />
</application>
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import com.owncloud.android.domain.files.usecases.DisableThumbnailsForFileUseCas
import com.owncloud.android.domain.files.usecases.GetFileByIdAsStreamUseCase
import com.owncloud.android.domain.files.usecases.GetFileByIdUseCase
import com.owncloud.android.domain.files.usecases.GetFileByRemotePathUseCase
import com.owncloud.android.domain.files.usecases.GetFileMetadataUseCase
import com.owncloud.android.domain.files.usecases.GetFolderContentAsStreamUseCase
import com.owncloud.android.domain.files.usecases.GetFolderContentUseCase
import com.owncloud.android.domain.files.usecases.GetFolderImagesUseCase
Expand Down Expand Up @@ -174,6 +175,7 @@ val useCaseModule = module {
factory { CleanWorkersUUIDUseCase(get()) }
factory { FilterFileMenuOptionsUseCase(get(), get(), get()) }
factory { GetFileWithSyncInfoByIdUseCase(get()) }
factory { GetFileMetadataUseCase(get()) }

// Open in web
factory { GetUrlToOpenInWebUseCase(get(), get()) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ val viewModelModule = module {
viewModel { PreviewAudioViewModel(get(), get(), get()) }
viewModel { PreviewTextViewModel(get(), get(), get()) }
viewModel { PreviewVideoViewModel(get(), get(), get()) }
viewModel { FileOperationsViewModel(get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get()) }
viewModel { FileOperationsViewModel(get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get()) }
viewModel { (initialFolderToDisplay: OCFile, fileListOption: FileListOption) ->
MainFileListViewModel(
get(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,10 @@ class MainFileListViewModel(
sortTypeAndOrder.update { Pair(sortType, sortOrder) }
}

fun getFileByLink(link:String){
// val file= getFileByRemotePathUseCase.execute(GetFileByRemotePathUseCase.Params(fileById.owner, ROOT_PATH)).getDataOrNull()
}

fun openInWeb(fileId: String, appName: String) {
runUseCaseWithResult(
coroutineDispatcher = coroutinesDispatcherProvider.io,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

package com.owncloud.android.presentation.files.operations

import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.ViewModel
Expand All @@ -35,6 +36,7 @@ import com.owncloud.android.domain.exceptions.NoNetworkConnectionException
import com.owncloud.android.domain.files.model.OCFile
import com.owncloud.android.domain.files.usecases.CopyFileUseCase
import com.owncloud.android.domain.files.usecases.CreateFolderAsyncUseCase
import com.owncloud.android.domain.files.usecases.GetFileMetadataUseCase
import com.owncloud.android.domain.files.usecases.MoveFileUseCase
import com.owncloud.android.domain.files.usecases.RemoveFileUseCase
import com.owncloud.android.domain.files.usecases.RenameFileUseCase
Expand All @@ -46,6 +48,7 @@ import com.owncloud.android.providers.CoroutinesDispatcherProvider
import com.owncloud.android.ui.dialog.FileAlreadyExistsDialog
import com.owncloud.android.usecases.synchronization.SynchronizeFileUseCase
import com.owncloud.android.usecases.synchronization.SynchronizeFolderUseCase
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
Expand All @@ -63,7 +66,8 @@ class FileOperationsViewModel(
private val setFilesAsAvailableOfflineUseCase: SetFilesAsAvailableOfflineUseCase,
private val unsetFilesAsAvailableOfflineUseCase: UnsetFilesAsAvailableOfflineUseCase,
private val contextProvider: ContextProvider,
private val coroutinesDispatcherProvider: CoroutinesDispatcherProvider
private val coroutinesDispatcherProvider: CoroutinesDispatcherProvider,
private val getFileMetadataUseCase: GetFileMetadataUseCase,
) : ViewModel() {

private val _createFolder = MediatorLiveData<Event<UIResult<Unit>>>()
Expand Down Expand Up @@ -95,7 +99,6 @@ class FileOperationsViewModel(

val openDialogs = mutableListOf<FileAlreadyExistsDialog>()


// Used to save the last operation folder
private var lastTargetFolder: OCFile? = null

Expand All @@ -115,6 +118,14 @@ class FileOperationsViewModel(
}
}

fun getFileMetadata(fileId: String, accountName: String, onGetOCFile: (OCFile) -> Unit) {
viewModelScope.launch(Dispatchers.IO) {
val result = getFileMetadataUseCase.execute(GetFileMetadataUseCase.Params(fileId, accountName))
Log.i("TEST METADATA", "metadata returned ${result.getDataOrNull()}")
result.getDataOrNull()?.let { onGetOCFile(it) }
}
}

private fun createFolderOperation(fileOperation: FileOperation.CreateFolder) {
runOperation(
liveData = _createFolder,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.RemoteException
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.View
Expand Down Expand Up @@ -178,6 +179,8 @@ class FileDisplayActivity : FileActivity(),

private lateinit var binding: ActivityMainBinding

private var isAlreadyHandledDeepLink = false

override fun onCreate(savedInstanceState: Bundle?) {
Timber.v("onCreate() start")

Expand Down Expand Up @@ -213,6 +216,13 @@ class FileDisplayActivity : FileActivity(),
if (account == null) "" else account.name
)
}
Log.d("INTENT", "intent: ${intent.extras} data: ${intent.data}")

val dataIntent: Uri? = intent.data
dataIntent?.let {
Log.d("URI INTENT", "uri: $it")
handleDeepLink(dataIntent)
}

/// USER INTERFACE

Expand Down Expand Up @@ -1782,6 +1792,45 @@ class FileDisplayActivity : FileActivity(),
)
}

private fun handleDeepLink(uri: Uri?) {
if (uri != null && com.owncloud.android.presentation.authentication.AccountUtils.getAccounts(applicationContext).isEmpty()) {
showMessageInSnackbar(message = getString(R.string.no_account_configured))
} else if (uri != null && com.owncloud.android.presentation.authentication.AccountUtils.getAccounts(applicationContext).size == 1) {
showLoadingDialog(R.string.getting_file)
getFileDiscovered(uri)
}
}

private fun getFileDiscovered(uri: Uri) {
fileOperationsViewModel.getFileMetadata(
uri.pathSegments[uri.pathSegments.size - 1].toString(),
com.owncloud.android.presentation.authentication.AccountUtils.getCurrentOwnCloudAccount(applicationContext).name,
) { ocFile ->
runOnUiThread {
manageItem(ocFile)
dismissLoadingDialog()
}
}
}

private fun manageItem(file: OCFile) {
setFile(file)
account = com.owncloud.android.presentation.authentication.AccountUtils.getOwnCloudAccountByName(this, file.owner)

if (file.isFolder) {
refreshListOfFilesFragment()
return
}

if (PreviewImageFragment.canBePreviewed(file)) {
showDetails(file)
} else {
initFragmentsWithFile()
}

isAlreadyHandledDeepLink = true
}

companion object {
private const val TAG_LIST_OF_FILES = "LIST_OF_FILES"
private const val TAG_LIST_OF_SPACES = "LIST_OF_SPACES"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ class SplashActivity : AppCompatActivity() {

checkLockDelayEnforced(mdmProvider)

startActivity(Intent(this, FileDisplayActivity::class.java))
val newIntent = Intent(this, FileDisplayActivity::class.java)
newIntent.data = intent.data
startActivity(newIntent)
finish()
}

Expand Down
5 changes: 5 additions & 0 deletions owncloudApp/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -784,4 +784,9 @@
<string name="tab_label_ascii">Text</string>
<string name="apply_to_all_conflicts">Apply to all %1$s conflicts</string>

<!--Deep Links-->
<string name="no_account_configured">No account configured previously</string>
<string name="no_file_found">No file found</string>
<string name="getting_file">Getting file</string>

</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,7 @@ interface RemoteFileDataSource {
accountName: String,
spaceWebDavUrl: String? = null,
)

fun getFileMetadata(fileId: String, accountName: String): String

}
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ class OCRemoteFileDataSource(
)
}

override fun getFileMetadata(fileId: String, accountName: String): String =
executeRemoteOperation { clientManager.getFileService(accountName).fileMetaInfo(fileId) }

private fun RemoteFile.toModel(): OCFile =
OCFile(
owner = owner,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ package com.owncloud.android.data.files.repository

import com.owncloud.android.data.files.datasources.LocalFileDataSource
import com.owncloud.android.data.files.datasources.RemoteFileDataSource
import com.owncloud.android.data.spaces.datasources.LocalSpacesDataSource
import com.owncloud.android.data.providers.LocalStorageProvider
import com.owncloud.android.data.spaces.datasources.LocalSpacesDataSource
import com.owncloud.android.domain.availableoffline.model.AvailableOfflineStatus
import com.owncloud.android.domain.availableoffline.model.AvailableOfflineStatus.AVAILABLE_OFFLINE_PARENT
import com.owncloud.android.domain.availableoffline.model.AvailableOfflineStatus.NOT_AVAILABLE_OFFLINE
Expand Down Expand Up @@ -525,6 +525,28 @@ class OCFileRepository(
localFileDataSource.updateDownloadedFilesStorageDirectoryInStoragePath(oldDirectory, newDirectory)
}

override fun getFileMetadata(fileId: String, accountName: String): OCFile? {
val result = remoteFileDataSource.getFileMetadata(fileId, accountName)
val splitPath = result.split("/")
val spaceId = fileId.split("!")[0]
var containerFolder = listOf<OCFile>()
for (i in 1..splitPath.size - 2) {
var path = splitPath[0]
for (j in 1..i) {
path += "/${splitPath[j]}"
}
containerFolder = refreshFolder(path, accountName, spaceId)
}
refreshFolder(result, accountName, spaceId)
return containerFolder.find { file ->
if (file.isFolder) {
file.remotePath.dropLast(1)
} else {
file.remotePath
} == result
}
}

override fun saveUploadWorkerUuid(fileId: Long, workerUuid: UUID) {
TODO("Not yet implemented")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,6 @@ interface FileRepository {
fun updateFileWithNewAvailableOfflineStatus(ocFile: OCFile, newAvailableOfflineStatus: AvailableOfflineStatus)
fun updateDownloadedFilesStorageDirectoryInStoragePath(oldDirectory: String, newDirectory: String)

fun getFileMetadata(fileId: String, accountName: String): OCFile?

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.owncloud.android.domain.files.usecases

import com.owncloud.android.domain.BaseUseCaseWithResult
import com.owncloud.android.domain.files.FileRepository
import com.owncloud.android.domain.files.model.OCFile

class GetFileMetadataUseCase(private val fileRepository: FileRepository) : BaseUseCaseWithResult<OCFile?, GetFileMetadataUseCase.Params>() {

override fun run(params: Params): OCFile? {
return fileRepository.getFileMetadata(params.id, params.accountName)
}

data class Params(val id: String, val accountName: String)

}