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

Bugfix/update folder icons #12003

Merged
merged 65 commits into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from 57 commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
22e1f7e
Add getFileIcon function inside OCFile
Oct 3, 2023
0358dce
Add isAutoUploadFolder function to SyncedFolderProvider
Oct 3, 2023
b351c57
Use getFileIcon for thumbnailView
Oct 3, 2023
2dc0d56
Add folder_encrypted icon
Oct 3, 2023
65461a7
Use folder key icon for encrypted state
Oct 3, 2023
e4dd05c
Add folder overlay icons
Oct 3, 2023
c7cb4fa
Use overlay method to get file icon
Oct 3, 2023
80cf6f0
Use new method for get thumbnail image
Oct 3, 2023
32b8993
Add DrawableUtil
Oct 3, 2023
4b35088
Use overlay method for UploadAdapter
Oct 3, 2023
bbea0e0
Apply color changes for folder
Oct 3, 2023
929b704
Use overlay method for ShortcutUtil
Oct 3, 2023
16db8c0
Use overlay method for ShareActivity
Oct 3, 2023
aee3ffd
Change drawable to layer drawable
Oct 3, 2023
44e38c6
Use overlay method for EditorWebView
Oct 3, 2023
3aa9c8a
Remove ViewThemeUtils usage to provide correct folder color
Oct 3, 2023
9870a80
Remove duplicated default folder icon func from MimeTypeUtil
Oct 3, 2023
ca09000
Use overlay method for GroupfolderListAdapter
Oct 3, 2023
1f39139
Mark failed tests
Oct 3, 2023
29e934f
Add DrawableUtilTests for testing overlaying icons
Oct 3, 2023
23cd9f9
Rename OCFile function name to getFileIcon
Oct 3, 2023
f745db1
Extract getFileOverlayIcon function from getFileIcon
Oct 4, 2023
bfd8079
Add OCFileIconTests
Oct 4, 2023
7aa837f
Add tests for each different folder icon type
Oct 4, 2023
6ed626d
Remove Mockito from OCFileIconTests
Oct 4, 2023
6fc9970
Rename getFileOverlayIcon to getFileOverlayIconId
Oct 4, 2023
48bdbac
Replace null check with assert due to ContextCompat.getDrawable nulla…
Oct 4, 2023
651908a
Todo comment added
Oct 4, 2023
c570c4f
Add viewThemeUtils for different primary colors
Oct 4, 2023
6ccefc4
Remove unused icons from project directory
Oct 4, 2023
15f5856
Move getFileIcon into the MimeTypeUtil
Oct 4, 2023
8105a02
Add default folder icon function added due to apply color primary
Oct 4, 2023
8b9361f
Use getDefaultFolderIcon
Oct 4, 2023
095c19b
Add different folder types
Oct 4, 2023
afdd18a
Change overlay icon color to white
Oct 4, 2023
88de0a2
Change top margin to 4
Oct 4, 2023
be543f6
Change top margin to 3 due to ss tests
Oct 4, 2023
b0c584b
Support overlay drawable icon for Dark mode
Oct 4, 2023
9e4bac2
Add isDarkModeEnabled function
Oct 5, 2023
59cacab
Use isDarkModeEnabled function
Oct 5, 2023
c618b20
Reset overlay icon size
Oct 5, 2023
6ae12b0
Add extensions package under utils
Oct 5, 2023
a0083b9
Change overlay icon size according to density
Oct 5, 2023
68f3c6e
Update usage of addDrawableAsOverlay function
Oct 5, 2023
b38c54a
Update screenshots
Oct 5, 2023
7458ba3
Fix detekt findings
Oct 5, 2023
bbeccfb
Change overlaying mechanism
Oct 5, 2023
dbbe6de
Add licence header for new files
Oct 5, 2023
3b74655
Add licence header for new icons
Oct 5, 2023
5be983b
Fix imports for gPlay flavour
Oct 5, 2023
c94a190
Fix spotlessKotlinCheck
Oct 5, 2023
a3014ad
Fix Static code analysis warnings
Oct 5, 2023
5b7bb2f
test analysis.yml not running on garm
tobiasKaminsky Oct 6, 2023
3ab49e4
Fix spotlessKotlinCheck
Oct 6, 2023
a24609f
Fix code analysis
Oct 6, 2023
ffdf859
Fix spotlessKotlinCheck
alperozturk96 Oct 6, 2023
1e4e417
Fix autoUploadFolder
alperozturk96 Oct 6, 2023
95453d8
Remove FIXME comments
alperozturk96 Oct 10, 2023
ff69191
fix nullability of getDarkThemeMode function
alperozturk96 Oct 10, 2023
887c197
Fix SplashScreen title tests
alperozturk96 Oct 11, 2023
b853dce
Add testOnlyOnServer function inside AbstractIT
alperozturk96 Oct 11, 2023
e56ab6d
Fix testMetaData
alperozturk96 Oct 11, 2023
cd54020
Fix testCreationAndUploadTimestamp
alperozturk96 Oct 11, 2023
7e0d058
Fix spotlessKotlinCheck
alperozturk96 Oct 11, 2023
cde7edb
Fix Codacy Spotbugs
alperozturk96 Oct 11, 2023
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: 1 addition & 1 deletion .github/workflows/analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ concurrency:

jobs:
analysis:
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- name: Setup variables
id: get-vars
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class FileDisplayActivityScreenshotIT : AbstractIT() {
Manifest.permission.WRITE_EXTERNAL_STORAGE
)

// FIXME test fails
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are those really failing?
In latest run I only saw location and activity error.
If they are not failing, please remove those comments.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran those marked test still fails in my local machine.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason why the tests fails is that CI/CD runs on Android 8. My local device is Android 14 so the tests are failing. For example the expected file path is different on newer Android versions.

@Test
@ScreenshotTest
fun open() {
Expand All @@ -66,6 +67,7 @@ class FileDisplayActivityScreenshotIT : AbstractIT() {
screenshot(sut)
}

// FIXME test fails
@Test
@ScreenshotTest
fun showMediaThenAllFiles() {
Expand Down Expand Up @@ -100,6 +102,7 @@ class FileDisplayActivityScreenshotIT : AbstractIT() {
screenshot(fileDisplayActivity)
}

// FIXME test fails
@Test
@ScreenshotTest
fun drawer() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ class LauncherActivityIT : AbstractIT() {
@Test
fun verifyUIElements() {
waitForIdleSync()

// FIXME test fails
onView(withId(R.id.ivSplash)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.splashScreenBold)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.splashScreenNormal)).check(matches(isCompletelyDisplayed()))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Nextcloud Android client application
*
* @author Alper Ozturk
* Copyright (C) 2023 Alper Ozturk
* Copyright (C) 2023 Nextcloud GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package com.owncloud.android.datamodel

import com.owncloud.android.R
import com.owncloud.android.lib.common.network.WebdavEntry.MountType
import org.junit.After
import org.junit.Before
import org.junit.Test

class OCFileIconTests {

private val path = "/path/to/a/file.txt"
private var sut: OCFile? = null

@Before
fun setup() {
sut = OCFile(path)
}

@Test
fun testGetFileOverlayIconWhenFileIsAutoUploadFolderShouldReturnFolderOverlayUploadIcon() {
val fileOverlayIcon = sut?.getFileOverlayIconId(true)
val expectedDrawable = R.drawable.ic_folder_overlay_upload
assert(fileOverlayIcon == expectedDrawable)
}

@Test
fun testGetFileOverlayIconWhenFileIsEncryptedShouldReturnFolderOverlayKeyIcon() {
sut?.isEncrypted = true
val fileOverlayIcon = sut?.getFileOverlayIconId(false)
val expectedDrawable = R.drawable.ic_folder_overlay_key
assert(fileOverlayIcon == expectedDrawable)
}

@Test
fun testGetFileOverlayIconWhenFileIsGroupFolderShouldReturnFolderOverlayAccountGroupIcon() {
sut?.mountType = MountType.GROUP
val fileOverlayIcon = sut?.getFileOverlayIconId(false)
val expectedDrawable = R.drawable.ic_folder_overlay_account_group
assert(fileOverlayIcon == expectedDrawable)
}

@Test
fun testGetFileOverlayIconWhenFileIsSharedViaLinkShouldReturnFolderOverlayLinkIcon() {
sut?.isSharedViaLink = true
val fileOverlayIcon = sut?.getFileOverlayIconId(false)
val expectedDrawable = R.drawable.ic_folder_overlay_link
assert(fileOverlayIcon == expectedDrawable)
}

@Test
fun testGetFileOverlayIconWhenFileIsSharedShouldReturnFolderOverlayShareIcon() {
sut?.isSharedWithSharee = true
val fileOverlayIcon = sut?.getFileOverlayIconId(false)
val expectedDrawable = R.drawable.ic_folder_overlay_share
assert(fileOverlayIcon == expectedDrawable)
}

@Test
fun testGetFileOverlayIconWhenFileIsExternalShouldReturnFolderOverlayExternalIcon() {
sut?.mountType = MountType.EXTERNAL
val fileOverlayIcon = sut?.getFileOverlayIconId(false)
val expectedDrawable = R.drawable.ic_folder_overlay_external
assert(fileOverlayIcon == expectedDrawable)
}

@Test
fun testGetFileOverlayIconWhenFileIsLockedShouldReturnFolderOverlayLockIcon() {
sut?.isLocked = true
val fileOverlayIcon = sut?.getFileOverlayIconId(false)
val expectedDrawable = R.drawable.ic_folder_overlay_lock
assert(fileOverlayIcon == expectedDrawable)
}

@Test
fun testGetFileOverlayIconWhenFileIsFolderShouldReturnNull() {
val fileOverlayIcon = sut?.getFileOverlayIconId(false)
assert(fileOverlayIcon == null)
}

@After
fun destroy() {
sut = null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ public void createDefaultOCFile() {
mFile = new OCFile(PATH);
}


@Test
public void writeThenReadAsParcelable() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class LoginIT : AbstractIT() {
ActivityScenario.launch(AuthenticatorActivity::class.java)
}

// FIXME test fails
@Test
@Throws(InterruptedException::class)
@Suppress("MagicNumber", "SwallowedException")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ public void switchAccountViaAccountList() {

waitForIdleSync();

// FIXME test fails
assertEquals(account2, sut.getUser().get().toPlatformAccount());

onView(withId(R.id.switch_account_button)).perform(click());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,8 @@ public void testSslUntrustedCertDialog() {

final SslCertificate certificate = new SslCertificate("foo", "bar", "2022/01/10", "2022/01/30");
final SslError sslError = new SslError(SslError.SSL_UNTRUSTED, certificate);

// FIXME test fails
final SslErrorHandler handler = Mockito.mock(SslErrorHandler.class);


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,22 @@ class OCFileListFragmentStaticServerIT : AbstractIT() {
sut.storageManager.saveFile(this)
}

OCFile("/sharedViaLink/").apply {
mimeType = MimeType.DIRECTORY
isSharedViaLink = true
modificationTimestamp = 1619003571000
parentId = sut.storageManager.getFileByEncryptedRemotePath("/").fileId
sut.storageManager.saveFile(this)
}

OCFile("/share/").apply {
mimeType = MimeType.DIRECTORY
isSharedWithSharee = true
modificationTimestamp = 1619303571000
parentId = sut.storageManager.getFileByEncryptedRemotePath("/").fileId
sut.storageManager.saveFile(this)
}

OCFile("/groupFolder/").apply {
mimeType = MimeType.DIRECTORY
modificationTimestamp = 1615003571000
Expand All @@ -259,6 +275,15 @@ class OCFileListFragmentStaticServerIT : AbstractIT() {
sut.storageManager.saveFile(this)
}

OCFile("/locked/").apply {
mimeType = MimeType.DIRECTORY
isLocked = true
decryptedRemotePath = "/locked/"
modificationTimestamp = 1613003571000
parentId = sut.storageManager.getFileByEncryptedRemotePath("/").fileId
sut.storageManager.saveFile(this)
}

sut.addFragment(fragment)

shortSleep()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Nextcloud Android client application
*
* @author Alper Ozturk
* Copyright (C) 2023 Alper Ozturk
* Copyright (C) 2023 Nextcloud GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package com.owncloud.android.utils

import android.content.Context
import android.graphics.Bitmap
import android.graphics.drawable.BitmapDrawable
import androidx.test.platform.app.InstrumentationRegistry
import org.junit.After
import org.junit.Assert.fail
import org.junit.Before
import org.junit.Test

class DrawableUtilTests {

private var sut: DrawableUtil? = null
private var context: Context? = null

@Before
fun setUp() {
sut = DrawableUtil()
context = InstrumentationRegistry.getInstrumentation().context
}

@Test
fun testAddDrawableAsOverlayWhenGivenValidDrawablesShouldContainTwoDrawable() {
val bitmap: Bitmap = Bitmap.createBitmap(2, 2, Bitmap.Config.ARGB_8888)
val drawable = BitmapDrawable(context?.resources, bitmap)

val layerDrawable = sut?.addDrawableAsOverlay(drawable, drawable)

if (layerDrawable == null) {
fail("Layer drawable expected to be not null")
}

assert(layerDrawable?.numberOfLayers == 2)
}

@After
fun destroy() {
sut = null
context = null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class FileExportUtilsIT : AbstractIT() {

sut.exportFile("export.txt", "/text/plain", targetContext.contentResolver, null, file)

// FIXME test fails
assertTrue(expectedFile.exists())
assertEquals(file.length(), expectedFile.length())
assertTrue(expectedFile.delete())
Expand All @@ -71,6 +72,7 @@ class FileExportUtilsIT : AbstractIT() {

sut.exportFile("export.txt", "/text/plain", targetContext.contentResolver, ocFile, null)

// FIXME test fails
assertTrue(expectedFile.exists())
assertEquals(file.length(), expectedFile.length())
assertTrue(expectedFile.delete())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ import com.google.android.play.core.review.ReviewManagerFactory
import com.nextcloud.appReview.AppReviewShownModel
import com.nextcloud.appReview.InAppReviewHelper
import com.nextcloud.client.preferences.AppPreferences
import com.nextcloud.utils.getFormattedStringDate
import com.nextcloud.utils.isCurrentYear
import com.nextcloud.utils.extensions.getFormattedStringDate
import com.nextcloud.utils.extensions.isCurrentYear
import com.owncloud.android.lib.common.utils.Log_OC

// Reference: https://developer.android.com/guide/playcore/in-app-review
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ default void onDarkThemeModeChanged(DarkMode mode) {

boolean instantPictureUploadEnabled();
boolean instantVideoUploadEnabled();
boolean isDarkModeEnabled();

boolean isShowHiddenFilesEnabled();
void setShowHiddenFilesEnabled(boolean enabled);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,11 @@ public int getUploaderBehaviour() {
return preferences.getInt(AUTO_PREF__UPLOADER_BEHAVIOR, 1);
}

@Override
public boolean isDarkModeEnabled() {
return getDarkThemeMode() == DarkMode.DARK;
}

@Override
public void setDarkThemeMode(DarkMode mode) {
preferences.edit().putString(PREF__DARK_THEME, mode.name()).apply();
Expand Down
16 changes: 6 additions & 10 deletions app/src/main/java/com/nextcloud/utils/ShortcutUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,12 @@ class ShortcutUtil @Inject constructor(private val mContext: Context) {
thumbnail = bitmapToAdaptiveBitmap(thumbnail)
icon = IconCompat.createWithAdaptiveBitmap(thumbnail)
} else if (file.isFolder) {
val bitmapIcon = MimeTypeUtil.getFolderTypeIcon(
file.isSharedWithMe || file.isSharedWithSharee,
file.isSharedViaLink,
file.isEncrypted,
syncedFolderProvider.findByRemotePathAndAccount(file.remotePath, user),
file.isGroupFolder,
file.mountType,
mContext,
viewThemeUtils
).toBitmap()
val isAutoUploadFolder = SyncedFolderProvider.isAutoUploadFolder(syncedFolderProvider, file, user)
val isDarkModeActive = syncedFolderProvider.preferences.isDarkModeEnabled

val overlayIconId = file.getFileOverlayIconId(isAutoUploadFolder)
val drawable = MimeTypeUtil.getFileIcon(isDarkModeActive, overlayIconId, mContext, viewThemeUtils)
val bitmapIcon = drawable.toBitmap()
icon = IconCompat.createWithBitmap(bitmapIcon)
} else {
icon = IconCompat.createWithResource(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package com.nextcloud.utils
package com.nextcloud.utils.extensions

import android.text.Selection
import android.text.Spannable
Expand Down
Loading
Loading