mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 12:23:58 +01:00
Merge branch 'master' into dependency-injection
This commit is contained in:
commit
2d91e81121
19 changed files with 288 additions and 168 deletions
|
|
@ -84,6 +84,29 @@ android {
|
|||
}
|
||||
}
|
||||
|
||||
productFlavors {
|
||||
prod {
|
||||
buildConfigField "String", "WIKIMEDIA_API_HOST", "\"https://commons.wikimedia.org/w/api.php\""
|
||||
buildConfigField "String", "WIKIMEDIA_FORGE_API_HOST", "\"https://tools.wmflabs.org/\""
|
||||
buildConfigField "String", "IMAGE_URL_BASE", "\"https://upload.wikimedia.org/wikipedia/commons\""
|
||||
buildConfigField "String", "HOME_URL", "\"https://commons.wikimedia.org/wiki/\""
|
||||
buildConfigField "String", "MOBILE_HOME_URL", "\"https://commons.m.wikimedia.org/wiki/\""
|
||||
buildConfigField "String", "EVENTLOG_URL", "\"https://www.wikimedia.org/beacon/event\""
|
||||
buildConfigField "String", "EVENTLOG_WIKI", "\"commonswiki\""
|
||||
}
|
||||
|
||||
beta {
|
||||
// What values do we need to hit the BETA versions of the site / api ?
|
||||
buildConfigField "String", "WIKIMEDIA_API_HOST", "\"https://commons.wikimedia.beta.wmflabs.org/w/api.php\""
|
||||
buildConfigField "String", "WIKIMEDIA_FORGE_API_HOST", "\"https://tools.wmflabs.org/\""
|
||||
buildConfigField "String", "IMAGE_URL_BASE", "\"https://upload.beta.wmflabs.org/wikipedia/commons\""
|
||||
buildConfigField "String", "HOME_URL", "\"https://commons.wikimedia.beta.wmflabs.org/wiki/\""
|
||||
buildConfigField "String", "MOBILE_HOME_URL", "\"https://commons.m.wikimedia.beta.wmflabs.org/wiki/\""
|
||||
buildConfigField "String", "EVENTLOG_URL", "\"https://commons.wikimedia.beta.wmflabs.org/beacon/event\""
|
||||
buildConfigField "String", "EVENTLOG_WIKI", "\"commonswiki\""
|
||||
}
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
disable 'MissingTranslation'
|
||||
disable 'ExtraTranslation'
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
package fr.free.nrw.commons;
|
||||
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
|
||||
// TODO: use Robolectric and make it runnable without a connected device
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class MediaTest {
|
||||
@Test public void displayTitleShouldStripExtension() {
|
||||
Media m = new Media("File:Example.jpg");
|
||||
Assert.assertThat(m.getDisplayTitle(), is("Example"));
|
||||
}
|
||||
|
||||
@Test public void displayTitleShouldUseSpaceForUnderscore() {
|
||||
Media m = new Media("File:Example 1_2.jpg");
|
||||
Assert.assertThat(m.getDisplayTitle(), is("Example 1 2"));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
package fr.free.nrw.commons;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import fr.free.nrw.commons.location.LatLng;
|
||||
import fr.free.nrw.commons.nearby.NearbyBaseMarker;
|
||||
import fr.free.nrw.commons.nearby.NearbyController;
|
||||
import fr.free.nrw.commons.nearby.Place;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class NearbyControllerTest {
|
||||
private Context instrumentationContext;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
instrumentationContext = InstrumentationRegistry.getTargetContext();
|
||||
}
|
||||
|
||||
@Test public void testNullAttractions() {
|
||||
LatLng location = new LatLng(0, 0, 0);
|
||||
|
||||
List<NearbyBaseMarker> options =
|
||||
NearbyController.loadAttractionsFromLocationToBaseMarkerOptions(
|
||||
location,
|
||||
null,
|
||||
instrumentationContext
|
||||
);
|
||||
|
||||
Assert.assertThat(options.size(), is(0));
|
||||
}
|
||||
|
||||
@Test public void testEmptyList() {
|
||||
LatLng location = new LatLng(0, 0, 0);
|
||||
List<Place> emptyList = new ArrayList<>();
|
||||
|
||||
List<NearbyBaseMarker> options =
|
||||
NearbyController.loadAttractionsFromLocationToBaseMarkerOptions(
|
||||
location,
|
||||
emptyList,
|
||||
instrumentationContext
|
||||
);
|
||||
|
||||
Assert.assertThat(options.size(), is(0));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
package fr.free.nrw.commons;
|
||||
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
|
||||
// TODO: use Robolectric and make it runnable without a connected device
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class PageTitleTest {
|
||||
@Test public void displayTextShouldNotBeUnderscored() {
|
||||
Assert.assertThat(new PageTitle("Ex_1 ").getDisplayText(),
|
||||
is("Ex 1"));
|
||||
}
|
||||
|
||||
@Test public void moreThanTwoColons() {
|
||||
Assert.assertThat(new PageTitle("File:sample:a.jpg").getPrefixedText(),
|
||||
is("File:Sample:a.jpg"));
|
||||
}
|
||||
|
||||
@Test public void getTextShouldReturnWithoutNamespace() {
|
||||
Assert.assertThat(new PageTitle("File:sample.jpg").getText(),
|
||||
is("Sample.jpg"));
|
||||
}
|
||||
|
||||
|
||||
@Test public void capitalizeNameAfterNamespace() {
|
||||
Assert.assertThat(new PageTitle("File:sample.jpg").getPrefixedText(),
|
||||
is("File:Sample.jpg"));
|
||||
}
|
||||
|
||||
@Test public void prefixedTextShouldBeUnderscored() {
|
||||
Assert.assertThat(new PageTitle("Ex 1 ").getPrefixedText(),
|
||||
is("Ex_1"));
|
||||
}
|
||||
|
||||
@Test public void getMobileUriForTest() {
|
||||
Assert.assertThat(new PageTitle("Test").getMobileUri().toString(),
|
||||
is("https://commons.m.wikimedia.org/wiki/Test"));
|
||||
}
|
||||
|
||||
@Test public void spaceBecomesUnderscoreInUri() {
|
||||
Assert.assertThat(new PageTitle("File:Ex 1.jpg").getCanonicalUri().toString(),
|
||||
is("https://commons.wikimedia.org/wiki/File:Ex_1.jpg"));
|
||||
}
|
||||
|
||||
@Test public void leaveSubpageNamesUncapitalizedInUri() {
|
||||
Assert.assertThat(new PageTitle("User:Ex/subpage").getCanonicalUri().toString(),
|
||||
is("https://commons.wikimedia.org/wiki/User:Ex/subpage"));
|
||||
}
|
||||
|
||||
@Test public void unicodeUri() throws Throwable {
|
||||
Assert.assertThat(new PageTitle("User:例").getCanonicalUri().toString(),
|
||||
is("https://commons.wikimedia.org/wiki/User:" + URLEncoder.encode("例", "utf-8")));
|
||||
}
|
||||
}
|
||||
BIN
app/src/betaDebug/res/drawable-hdpi/ic_launcher.png
Normal file
BIN
app/src/betaDebug/res/drawable-hdpi/ic_launcher.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.3 KiB |
BIN
app/src/betaDebug/res/drawable-mdpi/ic_launcher.png
Normal file
BIN
app/src/betaDebug/res/drawable-mdpi/ic_launcher.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/betaDebug/res/drawable-xhdpi/ic_launcher.png
Normal file
BIN
app/src/betaDebug/res/drawable-xhdpi/ic_launcher.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.5 KiB |
|
|
@ -49,13 +49,6 @@ public class CommonsApplication extends DaggerApplication {
|
|||
@Inject SessionManager sessionManager;
|
||||
@Inject DBOpenHelper dbOpenHelper;
|
||||
|
||||
public static final String API_URL = "https://commons.wikimedia.org/w/api.php";
|
||||
public static final String IMAGE_URL_BASE = "https://upload.wikimedia.org/wikipedia/commons";
|
||||
public static final String HOME_URL = "https://commons.wikimedia.org/wiki/";
|
||||
public static final String MOBILE_HOME_URL = "https://commons.m.wikimedia.org/wiki/";
|
||||
public static final String EVENTLOG_URL = "https://www.wikimedia.org/beacon/event";
|
||||
public static final String EVENTLOG_WIKI = "commonswiki";
|
||||
|
||||
public static final Object[] EVENT_UPLOAD_ATTEMPT = {"MobileAppUploadAttempts", 5334329L};
|
||||
public static final Object[] EVENT_LOGIN_ATTEMPT = {"MobileAppLoginAttempts", 5257721L};
|
||||
public static final Object[] EVENT_SHARE_ATTEMPT = {"MobileAppShareAttempts", 5346170L};
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ public class PageTitle {
|
|||
*/
|
||||
@NonNull
|
||||
public Uri getCanonicalUri() {
|
||||
String uriStr = CommonsApplication.HOME_URL + Uri.encode(getPrefixedText(), ":/");
|
||||
String uriStr = BuildConfig.HOME_URL + Uri.encode(getPrefixedText(), ":/");
|
||||
return Uri.parse(uriStr);
|
||||
}
|
||||
|
||||
|
|
@ -71,7 +71,7 @@ public class PageTitle {
|
|||
*/
|
||||
@NonNull
|
||||
public Uri getMobileUri() {
|
||||
String uriStr = CommonsApplication.MOBILE_HOME_URL + Uri.encode(getPrefixedText(), ":/");
|
||||
String uriStr = BuildConfig.MOBILE_HOME_URL + Uri.encode(getPrefixedText(), ":/");
|
||||
return Uri.parse(uriStr);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import java.util.regex.Pattern;
|
|||
|
||||
import fr.free.nrw.commons.settings.Prefs;
|
||||
|
||||
|
||||
public class Utils {
|
||||
|
||||
/**
|
||||
|
|
@ -32,7 +33,7 @@ public class Utils {
|
|||
public static String makeThumbBaseUrl(String filename) {
|
||||
String name = new PageTitle(filename).getPrefixedText();
|
||||
String sha = new String(Hex.encodeHex(DigestUtils.md5(name)));
|
||||
return String.format("%s/%s/%s/%s", CommonsApplication.IMAGE_URL_BASE, sha.substring(0, 1), sha.substring(0, 2), urlEncode(name));
|
||||
return String.format("%s/%s/%s/%s", BuildConfig.IMAGE_URL_BASE, sha.substring(0, 1), sha.substring(0, 2), urlEncode(name));
|
||||
}
|
||||
|
||||
public static String urlEncode(String url) {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import javax.inject.Singleton;
|
|||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import fr.free.nrw.commons.BuildConfig;
|
||||
import fr.free.nrw.commons.CommonsApplication;
|
||||
import fr.free.nrw.commons.auth.AccountUtil;
|
||||
import fr.free.nrw.commons.auth.SessionManager;
|
||||
|
|
@ -37,7 +38,7 @@ public class CommonsApplicationModule {
|
|||
@Provides
|
||||
@Singleton
|
||||
public MediaWikiApi provideMediaWikiApi() {
|
||||
return new ApacheHttpClientMediaWikiApi(CommonsApplication.API_URL);
|
||||
return new ApacheHttpClientMediaWikiApi(BuildConfig.WIKIMEDIA_API_HOST);
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
|
|||
|
|
@ -47,12 +47,12 @@ public class LogBuilder {
|
|||
try {
|
||||
fullData.put("schema", schema);
|
||||
fullData.put("revision", rev);
|
||||
fullData.put("wiki", CommonsApplication.EVENTLOG_WIKI);
|
||||
fullData.put("wiki", BuildConfig.EVENTLOG_WIKI);
|
||||
data.put("device", EventLog.DEVICE);
|
||||
data.put("platform", "Android/" + Build.VERSION.RELEASE);
|
||||
data.put("appversion", "Android/" + BuildConfig.VERSION_NAME);
|
||||
fullData.put("event", data);
|
||||
return new URL(CommonsApplication.EVENTLOG_URL + "?" + Utils.urlEncode(fullData.toString()) + ";");
|
||||
return new URL(BuildConfig.EVENTLOG_URL + "?" + Utils.urlEncode(fullData.toString()) + ";");
|
||||
} catch (MalformedURLException | JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import android.preference.PreferenceManager;
|
|||
import dagger.android.support.DaggerAppCompatActivity;
|
||||
import fr.free.nrw.commons.R;
|
||||
|
||||
public class BaseActivity extends DaggerAppCompatActivity {
|
||||
public abstract class BaseActivity extends DaggerAppCompatActivity {
|
||||
boolean currentTheme;
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -20,11 +20,11 @@
|
|||
<string name="upload_progress_notification_title_finishing">اتمام بارگذاری %1$s</string>
|
||||
<string name="upload_failed_notification_title">%1$s بارگذاری نشد</string>
|
||||
<string name="upload_failed_notification_subtitle">برای دیدن انگشت بزنید</string>
|
||||
<plurals name="uploads_pending_notification_indicator" fuzzy="true">
|
||||
<item quantity="one">یک پرونده در حال بارگذاری</item>
|
||||
<plurals name="uploads_pending_notification_indicator">
|
||||
<item quantity="one">%d پرونده در حال بارگذاری</item>
|
||||
<item quantity="other">%d پرونده در حال بارگذاری</item>
|
||||
</plurals>
|
||||
<string name="title_activity_contributions" fuzzy="true">بارگذاریهای من</string>
|
||||
<string name="title_activity_contributions">بارگذاریهای اخیر من</string>
|
||||
<string name="contribution_state_queued">در صف</string>
|
||||
<string name="contribution_state_failed">ناموفق بود</string>
|
||||
<string name="contribution_state_in_progress">%1$d٪ کامل شد</string>
|
||||
|
|
@ -42,6 +42,7 @@
|
|||
<string name="login_failed_password">ناتوانی در ورود - لطفاً گذرواژهیتان را بررسی کنید</string>
|
||||
<string name="login_failed_throttled">تلاش ناموفق بیش از حد. لطفاً چند دقیقهٔ دیگر دوباره تلاش کنید</string>
|
||||
<string name="login_failed_blocked">پوزش، کاربر در ویکیانبار بسته شدهاست</string>
|
||||
<string name="login_failed_2fa_needed">باید تأیید دومرحلهای را فعال کنید.</string>
|
||||
<string name="login_failed_generic">ورود ناموفق بود</string>
|
||||
<string name="share_upload_button">بارگذاری</string>
|
||||
<string name="multiple_share_base_title">نام این مجموعه</string>
|
||||
|
|
@ -49,17 +50,21 @@
|
|||
<string name="menu_upload_single">بارگذاری</string>
|
||||
<string name="categories_search_text_hint">جستجوی ردهها</string>
|
||||
<string name="menu_save_categories">ذخیره</string>
|
||||
<plurals name="contributions_subtitle" fuzzy="true">
|
||||
<item quantity="zero">هنوز بارگذاری نشده است</item>
|
||||
<item quantity="one">یک بارگذاری شد</item>
|
||||
<string name="refresh_button">تازه کردن</string>
|
||||
<string name="gps_disabled">مکانیاب در دستگاه شما خاموش است. آیا دوست دارید فعال شود؟</string>
|
||||
<string name="enable_gps">فعال کردن مکانیاب</string>
|
||||
<string name="contributions_subtitle_zero">هنوز هیچ بارگذاری</string>
|
||||
<plurals name="contributions_subtitle">
|
||||
<item quantity="zero">\@string/contributions_subtitle_zero</item>
|
||||
<item quantity="one">بارگذاری شد</item>
|
||||
<item quantity="other">%d بارگذاری شد</item>
|
||||
</plurals>
|
||||
<plurals name="starting_multiple_uploads" fuzzy="true">
|
||||
<item quantity="one">شروع بارگذاری پرونده</item>
|
||||
<item quantity="other">شروع بارگذاری %d پرونده</item>
|
||||
<plurals name="starting_multiple_uploads">
|
||||
<item quantity="one">شروع %d بارگذاری پرونده</item>
|
||||
<item quantity="other">شروع بارگذاری %d پرونده</item>
|
||||
</plurals>
|
||||
<plurals name="multiple_uploads_title" fuzzy="true">
|
||||
<item quantity="one">۱ بارگذاری</item>
|
||||
<plurals name="multiple_uploads_title">
|
||||
<item quantity="one">%d بارگذاری</item>
|
||||
<item quantity="other">%d بارگذاری</item>
|
||||
</plurals>
|
||||
<string name="categories_not_found">ردهای منطبق با %1$s یافت نشد</string>
|
||||
|
|
@ -68,9 +73,10 @@
|
|||
<string name="title_activity_settings">تنظیمات</string>
|
||||
<string name="title_activity_signup">ثبت نام</string>
|
||||
<string name="menu_about">درباره</string>
|
||||
<string name="about_license" fuzzy="true">نرمافزار متنباز آزاد تحت <a href=\"https://github.com/commons-app/apps-android-commons/blob/master/COPYING\">مجوز آپاچی نسخهٔ ۲</a>\n\nویکیانبار و نشانش یک نشان تجاریست و با اجازهٔ بنیاد ویکیمدیا استفاده میشود. ما زیرمجموعه یا شعبهٔ بنیاد نیستیم.</string>
|
||||
<string name="about_license">نرمافزار متنباز آزاد تحت <a href=\"https://github.com/commons-app/apps-android-commons/blob/master/COPYING\">مجوز آپاچی نسخهٔ ۲</a>\n\n%1$s و نشانش یک نشان تجاریست و با اجازهٔ بنیاد ویکیمدیا استفاده میشود. ما زیرمجموعه یا شعبهٔ بنیاد نیستیم.</string>
|
||||
<string name="about_improve"><a href=\"https://github.com/commons-app/apps-android-commons\">Source</a> and <a href=\"https://commons-app.github.io/\">وبسایت</a> در گیتهاب. ایجاد یک <a href=\"https://github.com/commons-app/apps-android-commons/issues\">درخواست در گیتهاب</a> برای گزارش باگ و یا پیشنهاد یک خصوصیت جدید.</string>
|
||||
<string name="about_privacy_policy"><a href=\"https://wikimediafoundation.org/wiki/Privacy_policy\">سیاست حفظ حریم خصوصی</a></string>
|
||||
<string name="about_credits"><a href=\"https://github.com/commons-app/apps-android-commons/blob/master/CREDITS\">مجوز</a></string>
|
||||
<string name="title_activity_about">درباره</string>
|
||||
<string name="menu_feedback">ارسال بازخورد (از طریق ایمیل)</string>
|
||||
<string name="no_email_client">نرمافزار ایمیل نصب نیست</string>
|
||||
|
|
@ -80,11 +86,16 @@
|
|||
<string name="menu_retry_upload">تلاش مجدد</string>
|
||||
<string name="menu_cancel_upload">لغو</string>
|
||||
<string name="share_license_summary">این نگاره تحت مجوز %1$s است</string>
|
||||
<string name="media_upload_policy">با بارگذاری این تصویر، تأیید میکنم که این اثر کار خودم است و از محتوای دارای حق تکثیر یا سلفی برای ایجاد آن استفاده نکردهام و شرایط ذکر شده در By submitting this picture, I declare that this is my own work, that it does not contain copyrighted material or selfies, and otherwise adheres to <a href=\"https://commons.wikimedia.org/wiki/Commons:Policies_and_guidelines\">سیاستهای ویکیانبار</a> را رعایت میکند.</string>
|
||||
<string name="menu_download">دریافت</string>
|
||||
<string name="preference_license">مجوز</string>
|
||||
<string name="use_previous">از عنوان/توضیحات پیشین استفاده کنید</string>
|
||||
<string name="allow_gps">دریافت خودکار موقعیت کنونی</string>
|
||||
<string name="allow_gps_summary">درحال دریافت موقعیت برای پیشنهاد رده در صورتی که برچسب جغرافیایی وجود نداشته باشد.</string>
|
||||
<string name="preference_theme">حالت شبانه</string>
|
||||
<string name="preference_theme_summary">استفاده از حالت تیره</string>
|
||||
<string name="license_name_cc_by_sa_four">CC Attribution-ShareAlike 4.0</string>
|
||||
<string name="license_name_cc_by_four">Attribution 4.0</string>
|
||||
<string name="license_name_cc_by_sa">CC Attribution-ShareAlike 3.0</string>
|
||||
<string name="license_name_cc_by">CC Attribution 3.0</string>
|
||||
<string name="license_name_cc0">CC0</string>
|
||||
|
|
@ -127,8 +138,60 @@
|
|||
<string name="location_permission_rationale">اجازههای اختیاری: دریافت موقعیت برای پیشنهاد رده</string>
|
||||
<string name="ok">تأیید</string>
|
||||
<string name="title_activity_nearby">مکانهای اطراف</string>
|
||||
<string name="no_nearby">مکانی در نزدیکی یافت نشد</string>
|
||||
<string name="warning">هشدار</string>
|
||||
<string name="file_exists">پرونده در ویکیانبار موجود است. آیا مطمئنید که میخواهید ادامه دهید؟</string>
|
||||
<string name="yes">بله</string>
|
||||
<string name="no">خیر</string>
|
||||
<string name="media_detail_title">عنوان</string>
|
||||
<string name="media_detail_media_title">عنوان رسانه</string>
|
||||
<string name="media_detail_description">توضیح</string>
|
||||
<string name="media_detail_description_explanation">توضیحات رسانه اینجا میروند. امکان دارد طولانی باشد و نیاز به چند خط شدن داشته باشد. امیدواریم خوب دیده شود.</string>
|
||||
<string name="media_detail_uploaded_date">تاریخ بارگذاری</string>
|
||||
<string name="media_detail_license">مجوز</string>
|
||||
<string name="media_detail_coordinates">مختصاتها</string>
|
||||
<string name="media_detail_coordinates_empty">ارائه نشده است</string>
|
||||
<string name="become_a_tester_title">آزمایشگر نسخهٔ آزمایشی شوید</string>
|
||||
<string name="become_a_tester_description">به گروه آزمایشی ما در گوگلپلی بپیوندید و از خصوصیات جدید و خطاهای رفعشده زودتر از دیگران برخوردار شوید.</string>
|
||||
<string name="use_wikidata">استفاده از ویکیداده</string>
|
||||
<string name="use_wikidata_summary">(هشدار: غیرفعال کردن این ممکن است حجم زیادی از اینترنت تلفن همراه را مصرف کند)</string>
|
||||
<string name="_2fa_code">کد 2FA</string>
|
||||
<string name="number_of_uploads">محدودیت بارگذاری اخیر من</string>
|
||||
<string name="maximum_limit">حداکثر محدودیت</string>
|
||||
<string name="maximum_limit_alert">عدم توانایی در نمایش بیش از ۵۰۰ مورد</string>
|
||||
<string name="set_limit">تنظیم محدودیت بارگذاریهای اخیر</string>
|
||||
<string name="login_failed_2fa_not_supported">تأیید دومرحلهای الان پشتیبانی نمیشود.</string>
|
||||
<string name="logout_verification">آیا واقعاً قصد خروج از سامانه را دارید؟</string>
|
||||
<string name="commons_logo">نشان ویکیانبار</string>
|
||||
<string name="background_image">تصویر پسزمینه</string>
|
||||
<string name="mediaimage_failed">خطای تصویر رسانه</string>
|
||||
<string name="no_image_found">تصویری یافت نشد</string>
|
||||
<string name="upload_image">بارگذاری تصویر</string>
|
||||
<string name="welcome_image_mount_zao">کوه زائو</string>
|
||||
<string name="welcome_image_llamas">لاما</string>
|
||||
<string name="welcome_image_rainbow_bridge">رینبو بریج</string>
|
||||
<string name="welcome_image_tulip">لاله</string>
|
||||
<string name="welcome_image_no_selfies">سلفی نه</string>
|
||||
<string name="welcome_image_proprietary">تصویر اختصاصی</string>
|
||||
<string name="welcome_image_welcome_wikipedia">به ویکیپدیا خوشآمدید</string>
|
||||
<string name="welcome_image_welcome_copyright">حقتکثیر خوشآمدگویی</string>
|
||||
<string name="welcome_image_sydney_opera_house">خانه اپرای سیدنی</string>
|
||||
<string name="cancel">لغو</string>
|
||||
<string name="navigation_drawer_open">باز کردن</string>
|
||||
<string name="navigation_drawer_close">بستن</string>
|
||||
<string name="navigation_item_home">خانه</string>
|
||||
<string name="navigation_item_upload">بارگذاری</string>
|
||||
<string name="navigation_item_nearby">در نزدیکی</string>
|
||||
<string name="navigation_item_about">درباره</string>
|
||||
<string name="navigation_item_settings">تنظیمات</string>
|
||||
<string name="navigation_item_feedback">بازخورد</string>
|
||||
<string name="navigation_item_logout">خروج</string>
|
||||
<string name="navigation_item_info">آموزش</string>
|
||||
<string name="nearby_needs_permissions">مکانهای اطراف بدون اجازه دادن به مکانیاب مقدور نیست</string>
|
||||
<string name="no_description_found">توضیحی یافت نشد</string>
|
||||
<string name="nearby_info_menu_commons_article">صفحهٔ دروند در ویکیانبار</string>
|
||||
<string name="nearby_info_menu_wikidata_article">آیتم ویکیداده</string>
|
||||
<string name="error_while_cache">خطا در زمان دریافت تصاویر</string>
|
||||
<string name="title_info">عنوانی توصیفی و یکتا برای پرونده که به عنوان نام پرونده در نظر گرفته خواهد شد. ترجیحاً به زبان ساده باشد، میتوانید فاصله هم به کار ببرید. پسوند پرونده را ننویسید.</string>
|
||||
<string name="description_info">لطفاً تصویر را تا حد توان شرح دهید. کجا گرفته شدهاست؟ شامل چه چیزی میشود؟ لطفاً اشیا یا افراد را شرح دهید. اطلاعاتی که به راحتی قابل مشاهده هستند را صرفهنظر کنید. اگر چیزی در تصویر غیر طبیعی به نظر میرسد آن را شرح دهید.</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
<string name="login_failed_username">ناقابلِ داخل ٿيڻ - براءِ مھرباني پنھنجو يُوزرنانءُ چڪاسيو</string>
|
||||
<string name="login_failed_password">ناقابل داخل ٿيڻ - براءِ مھرباني پنھنجو ڳجھولفظ چڪاسيو</string>
|
||||
<string name="login_failed_throttled">ھيڪانديون ناڪام ڪوششون. براءِ مھرباني ڪجھ منٽن کانپوءِ ٻيھر ڪوشش ڪريو.</string>
|
||||
<string name="login_failed_blocked">افسوس، ھي يوزر العام تي بندشيل آھي</string>
|
||||
<string name="login_failed_blocked">افسوس، ھي واھپ العام تي بندشيل آھي</string>
|
||||
<string name="login_failed_generic">داخل ٿيڻ ناڪام</string>
|
||||
<string name="share_upload_button">چاڙھيو</string>
|
||||
<string name="multiple_share_base_title">ھن سيٽ کي نالو ڏيو</string>
|
||||
|
|
|
|||
25
app/src/test/java/fr/free/nrw/commons/MediaTest.java
Normal file
25
app/src/test/java/fr/free/nrw/commons/MediaTest.java
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
package fr.free.nrw.commons;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(constants = BuildConfig.class, sdk = 21)
|
||||
public class MediaTest {
|
||||
@Test
|
||||
public void displayTitleShouldStripExtension() {
|
||||
Media m = new Media("File:Example.jpg");
|
||||
assertThat(m.getDisplayTitle(), is("Example"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayTitleShouldUseSpaceForUnderscore() {
|
||||
Media m = new Media("File:Example 1_2.jpg");
|
||||
assertThat(m.getDisplayTitle(), is("Example 1 2"));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
package fr.free.nrw.commons;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import fr.free.nrw.commons.location.LatLng;
|
||||
import fr.free.nrw.commons.nearby.NearbyBaseMarker;
|
||||
import fr.free.nrw.commons.nearby.Place;
|
||||
|
||||
import static fr.free.nrw.commons.nearby.NearbyController.loadAttractionsFromLocationToBaseMarkerOptions;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(constants = BuildConfig.class, sdk = 21)
|
||||
public class NearbyControllerTest {
|
||||
|
||||
@Test
|
||||
public void testNullAttractions() {
|
||||
LatLng location = new LatLng(0, 0, 0);
|
||||
|
||||
List<NearbyBaseMarker> options = loadAttractionsFromLocationToBaseMarkerOptions(
|
||||
location, null, RuntimeEnvironment.application);
|
||||
|
||||
assertThat(options.size(), is(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyList() {
|
||||
LatLng location = new LatLng(0, 0, 0);
|
||||
List<Place> emptyList = new ArrayList<>();
|
||||
|
||||
List<NearbyBaseMarker> options = loadAttractionsFromLocationToBaseMarkerOptions(
|
||||
location, emptyList, RuntimeEnvironment.application);
|
||||
|
||||
assertThat(options.size(), is(0));
|
||||
}
|
||||
}
|
||||
70
app/src/test/java/fr/free/nrw/commons/PageTitleTest.java
Normal file
70
app/src/test/java/fr/free/nrw/commons/PageTitleTest.java
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
package fr.free.nrw.commons;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(constants = BuildConfig.class, sdk = 21)
|
||||
public class PageTitleTest {
|
||||
@Test
|
||||
public void displayTextShouldNotBeUnderscored() {
|
||||
assertThat(new PageTitle("Ex_1 ").getDisplayText(),
|
||||
is("Ex 1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void moreThanTwoColons() {
|
||||
assertThat(new PageTitle("File:sample:a.jpg").getPrefixedText(),
|
||||
is("File:Sample:a.jpg"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getTextShouldReturnWithoutNamespace() {
|
||||
assertThat(new PageTitle("File:sample.jpg").getText(),
|
||||
is("Sample.jpg"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void capitalizeNameAfterNamespace() {
|
||||
assertThat(new PageTitle("File:sample.jpg").getPrefixedText(),
|
||||
is("File:Sample.jpg"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void prefixedTextShouldBeUnderscored() {
|
||||
assertThat(new PageTitle("Ex 1 ").getPrefixedText(),
|
||||
is("Ex_1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMobileUriForTest() {
|
||||
assertThat(new PageTitle("Test").getMobileUri().toString(),
|
||||
is(BuildConfig.MOBILE_HOME_URL + "Test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void spaceBecomesUnderscoreInUri() {
|
||||
assertThat(new PageTitle("File:Ex 1.jpg").getCanonicalUri().toString(),
|
||||
is(BuildConfig.HOME_URL + "File:Ex_1.jpg"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void leaveSubpageNamesUncapitalizedInUri() {
|
||||
assertThat(new PageTitle("User:Ex/subpage").getCanonicalUri().toString(),
|
||||
is(BuildConfig.HOME_URL + "User:Ex/subpage"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unicodeUri() throws Throwable {
|
||||
assertThat(new PageTitle("User:例").getCanonicalUri().toString(),
|
||||
is(BuildConfig.HOME_URL + "User:" + URLEncoder.encode("例", "utf-8")));
|
||||
}
|
||||
}
|
||||
41
dependency-injection.md
Normal file
41
dependency-injection.md
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
## Overview
|
||||
|
||||
At its core, dependency injection is just the principle of `"tell, dont ask"` put into practice; for instance, if a class needs to use the `MediaWikiApi`, it should be handed an instance of the classs rather than reaching out to get it. This has the effect of decoupling code, making it easier to test and reuse.
|
||||
|
||||
## Dependency Injection in the Commons app
|
||||
|
||||
We use Dagger 2 as our dependency injection engine. Dagger is a fully static, compile-time dependency injection framework for both Java and Android. Dagger aims to address many of the development and performance issues that have plagued reflection-based solutions that came before it, but it does come at something of a cost in complexity.
|
||||
|
||||
For more information about Dagger, take a look at the [Dagger user guide](https://google.github.io/dagger/users-guide.html).
|
||||
|
||||
## Dagger configuration in the Commons app
|
||||
|
||||
The top level `CommonsApplicationComponent` pulls together configuration for injection across the app. The most important files to understand
|
||||
|
||||
- if you need to add a new Activity, look at `ActivityBuilderModule` and copy how injection is configured. The `BaseActivity` class will take care of the rest.
|
||||
- if you are adding a new Fragment, look at `FragmentBuilderModule`
|
||||
- if you are adding a new ContentProvider, look at `ContentProviderBuilderModule`
|
||||
- if you are adding a new Service, look at `ServiceBuilderModule`
|
||||
- other dependencies are configured in `CommonsApplicationModule`
|
||||
|
||||
## "Provider" methods
|
||||
|
||||
Dagger will resolve the method arguments on provider methods in a module (or the constructor arguments when annotated with `@Inject`) and build the objects accordingly - either by calling another provider method or by looking for a constructor on a class that has the `@Inject` annotation. Dagger takes care of managing singletons, just annotate with the `@Singleton` annotation. For instance,
|
||||
|
||||
```java
|
||||
@Provides
|
||||
@Singleton
|
||||
public SessionManager providesSessionManager(MediaWikiApi mediaWikiApi) {
|
||||
return new SessionManager(application, mediaWikiApi);
|
||||
}
|
||||
```
|
||||
|
||||
If your code injects an interface (in this case, `MediaWikiApi`) then Dagger needs to know which concrete class to use. This comes by way of a provider method:
|
||||
|
||||
```java
|
||||
@Provides
|
||||
@Singleton
|
||||
public MediaWikiApi provideMediaWikiApi() {
|
||||
return new ApacheHttpClientMediaWikiApi(BuildConfig.WIKIMEDIA_API_HOST);
|
||||
}
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue