mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-25 21:03:56 +02:00
convert top level classes to kotlin (#6368)
* Converted welcome activity / pager to kotlin * Removed unused interface * Convert ViewPagerAdapter to kotlin and enforce that all tabs must have a title that comes from strings.xml * Convert OkHttpConnectionFactory and remove an exception class nobody was using * Convert MapController to kotlin along with fixing nullability in a few places
This commit is contained in:
parent
65f41beed8
commit
66395b9871
29 changed files with 555 additions and 655 deletions
1
.idea/codeStyles/Project.xml
generated
1
.idea/codeStyles/Project.xml
generated
|
|
@ -16,6 +16,7 @@
|
|||
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
|
||||
<option name="IMPORT_LAYOUT_TABLE">
|
||||
<value>
|
||||
<package name="" withSubpackages="true" static="false" module="true" />
|
||||
<package name="" withSubpackages="true" static="true" />
|
||||
<emptyLine />
|
||||
<package name="" withSubpackages="true" static="false" />
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
package fr.free.nrw.commons;
|
||||
|
||||
import fr.free.nrw.commons.location.LatLng;
|
||||
import fr.free.nrw.commons.nearby.Place;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class MapController {
|
||||
|
||||
/**
|
||||
* We pass this variable as a group of placeList and boundaryCoordinates
|
||||
*/
|
||||
public class NearbyPlacesInfo {
|
||||
public List<Place> placeList; // List of nearby places
|
||||
public LatLng[] boundaryCoordinates; // Corners of nearby area
|
||||
public LatLng currentLatLng; // Current location when this places are populated
|
||||
public LatLng searchLatLng; // Search location for finding this places
|
||||
public List<Media> mediaList; // Search location for finding this places
|
||||
}
|
||||
|
||||
/**
|
||||
* We pass this variable as a group of placeList and boundaryCoordinates
|
||||
*/
|
||||
public class ExplorePlacesInfo {
|
||||
public List<Place> explorePlaceList; // List of nearby places
|
||||
public LatLng[] boundaryCoordinates; // Corners of nearby area
|
||||
public LatLng currentLatLng; // Current location when this places are populated
|
||||
public LatLng searchLatLng; // Search location for finding this places
|
||||
public List<Media> mediaList; // Search location for finding this places
|
||||
}
|
||||
}
|
||||
46
app/src/main/java/fr/free/nrw/commons/MapController.kt
Normal file
46
app/src/main/java/fr/free/nrw/commons/MapController.kt
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
package fr.free.nrw.commons
|
||||
|
||||
import fr.free.nrw.commons.location.LatLng
|
||||
import fr.free.nrw.commons.nearby.Place
|
||||
|
||||
abstract class MapController {
|
||||
/**
|
||||
* We pass this variable as a group of placeList and boundaryCoordinates
|
||||
*/
|
||||
inner class NearbyPlacesInfo {
|
||||
@JvmField
|
||||
var placeList: List<Place> = emptyList() // List of nearby places
|
||||
|
||||
@JvmField
|
||||
var boundaryCoordinates: Array<LatLng> = emptyArray() // Corners of nearby area
|
||||
|
||||
@JvmField
|
||||
var currentLatLng: LatLng? = null // Current location when this places are populated
|
||||
|
||||
@JvmField
|
||||
var searchLatLng: LatLng? = null // Search location for finding this places
|
||||
|
||||
@JvmField
|
||||
var mediaList: List<Media>? = null // Search location for finding this places
|
||||
}
|
||||
|
||||
/**
|
||||
* We pass this variable as a group of placeList and boundaryCoordinates
|
||||
*/
|
||||
inner class ExplorePlacesInfo {
|
||||
@JvmField
|
||||
var explorePlaceList: List<Place> = emptyList() // List of nearby places
|
||||
|
||||
@JvmField
|
||||
var boundaryCoordinates: Array<LatLng> = emptyArray() // Corners of nearby area
|
||||
|
||||
@JvmField
|
||||
var currentLatLng: LatLng? = null // Current location when this places are populated
|
||||
|
||||
@JvmField
|
||||
var searchLatLng: LatLng? = null // Search location for finding this places
|
||||
|
||||
@JvmField
|
||||
var mediaList: List<Media> = emptyList() // Search location for finding this places
|
||||
}
|
||||
}
|
||||
|
|
@ -1,154 +0,0 @@
|
|||
package fr.free.nrw.commons;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import fr.free.nrw.commons.wikidata.cookies.CommonsCookieJar;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import okhttp3.Cache;
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.ResponseBody;
|
||||
import okhttp3.logging.HttpLoggingInterceptor;
|
||||
import okhttp3.logging.HttpLoggingInterceptor.Level;
|
||||
import timber.log.Timber;
|
||||
|
||||
public final class OkHttpConnectionFactory {
|
||||
private static final String CACHE_DIR_NAME = "okhttp-cache";
|
||||
private static final long NET_CACHE_SIZE = 64 * 1024 * 1024;
|
||||
|
||||
public static OkHttpClient CLIENT;
|
||||
|
||||
@NonNull public static OkHttpClient getClient(final CommonsCookieJar cookieJar) {
|
||||
if (CLIENT == null) {
|
||||
CLIENT = createClient(cookieJar);
|
||||
}
|
||||
return CLIENT;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static OkHttpClient createClient(final CommonsCookieJar cookieJar) {
|
||||
return new OkHttpClient.Builder()
|
||||
.cookieJar(cookieJar)
|
||||
.cache((CommonsApplication.getInstance()!=null) ? new Cache(new File(CommonsApplication.getInstance().getCacheDir(), CACHE_DIR_NAME), NET_CACHE_SIZE) : null)
|
||||
.connectTimeout(120, TimeUnit.SECONDS)
|
||||
.writeTimeout(120, TimeUnit.SECONDS)
|
||||
.readTimeout(120, TimeUnit.SECONDS)
|
||||
.addInterceptor(getLoggingInterceptor())
|
||||
.addInterceptor(new UnsuccessfulResponseInterceptor())
|
||||
.addInterceptor(new CommonHeaderRequestInterceptor())
|
||||
.build();
|
||||
}
|
||||
|
||||
private static HttpLoggingInterceptor getLoggingInterceptor() {
|
||||
final HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor()
|
||||
.setLevel(Level.BASIC);
|
||||
|
||||
httpLoggingInterceptor.redactHeader("Authorization");
|
||||
httpLoggingInterceptor.redactHeader("Cookie");
|
||||
|
||||
return httpLoggingInterceptor;
|
||||
}
|
||||
|
||||
private static class CommonHeaderRequestInterceptor implements Interceptor {
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public Response intercept(@NonNull final Chain chain) throws IOException {
|
||||
final Request request = chain.request().newBuilder()
|
||||
.header("User-Agent", CommonsApplication.getInstance().getUserAgent())
|
||||
.build();
|
||||
return chain.proceed(request);
|
||||
}
|
||||
}
|
||||
|
||||
public static class UnsuccessfulResponseInterceptor implements Interceptor {
|
||||
private static final String SUPPRESS_ERROR_LOG = "x-commons-suppress-error-log";
|
||||
public static final String SUPPRESS_ERROR_LOG_HEADER = SUPPRESS_ERROR_LOG+": true";
|
||||
private static final List<String> DO_NOT_INTERCEPT = Collections.singletonList(
|
||||
"api.php?format=json&formatversion=2&errorformat=plaintext&action=upload&ignorewarnings=1");
|
||||
|
||||
private static final String ERRORS_PREFIX = "{\"error";
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public Response intercept(@NonNull final Chain chain) throws IOException {
|
||||
final Request rq = chain.request();
|
||||
|
||||
// If the request contains our special "suppress errors" header, make note of it
|
||||
// but don't pass that on to the server.
|
||||
final boolean suppressErrors = rq.headers().names().contains(SUPPRESS_ERROR_LOG);
|
||||
final Request request = rq.newBuilder()
|
||||
.removeHeader(SUPPRESS_ERROR_LOG)
|
||||
.build();
|
||||
|
||||
final Response rsp = chain.proceed(request);
|
||||
|
||||
// Do not intercept certain requests and let the caller handle the errors
|
||||
if(isExcludedUrl(chain.request())) {
|
||||
return rsp;
|
||||
}
|
||||
if (rsp.isSuccessful()) {
|
||||
try (final ResponseBody responseBody = rsp.peekBody(ERRORS_PREFIX.length())) {
|
||||
if (ERRORS_PREFIX.equals(responseBody.string())) {
|
||||
try (final ResponseBody body = rsp.body()) {
|
||||
throw new IOException(body.string());
|
||||
}
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
// Log the error as debug (and therefore, "expected") or at error level
|
||||
if (suppressErrors) {
|
||||
Timber.d(e, "Suppressed (known / expected) error");
|
||||
} else {
|
||||
Timber.e(e);
|
||||
}
|
||||
}
|
||||
return rsp;
|
||||
}
|
||||
throw new HttpStatusException(rsp);
|
||||
}
|
||||
|
||||
private boolean isExcludedUrl(final Request request) {
|
||||
final String requestUrl = request.url().toString();
|
||||
for(final String url: DO_NOT_INTERCEPT) {
|
||||
if(requestUrl.contains(url)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private OkHttpConnectionFactory() {
|
||||
}
|
||||
|
||||
public static class HttpStatusException extends IOException {
|
||||
private final int code;
|
||||
private final String url;
|
||||
public HttpStatusException(@NonNull Response rsp) {
|
||||
this.code = rsp.code();
|
||||
this.url = rsp.request().url().uri().toString();
|
||||
try {
|
||||
if (rsp.body() != null && rsp.body().contentType() != null
|
||||
&& rsp.body().contentType().toString().contains("json")) {
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Log?
|
||||
}
|
||||
}
|
||||
|
||||
public int code() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
String str = "Code: " + code + ", URL: " + url;
|
||||
return str;
|
||||
}
|
||||
}
|
||||
}
|
||||
122
app/src/main/java/fr/free/nrw/commons/OkHttpConnectionFactory.kt
Normal file
122
app/src/main/java/fr/free/nrw/commons/OkHttpConnectionFactory.kt
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
package fr.free.nrw.commons
|
||||
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import fr.free.nrw.commons.wikidata.cookies.CommonsCookieJar
|
||||
import okhttp3.Cache
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
object OkHttpConnectionFactory {
|
||||
private const val CACHE_DIR_NAME = "okhttp-cache"
|
||||
private const val NET_CACHE_SIZE = (64 * 1024 * 1024).toLong()
|
||||
|
||||
@VisibleForTesting
|
||||
var CLIENT: OkHttpClient? = null
|
||||
|
||||
fun getClient(cookieJar: CommonsCookieJar): OkHttpClient {
|
||||
if (CLIENT == null) {
|
||||
CLIENT = createClient(cookieJar)
|
||||
}
|
||||
return CLIENT!!
|
||||
}
|
||||
|
||||
private fun createClient(cookieJar: CommonsCookieJar): OkHttpClient {
|
||||
return OkHttpClient.Builder()
|
||||
.cookieJar(cookieJar)
|
||||
.cache(
|
||||
if (CommonsApplication.instance != null) Cache(
|
||||
File(CommonsApplication.instance.cacheDir, CACHE_DIR_NAME),
|
||||
NET_CACHE_SIZE
|
||||
) else null
|
||||
)
|
||||
.connectTimeout(120, TimeUnit.SECONDS)
|
||||
.writeTimeout(120, TimeUnit.SECONDS)
|
||||
.readTimeout(120, TimeUnit.SECONDS)
|
||||
.addInterceptor(HttpLoggingInterceptor().apply {
|
||||
setLevel(HttpLoggingInterceptor.Level.BASIC)
|
||||
redactHeader("Authorization")
|
||||
redactHeader("Cookie")
|
||||
})
|
||||
.addInterceptor(UnsuccessfulResponseInterceptor())
|
||||
.addInterceptor(CommonHeaderRequestInterceptor())
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
private class CommonHeaderRequestInterceptor : Interceptor {
|
||||
@Throws(IOException::class)
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
val request = chain.request().newBuilder()
|
||||
.header("User-Agent", CommonsApplication.instance.userAgent)
|
||||
.build()
|
||||
return chain.proceed(request)
|
||||
}
|
||||
}
|
||||
|
||||
private const val SUPPRESS_ERROR_LOG = "x-commons-suppress-error-log"
|
||||
const val SUPPRESS_ERROR_LOG_HEADER: String = "$SUPPRESS_ERROR_LOG: true"
|
||||
|
||||
private class UnsuccessfulResponseInterceptor : Interceptor {
|
||||
@Throws(IOException::class)
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
val rq = chain.request()
|
||||
|
||||
// If the request contains our special "suppress errors" header, make note of it
|
||||
// but don't pass that on to the server.
|
||||
val suppressErrors = rq.headers.names().contains(SUPPRESS_ERROR_LOG)
|
||||
val request = rq.newBuilder()
|
||||
.removeHeader(SUPPRESS_ERROR_LOG)
|
||||
.build()
|
||||
|
||||
val rsp = chain.proceed(request)
|
||||
|
||||
// Do not intercept certain requests and let the caller handle the errors
|
||||
if (isExcludedUrl(chain.request())) {
|
||||
return rsp
|
||||
}
|
||||
if (rsp.isSuccessful) {
|
||||
try {
|
||||
rsp.peekBody(ERRORS_PREFIX.length.toLong()).use { responseBody ->
|
||||
if (ERRORS_PREFIX == responseBody.string()) {
|
||||
rsp.body.use { body ->
|
||||
throw IOException(body!!.string())
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
// Log the error as debug (and therefore, "expected") or at error level
|
||||
if (suppressErrors) {
|
||||
Timber.d(e, "Suppressed (known / expected) error")
|
||||
} else {
|
||||
Timber.e(e)
|
||||
}
|
||||
}
|
||||
return rsp
|
||||
}
|
||||
throw IOException("Unsuccessful response")
|
||||
}
|
||||
|
||||
private fun isExcludedUrl(request: Request): Boolean {
|
||||
val requestUrl = request.url.toString()
|
||||
for (url in DO_NOT_INTERCEPT) {
|
||||
if (requestUrl.contains(url)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
companion object {
|
||||
val DO_NOT_INTERCEPT = listOf(
|
||||
"api.php?format=json&formatversion=2&errorformat=plaintext&action=upload&ignorewarnings=1"
|
||||
)
|
||||
const val ERRORS_PREFIX = "{\"error"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
package fr.free.nrw.commons;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
public interface ViewHolder<T> {
|
||||
void bindModel(Context context, T model);
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
package fr.free.nrw.commons;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentPagerAdapter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This adapter will be used to display fragments in a ViewPager
|
||||
*/
|
||||
public class ViewPagerAdapter extends FragmentPagerAdapter {
|
||||
private List<Fragment> fragmentList = new ArrayList<>();
|
||||
private List<String> fragmentTitleList = new ArrayList<>();
|
||||
|
||||
public ViewPagerAdapter(FragmentManager manager) {
|
||||
super(manager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a ViewPagerAdapter with a specified Fragment Manager and Fragment resume behavior.
|
||||
*
|
||||
* @param manager The FragmentManager
|
||||
* @param behavior An integer which represents the behavior of non visible fragments. See
|
||||
* FragmentPagerAdapter.java for options.
|
||||
*/
|
||||
public ViewPagerAdapter(FragmentManager manager, int behavior) {
|
||||
super(manager, behavior);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the fragment of the viewpager at a particular position
|
||||
* @param position
|
||||
*/
|
||||
@Override
|
||||
public Fragment getItem(int position) {
|
||||
return fragmentList.get(position);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the total number of fragments in the viewpager.
|
||||
* @return size
|
||||
*/
|
||||
@Override
|
||||
public int getCount() {
|
||||
return fragmentList.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the fragment and title list in the viewpager
|
||||
* @param fragmentList List of all fragments to be displayed in the viewpager
|
||||
* @param fragmentTitleList List of all titles of the fragments
|
||||
*/
|
||||
public void setTabData(List<Fragment> fragmentList, List<String> fragmentTitleList) {
|
||||
this.fragmentList = fragmentList;
|
||||
this.fragmentTitleList = fragmentTitleList;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the title of the page at a particular position
|
||||
* @param position
|
||||
*/
|
||||
@Override
|
||||
public CharSequence getPageTitle(int position) {
|
||||
return fragmentTitleList.get(position);
|
||||
}
|
||||
}
|
||||
44
app/src/main/java/fr/free/nrw/commons/ViewPagerAdapter.kt
Normal file
44
app/src/main/java/fr/free/nrw/commons/ViewPagerAdapter.kt
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
package fr.free.nrw.commons
|
||||
|
||||
import android.content.Context
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.fragment.app.FragmentPagerAdapter
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
* This adapter will be used to display fragments in a ViewPager
|
||||
*/
|
||||
class ViewPagerAdapter : FragmentPagerAdapter {
|
||||
private val context: Context
|
||||
private var fragmentList: List<Fragment> = emptyList()
|
||||
private var fragmentTitleList: List<String> = emptyList()
|
||||
|
||||
constructor(context: Context, manager: FragmentManager) : super(manager) {
|
||||
this.context = context
|
||||
}
|
||||
|
||||
constructor(context: Context, manager: FragmentManager, behavior: Int) : super(manager, behavior) {
|
||||
this.context = context
|
||||
}
|
||||
|
||||
override fun getItem(position: Int): Fragment = fragmentList[position]
|
||||
|
||||
override fun getPageTitle(position: Int): CharSequence = fragmentTitleList[position]
|
||||
|
||||
override fun getCount(): Int = fragmentList.size
|
||||
|
||||
fun setTabs(vararg titlesToFragments: Pair<Int, Fragment>) {
|
||||
// Enforce that every title must come from strings.xml and all will consistently be uppercase
|
||||
fragmentTitleList = titlesToFragments.map {
|
||||
context.getString(it.first).uppercase(Locale.ROOT)
|
||||
}
|
||||
fragmentList = titlesToFragments.map { it.second }
|
||||
}
|
||||
|
||||
companion object {
|
||||
// Convenience method for Java callers, can be removed when everything is migrated
|
||||
@JvmStatic
|
||||
fun pairOf(first: Int, second: Fragment) = first to second
|
||||
}
|
||||
}
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
package fr.free.nrw.commons;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import fr.free.nrw.commons.databinding.ActivityWelcomeBinding;
|
||||
import fr.free.nrw.commons.databinding.PopupForCopyrightBinding;
|
||||
import fr.free.nrw.commons.quiz.QuizActivity;
|
||||
import fr.free.nrw.commons.theme.BaseActivity;
|
||||
import fr.free.nrw.commons.utils.ConfigUtils;
|
||||
|
||||
public class WelcomeActivity extends BaseActivity {
|
||||
|
||||
private ActivityWelcomeBinding binding;
|
||||
private PopupForCopyrightBinding copyrightBinding;
|
||||
|
||||
private final WelcomePagerAdapter adapter = new WelcomePagerAdapter();
|
||||
private boolean isQuiz;
|
||||
private AlertDialog.Builder dialogBuilder;
|
||||
private AlertDialog dialog;
|
||||
|
||||
/**
|
||||
* Initialises exiting fields and dependencies
|
||||
*
|
||||
* @param savedInstanceState WelcomeActivity bundled data
|
||||
*/
|
||||
@Override
|
||||
public void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
binding = ActivityWelcomeBinding.inflate(getLayoutInflater());
|
||||
final View view = binding.getRoot();
|
||||
setContentView(view);
|
||||
|
||||
if (getIntent() != null) {
|
||||
final Bundle bundle = getIntent().getExtras();
|
||||
if (bundle != null) {
|
||||
isQuiz = bundle.getBoolean("isQuiz");
|
||||
}
|
||||
} else {
|
||||
isQuiz = false;
|
||||
}
|
||||
|
||||
// Enable skip button if beta flavor
|
||||
if (ConfigUtils.isBetaFlavour()) {
|
||||
binding.finishTutorialButton.setVisibility(View.VISIBLE);
|
||||
|
||||
dialogBuilder = new AlertDialog.Builder(this);
|
||||
copyrightBinding = PopupForCopyrightBinding.inflate(getLayoutInflater());
|
||||
final View contactPopupView = copyrightBinding.getRoot();
|
||||
dialogBuilder.setView(contactPopupView);
|
||||
dialogBuilder.setCancelable(false);
|
||||
dialog = dialogBuilder.create();
|
||||
dialog.show();
|
||||
|
||||
copyrightBinding.buttonOk.setOnClickListener(v -> dialog.dismiss());
|
||||
}
|
||||
|
||||
binding.welcomePager.setAdapter(adapter);
|
||||
binding.welcomePagerIndicator.setViewPager(binding.welcomePager);
|
||||
|
||||
binding.finishTutorialButton.setOnClickListener(v -> finishTutorial());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* References WelcomePageAdapter to null before the activity is destroyed
|
||||
*/
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
if (isQuiz) {
|
||||
final Intent i = new Intent(this, QuizActivity.class);
|
||||
startActivity(i);
|
||||
}
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a way to change current activity to WelcomeActivity
|
||||
*
|
||||
* @param context Activity context
|
||||
*/
|
||||
public static void startYourself(final Context context) {
|
||||
final Intent welcomeIntent = new Intent(context, WelcomeActivity.class);
|
||||
context.startActivity(welcomeIntent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override onBackPressed() to go to previous tutorial 'pages' if not on first page
|
||||
*/
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (binding.welcomePager.getCurrentItem() != 0) {
|
||||
binding.welcomePager.setCurrentItem(binding.welcomePager.getCurrentItem() - 1, true);
|
||||
} else {
|
||||
if (defaultKvStore.getBoolean("firstrun", true)) {
|
||||
finishAffinity();
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void finishTutorial() {
|
||||
defaultKvStore.putBoolean("firstrun", false);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
78
app/src/main/java/fr/free/nrw/commons/WelcomeActivity.kt
Normal file
78
app/src/main/java/fr/free/nrw/commons/WelcomeActivity.kt
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
package fr.free.nrw.commons
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import fr.free.nrw.commons.databinding.ActivityWelcomeBinding
|
||||
import fr.free.nrw.commons.databinding.PopupForCopyrightBinding
|
||||
import fr.free.nrw.commons.quiz.QuizActivity
|
||||
import fr.free.nrw.commons.theme.BaseActivity
|
||||
import fr.free.nrw.commons.utils.ConfigUtils.isBetaFlavour
|
||||
|
||||
class WelcomeActivity : BaseActivity() {
|
||||
private var binding: ActivityWelcomeBinding? = null
|
||||
private var isQuiz = false
|
||||
|
||||
/**
|
||||
* Initialises exiting fields and dependencies
|
||||
*
|
||||
* @param savedInstanceState WelcomeActivity bundled data
|
||||
*/
|
||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityWelcomeBinding.inflate(layoutInflater)
|
||||
setContentView(binding!!.root)
|
||||
|
||||
isQuiz = intent?.extras?.getBoolean("isQuiz", false) ?: false
|
||||
|
||||
// Enable skip button if beta flavor
|
||||
if (isBetaFlavour) {
|
||||
binding!!.finishTutorialButton.visibility = View.VISIBLE
|
||||
|
||||
val copyrightBinding = PopupForCopyrightBinding.inflate(layoutInflater)
|
||||
|
||||
val dialog = AlertDialog.Builder(this)
|
||||
.setView(copyrightBinding.root)
|
||||
.setCancelable(false)
|
||||
.create()
|
||||
dialog.show()
|
||||
|
||||
copyrightBinding.buttonOk.setOnClickListener { v: View? -> dialog.dismiss() }
|
||||
}
|
||||
|
||||
val adapter = WelcomePagerAdapter()
|
||||
binding!!.welcomePager.adapter = adapter
|
||||
binding!!.welcomePagerIndicator.setViewPager(binding!!.welcomePager)
|
||||
binding!!.finishTutorialButton.setOnClickListener { v: View? -> finishTutorial() }
|
||||
}
|
||||
|
||||
public override fun onDestroy() {
|
||||
if (isQuiz) {
|
||||
startActivity(Intent(this, QuizActivity::class.java))
|
||||
}
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
if (binding!!.welcomePager.currentItem != 0) {
|
||||
binding!!.welcomePager.setCurrentItem(binding!!.welcomePager.currentItem - 1, true)
|
||||
} else {
|
||||
if (defaultKvStore.getBoolean("firstrun", true)) {
|
||||
finishAffinity()
|
||||
} else {
|
||||
super.onBackPressed()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun finishTutorial() {
|
||||
defaultKvStore.putBoolean("firstrun", false)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
fun Context.startWelcome() {
|
||||
startActivity(Intent(this, WelcomeActivity::class.java))
|
||||
}
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
package fr.free.nrw.commons;
|
||||
|
||||
import static fr.free.nrw.commons.utils.UrlUtilsKt.handleWebUrl;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.viewpager.widget.PagerAdapter;
|
||||
import fr.free.nrw.commons.utils.UnderlineUtils;
|
||||
|
||||
public class WelcomePagerAdapter extends PagerAdapter {
|
||||
private static final int[] PAGE_LAYOUTS = new int[]{
|
||||
R.layout.welcome_wikipedia,
|
||||
R.layout.welcome_do_upload,
|
||||
R.layout.welcome_dont_upload,
|
||||
R.layout.welcome_image_example,
|
||||
R.layout.welcome_final
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets total number of layouts
|
||||
* @return Number of layouts
|
||||
*/
|
||||
@Override
|
||||
public int getCount() {
|
||||
return PAGE_LAYOUTS.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares given view with provided object
|
||||
* @param view Adapter view
|
||||
* @param object Adapter object
|
||||
* @return Equality between view and object
|
||||
*/
|
||||
@Override
|
||||
public boolean isViewFromObject(View view, Object object) {
|
||||
return (view == object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object instantiateItem(ViewGroup container, int position) {
|
||||
LayoutInflater inflater = LayoutInflater.from(container.getContext());
|
||||
ViewGroup layout = (ViewGroup) inflater.inflate(PAGE_LAYOUTS[position], container, false);
|
||||
|
||||
// If final page
|
||||
if (position == PAGE_LAYOUTS.length - 1) {
|
||||
// Add link to more information
|
||||
TextView moreInfo = layout.findViewById(R.id.welcomeInfo);
|
||||
UnderlineUtils.setUnderlinedText(moreInfo, R.string.welcome_help_button_text);
|
||||
moreInfo.setOnClickListener(view -> handleWebUrl(
|
||||
container.getContext(),
|
||||
Uri.parse("https://commons.wikimedia.org/wiki/Help:Contents")
|
||||
));
|
||||
|
||||
// Handle click of finishTutorialButton ("YES!" button) inside layout
|
||||
layout.findViewById(R.id.finishTutorialButton)
|
||||
.setOnClickListener(view -> ((WelcomeActivity) container.getContext()).finishTutorial());
|
||||
}
|
||||
|
||||
container.addView(layout);
|
||||
return layout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a way to remove an item from container
|
||||
* @param container Adapter view group container
|
||||
* @param position Index of item
|
||||
* @param obj Adapter object
|
||||
*/
|
||||
@Override
|
||||
public void destroyItem(ViewGroup container, int position, Object obj) {
|
||||
container.removeView((View) obj);
|
||||
}
|
||||
}
|
||||
70
app/src/main/java/fr/free/nrw/commons/WelcomePagerAdapter.kt
Normal file
70
app/src/main/java/fr/free/nrw/commons/WelcomePagerAdapter.kt
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
package fr.free.nrw.commons
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.core.net.toUri
|
||||
import androidx.viewpager.widget.PagerAdapter
|
||||
import fr.free.nrw.commons.utils.UnderlineUtils.setUnderlinedText
|
||||
import fr.free.nrw.commons.utils.handleWebUrl
|
||||
|
||||
class WelcomePagerAdapter : PagerAdapter() {
|
||||
/**
|
||||
* Gets total number of layouts
|
||||
* @return Number of layouts
|
||||
*/
|
||||
override fun getCount(): Int = PAGE_LAYOUTS.size
|
||||
|
||||
/**
|
||||
* Compares given view with provided object
|
||||
* @param view Adapter view
|
||||
* @param obj Adapter object
|
||||
* @return Equality between view and object
|
||||
*/
|
||||
override fun isViewFromObject(view: View, obj: Any): Boolean = (view === obj)
|
||||
|
||||
/**
|
||||
* Provides a way to remove an item from container
|
||||
* @param container Adapter view group container
|
||||
* @param position Index of item
|
||||
* @param obj Adapter object
|
||||
*/
|
||||
override fun destroyItem(container: ViewGroup, position: Int, obj: Any) =
|
||||
container.removeView(obj as View)
|
||||
|
||||
override fun instantiateItem(container: ViewGroup, position: Int): Any {
|
||||
val inflater = LayoutInflater.from(container.context)
|
||||
val layout = inflater.inflate(PAGE_LAYOUTS[position], container, false) as ViewGroup
|
||||
|
||||
// If final page
|
||||
if (position == PAGE_LAYOUTS.size - 1) {
|
||||
// Add link to more information
|
||||
val moreInfo = layout.findViewById<TextView>(R.id.welcomeInfo)
|
||||
setUnderlinedText(moreInfo, R.string.welcome_help_button_text)
|
||||
moreInfo.setOnClickListener {
|
||||
handleWebUrl(
|
||||
container.context,
|
||||
"https://commons.wikimedia.org/wiki/Help:Contents".toUri()
|
||||
)
|
||||
}
|
||||
|
||||
// Handle click of finishTutorialButton ("YES!" button) inside layout
|
||||
layout.findViewById<View>(R.id.finishTutorialButton)
|
||||
.setOnClickListener { view: View? -> (container.context as WelcomeActivity).finishTutorial() }
|
||||
}
|
||||
|
||||
container.addView(layout)
|
||||
return layout
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val PAGE_LAYOUTS = intArrayOf(
|
||||
R.layout.welcome_wikipedia,
|
||||
R.layout.welcome_do_upload,
|
||||
R.layout.welcome_dont_upload,
|
||||
R.layout.welcome_image_example,
|
||||
R.layout.welcome_final
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -59,7 +59,7 @@ class CategoryDetailsActivity : BaseActivity(),
|
|||
val view = binding.root
|
||||
setContentView(view)
|
||||
supportFragmentManager = getSupportFragmentManager()
|
||||
viewPagerAdapter = ViewPagerAdapter(supportFragmentManager)
|
||||
viewPagerAdapter = ViewPagerAdapter(this, supportFragmentManager)
|
||||
binding.viewPager.adapter = viewPagerAdapter
|
||||
binding.viewPager.offscreenPageLimit = 2
|
||||
binding.tabLayout.setupWithViewPager(binding.viewPager)
|
||||
|
|
@ -83,8 +83,6 @@ class CategoryDetailsActivity : BaseActivity(),
|
|||
* Set the fragments according to the tab selected in the viewPager.
|
||||
*/
|
||||
private fun setTabs() {
|
||||
val fragmentList = mutableListOf<Fragment>()
|
||||
val titleList = mutableListOf<String>()
|
||||
categoriesMediaFragment = CategoriesMediaFragment()
|
||||
val subCategoryListFragment = SubCategoriesFragment()
|
||||
val parentCategoriesFragment = ParentCategoriesFragment()
|
||||
|
|
@ -99,13 +97,12 @@ class CategoryDetailsActivity : BaseActivity(),
|
|||
|
||||
viewModel.onCheckIfBookmarked(categoryName!!)
|
||||
}
|
||||
fragmentList.add(categoriesMediaFragment)
|
||||
titleList.add("MEDIA")
|
||||
fragmentList.add(subCategoryListFragment)
|
||||
titleList.add("SUBCATEGORIES")
|
||||
fragmentList.add(parentCategoriesFragment)
|
||||
titleList.add("PARENT CATEGORIES")
|
||||
viewPagerAdapter.setTabData(fragmentList, titleList)
|
||||
|
||||
viewPagerAdapter.setTabs(
|
||||
R.string.title_for_media to categoriesMediaFragment,
|
||||
R.string.title_for_subcategories to subCategoryListFragment,
|
||||
R.string.title_for_parent_categories to parentCategoriesFragment
|
||||
)
|
||||
viewPagerAdapter.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import androidx.fragment.app.FragmentManager
|
|||
import androidx.work.ExistingWorkPolicy
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
import fr.free.nrw.commons.R
|
||||
import fr.free.nrw.commons.WelcomeActivity
|
||||
import fr.free.nrw.commons.auth.SessionManager
|
||||
import fr.free.nrw.commons.bookmarks.BookmarkFragment
|
||||
import fr.free.nrw.commons.contributions.ContributionsFragment.Companion.newInstance
|
||||
|
|
@ -33,6 +32,7 @@ import fr.free.nrw.commons.notification.NotificationActivity.Companion.startYour
|
|||
import fr.free.nrw.commons.notification.NotificationController
|
||||
import fr.free.nrw.commons.quiz.QuizChecker
|
||||
import fr.free.nrw.commons.settings.SettingsFragment
|
||||
import fr.free.nrw.commons.startWelcome
|
||||
import fr.free.nrw.commons.theme.BaseActivity
|
||||
import fr.free.nrw.commons.upload.UploadProgressActivity
|
||||
import fr.free.nrw.commons.upload.worker.WorkRequestHelper.Companion.makeOneTimeWorkRequest
|
||||
|
|
@ -517,7 +517,7 @@ after opening the app.
|
|||
(!applicationKvStore!!.getBoolean("login_skipped"))
|
||||
) {
|
||||
defaultKvStore.putBoolean("inAppCameraFirstRun", true)
|
||||
WelcomeActivity.startYourself(this)
|
||||
startWelcome()
|
||||
}
|
||||
|
||||
retryAllFailedUploads()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package fr.free.nrw.commons.explore;
|
||||
|
||||
import static androidx.viewpager.widget.ViewPager.SCROLL_STATE_IDLE;
|
||||
import static fr.free.nrw.commons.ViewPagerAdapter.pairOf;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
|
|
@ -23,10 +24,12 @@ import fr.free.nrw.commons.kvstore.JsonKvStore;
|
|||
import fr.free.nrw.commons.theme.BaseActivity;
|
||||
import fr.free.nrw.commons.utils.ActivityUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import kotlin.Pair;
|
||||
|
||||
public class ExploreFragment extends CommonsDaggerSupportFragment {
|
||||
|
||||
|
|
@ -70,7 +73,7 @@ public class ExploreFragment extends CommonsDaggerSupportFragment {
|
|||
loadNearbyMapData();
|
||||
binding = FragmentExploreBinding.inflate(inflater, container, false);
|
||||
|
||||
viewPagerAdapter = new ViewPagerAdapter(getChildFragmentManager(),
|
||||
viewPagerAdapter = new ViewPagerAdapter(requireContext(), getChildFragmentManager(),
|
||||
FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
|
||||
|
||||
binding.viewPager.setAdapter(viewPagerAdapter);
|
||||
|
|
@ -111,9 +114,6 @@ public class ExploreFragment extends CommonsDaggerSupportFragment {
|
|||
* Sets the titles in the tabLayout and fragments in the viewPager
|
||||
*/
|
||||
public void setTabs() {
|
||||
List<Fragment> fragmentList = new ArrayList<>();
|
||||
List<String> titleList = new ArrayList<>();
|
||||
|
||||
Bundle featuredArguments = new Bundle();
|
||||
featuredArguments.putString("categoryName", FEATURED_IMAGES_CATEGORY);
|
||||
|
||||
|
|
@ -133,19 +133,15 @@ public class ExploreFragment extends CommonsDaggerSupportFragment {
|
|||
featuredRootFragment = new ExploreListRootFragment(featuredArguments);
|
||||
mobileRootFragment = new ExploreListRootFragment(mobileArguments);
|
||||
mapRootFragment = new ExploreMapRootFragment(mapArguments);
|
||||
fragmentList.add(featuredRootFragment);
|
||||
titleList.add(getString(R.string.explore_tab_title_featured).toUpperCase(Locale.ROOT));
|
||||
|
||||
fragmentList.add(mobileRootFragment);
|
||||
titleList.add(getString(R.string.explore_tab_title_mobile).toUpperCase(Locale.ROOT));
|
||||
|
||||
fragmentList.add(mapRootFragment);
|
||||
titleList.add(getString(R.string.explore_tab_title_map).toUpperCase(Locale.ROOT));
|
||||
|
||||
((MainActivity) getActivity()).showTabs();
|
||||
((BaseActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(false);
|
||||
|
||||
viewPagerAdapter.setTabData(fragmentList, titleList);
|
||||
viewPagerAdapter.setTabs(
|
||||
pairOf(R.string.explore_tab_title_featured, featuredRootFragment),
|
||||
pairOf(R.string.explore_tab_title_mobile, mobileRootFragment),
|
||||
pairOf(R.string.explore_tab_title_map, mapRootFragment)
|
||||
);
|
||||
viewPagerAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package fr.free.nrw.commons.explore;
|
||||
|
||||
import static fr.free.nrw.commons.ViewPagerAdapter.pairOf;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
|
|
@ -26,11 +28,13 @@ import fr.free.nrw.commons.utils.FragmentUtils;
|
|||
import fr.free.nrw.commons.utils.ViewUtil;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.inject.Inject;
|
||||
import kotlin.Pair;
|
||||
import timber.log.Timber;
|
||||
|
||||
/**
|
||||
|
|
@ -65,7 +69,7 @@ public class SearchActivity extends BaseActivity
|
|||
binding.toolbarSearch.setNavigationOnClickListener(v->onBackPressed());
|
||||
supportFragmentManager = getSupportFragmentManager();
|
||||
setSearchHistoryFragment();
|
||||
viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
|
||||
viewPagerAdapter = new ViewPagerAdapter(this, getSupportFragmentManager());
|
||||
binding.viewPager.setAdapter(viewPagerAdapter);
|
||||
binding.viewPager.setOffscreenPageLimit(2); // Because we want all the fragments to be alive
|
||||
binding.tabLayout.setupWithViewPager(binding.viewPager);
|
||||
|
|
@ -90,19 +94,15 @@ public class SearchActivity extends BaseActivity
|
|||
* Sets the titles in the tabLayout and fragments in the viewPager
|
||||
*/
|
||||
public void setTabs() {
|
||||
List<Fragment> fragmentList = new ArrayList<>();
|
||||
List<String> titleList = new ArrayList<>();
|
||||
searchMediaFragment = new SearchMediaFragment();
|
||||
searchDepictionsFragment = new SearchDepictionsFragment();
|
||||
searchCategoryFragment= new SearchCategoryFragment();
|
||||
fragmentList.add(searchMediaFragment);
|
||||
titleList.add(getResources().getString(R.string.search_tab_title_media).toUpperCase(Locale.ROOT));
|
||||
fragmentList.add(searchCategoryFragment);
|
||||
titleList.add(getResources().getString(R.string.search_tab_title_categories).toUpperCase(Locale.ROOT));
|
||||
fragmentList.add(searchDepictionsFragment);
|
||||
titleList.add(getResources().getString(R.string.search_tab_title_depictions).toUpperCase(Locale.ROOT));
|
||||
|
||||
viewPagerAdapter.setTabData(fragmentList, titleList);
|
||||
viewPagerAdapter.setTabs(
|
||||
pairOf(R.string.search_tab_title_media, searchMediaFragment),
|
||||
pairOf(R.string.search_tab_title_categories, searchCategoryFragment),
|
||||
pairOf(R.string.search_tab_title_depictions, searchDepictionsFragment)
|
||||
);
|
||||
viewPagerAdapter.notifyDataSetChanged();
|
||||
getCompositeDisposable().add(RxSearchView.queryTextChanges(binding.searchBox)
|
||||
.takeUntil(RxView.detaches(binding.searchBox))
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package fr.free.nrw.commons.explore.depictions;
|
||||
|
||||
import static fr.free.nrw.commons.ViewPagerAdapter.pairOf;
|
||||
import static fr.free.nrw.commons.utils.UrlUtilsKt.handleWebUrl;
|
||||
|
||||
import android.content.Context;
|
||||
|
|
@ -31,8 +32,10 @@ import io.reactivex.android.schedulers.AndroidSchedulers;
|
|||
import io.reactivex.disposables.CompositeDisposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import kotlin.Pair;
|
||||
|
||||
/**
|
||||
* Activity to show depiction media, parent classes and child classes of depicted items in Explore
|
||||
|
|
@ -66,7 +69,7 @@ public class WikidataItemDetailsActivity extends BaseActivity implements MediaDe
|
|||
setContentView(binding.getRoot());
|
||||
compositeDisposable = new CompositeDisposable();
|
||||
supportFragmentManager = getSupportFragmentManager();
|
||||
viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
|
||||
viewPagerAdapter = new ViewPagerAdapter(this, getSupportFragmentManager());
|
||||
binding.viewPager.setAdapter(viewPagerAdapter);
|
||||
binding.viewPager.setOffscreenPageLimit(2);
|
||||
binding.tabLayout.setupWithViewPager(binding.viewPager);
|
||||
|
|
@ -105,8 +108,6 @@ public class WikidataItemDetailsActivity extends BaseActivity implements MediaDe
|
|||
* Set the fragments according to the tab selected in the viewPager.
|
||||
*/
|
||||
private void setTabs() {
|
||||
List<Fragment> fragmentList = new ArrayList<>();
|
||||
List<String> titleList = new ArrayList<>();
|
||||
depictionImagesListFragment = new DepictedImagesFragment();
|
||||
ChildDepictionsFragment childDepictionsFragment = new ChildDepictionsFragment();
|
||||
ParentDepictionsFragment parentDepictionsFragment = new ParentDepictionsFragment();
|
||||
|
|
@ -120,13 +121,12 @@ public class WikidataItemDetailsActivity extends BaseActivity implements MediaDe
|
|||
parentDepictionsFragment.setArguments(arguments);
|
||||
childDepictionsFragment.setArguments(arguments);
|
||||
}
|
||||
fragmentList.add(depictionImagesListFragment);
|
||||
titleList.add(getResources().getString(R.string.title_for_media));
|
||||
fragmentList.add(childDepictionsFragment);
|
||||
titleList.add(getResources().getString(R.string.title_for_child_classes));
|
||||
fragmentList.add(parentDepictionsFragment);
|
||||
titleList.add(getResources().getString(R.string.title_for_parent_classes));
|
||||
viewPagerAdapter.setTabData(fragmentList, titleList);
|
||||
|
||||
viewPagerAdapter.setTabs(
|
||||
pairOf(R.string.title_for_media, depictionImagesListFragment),
|
||||
pairOf(R.string.title_for_subcategories, childDepictionsFragment),
|
||||
pairOf(R.string.title_for_parent_categories, parentDepictionsFragment)
|
||||
);
|
||||
binding.viewPager.setOffscreenPageLimit(2);
|
||||
viewPagerAdapter.notifyDataSetChanged();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
package fr.free.nrw.commons.explore.map;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import fr.free.nrw.commons.Media;
|
||||
import fr.free.nrw.commons.location.LatLng;
|
||||
import fr.free.nrw.commons.media.MediaClient;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
|
@ -23,6 +25,7 @@ public class ExploreMapCalls {
|
|||
* @param currentLatLng coordinates of search location
|
||||
* @return list of places obtained
|
||||
*/
|
||||
@NonNull
|
||||
List<Media> callCommonsQuery(final LatLng currentLatLng) {
|
||||
String coordinates = currentLatLng.getLatitude() + "|" + currentLatLng.getLongitude();
|
||||
return mediaClient.getMediaListFromGeoSearch(coordinates).blockingGet();
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import fr.free.nrw.commons.explore.map.ExploreMapController.NearbyBaseMarkerThum
|
|||
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
||||
import fr.free.nrw.commons.location.LatLng;
|
||||
import fr.free.nrw.commons.location.LocationServiceManager.LocationChangeType;
|
||||
import fr.free.nrw.commons.nearby.Place;
|
||||
import io.reactivex.Observable;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.List;
|
||||
|
|
@ -182,7 +183,7 @@ public class ExploreMapPresenter
|
|||
exploreMapController
|
||||
.loadAttractionsFromLocationToBaseMarkerOptions(explorePlacesInfo.currentLatLng,
|
||||
// Curlatlang will be used to calculate distances
|
||||
explorePlacesInfo.explorePlaceList,
|
||||
(List<Place>) explorePlacesInfo.explorePlaceList,
|
||||
exploreMapFragmentView.getContext(),
|
||||
this,
|
||||
explorePlacesInfo);
|
||||
|
|
@ -230,11 +231,7 @@ public class ExploreMapPresenter
|
|||
mylocation.setLongitude(exploreMapFragmentView.getLastMapFocus().getLongitude());
|
||||
Float distance = mylocation.distanceTo(dest_location);
|
||||
|
||||
if (distance > 2000.0 * 3 / 4) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
return !(distance > 2000.0 * 3 / 4);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package fr.free.nrw.commons.media
|
||||
|
||||
import fr.free.nrw.commons.OkHttpConnectionFactory.UnsuccessfulResponseInterceptor.SUPPRESS_ERROR_LOG_HEADER
|
||||
import fr.free.nrw.commons.SUPPRESS_ERROR_LOG_HEADER
|
||||
import fr.free.nrw.commons.wikidata.mwapi.MwQueryResponse
|
||||
import io.reactivex.Single
|
||||
import retrofit2.http.GET
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ import fr.free.nrw.commons.BuildConfig
|
|||
import fr.free.nrw.commons.CommonsApplication
|
||||
import fr.free.nrw.commons.CommonsApplication.ActivityLogoutListener
|
||||
import fr.free.nrw.commons.R
|
||||
import fr.free.nrw.commons.WelcomeActivity
|
||||
import fr.free.nrw.commons.actions.PageEditClient
|
||||
import fr.free.nrw.commons.databinding.FragmentMoreBottomSheetBinding
|
||||
import fr.free.nrw.commons.di.ApplicationlessInjection
|
||||
|
|
@ -32,6 +31,7 @@ import fr.free.nrw.commons.logging.CommonsLogSender
|
|||
import fr.free.nrw.commons.profile.ProfileActivity
|
||||
import fr.free.nrw.commons.review.ReviewActivity
|
||||
import fr.free.nrw.commons.settings.SettingsActivity
|
||||
import fr.free.nrw.commons.startWelcome
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
|
|
@ -241,7 +241,7 @@ class MoreBottomSheetFragment : BottomSheetDialogFragment() {
|
|||
}
|
||||
|
||||
fun onTutorialClicked() {
|
||||
WelcomeActivity.startYourself(requireActivity())
|
||||
requireContext().startWelcome()
|
||||
}
|
||||
|
||||
fun onSettingsClicked() {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
package fr.free.nrw.commons.nearby;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
|
||||
import android.location.Location;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import fr.free.nrw.commons.nearby.model.NearbyQueryParams;
|
||||
import fr.free.nrw.commons.nearby.model.NearbyQueryParams.Radial;
|
||||
import fr.free.nrw.commons.nearby.model.NearbyQueryParams.Rectangular;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
|
@ -46,13 +50,14 @@ public class NearbyPlaces {
|
|||
* @param customQuery
|
||||
* @return list of places obtained
|
||||
*/
|
||||
@NonNull
|
||||
List<Place> radiusExpander(final LatLng currentLatLng, final String lang,
|
||||
final boolean returnClosestResult, @Nullable final String customQuery) throws Exception {
|
||||
|
||||
final int minResults;
|
||||
final double maxRadius;
|
||||
|
||||
List<Place> places = Collections.emptyList();
|
||||
List<Place> places = emptyList();
|
||||
|
||||
// If returnClosestResult is true, then this means that we are trying to get closest point
|
||||
// to use in cardView in Contributions fragment
|
||||
|
|
@ -113,6 +118,7 @@ public class NearbyPlaces {
|
|||
* @return A list of places obtained from the Wikidata query.
|
||||
* @throws Exception If an error occurs during the retrieval process.
|
||||
*/
|
||||
@NonNull
|
||||
public List<Place> getFromWikidataQuery(
|
||||
final fr.free.nrw.commons.location.LatLng centerPoint,
|
||||
final fr.free.nrw.commons.location.LatLng screenTopRight,
|
||||
|
|
@ -120,11 +126,11 @@ public class NearbyPlaces {
|
|||
final boolean shouldQueryForMonuments,
|
||||
@Nullable final String customQuery) throws Exception {
|
||||
if (customQuery != null) {
|
||||
return okHttpJsonApiClient
|
||||
.getNearbyPlaces(
|
||||
new NearbyQueryParams.Rectangular(screenTopRight, screenBottomLeft), lang,
|
||||
final List<Place> nearbyPlaces = okHttpJsonApiClient.getNearbyPlaces(
|
||||
new Rectangular(screenTopRight, screenBottomLeft), lang,
|
||||
shouldQueryForMonuments,
|
||||
customQuery);
|
||||
return nearbyPlaces != null ? nearbyPlaces : emptyList();
|
||||
}
|
||||
|
||||
final int lowerLimit = 1000, upperLimit = 1500;
|
||||
|
|
@ -141,9 +147,10 @@ public class NearbyPlaces {
|
|||
final int itemCount = okHttpJsonApiClient.getNearbyItemCount(
|
||||
new NearbyQueryParams.Rectangular(screenTopRight, screenBottomLeft));
|
||||
if (itemCount < upperLimit) {
|
||||
return okHttpJsonApiClient.getNearbyPlaces(
|
||||
new NearbyQueryParams.Rectangular(screenTopRight, screenBottomLeft), lang,
|
||||
final List<Place> nearbyPlaces = okHttpJsonApiClient.getNearbyPlaces(
|
||||
new Rectangular(screenTopRight, screenBottomLeft), lang,
|
||||
shouldQueryForMonuments, null);
|
||||
return nearbyPlaces != null ? nearbyPlaces : emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -175,9 +182,10 @@ public class NearbyPlaces {
|
|||
maxRadius = targetRadius - 1;
|
||||
}
|
||||
}
|
||||
return okHttpJsonApiClient.getNearbyPlaces(
|
||||
new NearbyQueryParams.Radial(centerPoint, targetRadius / 100f), lang, shouldQueryForMonuments,
|
||||
final List<Place> nearbyPlaces = okHttpJsonApiClient.getNearbyPlaces(
|
||||
new Radial(centerPoint, targetRadius / 100f), lang, shouldQueryForMonuments,
|
||||
null);
|
||||
return nearbyPlaces != null ? nearbyPlaces : emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import android.view.View
|
|||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.fragment.app.Fragment
|
||||
import fr.free.nrw.commons.R
|
||||
import fr.free.nrw.commons.ViewPagerAdapter
|
||||
|
|
@ -71,7 +72,7 @@ class ProfileActivity : BaseActivity() {
|
|||
title = userName
|
||||
shouldShowContributions = intent.getBooleanExtra(KEY_SHOULD_SHOW_CONTRIBUTIONS, false)
|
||||
|
||||
viewPagerAdapter = ViewPagerAdapter(supportFragmentManager)
|
||||
viewPagerAdapter = ViewPagerAdapter(this, supportFragmentManager)
|
||||
binding.viewPager.adapter = viewPagerAdapter
|
||||
binding.tabLayout.setupWithViewPager(binding.viewPager)
|
||||
setTabs()
|
||||
|
|
@ -83,39 +84,23 @@ class ProfileActivity : BaseActivity() {
|
|||
}
|
||||
|
||||
private fun setTabs() {
|
||||
val fragmentList = mutableListOf<Fragment>()
|
||||
val titleList = mutableListOf<String>()
|
||||
|
||||
// Add Achievements tab
|
||||
achievementsFragment = AchievementsFragment().apply {
|
||||
arguments = Bundle().apply {
|
||||
putString(KEY_USERNAME, userName)
|
||||
}
|
||||
arguments = bundleOf(KEY_USERNAME to userName)
|
||||
}
|
||||
fragmentList.add(achievementsFragment)
|
||||
titleList.add(resources.getString(R.string.achievements_tab_title).uppercase())
|
||||
|
||||
// Add Leaderboard tab
|
||||
leaderboardFragment = LeaderboardFragment().apply {
|
||||
arguments = Bundle().apply {
|
||||
putString(KEY_USERNAME, userName)
|
||||
}
|
||||
arguments = bundleOf(KEY_USERNAME to userName)
|
||||
}
|
||||
fragmentList.add(leaderboardFragment)
|
||||
titleList.add(resources.getString(R.string.leaderboard_tab_title).uppercase(Locale.ROOT))
|
||||
|
||||
// Add Contributions tab
|
||||
contributionsFragment = ContributionsFragment().apply {
|
||||
arguments = Bundle().apply {
|
||||
putString(KEY_USERNAME, userName)
|
||||
}
|
||||
}
|
||||
contributionsFragment?.let {
|
||||
fragmentList.add(it)
|
||||
titleList.add(getString(R.string.contributions_fragment).uppercase(Locale.ROOT))
|
||||
arguments = bundleOf(KEY_USERNAME to userName)
|
||||
}
|
||||
|
||||
viewPagerAdapter.setTabData(fragmentList, titleList)
|
||||
viewPagerAdapter.setTabs(
|
||||
R.string.achievements_tab_title to achievementsFragment,
|
||||
R.string.leaderboard_tab_title to leaderboardFragment,
|
||||
R.string.contributions_fragment to contributionsFragment!!
|
||||
)
|
||||
viewPagerAdapter.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,6 @@ class UploadProgressActivity : BaseActivity() {
|
|||
@Inject
|
||||
lateinit var contributionDao: ContributionDao
|
||||
|
||||
val fragmentList: MutableList<Fragment> = ArrayList()
|
||||
val titleList: MutableList<String> = ArrayList()
|
||||
var isPaused = true
|
||||
var isPendingIconsVisible = true
|
||||
var isErrorIconsVisisble = false
|
||||
|
|
@ -38,7 +36,7 @@ class UploadProgressActivity : BaseActivity() {
|
|||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityUploadProgressBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
viewPagerAdapter = ViewPagerAdapter(supportFragmentManager)
|
||||
viewPagerAdapter = ViewPagerAdapter(this, supportFragmentManager)
|
||||
binding.uploadProgressViewPager.setAdapter(viewPagerAdapter)
|
||||
binding.uploadProgressViewPager.setId(R.id.upload_progress_view_pager)
|
||||
binding.uploadProgressTabLayout.setupWithViewPager(binding.uploadProgressViewPager)
|
||||
|
|
@ -81,11 +79,10 @@ class UploadProgressActivity : BaseActivity() {
|
|||
pendingUploadsFragment = PendingUploadsFragment()
|
||||
failedUploadsFragment = FailedUploadsFragment()
|
||||
|
||||
fragmentList.add(pendingUploadsFragment!!)
|
||||
titleList.add(getString(R.string.pending))
|
||||
fragmentList.add(failedUploadsFragment!!)
|
||||
titleList.add(getString(R.string.failed))
|
||||
viewPagerAdapter!!.setTabData(fragmentList, titleList)
|
||||
viewPagerAdapter!!.setTabs(
|
||||
R.string.pending to pendingUploadsFragment!!,
|
||||
R.string.failed to failedUploadsFragment!!
|
||||
)
|
||||
viewPagerAdapter!!.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -617,6 +617,8 @@ Upload your first media by tapping on the add button.</string>
|
|||
<string name="title_for_media">MEDIA</string>
|
||||
<string name="title_for_child_classes">CHILD CLASSES</string>
|
||||
<string name="title_for_parent_classes">PARENT CLASSES</string>
|
||||
<string name="title_for_subcategories">SUBCATEGORIES</string>
|
||||
<string name="title_for_parent_categories">PARENT CATEGORIES</string>
|
||||
|
||||
<string name="upload_nearby_place_found_title">Nearby Place Found</string>
|
||||
<string name="upload_nearby_place_found_description_plural">Are these pictures of %1$s?</string>
|
||||
|
|
|
|||
|
|
@ -1,110 +0,0 @@
|
|||
package fr.free.nrw.commons;
|
||||
|
||||
import static fr.free.nrw.commons.TestConnectionFactoryKt.createTestClient;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.AbstractExecutorService;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import okhttp3.Dispatcher;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.mockwebserver.MockResponse;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import fr.free.nrw.commons.wikidata.GsonUtil;
|
||||
import retrofit2.Retrofit;
|
||||
import retrofit2.converter.gson.GsonConverterFactory;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public abstract class MockWebServerTest {
|
||||
private OkHttpClient okHttpClient;
|
||||
private final TestWebServer server = new TestWebServer();
|
||||
|
||||
@Before public void setUp() throws Throwable {
|
||||
OkHttpConnectionFactory.CLIENT = createTestClient();
|
||||
okHttpClient = OkHttpConnectionFactory.CLIENT.newBuilder()
|
||||
.dispatcher(new Dispatcher(new ImmediateExecutorService())).build();
|
||||
server.setUp();
|
||||
}
|
||||
|
||||
@After public void tearDown() throws Throwable {
|
||||
server.tearDown();
|
||||
}
|
||||
|
||||
@NonNull protected TestWebServer server() {
|
||||
return server;
|
||||
}
|
||||
|
||||
protected void enqueueFromFile(@NonNull String filename) throws Throwable {
|
||||
String json = TestFileUtil.readRawFile(filename);
|
||||
server.enqueue(json);
|
||||
}
|
||||
|
||||
protected void enqueue404() {
|
||||
final int code = 404;
|
||||
server.enqueue(new MockResponse().setResponseCode(code).setBody("Not Found"));
|
||||
}
|
||||
|
||||
protected void enqueueMalformed() {
|
||||
server.enqueue("(╯°□°)╯︵ ┻━┻");
|
||||
}
|
||||
|
||||
protected void enqueueEmptyJson() {
|
||||
server.enqueue(new MockResponse().setBody("{}"));
|
||||
}
|
||||
|
||||
@NonNull protected OkHttpClient okHttpClient() {
|
||||
return okHttpClient;
|
||||
}
|
||||
|
||||
@NonNull protected <T> T service(Class<T> clazz) {
|
||||
return service(clazz, server().getUrl());
|
||||
}
|
||||
|
||||
@NonNull protected <T> T service(Class<T> clazz, @NonNull String url) {
|
||||
return new Retrofit.Builder()
|
||||
.baseUrl(url)
|
||||
.callbackExecutor(new ImmediateExecutor())
|
||||
.client(okHttpClient)
|
||||
.addConverterFactory(GsonConverterFactory.create(GsonUtil.INSTANCE.getDefaultGson()))
|
||||
.build()
|
||||
.create(clazz);
|
||||
}
|
||||
|
||||
public final class ImmediateExecutorService extends AbstractExecutorService {
|
||||
@Override public void shutdown() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@NonNull @Override public List<Runnable> shutdownNow() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override public boolean isShutdown() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override public boolean isTerminated() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override public boolean awaitTermination(long l, @NonNull TimeUnit timeUnit)
|
||||
throws InterruptedException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override public void execute(@NonNull Runnable runnable) {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
public class ImmediateExecutor implements Executor {
|
||||
@Override
|
||||
public void execute(@NonNull Runnable runnable) {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
110
app/src/test/kotlin/fr/free/nrw/commons/MockWebServerTest.kt
Normal file
110
app/src/test/kotlin/fr/free/nrw/commons/MockWebServerTest.kt
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
package fr.free.nrw.commons
|
||||
|
||||
import fr.free.nrw.commons.wikidata.GsonUtil.defaultGson
|
||||
import okhttp3.Dispatcher
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.mockwebserver.MockResponse
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
import java.util.concurrent.AbstractExecutorService
|
||||
import java.util.concurrent.Executor
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
abstract class MockWebServerTest {
|
||||
private var okHttpClient: OkHttpClient? = null
|
||||
private val server = TestWebServer()
|
||||
|
||||
@Before
|
||||
@Throws(Throwable::class)
|
||||
open fun setUp() {
|
||||
OkHttpConnectionFactory.CLIENT = createTestClient()
|
||||
okHttpClient = OkHttpConnectionFactory.CLIENT!!.newBuilder()
|
||||
.dispatcher(Dispatcher(ImmediateExecutorService())).build()
|
||||
server.setUp()
|
||||
}
|
||||
|
||||
@After
|
||||
@Throws(Throwable::class)
|
||||
fun tearDown() {
|
||||
server.tearDown()
|
||||
}
|
||||
|
||||
protected fun server(): TestWebServer {
|
||||
return server
|
||||
}
|
||||
|
||||
@Throws(Throwable::class)
|
||||
protected fun enqueueFromFile(filename: String) {
|
||||
val json = TestFileUtil.readRawFile(filename)
|
||||
server.enqueue(json)
|
||||
}
|
||||
|
||||
protected fun enqueue404() {
|
||||
val code = 404
|
||||
server.enqueue(MockResponse().setResponseCode(code).setBody("Not Found"))
|
||||
}
|
||||
|
||||
protected fun enqueueMalformed() {
|
||||
server.enqueue("(╯°□°)╯︵ ┻━┻")
|
||||
}
|
||||
|
||||
protected fun enqueueEmptyJson() {
|
||||
server.enqueue(MockResponse().setBody("{}"))
|
||||
}
|
||||
|
||||
protected fun okHttpClient(): OkHttpClient {
|
||||
return okHttpClient!!
|
||||
}
|
||||
|
||||
protected fun <T> service(clazz: Class<T>): T {
|
||||
return service(clazz, server().url)
|
||||
}
|
||||
|
||||
protected fun <T> service(clazz: Class<T>, url: String): T {
|
||||
return Retrofit.Builder()
|
||||
.baseUrl(url)
|
||||
.callbackExecutor(ImmediateExecutor())
|
||||
.client(okHttpClient)
|
||||
.addConverterFactory(GsonConverterFactory.create(defaultGson))
|
||||
.build()
|
||||
.create(clazz)
|
||||
}
|
||||
|
||||
inner class ImmediateExecutorService : AbstractExecutorService() {
|
||||
override fun shutdown() {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
override fun shutdownNow(): List<Runnable> {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
override fun isShutdown(): Boolean {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
override fun isTerminated(): Boolean {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
@Throws(InterruptedException::class)
|
||||
override fun awaitTermination(l: Long, timeUnit: TimeUnit): Boolean {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
override fun execute(runnable: Runnable) {
|
||||
runnable.run()
|
||||
}
|
||||
}
|
||||
|
||||
inner class ImmediateExecutor : Executor {
|
||||
override fun execute(runnable: Runnable) {
|
||||
runnable.run()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
package fr.free.nrw.commons
|
||||
|
||||
import fr.free.nrw.commons.OkHttpConnectionFactory.HttpStatusException
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Response
|
||||
|
|
@ -39,6 +38,6 @@ private class UnsuccessfulResponseInterceptor : Interceptor {
|
|||
if (rsp.isSuccessful) {
|
||||
return rsp
|
||||
}
|
||||
throw HttpStatusException(rsp)
|
||||
throw IOException("Unsuccessful response")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package fr.free.nrw.commons.auth.csrf
|
|||
|
||||
import com.google.gson.stream.MalformedJsonException
|
||||
import fr.free.nrw.commons.MockWebServerTest
|
||||
import fr.free.nrw.commons.OkHttpConnectionFactory.HttpStatusException
|
||||
import fr.free.nrw.commons.auth.SessionManager
|
||||
import fr.free.nrw.commons.auth.login.LoginClient
|
||||
import fr.free.nrw.commons.wikidata.mwapi.MwException
|
||||
|
|
@ -13,6 +12,7 @@ import org.mockito.ArgumentMatchers.isA
|
|||
import org.mockito.Mockito.mock
|
||||
import org.mockito.Mockito.never
|
||||
import org.mockito.Mockito.verify
|
||||
import java.io.IOException
|
||||
|
||||
class CsrfTokenClientTest : MockWebServerTest() {
|
||||
private val cb = mock(CsrfTokenClient.Callback::class.java)
|
||||
|
|
@ -53,7 +53,7 @@ class CsrfTokenClientTest : MockWebServerTest() {
|
|||
performRequest()
|
||||
|
||||
verify(cb, never()).success(any(String::class.java))
|
||||
verify(cb).failure(isA(HttpStatusException::class.java))
|
||||
verify(cb).failure(isA(IOException::class.java))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue