mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 12:23:58 +01:00
Migrated ui and theme modules from Java to Kotlin (#5942)
* Rename .java to .kt * Migrated ui and theme module to Kotlin
This commit is contained in:
parent
cb4ffd8ca8
commit
ed18a37577
13 changed files with 230 additions and 245 deletions
|
|
@ -367,7 +367,7 @@ public class LocationPickerActivity extends BaseActivity implements
|
|||
*/
|
||||
private void removeLocationFromImage() {
|
||||
if (media != null) {
|
||||
compositeDisposable.add(coordinateEditHelper.makeCoordinatesEdit(getApplicationContext()
|
||||
getCompositeDisposable().add(coordinateEditHelper.makeCoordinatesEdit(getApplicationContext()
|
||||
, media, "0.0", "0.0", "0.0f")
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
|
@ -479,7 +479,7 @@ public class LocationPickerActivity extends BaseActivity implements
|
|||
}
|
||||
|
||||
try {
|
||||
compositeDisposable.add(
|
||||
getCompositeDisposable().add(
|
||||
coordinateEditHelper.makeCoordinatesEdit(getApplicationContext(), media,
|
||||
Latitude, Longitude, Accuracy)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package fr.free.nrw.commons.customselector.ui.selector
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Context.MODE_PRIVATE
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Bundle
|
||||
|
|
@ -346,7 +347,7 @@ class ImageFragment :
|
|||
context
|
||||
.getSharedPreferences(
|
||||
"CustomSelector",
|
||||
BaseActivity.MODE_PRIVATE,
|
||||
MODE_PRIVATE,
|
||||
)?.let { prefs ->
|
||||
prefs.edit()?.let { editor ->
|
||||
editor.putLong("ItemId", imageAdapter.getImageIdAt(position))?.apply()
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ public class SearchActivity extends BaseActivity
|
|||
|
||||
viewPagerAdapter.setTabData(fragmentList, titleList);
|
||||
viewPagerAdapter.notifyDataSetChanged();
|
||||
compositeDisposable.add(RxSearchView.queryTextChanges(binding.searchBox)
|
||||
getCompositeDisposable().add(RxSearchView.queryTextChanges(binding.searchBox)
|
||||
.takeUntil(RxView.detaches(binding.searchBox))
|
||||
.debounce(500, TimeUnit.MILLISECONDS)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
|
@ -284,7 +284,7 @@ public class SearchActivity extends BaseActivity
|
|||
@Override protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
//Dispose the disposables when the activity is destroyed
|
||||
compositeDisposable.dispose();
|
||||
getCompositeDisposable().dispose();
|
||||
binding = null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ public class NotificationActivity extends BaseActivity {
|
|||
}
|
||||
binding.progressBar.setVisibility(View.GONE);
|
||||
});
|
||||
compositeDisposable.add(disposable);
|
||||
getCompositeDisposable().add(disposable);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -178,7 +178,7 @@ public class NotificationActivity extends BaseActivity {
|
|||
Timber.d("Add notifications");
|
||||
if (mNotificationWorkerFragment == null) {
|
||||
binding.progressBar.setVisibility(View.VISIBLE);
|
||||
compositeDisposable.add(controller.getNotifications(archived)
|
||||
getCompositeDisposable().add(controller.getNotifications(archived)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(notificationList -> {
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ public class ProfileActivity extends BaseActivity {
|
|||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
compositeDisposable.clear();
|
||||
getCompositeDisposable().clear();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,66 +0,0 @@
|
|||
package fr.free.nrw.commons.theme;
|
||||
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.WindowManager;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.di.CommonsDaggerAppCompatActivity;
|
||||
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
||||
import fr.free.nrw.commons.utils.SystemThemeUtils;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
|
||||
public abstract class BaseActivity extends CommonsDaggerAppCompatActivity {
|
||||
@Inject
|
||||
@Named("default_preferences")
|
||||
public JsonKvStore defaultKvStore;
|
||||
|
||||
@Inject
|
||||
SystemThemeUtils systemThemeUtils;
|
||||
|
||||
protected CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||
protected boolean wasPreviouslyDarkTheme;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
wasPreviouslyDarkTheme = systemThemeUtils.isDeviceInNightMode();
|
||||
setTheme(wasPreviouslyDarkTheme ? R.style.DarkAppTheme : R.style.LightAppTheme);
|
||||
float fontScale = android.provider.Settings.System.getFloat(
|
||||
getBaseContext().getContentResolver(),
|
||||
android.provider.Settings.System.FONT_SCALE,
|
||||
1f);
|
||||
adjustFontScale(getResources().getConfiguration(), fontScale);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
// Restart activity if theme is changed
|
||||
if (wasPreviouslyDarkTheme != systemThemeUtils.isDeviceInNightMode()) {
|
||||
recreate();
|
||||
}
|
||||
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
compositeDisposable.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply fontScale on device
|
||||
*/
|
||||
public void adjustFontScale(Configuration configuration, float scale) {
|
||||
configuration.fontScale = scale;
|
||||
final DisplayMetrics metrics = getResources().getDisplayMetrics();
|
||||
final WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
|
||||
wm.getDefaultDisplay().getMetrics(metrics);
|
||||
metrics.scaledDensity = configuration.fontScale * metrics.density;
|
||||
getBaseContext().getResources().updateConfiguration(configuration, metrics);
|
||||
}
|
||||
|
||||
}
|
||||
65
app/src/main/java/fr/free/nrw/commons/theme/BaseActivity.kt
Normal file
65
app/src/main/java/fr/free/nrw/commons/theme/BaseActivity.kt
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
package fr.free.nrw.commons.theme
|
||||
|
||||
import android.content.res.Configuration
|
||||
import android.os.Bundle
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.WindowManager
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Named
|
||||
import fr.free.nrw.commons.R
|
||||
import fr.free.nrw.commons.di.CommonsDaggerAppCompatActivity
|
||||
import fr.free.nrw.commons.kvstore.JsonKvStore
|
||||
import fr.free.nrw.commons.utils.SystemThemeUtils
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
|
||||
|
||||
abstract class BaseActivity : CommonsDaggerAppCompatActivity() {
|
||||
|
||||
@Inject
|
||||
@field:Named("default_preferences")
|
||||
lateinit var defaultKvStore: JsonKvStore
|
||||
|
||||
@Inject
|
||||
lateinit var systemThemeUtils: SystemThemeUtils
|
||||
|
||||
protected val compositeDisposable = CompositeDisposable()
|
||||
protected var wasPreviouslyDarkTheme: Boolean = false
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
wasPreviouslyDarkTheme = systemThemeUtils.isDeviceInNightMode()
|
||||
setTheme(if (wasPreviouslyDarkTheme) R.style.DarkAppTheme else R.style.LightAppTheme)
|
||||
|
||||
val fontScale = android.provider.Settings.System.getFloat(
|
||||
baseContext.contentResolver,
|
||||
android.provider.Settings.System.FONT_SCALE,
|
||||
1f
|
||||
)
|
||||
adjustFontScale(resources.configuration, fontScale)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
// Restart activity if theme is changed
|
||||
if (wasPreviouslyDarkTheme != systemThemeUtils.isDeviceInNightMode()) {
|
||||
recreate()
|
||||
}
|
||||
super.onResume()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
compositeDisposable.clear()
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply fontScale on device
|
||||
*/
|
||||
fun adjustFontScale(configuration: Configuration, scale: Float) {
|
||||
configuration.fontScale = scale
|
||||
val metrics = resources.displayMetrics
|
||||
val wm = getSystemService(WINDOW_SERVICE) as WindowManager
|
||||
wm.defaultDisplay.getMetrics(metrics)
|
||||
metrics.scaledDensity = configuration.fontScale * metrics.density
|
||||
baseContext.resources.updateConfiguration(configuration, metrics)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
package fr.free.nrw.commons.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.os.Build.VERSION;
|
||||
import android.util.AttributeSet;
|
||||
import com.google.android.material.textfield.TextInputEditText;
|
||||
import fr.free.nrw.commons.R;
|
||||
|
||||
public class PasteSensitiveTextInputEditText extends TextInputEditText {
|
||||
|
||||
private boolean formattingAllowed = true;
|
||||
|
||||
public PasteSensitiveTextInputEditText(final Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public PasteSensitiveTextInputEditText(final Context context, final AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
formattingAllowed = extractFormattingAttribute(context, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTextContextMenuItem(int id) {
|
||||
|
||||
// if not paste command, or formatting is allowed, return default
|
||||
if(id != android.R.id.paste || formattingAllowed){
|
||||
return super.onTextContextMenuItem(id);
|
||||
}
|
||||
|
||||
// if its paste and formatting not allowed
|
||||
boolean proceeded;
|
||||
if(VERSION.SDK_INT >= 23) {
|
||||
proceeded = super.onTextContextMenuItem(android.R.id.pasteAsPlainText);
|
||||
}else {
|
||||
proceeded = super.onTextContextMenuItem(id);
|
||||
if (proceeded && getText() != null) {
|
||||
// rewrite with plain text so formatting is lost
|
||||
setText(getText().toString());
|
||||
setSelection(getText().length());
|
||||
}
|
||||
}
|
||||
return proceeded;
|
||||
}
|
||||
|
||||
private boolean extractFormattingAttribute(Context context, AttributeSet attrs){
|
||||
|
||||
boolean formatAllowed = true;
|
||||
|
||||
TypedArray a = context.getTheme().obtainStyledAttributes(
|
||||
attrs, R.styleable.PasteSensitiveTextInputEditText, 0, 0);
|
||||
|
||||
try {
|
||||
formatAllowed = a.getBoolean(
|
||||
R.styleable.PasteSensitiveTextInputEditText_allowFormatting, true);
|
||||
} finally {
|
||||
a.recycle();
|
||||
}
|
||||
return formatAllowed;
|
||||
}
|
||||
|
||||
public void setFormattingAllowed(boolean formattingAllowed){
|
||||
this.formattingAllowed = formattingAllowed;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package fr.free.nrw.commons.ui
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.TypedArray
|
||||
import android.os.Build
|
||||
import android.os.Build.VERSION
|
||||
import android.util.AttributeSet
|
||||
import com.google.android.material.textfield.TextInputEditText
|
||||
import fr.free.nrw.commons.R
|
||||
|
||||
|
||||
class PasteSensitiveTextInputEditText @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null
|
||||
) : TextInputEditText(context, attrs) {
|
||||
|
||||
private var formattingAllowed: Boolean = true
|
||||
|
||||
init {
|
||||
if (attrs != null) {
|
||||
formattingAllowed = extractFormattingAttribute(context, attrs)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTextContextMenuItem(id: Int): Boolean {
|
||||
// if not paste command, or formatting is allowed, return default
|
||||
if (id != android.R.id.paste || formattingAllowed) {
|
||||
return super.onTextContextMenuItem(id)
|
||||
}
|
||||
|
||||
// if it's paste and formatting not allowed
|
||||
val proceeded: Boolean = if (VERSION.SDK_INT >= 23) {
|
||||
super.onTextContextMenuItem(android.R.id.pasteAsPlainText)
|
||||
} else {
|
||||
val success = super.onTextContextMenuItem(id)
|
||||
if (success && text != null) {
|
||||
// rewrite with plain text so formatting is lost
|
||||
setText(text.toString())
|
||||
setSelection(text?.length ?: 0)
|
||||
}
|
||||
success
|
||||
}
|
||||
return proceeded
|
||||
}
|
||||
|
||||
private fun extractFormattingAttribute(context: Context, attrs: AttributeSet): Boolean {
|
||||
val a = context.theme.obtainStyledAttributes(
|
||||
attrs, R.styleable.PasteSensitiveTextInputEditText, 0, 0
|
||||
)
|
||||
return try {
|
||||
a.getBoolean(R.styleable.PasteSensitiveTextInputEditText_allowFormatting, true)
|
||||
} finally {
|
||||
a.recycle()
|
||||
}
|
||||
}
|
||||
|
||||
fun setFormattingAllowed(formattingAllowed: Boolean) {
|
||||
this.formattingAllowed = formattingAllowed
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
package fr.free.nrw.commons.ui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import androidx.appcompat.widget.AppCompatTextView;
|
||||
|
||||
import fr.free.nrw.commons.utils.StringUtil;
|
||||
|
||||
/**
|
||||
* An {@link AppCompatTextView} which formats the text to HTML displayable text and makes any
|
||||
* links clickable.
|
||||
*/
|
||||
public class HtmlTextView extends AppCompatTextView {
|
||||
|
||||
/**
|
||||
* Constructs a new instance of HtmlTextView
|
||||
* @param context the context of the view
|
||||
* @param attrs the set of attributes for the view
|
||||
*/
|
||||
public HtmlTextView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
setMovementMethod(LinkMovementMethod.getInstance());
|
||||
setText(StringUtil.fromHtml(getText().toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text to be displayed
|
||||
* @param newText the text to be displayed
|
||||
*/
|
||||
public void setHtmlText(String newText) {
|
||||
setText(StringUtil.fromHtml(newText));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package fr.free.nrw.commons.ui.widget
|
||||
|
||||
import android.content.Context
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.util.AttributeSet
|
||||
|
||||
import androidx.appcompat.widget.AppCompatTextView
|
||||
|
||||
import fr.free.nrw.commons.utils.StringUtil
|
||||
|
||||
/**
|
||||
* An [AppCompatTextView] which formats the text to HTML displayable text and makes any
|
||||
* links clickable.
|
||||
*/
|
||||
class HtmlTextView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null
|
||||
) : AppCompatTextView(context, attrs) {
|
||||
|
||||
init {
|
||||
movementMethod = LinkMovementMethod.getInstance()
|
||||
text = StringUtil.fromHtml(text.toString())
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text to be displayed
|
||||
* @param newText the text to be displayed
|
||||
*/
|
||||
fun setHtmlText(newText: String) {
|
||||
text = StringUtil.fromHtml(newText)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
package fr.free.nrw.commons.ui.widget;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
|
||||
/**
|
||||
* a formatted dialog fragment
|
||||
* This class is used by NearbyInfoDialog
|
||||
*/
|
||||
public abstract class OverlayDialog extends DialogFragment {
|
||||
|
||||
/**
|
||||
* creates a DialogFragment with the correct style and theme
|
||||
* @param savedInstanceState bundle re-constructed from a previous saved state
|
||||
*/
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setStyle(STYLE_NO_FRAME, android.R.style.Theme_Holo_Light);
|
||||
}
|
||||
|
||||
/**
|
||||
* When the view is created, sets the dialog layout to full screen
|
||||
*
|
||||
* @param view the view being used
|
||||
* @param savedInstanceState bundle re-constructed from a previous saved state
|
||||
*/
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
setDialogLayoutToFullScreen();
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the dialog layout to fullscreen
|
||||
*/
|
||||
private void setDialogLayoutToFullScreen() {
|
||||
Window window = getDialog().getWindow();
|
||||
WindowManager.LayoutParams wlp = window.getAttributes();
|
||||
window.requestFeature(Window.FEATURE_NO_TITLE);
|
||||
wlp.gravity = Gravity.BOTTOM;
|
||||
wlp.width = WindowManager.LayoutParams.MATCH_PARENT;
|
||||
wlp.height = WindowManager.LayoutParams.MATCH_PARENT;
|
||||
window.setAttributes(wlp);
|
||||
}
|
||||
|
||||
/**
|
||||
* builds custom dialog container
|
||||
*
|
||||
* @param savedInstanceState the previously saved state
|
||||
* @return the dialog
|
||||
*/
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
Dialog dialog = super.onCreateDialog(savedInstanceState);
|
||||
Window window = dialog.getWindow();
|
||||
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
return dialog;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
package fr.free.nrw.commons.ui.widget
|
||||
|
||||
import android.app.Dialog
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.os.Bundle
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.view.Window
|
||||
import android.view.WindowManager
|
||||
|
||||
import androidx.fragment.app.DialogFragment
|
||||
|
||||
/**
|
||||
* A formatted dialog fragment
|
||||
* This class is used by NearbyInfoDialog
|
||||
*/
|
||||
abstract class OverlayDialog : DialogFragment() {
|
||||
|
||||
/**
|
||||
* Creates a DialogFragment with the correct style and theme
|
||||
* @param savedInstanceState bundle re-constructed from a previous saved state
|
||||
*/
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setStyle(STYLE_NO_FRAME, android.R.style.Theme_Holo_Light)
|
||||
}
|
||||
|
||||
/**
|
||||
* When the view is created, sets the dialog layout to full screen
|
||||
*
|
||||
* @param view the view being used
|
||||
* @param savedInstanceState bundle re-constructed from a previous saved state
|
||||
*/
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
setDialogLayoutToFullScreen()
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the dialog layout to fullscreen
|
||||
*/
|
||||
private fun setDialogLayoutToFullScreen() {
|
||||
val window = dialog?.window ?: return
|
||||
val wlp = window.attributes
|
||||
window.requestFeature(Window.FEATURE_NO_TITLE)
|
||||
wlp.gravity = Gravity.BOTTOM
|
||||
wlp.width = WindowManager.LayoutParams.MATCH_PARENT
|
||||
wlp.height = WindowManager.LayoutParams.MATCH_PARENT
|
||||
window.attributes = wlp
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds custom dialog container
|
||||
*
|
||||
* @param savedInstanceState the previously saved state
|
||||
* @return the dialog
|
||||
*/
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val dialog = super.onCreateDialog(savedInstanceState)
|
||||
dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||
return dialog
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue