diff --git a/app/build.gradle b/app/build.gradle index 14bf5f3b7..f50a4e6dd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -50,6 +50,8 @@ dependencies { implementation "com.google.android.material:material:1.12.0" implementation 'com.karumi:dexter:5.0.0' implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' + implementation 'androidx.compose.ui:ui-tooling-preview' + androidTestImplementation 'androidx.compose.ui:ui-test-junit4' // Jetpack Compose def composeBom = platform('androidx.compose:compose-bom:2024.11.00') @@ -87,6 +89,8 @@ dependencies { // Dependency injector implementation "com.google.dagger:dagger-android:$DAGGER_VERSION" implementation "com.google.dagger:dagger-android-support:$DAGGER_VERSION" + debugImplementation 'androidx.compose.ui:ui-tooling' + debugImplementation 'androidx.compose.ui:ui-test-manifest' kapt "com.google.dagger:dagger-android-processor:$DAGGER_VERSION" kapt "com.google.dagger:dagger-compiler:$DAGGER_VERSION" annotationProcessor "com.google.dagger:dagger-android-processor:$DAGGER_VERSION" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ab2edf719..e7c64f929 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -55,6 +55,10 @@ android:theme="@style/LightAppTheme" tools:ignore="GoogleAppIndexingWarning" tools:replace="android:appComponentFactory"> + diff --git a/app/src/main/java/fr/free/nrw/commons/activity/SingleWebViewActivity.kt b/app/src/main/java/fr/free/nrw/commons/activity/SingleWebViewActivity.kt new file mode 100644 index 000000000..284c84caf --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/activity/SingleWebViewActivity.kt @@ -0,0 +1,181 @@ +package fr.free.nrw.commons.activity + +import android.annotation.SuppressLint +import android.content.Context +import android.content.Intent +import android.os.Bundle +import android.webkit.ConsoleMessage +import android.webkit.WebChromeClient +import android.webkit.WebResourceRequest +import android.webkit.WebView +import android.webkit.WebViewClient +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.viewinterop.AndroidView +import fr.free.nrw.commons.R +import timber.log.Timber + +/** + * SingleWebViewActivity is a reusable activity webView based on a given url(initial url) and + * closes itself when a specified success URL is reached to success url. + */ +class SingleWebViewActivity : ComponentActivity() { + @OptIn(ExperimentalMaterial3Api::class) + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val url = intent.getStringExtra(VANISH_ACCOUNT_URL) + val successUrl = intent.getStringExtra(VANISH_ACCOUNT_SUCCESS_URL) + if (url == null || successUrl == null) { + finish() + return + } + enableEdgeToEdge() + setContent { + Scaffold( + topBar = { + TopAppBar( + modifier = Modifier, + title = { Text(getString(R.string.vanish_account)) }, + navigationIcon = { + IconButton( + onClick = { + // Close the WebView Activity if the user taps the back button + finish() + }, + ) { + Icon( + imageVector = Icons.AutoMirrored.Filled.ArrowBack, + // TODO("Add contentDescription) + contentDescription = "" + ) + } + } + ) + }, + content = { + WebViewComponent( + url = url, + successUrl = successUrl, + onSuccess = { + // TODO Redirect the user to login screen like we do when the user logout's + finish() + }, + modifier = Modifier + .fillMaxSize() + .padding(it) + ) + } + ) + } + } + + + /** + * @param url The initial URL which we are loading in the WebView. + * @param successUrl The URL that, when reached, triggers the `onSuccess` callback. + * @param onSuccess A callback that is invoked when the current url of webView is successUrl. + * This is used when we want to close when the webView once a success url is hit. + * @param modifier An optional [Modifier] to customize the layout or appearance of the WebView. + */ + @SuppressLint("SetJavaScriptEnabled") + @Composable + private fun WebViewComponent( + url: String, + successUrl: String, + onSuccess: () -> Unit, + modifier: Modifier = Modifier + ) { + val webView = remember { mutableStateOf(null) } + AndroidView( + modifier = modifier, + factory = { + WebView(it).apply { + settings.apply { + javaScriptEnabled = true + domStorageEnabled = true + javaScriptCanOpenWindowsAutomatically = true + + } + webViewClient = object : WebViewClient() { + override fun shouldOverrideUrlLoading( + view: WebView?, + request: WebResourceRequest? + ): Boolean { + + request?.url?.let { url -> + Timber.d("URL Loading: $url") + if (url.toString() == successUrl) { + Timber.d("Success URL detected. Closing WebView.") + onSuccess() // Close the activity + return true + } + return false + } + return false + } + + override fun onPageFinished(view: WebView?, url: String?) { + super.onPageFinished(view, url) + } + + } + + webChromeClient = object : WebChromeClient() { + override fun onConsoleMessage(message: ConsoleMessage): Boolean { + Timber.d("Console: ${message.message()} -- From line ${message.lineNumber()} of ${message.sourceId()}") + return true + } + } + + loadUrl(url) + } + }, + update = { + webView.value = it + } + ) + + } + + companion object { + private const val VANISH_ACCOUNT_URL = "VanishAccountUrl" + private const val VANISH_ACCOUNT_SUCCESS_URL = "vanishAccountSuccessUrl" + + /** + * Launch the WebViewActivity with the specified URL and success URL. + * @param context The context from which the activity is launched. + * @param url The initial URL to load in the WebView. + * @param successUrl The URL that triggers the WebView to close when matched. + */ + fun showWebView( + context: Context, + url: String, + successUrl: String + ) { + val intent = Intent( + context, + SingleWebViewActivity::class.java + ).apply { + putExtra(VANISH_ACCOUNT_URL, url) + putExtra(VANISH_ACCOUNT_SUCCESS_URL, successUrl) + } + context.startActivity(intent) + } + } +} + diff --git a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.kt b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.kt index 47ee8588b..75c4ac26d 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.kt @@ -184,32 +184,32 @@ class LoginActivity : AccountAuthenticatorActivity() { // if progressDialog is visible during the configuration change then store state as true else false so that // we maintain visibility of progressDialog after configuration change if (progressDialog != null && progressDialog!!.isShowing) { - outState.putBoolean(saveProgressDialog, true) + outState.putBoolean(SAVE_PROGRESS_DIALOG, true) } else { - outState.putBoolean(saveProgressDialog, false) + outState.putBoolean(SAVE_PROGRESS_DIALOG, false) } outState.putString( - saveErrorMessage, + SAVE_ERROR_MESSAGE, binding!!.errorMessage.text.toString() ) //Save the errorMessage outState.putString( - saveUsername, + SAVE_USERNAME, binding!!.loginUsername.text.toString() ) // Save the username outState.putString( - savePassword, + SAVE_PASSWORD, binding!!.loginPassword.text.toString() ) // Save the password } override fun onRestoreInstanceState(savedInstanceState: Bundle) { super.onRestoreInstanceState(savedInstanceState) - binding!!.loginUsername.setText(savedInstanceState.getString(saveUsername)) - binding!!.loginPassword.setText(savedInstanceState.getString(savePassword)) - if (savedInstanceState.getBoolean(saveProgressDialog)) { + binding!!.loginUsername.setText(savedInstanceState.getString(SAVE_USERNAME)) + binding!!.loginPassword.setText(savedInstanceState.getString(SAVE_PASSWORD)) + if (savedInstanceState.getBoolean(SAVE_PROGRESS_DIALOG)) { performLogin() } - val errorMessage = savedInstanceState.getString(saveErrorMessage) + val errorMessage = savedInstanceState.getString(SAVE_ERROR_MESSAGE) if (sessionManager.isUserLoggedIn) { showMessage(R.string.login_success, R.color.primaryDarkColor) } else { @@ -396,9 +396,9 @@ class LoginActivity : AccountAuthenticatorActivity() { fun startYourself(context: Context) = context.startActivity(Intent(context, LoginActivity::class.java)) - const val saveProgressDialog: String = "ProgressDialog_state" - const val saveErrorMessage: String = "errorMessage" - const val saveUsername: String = "username" - const val savePassword: String = "password" + const val SAVE_PROGRESS_DIALOG: String = "ProgressDialog_state" + const val SAVE_ERROR_MESSAGE: String = "errorMessage" + const val SAVE_USERNAME: String = "username" + const val SAVE_PASSWORD: String = "password" } } diff --git a/app/src/main/java/fr/free/nrw/commons/concurrency/BackgroundPoolExceptionHandler.java b/app/src/main/java/fr/free/nrw/commons/concurrency/BackgroundPoolExceptionHandler.java deleted file mode 100644 index c1c8fac18..000000000 --- a/app/src/main/java/fr/free/nrw/commons/concurrency/BackgroundPoolExceptionHandler.java +++ /dev/null @@ -1,23 +0,0 @@ -package fr.free.nrw.commons.concurrency; - -import androidx.annotation.NonNull; - -import fr.free.nrw.commons.BuildConfig; - -public class BackgroundPoolExceptionHandler implements ExceptionHandler { - /** - * If an exception occurs on a background thread, this handler will crash for debug builds - * but fail silently for release builds. - * @param t - */ - @Override - public void onException(@NonNull final Throwable t) { - //Crash for debug build - if (BuildConfig.DEBUG) { - Thread thread = new Thread(() -> { - throw new RuntimeException(t); - }); - thread.start(); - } - } -} diff --git a/app/src/main/java/fr/free/nrw/commons/concurrency/BackgroundPoolExceptionHandler.kt b/app/src/main/java/fr/free/nrw/commons/concurrency/BackgroundPoolExceptionHandler.kt new file mode 100644 index 000000000..378a98893 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/concurrency/BackgroundPoolExceptionHandler.kt @@ -0,0 +1,21 @@ +package fr.free.nrw.commons.concurrency + +import fr.free.nrw.commons.BuildConfig + + +class BackgroundPoolExceptionHandler : ExceptionHandler { + /** + * If an exception occurs on a background thread, this handler will crash for debug builds + * but fail silently for release builds. + * @param t + */ + override fun onException(t: Throwable) { + // Crash for debug build + if (BuildConfig.DEBUG) { + val thread = Thread { + throw RuntimeException(t) + } + thread.start() + } + } +} diff --git a/app/src/main/java/fr/free/nrw/commons/concurrency/ExceptionAwareThreadPoolExecutor.java b/app/src/main/java/fr/free/nrw/commons/concurrency/ExceptionAwareThreadPoolExecutor.java deleted file mode 100644 index 80931b1c1..000000000 --- a/app/src/main/java/fr/free/nrw/commons/concurrency/ExceptionAwareThreadPoolExecutor.java +++ /dev/null @@ -1,39 +0,0 @@ -package fr.free.nrw.commons.concurrency; - -import java.util.concurrent.CancellationException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.ThreadFactory; - -class ExceptionAwareThreadPoolExecutor extends ScheduledThreadPoolExecutor { - - private final ExceptionHandler exceptionHandler; - - public ExceptionAwareThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory, - ExceptionHandler exceptionHandler) { - super(corePoolSize, threadFactory); - this.exceptionHandler = exceptionHandler; - } - - @Override - protected void afterExecute(Runnable r, Throwable t) { - super.afterExecute(r, t); - if (t == null && r instanceof Future) { - try { - Future future = (Future) r; - if (future.isDone()) future.get(); - } catch (CancellationException | InterruptedException e) { - //ignore - } catch (ExecutionException e) { - t = e.getCause() != null ? e.getCause() : e; - } catch (Exception e) { - t = e; - } - } - - if (t != null) { - exceptionHandler.onException(t); - } - } -} diff --git a/app/src/main/java/fr/free/nrw/commons/concurrency/ExceptionAwareThreadPoolExecutor.kt b/app/src/main/java/fr/free/nrw/commons/concurrency/ExceptionAwareThreadPoolExecutor.kt new file mode 100644 index 000000000..0efe057f2 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/concurrency/ExceptionAwareThreadPoolExecutor.kt @@ -0,0 +1,40 @@ +package fr.free.nrw.commons.concurrency + +import java.util.concurrent.CancellationException +import java.util.concurrent.ExecutionException +import java.util.concurrent.Future +import java.util.concurrent.ScheduledThreadPoolExecutor +import java.util.concurrent.ThreadFactory + + +class ExceptionAwareThreadPoolExecutor( + corePoolSize: Int, + threadFactory: ThreadFactory, + private val exceptionHandler: ExceptionHandler? +) : ScheduledThreadPoolExecutor(corePoolSize, threadFactory) { + + override fun afterExecute(r: Runnable, t: Throwable?) { + super.afterExecute(r, t) + var throwable = t + + if (throwable == null && r is Future<*>) { + try { + if (r.isDone) { + r.get() + } + } catch (e: CancellationException) { + // ignore + } catch (e: InterruptedException) { + // ignore + } catch (e: ExecutionException) { + throwable = e.cause ?: e + } catch (e: Exception) { + throwable = e + } + } + + throwable?.let { + exceptionHandler?.onException(it) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/fr/free/nrw/commons/concurrency/ExceptionHandler.java b/app/src/main/java/fr/free/nrw/commons/concurrency/ExceptionHandler.java deleted file mode 100644 index 38690305a..000000000 --- a/app/src/main/java/fr/free/nrw/commons/concurrency/ExceptionHandler.java +++ /dev/null @@ -1,7 +0,0 @@ -package fr.free.nrw.commons.concurrency; - -import androidx.annotation.NonNull; - -public interface ExceptionHandler { - void onException(@NonNull Throwable t); -} diff --git a/app/src/main/java/fr/free/nrw/commons/concurrency/ExceptionHandler.kt b/app/src/main/java/fr/free/nrw/commons/concurrency/ExceptionHandler.kt new file mode 100644 index 000000000..6b3d2a0f7 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/concurrency/ExceptionHandler.kt @@ -0,0 +1,7 @@ +package fr.free.nrw.commons.concurrency + +interface ExceptionHandler { + + fun onException(t: Throwable) + +} \ No newline at end of file diff --git a/app/src/main/java/fr/free/nrw/commons/concurrency/ThreadPoolService.java b/app/src/main/java/fr/free/nrw/commons/concurrency/ThreadPoolService.java deleted file mode 100644 index f057f61b2..000000000 --- a/app/src/main/java/fr/free/nrw/commons/concurrency/ThreadPoolService.java +++ /dev/null @@ -1,124 +0,0 @@ -package fr.free.nrw.commons.concurrency; - -import androidx.annotation.NonNull; - -import java.util.concurrent.Callable; -import java.util.concurrent.Executor; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; - -/** - * This class is a thread pool which provides some additional features: - * - it sets the thread priority to a value lower than foreground priority by default, or you can - * supply your own priority - * - it gives you a way to handle exceptions thrown in the thread pool - */ - -public class ThreadPoolService implements Executor { - private final ScheduledThreadPoolExecutor backgroundPool; - - private ThreadPoolService(final Builder b) { - backgroundPool = new ExceptionAwareThreadPoolExecutor(b.poolSize, - new ThreadFactory() { - int count = 0; - @Override - public Thread newThread(@NonNull Runnable r) { - count++; - Thread t = new Thread(r, String.format("%s-%s", b.name, count)); - //If the priority is specified out of range, we set the thread priority to Thread.MIN_PRIORITY - //It's done prevent IllegalArgumentException and to prevent setting of improper high priority for a less priority task - t.setPriority(b.priority > Thread.MAX_PRIORITY || b.priority < Thread.MIN_PRIORITY ? - Thread.MIN_PRIORITY : b.priority); - return t; - } - }, b.exceptionHandler); - } - - public ScheduledFuture schedule(Callable callable, long time, TimeUnit timeUnit) { - return backgroundPool.schedule(callable, time, timeUnit); - } - - public ScheduledFuture schedule(Runnable runnable) { - return schedule(runnable, 0, TimeUnit.SECONDS); - } - - public ScheduledFuture schedule(Runnable runnable, long time, TimeUnit timeUnit) { - return backgroundPool.schedule(runnable, time, timeUnit); - } - - public ScheduledFuture scheduleAtFixedRate(final Runnable task, long initialDelay, - long period, final TimeUnit timeUnit) { - return backgroundPool.scheduleAtFixedRate(task, initialDelay, period, timeUnit); - } - - public ScheduledThreadPoolExecutor executor() { - return backgroundPool; - } - - public void shutdown(){ - backgroundPool.shutdown(); - } - - @Override - public void execute(Runnable command) { - backgroundPool.execute(command); - } - - /** - * Builder class for {@link ThreadPoolService} - */ - public static class Builder { - //Required - private final String name; - - //Optional - private int poolSize = 1; - private int priority = Thread.MIN_PRIORITY; - private ExceptionHandler exceptionHandler = null; - - /** - * @param name the name of the threads in the service. if there are N threads, - * the thread names will be like name-1, name-2, name-3,...,name-N - */ - public Builder(@NonNull String name) { - this.name = name; - } - - /** - * @param poolSize the number of threads to keep in the pool - * @throws IllegalArgumentException if size of pool <=0 - */ - public Builder setPoolSize(int poolSize) throws IllegalArgumentException { - if (poolSize <= 0) { - throw new IllegalArgumentException("Pool size must be grater than 0"); - } - this.poolSize = poolSize; - return this; - } - - /** - * @param priority Priority of the threads in the service. You can supply a constant from - * {@link java.lang.Thread} or - * specify your own priority in the range 1(MIN_PRIORITY) to 10(MAX_PRIORITY) - * By default, the priority is set to {@link java.lang.Thread#MIN_PRIORITY} - */ - public Builder setPriority(int priority) { - this.priority = priority; - return this; - } - - /** - * @param handler The handler to use to handle exceptions in the service - */ - public Builder setExceptionHandler(ExceptionHandler handler) { - this.exceptionHandler = handler; - return this; - } - - public ThreadPoolService build() { - return new ThreadPoolService(this); - } - } -} diff --git a/app/src/main/java/fr/free/nrw/commons/concurrency/ThreadPoolService.kt b/app/src/main/java/fr/free/nrw/commons/concurrency/ThreadPoolService.kt new file mode 100644 index 000000000..46138d676 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/concurrency/ThreadPoolService.kt @@ -0,0 +1,122 @@ +package fr.free.nrw.commons.concurrency + +import java.util.concurrent.Callable +import java.util.concurrent.Executor +import java.util.concurrent.ScheduledFuture +import java.util.concurrent.ScheduledThreadPoolExecutor +import java.util.concurrent.ThreadFactory +import java.util.concurrent.TimeUnit + + +/** + * This class is a thread pool which provides some additional features: + * - it sets the thread priority to a value lower than foreground priority by default, or you can + * supply your own priority + * - it gives you a way to handle exceptions thrown in the thread pool + */ +class ThreadPoolService private constructor(builder: Builder) : Executor { + private val backgroundPool: ScheduledThreadPoolExecutor = ExceptionAwareThreadPoolExecutor( + builder.poolSize, + object : ThreadFactory { + private var count = 0 + override fun newThread(r: Runnable): Thread { + count++ + val t = Thread(r, "${builder.name}-$count") + // If the priority is specified out of range, we set the thread priority to + // Thread.MIN_PRIORITY + // It's done to prevent IllegalArgumentException and to prevent setting of + // improper high priority for a less priority task + t.priority = + if ( + builder.priority > Thread.MAX_PRIORITY + || + builder.priority < Thread.MIN_PRIORITY + ) { + Thread.MIN_PRIORITY + } else { + builder.priority + } + return t + } + }, + builder.exceptionHandler + ) + + fun schedule(callable: Callable, time: Long, timeUnit: TimeUnit): ScheduledFuture { + return backgroundPool.schedule(callable, time, timeUnit) + } + + fun schedule(runnable: Runnable): ScheduledFuture<*> { + return schedule(runnable, 0, TimeUnit.SECONDS) + } + + fun schedule(runnable: Runnable, time: Long, timeUnit: TimeUnit): ScheduledFuture<*> { + return backgroundPool.schedule(runnable, time, timeUnit) + } + + fun scheduleAtFixedRate( + task: Runnable, + initialDelay: Long, + period: Long, + timeUnit: TimeUnit + ): ScheduledFuture<*> { + return backgroundPool.scheduleWithFixedDelay(task, initialDelay, period, timeUnit) + } + + fun executor(): ScheduledThreadPoolExecutor { + return backgroundPool + } + + fun shutdown() { + backgroundPool.shutdown() + } + + override fun execute(command: Runnable) { + backgroundPool.execute(command) + } + + /** + * Builder class for [ThreadPoolService] + */ + class Builder(val name: String) { + var poolSize: Int = 1 + var priority: Int = Thread.MIN_PRIORITY + var exceptionHandler: ExceptionHandler? = null + + /** + * @param poolSize the number of threads to keep in the pool + * @throws IllegalArgumentException if size of pool <= 0 + */ + fun setPoolSize(poolSize: Int): Builder { + if (poolSize <= 0) { + throw IllegalArgumentException("Pool size must be greater than 0") + } + this.poolSize = poolSize + return this + } + + /** + * @param priority Priority of the threads in the service. You can supply a constant from + * [java.lang.Thread] or + * specify your own priority in the range 1(MIN_PRIORITY) + * to 10(MAX_PRIORITY) + * By default, the priority is set to [java.lang.Thread.MIN_PRIORITY] + */ + fun setPriority(priority: Int): Builder { + this.priority = priority + return this + } + + /** + * @param handler The handler to use to handle exceptions in the service + */ + fun setExceptionHandler(handler: ExceptionHandler): Builder { + exceptionHandler = handler + return this + } + + fun build(): ThreadPoolService { + return ThreadPoolService(this) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.kt b/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.kt index 84ce0eb9c..92fab56af 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.kt +++ b/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.kt @@ -101,7 +101,7 @@ data class Contribution constructor( */ fun formatCaptions(uploadMediaDetails: List) = uploadMediaDetails - .associate { it.languageCode!! to it.captionText } + .associate { it.languageCode!! to it.captionText!! } .filter { it.value.isNotBlank() } /** @@ -112,7 +112,7 @@ data class Contribution constructor( */ fun formatDescriptions(descriptions: List) = descriptions - .filter { it.descriptionText.isNotEmpty() } + .filter { !it.descriptionText.isNullOrEmpty() } .joinToString(separator = "") { "{{${it.languageCode}|1=${it.descriptionText}}}" } } diff --git a/app/src/main/java/fr/free/nrw/commons/coordinates/CoordinateEditHelper.kt b/app/src/main/java/fr/free/nrw/commons/coordinates/CoordinateEditHelper.kt index 3095497c3..1bad2e2a5 100644 --- a/app/src/main/java/fr/free/nrw/commons/coordinates/CoordinateEditHelper.kt +++ b/app/src/main/java/fr/free/nrw/commons/coordinates/CoordinateEditHelper.kt @@ -61,16 +61,16 @@ class CoordinateEditHelper @Inject constructor( /** * Replaces new coordinates * @param media to be added - * @param Latitude to be added - * @param Longitude to be added - * @param Accuracy to be added + * @param latitude to be added + * @param longitude to be added + * @param accuracy to be added * @return Observable */ private fun addCoordinates( media: Media, - Latitude: String, - Longitude: String, - Accuracy: String + latitude: String, + longitude: String, + accuracy: String ): Observable? { Timber.d("thread is coordinates adding %s", Thread.currentThread().getName()) val summary = "Adding Coordinates" @@ -83,9 +83,9 @@ class CoordinateEditHelper @Inject constructor( .blockingGet() } - if (Latitude != null) { - buffer.append("\n{{Location|").append(Latitude).append("|").append(Longitude) - .append("|").append(Accuracy).append("}}") + if (latitude != null) { + buffer.append("\n{{Location|").append(latitude).append("|").append(longitude) + .append("|").append(accuracy).append("}}") } val editedLocation = buffer.toString() @@ -141,7 +141,7 @@ class CoordinateEditHelper @Inject constructor( * @param media to be added * @param latitude to be added * @param longitude to be added - * @param Accuracy to be added + * @param accuracy to be added * @param result to be added * @return boolean */ @@ -150,7 +150,7 @@ class CoordinateEditHelper @Inject constructor( media: Media, latitude: String, longitude: String, - Accuracy: String, + accuracy: String, result: Boolean ): Boolean { val message: String @@ -160,7 +160,7 @@ class CoordinateEditHelper @Inject constructor( media.coordinates = fr.free.nrw.commons.location.LatLng( latitude.toDouble(), longitude.toDouble(), - Accuracy.toFloat() + accuracy.toFloat() ) title += ": " + context.getString(R.string.coordinates_edit_helper_show_edit_title_success) val coordinatesInMessage = StringBuilder() diff --git a/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/CustomSelectorActivity.kt b/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/CustomSelectorActivity.kt index 52b615175..4e2d58bab 100644 --- a/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/CustomSelectorActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/CustomSelectorActivity.kt @@ -271,7 +271,7 @@ class CustomSelectorActivity : dialog.setCancelable(false) dialog.requestWindowFeature(Window.FEATURE_NO_TITLE) dialog.setContentView(R.layout.custom_selector_info_dialog) - (dialog.findViewById(R.id.btn_ok) as Button).setOnClickListener { dialog.dismiss() } + (dialog.findViewById