mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Merge remote-tracking branch 'refs/remotes/commons-app/master'
This commit is contained in:
commit
3ea9b1b80a
174 changed files with 3381 additions and 1238 deletions
|
|
@ -23,11 +23,11 @@ dependencies {
|
|||
}
|
||||
|
||||
|
||||
implementation "com.android.support:support-v4:${project.supportLibVersion}"
|
||||
implementation "com.android.support:appcompat-v7:${project.supportLibVersion}"
|
||||
implementation "com.android.support:design:${project.supportLibVersion}"
|
||||
implementation "com.android.support:support-v4:$SUPPORT_LIB_VERSION"
|
||||
implementation "com.android.support:appcompat-v7:$SUPPORT_LIB_VERSION"
|
||||
implementation "com.android.support:design:$SUPPORT_LIB_VERSION"
|
||||
|
||||
implementation "com.android.support:cardview-v7:${project.supportLibVersion}"
|
||||
implementation "com.android.support:cardview-v7:$SUPPORT_LIB_VERSION"
|
||||
|
||||
implementation "com.jakewharton:butterknife:$BUTTERKNIFE_VERSION"
|
||||
kapt "com.jakewharton:butterknife-compiler:$BUTTERKNIFE_VERSION"
|
||||
|
|
@ -44,7 +44,7 @@ dependencies {
|
|||
implementation 'com.jakewharton.rxbinding2:rxbinding-appcompat-v7:2.0.0'
|
||||
implementation 'com.jakewharton.rxbinding2:rxbinding-design:2.0.0'
|
||||
|
||||
implementation 'com.facebook.fresco:fresco:1.3.0'
|
||||
implementation 'com.facebook.fresco:fresco:1.5.0'
|
||||
implementation 'com.facebook.stetho:stetho:1.5.0'
|
||||
|
||||
implementation "com.google.dagger:dagger:$DAGGER_VERSION"
|
||||
|
|
@ -62,17 +62,17 @@ dependencies {
|
|||
|
||||
testImplementation 'com.squareup.okhttp3:mockwebserver:3.8.1'
|
||||
androidTestImplementation 'com.squareup.okhttp3:mockwebserver:3.8.1'
|
||||
androidTestImplementation "com.android.support:support-annotations:${project.supportLibVersion}"
|
||||
androidTestImplementation "com.android.support:support-annotations:$SUPPORT_LIB_VERSION"
|
||||
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
|
||||
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.5.1'
|
||||
releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
|
||||
testImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
|
||||
debugImplementation "com.squareup.leakcanary:leakcanary-android:$LEAK_CANARY"
|
||||
releaseImplementation "com.squareup.leakcanary:leakcanary-android-no-op:$LEAK_CANARY"
|
||||
testImplementation "com.squareup.leakcanary:leakcanary-android-no-op:$LEAK_CANARY"
|
||||
|
||||
implementation 'com.google.dagger:dagger:2.11'
|
||||
implementation 'com.google.dagger:dagger-android-support:2.11'
|
||||
annotationProcessor 'com.google.dagger:dagger-compiler:2.11'
|
||||
annotationProcessor 'com.google.dagger:dagger-android-processor:2.11'
|
||||
implementation "com.google.dagger:dagger:$DAGGER_VERSION"
|
||||
implementation "com.google.dagger:dagger-android-support:$DAGGER_VERSION"
|
||||
kapt "com.google.dagger:dagger-compiler:$DAGGER_VERSION"
|
||||
kapt "com.google.dagger:dagger-android-processor:$DAGGER_VERSION"
|
||||
}
|
||||
|
||||
android {
|
||||
|
|
|
|||
|
|
@ -87,6 +87,10 @@
|
|||
android:label="@string/title_activity_nearby"
|
||||
android:parentActivityName=".contributions.ContributionsActivity" />
|
||||
|
||||
<activity
|
||||
android:name=".notification.NotificationActivity"
|
||||
android:label="@string/navigation_item_notification" />
|
||||
|
||||
<service android:name=".upload.UploadService" />
|
||||
|
||||
<service
|
||||
|
|
|
|||
|
|
@ -21,13 +21,13 @@ import javax.inject.Named;
|
|||
import dagger.android.AndroidInjector;
|
||||
import dagger.android.DaggerApplication;
|
||||
import fr.free.nrw.commons.auth.SessionManager;
|
||||
import fr.free.nrw.commons.contributions.Contribution;
|
||||
import fr.free.nrw.commons.data.Category;
|
||||
import fr.free.nrw.commons.category.CategoryDao;
|
||||
import fr.free.nrw.commons.contributions.ContributionDao;
|
||||
import fr.free.nrw.commons.data.DBOpenHelper;
|
||||
import fr.free.nrw.commons.di.CommonsApplicationComponent;
|
||||
import fr.free.nrw.commons.di.CommonsApplicationModule;
|
||||
import fr.free.nrw.commons.di.DaggerCommonsApplicationComponent;
|
||||
import fr.free.nrw.commons.modifications.ModifierSequence;
|
||||
import fr.free.nrw.commons.modifications.ModifierSequenceDao;
|
||||
import fr.free.nrw.commons.utils.FileUtils;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
|
@ -168,9 +168,9 @@ public class CommonsApplication extends DaggerApplication {
|
|||
dbOpenHelper.getReadableDatabase().close();
|
||||
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
|
||||
|
||||
ModifierSequence.Table.onDelete(db);
|
||||
Category.Table.onDelete(db);
|
||||
Contribution.Table.onDelete(db);
|
||||
ModifierSequenceDao.Table.onDelete(db);
|
||||
CategoryDao.Table.onDelete(db);
|
||||
ContributionDao.Table.onDelete(db);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -38,6 +38,10 @@ public class MediaWikiImageView extends SimpleDraweeView {
|
|||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the media. Fetches its thumbnail if necessary.
|
||||
* @param media the new media
|
||||
*/
|
||||
public void setMedia(Media media) {
|
||||
if (currentThumbnailTask != null) {
|
||||
currentThumbnailTask.cancel(true);
|
||||
|
|
@ -63,6 +67,9 @@ public class MediaWikiImageView extends SimpleDraweeView {
|
|||
super.onDetachedFromWindow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes MediaWikiImageView.
|
||||
*/
|
||||
private void init() {
|
||||
((CommonsApplication) getContext().getApplicationContext()).injector().inject(this);
|
||||
setHierarchy(GenericDraweeHierarchyBuilder
|
||||
|
|
@ -74,6 +81,10 @@ public class MediaWikiImageView extends SimpleDraweeView {
|
|||
.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the image from the URL.
|
||||
* @param url the URL of the image
|
||||
*/
|
||||
private void setImageUrl(@Nullable String url) {
|
||||
setImageURI(url);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,13 +8,13 @@ import android.content.Context;
|
|||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import fr.free.nrw.commons.contributions.ContributionsContentProvider;
|
||||
import fr.free.nrw.commons.modifications.ModificationsContentProvider;
|
||||
import timber.log.Timber;
|
||||
|
||||
import static android.accounts.AccountManager.ERROR_CODE_REMOTE_EXCEPTION;
|
||||
import static android.accounts.AccountManager.KEY_ACCOUNT_NAME;
|
||||
import static android.accounts.AccountManager.KEY_ACCOUNT_TYPE;
|
||||
import static fr.free.nrw.commons.contributions.ContributionsContentProvider.CONTRIBUTION_AUTHORITY;
|
||||
import static fr.free.nrw.commons.modifications.ModificationsContentProvider.MODIFICATIONS_AUTHORITY;
|
||||
|
||||
public class AccountUtil {
|
||||
|
||||
|
|
@ -51,8 +51,8 @@ public class AccountUtil {
|
|||
}
|
||||
|
||||
// FIXME: If the user turns it off, it shouldn't be auto turned back on
|
||||
ContentResolver.setSyncAutomatically(account, ContributionsContentProvider.AUTHORITY, true); // Enable sync by default!
|
||||
ContentResolver.setSyncAutomatically(account, ModificationsContentProvider.AUTHORITY, true); // Enable sync by default!
|
||||
ContentResolver.setSyncAutomatically(account, CONTRIBUTION_AUTHORITY, true); // Enable sync by default!
|
||||
ContentResolver.setSyncAutomatically(account, MODIFICATIONS_AUTHORITY, true); // Enable sync by default!
|
||||
}
|
||||
|
||||
private AccountManager accountManager() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package fr.free.nrw.commons.category;
|
||||
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
|
|
@ -36,7 +35,6 @@ import butterknife.BindView;
|
|||
import butterknife.ButterKnife;
|
||||
import dagger.android.support.DaggerFragment;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.data.Category;
|
||||
import fr.free.nrw.commons.mwapi.MediaWikiApi;
|
||||
import fr.free.nrw.commons.upload.MwVolleyApi;
|
||||
import fr.free.nrw.commons.utils.StringSortingUtils;
|
||||
|
|
@ -47,7 +45,6 @@ import timber.log.Timber;
|
|||
|
||||
import static android.view.KeyEvent.ACTION_UP;
|
||||
import static android.view.KeyEvent.KEYCODE_BACK;
|
||||
import static fr.free.nrw.commons.category.CategoryContentProvider.AUTHORITY;
|
||||
|
||||
/**
|
||||
* Displays the category suggestion and selection screen. Category search is initiated here.
|
||||
|
|
@ -69,17 +66,17 @@ public class CategorizationFragment extends DaggerFragment {
|
|||
|
||||
@Inject MediaWikiApi mwApi;
|
||||
@Inject @Named("default_preferences") SharedPreferences prefs;
|
||||
@Inject CategoryDao categoryDao;
|
||||
|
||||
private RVRendererAdapter<CategoryItem> categoriesAdapter;
|
||||
private OnCategoriesSaveHandler onCategoriesSaveHandler;
|
||||
private HashMap<String, ArrayList<String>> categoriesCache;
|
||||
private List<CategoryItem> selectedCategories = new ArrayList<>();
|
||||
private ContentProviderClient databaseClient;
|
||||
|
||||
private final CategoriesAdapterFactory adapterFactory = new CategoriesAdapterFactory(item -> {
|
||||
if (item.isSelected()) {
|
||||
selectedCategories.add(item);
|
||||
updateCategoryCount(item, databaseClient);
|
||||
updateCategoryCount(item);
|
||||
} else {
|
||||
selectedCategories.remove(item);
|
||||
}
|
||||
|
|
@ -140,7 +137,6 @@ public class CategorizationFragment extends DaggerFragment {
|
|||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
databaseClient.release();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -178,7 +174,6 @@ public class CategorizationFragment extends DaggerFragment {
|
|||
setHasOptionsMenu(true);
|
||||
onCategoriesSaveHandler = (OnCategoriesSaveHandler) getActivity();
|
||||
getActivity().setTitle(R.string.categories_activity_title);
|
||||
databaseClient = getActivity().getContentResolver().acquireContentProviderClient(AUTHORITY);
|
||||
}
|
||||
|
||||
private void updateCategoryList(String filter) {
|
||||
|
|
@ -261,7 +256,7 @@ public class CategorizationFragment extends DaggerFragment {
|
|||
}
|
||||
|
||||
private Observable<CategoryItem> recentCategories() {
|
||||
return Observable.fromIterable(Category.recentCategories(databaseClient, SEARCH_CATS_LIMIT))
|
||||
return Observable.fromIterable(categoryDao.recentCategories(SEARCH_CATS_LIMIT))
|
||||
.map(s -> new CategoryItem(s, false));
|
||||
}
|
||||
|
||||
|
|
@ -311,24 +306,16 @@ public class CategorizationFragment extends DaggerFragment {
|
|||
|| item.matches("(.*)needing(.*)") || item.matches("(.*)taken on(.*)"));
|
||||
}
|
||||
|
||||
private void updateCategoryCount(CategoryItem item, ContentProviderClient client) {
|
||||
Category cat = lookupCategory(item.getName());
|
||||
cat.incTimesUsed();
|
||||
cat.save(client);
|
||||
}
|
||||
private void updateCategoryCount(CategoryItem item) {
|
||||
Category category = categoryDao.find(item.getName());
|
||||
|
||||
private Category lookupCategory(String name) {
|
||||
Category cat = Category.find(databaseClient, name);
|
||||
|
||||
if (cat == null) {
|
||||
// Newly used category...
|
||||
cat = new Category();
|
||||
cat.setName(name);
|
||||
cat.setLastUsed(new Date());
|
||||
cat.setTimesUsed(0);
|
||||
// Newly used category...
|
||||
if (category == null) {
|
||||
category = new Category(null, item.getName(), new Date(), 0);
|
||||
}
|
||||
|
||||
return cat;
|
||||
category.incTimesUsed();
|
||||
categoryDao.save(category);
|
||||
}
|
||||
|
||||
public int getCurrentSelectedCount() {
|
||||
|
|
|
|||
96
app/src/main/java/fr/free/nrw/commons/category/Category.java
Normal file
96
app/src/main/java/fr/free/nrw/commons/category/Category.java
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
package fr.free.nrw.commons.category;
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Represents a category
|
||||
*/
|
||||
public class Category {
|
||||
private Uri contentUri;
|
||||
private String name;
|
||||
private Date lastUsed;
|
||||
private int timesUsed;
|
||||
|
||||
public Category() {
|
||||
}
|
||||
|
||||
public Category(Uri contentUri, String name, Date lastUsed, int timesUsed) {
|
||||
this.contentUri = contentUri;
|
||||
this.name = name;
|
||||
this.lastUsed = lastUsed;
|
||||
this.timesUsed = timesUsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets name
|
||||
*
|
||||
* @return name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies name
|
||||
*
|
||||
* @param name Category name
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets last used date
|
||||
*
|
||||
* @return Last used date
|
||||
*/
|
||||
public Date getLastUsed() {
|
||||
// warning: Date objects are mutable.
|
||||
return (Date)lastUsed.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates new last used date
|
||||
*/
|
||||
private void touch() {
|
||||
lastUsed = new Date();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets no. of times the category is used
|
||||
*
|
||||
* @return no. of times used
|
||||
*/
|
||||
public int getTimesUsed() {
|
||||
return timesUsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments timesUsed by 1 and sets last used date as now.
|
||||
*/
|
||||
public void incTimesUsed() {
|
||||
timesUsed++;
|
||||
touch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the content URI for this category
|
||||
*
|
||||
* @return content URI
|
||||
*/
|
||||
public Uri getContentUri() {
|
||||
return contentUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the content URI - marking this category as already saved in the database
|
||||
*
|
||||
* @param contentUri the content URI
|
||||
*/
|
||||
public void setContentUri(Uri contentUri) {
|
||||
this.contentUri = contentUri;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -17,9 +17,9 @@ import fr.free.nrw.commons.data.DBOpenHelper;
|
|||
import timber.log.Timber;
|
||||
|
||||
import static android.content.UriMatcher.NO_MATCH;
|
||||
import static fr.free.nrw.commons.data.Category.Table.ALL_FIELDS;
|
||||
import static fr.free.nrw.commons.data.Category.Table.COLUMN_ID;
|
||||
import static fr.free.nrw.commons.data.Category.Table.TABLE_NAME;
|
||||
import static fr.free.nrw.commons.category.CategoryDao.Table.ALL_FIELDS;
|
||||
import static fr.free.nrw.commons.category.CategoryDao.Table.COLUMN_ID;
|
||||
import static fr.free.nrw.commons.category.CategoryDao.Table.TABLE_NAME;
|
||||
|
||||
public class CategoryContentProvider extends ContentProvider {
|
||||
|
||||
|
|
|
|||
184
app/src/main/java/fr/free/nrw/commons/category/CategoryDao.java
Normal file
184
app/src/main/java/fr/free/nrw/commons/category/CategoryDao.java
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
package fr.free.nrw.commons.category;
|
||||
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.RemoteException;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
|
||||
public class CategoryDao {
|
||||
|
||||
private final Provider<ContentProviderClient> clientProvider;
|
||||
|
||||
@Inject
|
||||
public CategoryDao(@Named("category") Provider<ContentProviderClient> clientProvider) {
|
||||
this.clientProvider = clientProvider;
|
||||
}
|
||||
|
||||
public void save(Category category) {
|
||||
ContentProviderClient db = clientProvider.get();
|
||||
try {
|
||||
if (category.getContentUri() == null) {
|
||||
category.setContentUri(db.insert(CategoryContentProvider.BASE_URI, toContentValues(category)));
|
||||
} else {
|
||||
db.update(category.getContentUri(), toContentValues(category), null, null);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
db.release();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find persisted category in database, based on its name.
|
||||
*
|
||||
* @param name Category's name
|
||||
* @return category from database, or null if not found
|
||||
*/
|
||||
@Nullable
|
||||
Category find(String name) {
|
||||
Cursor cursor = null;
|
||||
ContentProviderClient db = clientProvider.get();
|
||||
try {
|
||||
cursor = db.query(
|
||||
CategoryContentProvider.BASE_URI,
|
||||
Table.ALL_FIELDS,
|
||||
Table.COLUMN_NAME + "=?",
|
||||
new String[]{name},
|
||||
null);
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
return fromCursor(cursor);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
// This feels lazy, but to hell with checked exceptions. :)
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
db.release();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve recently-used categories, ordered by descending date.
|
||||
*
|
||||
* @return a list containing recent categories
|
||||
*/
|
||||
@NonNull
|
||||
List<String> recentCategories(int limit) {
|
||||
List<String> items = new ArrayList<>();
|
||||
Cursor cursor = null;
|
||||
ContentProviderClient db = clientProvider.get();
|
||||
try {
|
||||
cursor = db.query(
|
||||
CategoryContentProvider.BASE_URI,
|
||||
Table.ALL_FIELDS,
|
||||
null,
|
||||
new String[]{},
|
||||
Table.COLUMN_LAST_USED + " DESC");
|
||||
// fixme add a limit on the original query instead of falling out of the loop?
|
||||
while (cursor != null && cursor.moveToNext()
|
||||
&& cursor.getPosition() < limit) {
|
||||
items.add(fromCursor(cursor).getName());
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
db.release();
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
Category fromCursor(Cursor cursor) {
|
||||
// Hardcoding column positions!
|
||||
return new Category(
|
||||
CategoryContentProvider.uriForId(cursor.getInt(0)),
|
||||
cursor.getString(1),
|
||||
new Date(cursor.getLong(2)),
|
||||
cursor.getInt(3)
|
||||
);
|
||||
}
|
||||
|
||||
private ContentValues toContentValues(Category category) {
|
||||
ContentValues cv = new ContentValues();
|
||||
cv.put(CategoryDao.Table.COLUMN_NAME, category.getName());
|
||||
cv.put(CategoryDao.Table.COLUMN_LAST_USED, category.getLastUsed().getTime());
|
||||
cv.put(CategoryDao.Table.COLUMN_TIMES_USED, category.getTimesUsed());
|
||||
return cv;
|
||||
}
|
||||
|
||||
public static class Table {
|
||||
public static final String TABLE_NAME = "categories";
|
||||
|
||||
public static final String COLUMN_ID = "_id";
|
||||
static final String COLUMN_NAME = "name";
|
||||
static final String COLUMN_LAST_USED = "last_used";
|
||||
static final String COLUMN_TIMES_USED = "times_used";
|
||||
|
||||
// NOTE! KEEP IN SAME ORDER AS THEY ARE DEFINED UP THERE. HELPS HARD CODE COLUMN INDICES.
|
||||
public static final String[] ALL_FIELDS = {
|
||||
COLUMN_ID,
|
||||
COLUMN_NAME,
|
||||
COLUMN_LAST_USED,
|
||||
COLUMN_TIMES_USED
|
||||
};
|
||||
|
||||
static final String DROP_TABLE_STATEMENT = "DROP TABLE IF EXISTS " + TABLE_NAME;
|
||||
|
||||
static final String CREATE_TABLE_STATEMENT = "CREATE TABLE " + TABLE_NAME + " ("
|
||||
+ COLUMN_ID + " INTEGER PRIMARY KEY,"
|
||||
+ COLUMN_NAME + " STRING,"
|
||||
+ COLUMN_LAST_USED + " INTEGER,"
|
||||
+ COLUMN_TIMES_USED + " INTEGER"
|
||||
+ ");";
|
||||
|
||||
public static void onCreate(SQLiteDatabase db) {
|
||||
db.execSQL(CREATE_TABLE_STATEMENT);
|
||||
}
|
||||
|
||||
public static void onDelete(SQLiteDatabase db) {
|
||||
db.execSQL(DROP_TABLE_STATEMENT);
|
||||
onCreate(db);
|
||||
}
|
||||
|
||||
public static void onUpdate(SQLiteDatabase db, int from, int to) {
|
||||
if (from == to) {
|
||||
return;
|
||||
}
|
||||
if (from < 4) {
|
||||
// doesn't exist yet
|
||||
from++;
|
||||
onUpdate(db, from, to);
|
||||
return;
|
||||
}
|
||||
if (from == 4) {
|
||||
// table added in version 5
|
||||
onCreate(db);
|
||||
from++;
|
||||
onUpdate(db, from, to);
|
||||
return;
|
||||
}
|
||||
if (from == 5) {
|
||||
from++;
|
||||
onUpdate(db, from, to);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +1,8 @@
|
|||
package fr.free.nrw.commons.contributions;
|
||||
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
import android.os.RemoteException;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
|
@ -43,7 +37,6 @@ public class Contribution extends Media {
|
|||
public static final String SOURCE_GALLERY = "gallery";
|
||||
public static final String SOURCE_EXTERNAL = "external";
|
||||
|
||||
private ContentProviderClient client;
|
||||
private Uri contentUri;
|
||||
private String source;
|
||||
private String editSummary;
|
||||
|
|
@ -51,24 +44,42 @@ public class Contribution extends Media {
|
|||
private int state;
|
||||
private long transferred;
|
||||
private String decimalCoords;
|
||||
|
||||
private boolean isMultiple;
|
||||
|
||||
public boolean getMultiple() {
|
||||
return isMultiple;
|
||||
public Contribution(Uri contentUri, String filename, Uri localUri, String imageUrl, Date timestamp,
|
||||
int state, long dataLength, Date dateUploaded, long transferred,
|
||||
String source, String description, String creator, boolean isMultiple,
|
||||
int width, int height, String license) {
|
||||
super(localUri, imageUrl, filename, description, dataLength, timestamp, dateUploaded, creator);
|
||||
this.contentUri = contentUri;
|
||||
this.state = state;
|
||||
this.timestamp = timestamp;
|
||||
this.transferred = transferred;
|
||||
this.source = source;
|
||||
this.isMultiple = isMultiple;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.license = license;
|
||||
}
|
||||
|
||||
public void setMultiple(boolean multiple) {
|
||||
isMultiple = multiple;
|
||||
}
|
||||
|
||||
public Contribution(Uri localUri, String remoteUri, String filename, String description, long dataLength, Date dateCreated, Date dateUploaded, String creator, String editSummary, String decimalCoords) {
|
||||
super(localUri, remoteUri, filename, description, dataLength, dateCreated, dateUploaded, creator);
|
||||
public Contribution(Uri localUri, String imageUrl, String filename, String description, long dataLength,
|
||||
Date dateCreated, Date dateUploaded, String creator, String editSummary, String decimalCoords) {
|
||||
super(localUri, imageUrl, filename, description, dataLength, dateCreated, dateUploaded, creator);
|
||||
this.decimalCoords = decimalCoords;
|
||||
this.editSummary = editSummary;
|
||||
timestamp = new Date(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public Contribution(Parcel in) {
|
||||
super(in);
|
||||
contentUri = in.readParcelable(Uri.class.getClassLoader());
|
||||
source = in.readString();
|
||||
timestamp = (Date) in.readSerializable();
|
||||
state = in.readInt();
|
||||
transferred = in.readLong();
|
||||
isMultiple = in.readInt() == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int flags) {
|
||||
super.writeToParcel(parcel, flags);
|
||||
|
|
@ -80,14 +91,12 @@ public class Contribution extends Media {
|
|||
parcel.writeInt(isMultiple ? 1 : 0);
|
||||
}
|
||||
|
||||
public Contribution(Parcel in) {
|
||||
super(in);
|
||||
contentUri = in.readParcelable(Uri.class.getClassLoader());
|
||||
source = in.readString();
|
||||
timestamp = (Date) in.readSerializable();
|
||||
state = in.readInt();
|
||||
transferred = in.readLong();
|
||||
isMultiple = in.readInt() == 1;
|
||||
public boolean getMultiple() {
|
||||
return isMultiple;
|
||||
}
|
||||
|
||||
public void setMultiple(boolean multiple) {
|
||||
isMultiple = multiple;
|
||||
}
|
||||
|
||||
public long getTransferred() {
|
||||
|
|
@ -106,10 +115,18 @@ public class Contribution extends Media {
|
|||
return contentUri;
|
||||
}
|
||||
|
||||
public void setContentUri(Uri contentUri) {
|
||||
this.contentUri = contentUri;
|
||||
}
|
||||
|
||||
public Date getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(Date timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public int getState() {
|
||||
return state;
|
||||
}
|
||||
|
|
@ -155,62 +172,6 @@ public class Contribution extends Media {
|
|||
return buffer.toString();
|
||||
}
|
||||
|
||||
public void setContentProviderClient(ContentProviderClient client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public void save() {
|
||||
try {
|
||||
if (contentUri == null) {
|
||||
contentUri = client.insert(ContributionsContentProvider.BASE_URI, this.toContentValues());
|
||||
} else {
|
||||
client.update(contentUri, toContentValues(), null, null);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
try {
|
||||
if (contentUri == null) {
|
||||
// noooo
|
||||
throw new RuntimeException("tried to delete item with no content URI");
|
||||
} else {
|
||||
client.delete(contentUri, null, null);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public ContentValues toContentValues() {
|
||||
ContentValues cv = new ContentValues();
|
||||
cv.put(Table.COLUMN_FILENAME, getFilename());
|
||||
if (getLocalUri() != null) {
|
||||
cv.put(Table.COLUMN_LOCAL_URI, getLocalUri().toString());
|
||||
}
|
||||
if (getImageUrl() != null) {
|
||||
cv.put(Table.COLUMN_IMAGE_URL, getImageUrl());
|
||||
}
|
||||
if (getDateUploaded() != null) {
|
||||
cv.put(Table.COLUMN_UPLOADED, getDateUploaded().getTime());
|
||||
}
|
||||
cv.put(Table.COLUMN_LENGTH, getDataLength());
|
||||
cv.put(Table.COLUMN_TIMESTAMP, getTimestamp().getTime());
|
||||
cv.put(Table.COLUMN_STATE, getState());
|
||||
cv.put(Table.COLUMN_TRANSFERRED, transferred);
|
||||
cv.put(Table.COLUMN_SOURCE, source);
|
||||
cv.put(Table.COLUMN_DESCRIPTION, description);
|
||||
cv.put(Table.COLUMN_CREATOR, creator);
|
||||
cv.put(Table.COLUMN_MULTIPLE, isMultiple ? 1 : 0);
|
||||
cv.put(Table.COLUMN_WIDTH, width);
|
||||
cv.put(Table.COLUMN_HEIGHT, height);
|
||||
cv.put(Table.COLUMN_LICENSE, license);
|
||||
return cv;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFilename(String filename) {
|
||||
this.filename = filename;
|
||||
|
|
@ -224,33 +185,6 @@ public class Contribution extends Media {
|
|||
timestamp = new Date(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public static Contribution fromCursor(Cursor cursor) {
|
||||
// Hardcoding column positions!
|
||||
Contribution c = new Contribution();
|
||||
|
||||
//Check that cursor has a value to avoid CursorIndexOutOfBoundsException
|
||||
if (cursor.getCount() > 0) {
|
||||
c.contentUri = ContributionsContentProvider.uriForId(cursor.getInt(0));
|
||||
c.filename = cursor.getString(1);
|
||||
c.localUri = TextUtils.isEmpty(cursor.getString(2)) ? null : Uri.parse(cursor.getString(2));
|
||||
c.imageUrl = cursor.getString(3);
|
||||
c.timestamp = cursor.getLong(4) == 0 ? null : new Date(cursor.getLong(4));
|
||||
c.state = cursor.getInt(5);
|
||||
c.dataLength = cursor.getLong(6);
|
||||
c.dateUploaded = cursor.getLong(7) == 0 ? null : new Date(cursor.getLong(7));
|
||||
c.transferred = cursor.getLong(8);
|
||||
c.source = cursor.getString(9);
|
||||
c.description = cursor.getString(10);
|
||||
c.creator = cursor.getString(11);
|
||||
c.isMultiple = cursor.getInt(12) == 1;
|
||||
c.width = cursor.getInt(13);
|
||||
c.height = cursor.getInt(14);
|
||||
c.license = cursor.getString(15);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
public String getSource() {
|
||||
return source;
|
||||
}
|
||||
|
|
@ -263,121 +197,6 @@ public class Contribution extends Media {
|
|||
this.localUri = localUri;
|
||||
}
|
||||
|
||||
public static class Table {
|
||||
public static final String TABLE_NAME = "contributions";
|
||||
|
||||
public static final String COLUMN_ID = "_id";
|
||||
public static final String COLUMN_FILENAME = "filename";
|
||||
public static final String COLUMN_LOCAL_URI = "local_uri";
|
||||
public static final String COLUMN_IMAGE_URL = "image_url";
|
||||
public static final String COLUMN_TIMESTAMP = "timestamp";
|
||||
public static final String COLUMN_STATE = "state";
|
||||
public static final String COLUMN_LENGTH = "length";
|
||||
public static final String COLUMN_UPLOADED = "uploaded";
|
||||
public static final String COLUMN_TRANSFERRED = "transferred"; // Currently transferred number of bytes
|
||||
public static final String COLUMN_SOURCE = "source";
|
||||
public static final String COLUMN_DESCRIPTION = "description";
|
||||
public static final String COLUMN_CREATOR = "creator"; // Initial uploader
|
||||
public static final String COLUMN_MULTIPLE = "multiple";
|
||||
public static final String COLUMN_WIDTH = "width";
|
||||
public static final String COLUMN_HEIGHT = "height";
|
||||
public static final String COLUMN_LICENSE = "license";
|
||||
|
||||
// NOTE! KEEP IN SAME ORDER AS THEY ARE DEFINED UP THERE. HELPS HARD CODE COLUMN INDICES.
|
||||
public static final String[] ALL_FIELDS = {
|
||||
COLUMN_ID,
|
||||
COLUMN_FILENAME,
|
||||
COLUMN_LOCAL_URI,
|
||||
COLUMN_IMAGE_URL,
|
||||
COLUMN_TIMESTAMP,
|
||||
COLUMN_STATE,
|
||||
COLUMN_LENGTH,
|
||||
COLUMN_UPLOADED,
|
||||
COLUMN_TRANSFERRED,
|
||||
COLUMN_SOURCE,
|
||||
COLUMN_DESCRIPTION,
|
||||
COLUMN_CREATOR,
|
||||
COLUMN_MULTIPLE,
|
||||
COLUMN_WIDTH,
|
||||
COLUMN_HEIGHT,
|
||||
COLUMN_LICENSE
|
||||
};
|
||||
|
||||
|
||||
private static final String CREATE_TABLE_STATEMENT = "CREATE TABLE " + TABLE_NAME + " ("
|
||||
+ "_id INTEGER PRIMARY KEY,"
|
||||
+ "filename STRING,"
|
||||
+ "local_uri STRING,"
|
||||
+ "image_url STRING,"
|
||||
+ "uploaded INTEGER,"
|
||||
+ "timestamp INTEGER,"
|
||||
+ "state INTEGER,"
|
||||
+ "length INTEGER,"
|
||||
+ "transferred INTEGER,"
|
||||
+ "source STRING,"
|
||||
+ "description STRING,"
|
||||
+ "creator STRING,"
|
||||
+ "multiple INTEGER,"
|
||||
+ "width INTEGER,"
|
||||
+ "height INTEGER,"
|
||||
+ "LICENSE STRING"
|
||||
+ ");";
|
||||
|
||||
|
||||
public static void onCreate(SQLiteDatabase db) {
|
||||
db.execSQL(CREATE_TABLE_STATEMENT);
|
||||
}
|
||||
|
||||
public static void onDelete(SQLiteDatabase db) {
|
||||
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
|
||||
onCreate(db);
|
||||
}
|
||||
|
||||
public static void onUpdate(SQLiteDatabase db, int from, int to) {
|
||||
if (from == to) {
|
||||
return;
|
||||
}
|
||||
if (from == 1) {
|
||||
db.execSQL("ALTER TABLE " + TABLE_NAME + " ADD COLUMN description STRING;");
|
||||
db.execSQL("ALTER TABLE " + TABLE_NAME + " ADD COLUMN creator STRING;");
|
||||
from++;
|
||||
onUpdate(db, from, to);
|
||||
return;
|
||||
}
|
||||
if (from == 2) {
|
||||
db.execSQL("ALTER TABLE " + TABLE_NAME + " ADD COLUMN multiple INTEGER;");
|
||||
db.execSQL("UPDATE " + TABLE_NAME + " SET multiple = 0");
|
||||
from++;
|
||||
onUpdate(db, from, to);
|
||||
return;
|
||||
}
|
||||
if (from == 3) {
|
||||
// Do nothing
|
||||
from++;
|
||||
onUpdate(db, from, to);
|
||||
return;
|
||||
}
|
||||
if (from == 4) {
|
||||
// Do nothing -- added Category
|
||||
from++;
|
||||
onUpdate(db, from, to);
|
||||
return;
|
||||
}
|
||||
if (from == 5) {
|
||||
// Added width and height fields
|
||||
db.execSQL("ALTER TABLE " + TABLE_NAME + " ADD COLUMN width INTEGER;");
|
||||
db.execSQL("UPDATE " + TABLE_NAME + " SET width = 0");
|
||||
db.execSQL("ALTER TABLE " + TABLE_NAME + " ADD COLUMN height INTEGER;");
|
||||
db.execSQL("UPDATE " + TABLE_NAME + " SET height = 0");
|
||||
db.execSQL("ALTER TABLE " + TABLE_NAME + " ADD COLUMN license STRING;");
|
||||
db.execSQL("UPDATE " + TABLE_NAME + " SET license='" + Prefs.Licenses.CC_BY_SA_3 + "';");
|
||||
from++;
|
||||
onUpdate(db, from, to);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private String licenseTemplateFor(String license) {
|
||||
switch (license) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,281 @@
|
|||
package fr.free.nrw.commons.contributions;
|
||||
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.net.Uri;
|
||||
import android.os.RemoteException;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import fr.free.nrw.commons.settings.Prefs;
|
||||
|
||||
import static fr.free.nrw.commons.contributions.ContributionDao.Table.ALL_FIELDS;
|
||||
import static fr.free.nrw.commons.contributions.ContributionsContentProvider.BASE_URI;
|
||||
import static fr.free.nrw.commons.contributions.ContributionsContentProvider.uriForId;
|
||||
|
||||
public class ContributionDao {
|
||||
/*
|
||||
This sorts in the following order:
|
||||
Currently Uploading
|
||||
Failed (Sorted in ascending order of time added - FIFO)
|
||||
Queued to Upload (Sorted in ascending order of time added - FIFO)
|
||||
Completed (Sorted in descending order of time added)
|
||||
|
||||
This is why Contribution.STATE_COMPLETED is -1.
|
||||
*/
|
||||
static final String CONTRIBUTION_SORT = Table.COLUMN_STATE + " DESC, "
|
||||
+ Table.COLUMN_UPLOADED + " DESC , ("
|
||||
+ Table.COLUMN_TIMESTAMP + " * "
|
||||
+ Table.COLUMN_STATE + ")";
|
||||
|
||||
private final Provider<ContentProviderClient> clientProvider;
|
||||
|
||||
@Inject
|
||||
public ContributionDao(@Named("contribution") Provider<ContentProviderClient> clientProvider) {
|
||||
this.clientProvider = clientProvider;
|
||||
}
|
||||
|
||||
Cursor loadAllContributions() {
|
||||
ContentProviderClient db = clientProvider.get();
|
||||
try {
|
||||
return db.query(BASE_URI, ALL_FIELDS, "", null, CONTRIBUTION_SORT);
|
||||
} catch (RemoteException e) {
|
||||
return null;
|
||||
} finally {
|
||||
db.release();
|
||||
}
|
||||
}
|
||||
|
||||
public void save(Contribution contribution) {
|
||||
ContentProviderClient db = clientProvider.get();
|
||||
try {
|
||||
if (contribution.getContentUri() == null) {
|
||||
contribution.setContentUri(db.insert(BASE_URI, toContentValues(contribution)));
|
||||
} else {
|
||||
db.update(contribution.getContentUri(), toContentValues(contribution), null, null);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
db.release();
|
||||
}
|
||||
}
|
||||
|
||||
public void delete(Contribution contribution) {
|
||||
ContentProviderClient db = clientProvider.get();
|
||||
try {
|
||||
if (contribution.getContentUri() == null) {
|
||||
// noooo
|
||||
throw new RuntimeException("tried to delete item with no content URI");
|
||||
} else {
|
||||
db.delete(contribution.getContentUri(), null, null);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
db.release();
|
||||
}
|
||||
}
|
||||
|
||||
ContentValues toContentValues(Contribution contribution) {
|
||||
ContentValues cv = new ContentValues();
|
||||
cv.put(Table.COLUMN_FILENAME, contribution.getFilename());
|
||||
if (contribution.getLocalUri() != null) {
|
||||
cv.put(Table.COLUMN_LOCAL_URI, contribution.getLocalUri().toString());
|
||||
}
|
||||
if (contribution.getImageUrl() != null) {
|
||||
cv.put(Table.COLUMN_IMAGE_URL, contribution.getImageUrl());
|
||||
}
|
||||
if (contribution.getDateUploaded() != null) {
|
||||
cv.put(Table.COLUMN_UPLOADED, contribution.getDateUploaded().getTime());
|
||||
}
|
||||
cv.put(Table.COLUMN_LENGTH, contribution.getDataLength());
|
||||
cv.put(Table.COLUMN_TIMESTAMP, contribution.getTimestamp().getTime());
|
||||
cv.put(Table.COLUMN_STATE, contribution.getState());
|
||||
cv.put(Table.COLUMN_TRANSFERRED, contribution.getTransferred());
|
||||
cv.put(Table.COLUMN_SOURCE, contribution.getSource());
|
||||
cv.put(Table.COLUMN_DESCRIPTION, contribution.getDescription());
|
||||
cv.put(Table.COLUMN_CREATOR, contribution.getCreator());
|
||||
cv.put(Table.COLUMN_MULTIPLE, contribution.getMultiple() ? 1 : 0);
|
||||
cv.put(Table.COLUMN_WIDTH, contribution.getWidth());
|
||||
cv.put(Table.COLUMN_HEIGHT, contribution.getHeight());
|
||||
cv.put(Table.COLUMN_LICENSE, contribution.getLicense());
|
||||
return cv;
|
||||
}
|
||||
|
||||
public Contribution fromCursor(Cursor cursor) {
|
||||
// Hardcoding column positions!
|
||||
//Check that cursor has a value to avoid CursorIndexOutOfBoundsException
|
||||
if (cursor.getCount() > 0) {
|
||||
return new Contribution(
|
||||
uriForId(cursor.getInt(0)),
|
||||
cursor.getString(1),
|
||||
parseUri(cursor.getString(2)),
|
||||
cursor.getString(3),
|
||||
parseTimestamp(cursor.getLong(4)),
|
||||
cursor.getInt(5),
|
||||
cursor.getLong(6),
|
||||
parseTimestamp(cursor.getLong(7)),
|
||||
cursor.getLong(8),
|
||||
cursor.getString(9),
|
||||
cursor.getString(10),
|
||||
cursor.getString(11),
|
||||
cursor.getInt(12) == 1,
|
||||
cursor.getInt(13),
|
||||
cursor.getInt(14),
|
||||
cursor.getString(15));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Date parseTimestamp(long timestamp) {
|
||||
return timestamp == 0 ? null : new Date(timestamp);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Uri parseUri(String uriString) {
|
||||
return TextUtils.isEmpty(uriString) ? null : Uri.parse(uriString);
|
||||
}
|
||||
|
||||
public static class Table {
|
||||
public static final String TABLE_NAME = "contributions";
|
||||
|
||||
public static final String COLUMN_ID = "_id";
|
||||
public static final String COLUMN_FILENAME = "filename";
|
||||
public static final String COLUMN_LOCAL_URI = "local_uri";
|
||||
public static final String COLUMN_IMAGE_URL = "image_url";
|
||||
public static final String COLUMN_TIMESTAMP = "timestamp";
|
||||
public static final String COLUMN_STATE = "state";
|
||||
public static final String COLUMN_LENGTH = "length";
|
||||
public static final String COLUMN_UPLOADED = "uploaded";
|
||||
public static final String COLUMN_TRANSFERRED = "transferred"; // Currently transferred number of bytes
|
||||
public static final String COLUMN_SOURCE = "source";
|
||||
public static final String COLUMN_DESCRIPTION = "description";
|
||||
public static final String COLUMN_CREATOR = "creator"; // Initial uploader
|
||||
public static final String COLUMN_MULTIPLE = "multiple";
|
||||
public static final String COLUMN_WIDTH = "width";
|
||||
public static final String COLUMN_HEIGHT = "height";
|
||||
public static final String COLUMN_LICENSE = "license";
|
||||
|
||||
// NOTE! KEEP IN SAME ORDER AS THEY ARE DEFINED UP THERE. HELPS HARD CODE COLUMN INDICES.
|
||||
public static final String[] ALL_FIELDS = {
|
||||
COLUMN_ID,
|
||||
COLUMN_FILENAME,
|
||||
COLUMN_LOCAL_URI,
|
||||
COLUMN_IMAGE_URL,
|
||||
COLUMN_TIMESTAMP,
|
||||
COLUMN_STATE,
|
||||
COLUMN_LENGTH,
|
||||
COLUMN_UPLOADED,
|
||||
COLUMN_TRANSFERRED,
|
||||
COLUMN_SOURCE,
|
||||
COLUMN_DESCRIPTION,
|
||||
COLUMN_CREATOR,
|
||||
COLUMN_MULTIPLE,
|
||||
COLUMN_WIDTH,
|
||||
COLUMN_HEIGHT,
|
||||
COLUMN_LICENSE
|
||||
};
|
||||
|
||||
public static final String DROP_TABLE_STATEMENT = "DROP TABLE IF EXISTS " + TABLE_NAME;
|
||||
|
||||
public static final String CREATE_TABLE_STATEMENT = "CREATE TABLE " + TABLE_NAME + " ("
|
||||
+ "_id INTEGER PRIMARY KEY,"
|
||||
+ "filename STRING,"
|
||||
+ "local_uri STRING,"
|
||||
+ "image_url STRING,"
|
||||
+ "uploaded INTEGER,"
|
||||
+ "timestamp INTEGER,"
|
||||
+ "state INTEGER,"
|
||||
+ "length INTEGER,"
|
||||
+ "transferred INTEGER,"
|
||||
+ "source STRING,"
|
||||
+ "description STRING,"
|
||||
+ "creator STRING,"
|
||||
+ "multiple INTEGER,"
|
||||
+ "width INTEGER,"
|
||||
+ "height INTEGER,"
|
||||
+ "LICENSE STRING"
|
||||
+ ");";
|
||||
|
||||
// Upgrade from version 1 ->
|
||||
static final String ADD_CREATOR_FIELD = "ALTER TABLE " + TABLE_NAME + " ADD COLUMN creator STRING;";
|
||||
static final String ADD_DESCRIPTION_FIELD = "ALTER TABLE " + TABLE_NAME + " ADD COLUMN description STRING;";
|
||||
|
||||
// Upgrade from version 2 ->
|
||||
static final String ADD_MULTIPLE_FIELD = "ALTER TABLE " + TABLE_NAME + " ADD COLUMN multiple INTEGER;";
|
||||
static final String SET_DEFAULT_MULTIPLE = "UPDATE " + TABLE_NAME + " SET multiple = 0";
|
||||
|
||||
// Upgrade from version 5 ->
|
||||
static final String ADD_WIDTH_FIELD = "ALTER TABLE " + TABLE_NAME + " ADD COLUMN width INTEGER;";
|
||||
static final String SET_DEFAULT_WIDTH = "UPDATE " + TABLE_NAME + " SET width = 0";
|
||||
static final String ADD_HEIGHT_FIELD = "ALTER TABLE " + TABLE_NAME + " ADD COLUMN height INTEGER;";
|
||||
static final String SET_DEFAULT_HEIGHT = "UPDATE " + TABLE_NAME + " SET height = 0";
|
||||
static final String ADD_LICENSE_FIELD = "ALTER TABLE " + TABLE_NAME + " ADD COLUMN license STRING;";
|
||||
static final String SET_DEFAULT_LICENSE = "UPDATE " + TABLE_NAME + " SET license='" + Prefs.Licenses.CC_BY_SA_3 + "';";
|
||||
|
||||
|
||||
public static void onCreate(SQLiteDatabase db) {
|
||||
db.execSQL(CREATE_TABLE_STATEMENT);
|
||||
}
|
||||
|
||||
public static void onDelete(SQLiteDatabase db) {
|
||||
db.execSQL(DROP_TABLE_STATEMENT);
|
||||
onCreate(db);
|
||||
}
|
||||
|
||||
public static void onUpdate(SQLiteDatabase db, int from, int to) {
|
||||
if (from == to) {
|
||||
return;
|
||||
}
|
||||
if (from == 1) {
|
||||
db.execSQL(ADD_DESCRIPTION_FIELD);
|
||||
db.execSQL(ADD_CREATOR_FIELD);
|
||||
from++;
|
||||
onUpdate(db, from, to);
|
||||
return;
|
||||
}
|
||||
if (from == 2) {
|
||||
db.execSQL(ADD_MULTIPLE_FIELD);
|
||||
db.execSQL(SET_DEFAULT_MULTIPLE);
|
||||
from++;
|
||||
onUpdate(db, from, to);
|
||||
return;
|
||||
}
|
||||
if (from == 3) {
|
||||
// Do nothing
|
||||
from++;
|
||||
onUpdate(db, from, to);
|
||||
return;
|
||||
}
|
||||
if (from == 4) {
|
||||
// Do nothing -- added Category
|
||||
from++;
|
||||
onUpdate(db, from, to);
|
||||
return;
|
||||
}
|
||||
if (from == 5) {
|
||||
// Added width and height fields
|
||||
db.execSQL(ADD_WIDTH_FIELD);
|
||||
db.execSQL(SET_DEFAULT_WIDTH);
|
||||
db.execSQL(ADD_HEIGHT_FIELD);
|
||||
db.execSQL(SET_DEFAULT_HEIGHT);
|
||||
db.execSQL(ADD_LICENSE_FIELD);
|
||||
db.execSQL(SET_DEFAULT_LICENSE);
|
||||
from++;
|
||||
onUpdate(db, from, to);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -42,8 +42,7 @@ import timber.log.Timber;
|
|||
|
||||
import static android.content.ContentResolver.requestSync;
|
||||
import static fr.free.nrw.commons.contributions.Contribution.STATE_FAILED;
|
||||
import static fr.free.nrw.commons.contributions.Contribution.Table.ALL_FIELDS;
|
||||
import static fr.free.nrw.commons.contributions.ContributionsContentProvider.AUTHORITY;
|
||||
import static fr.free.nrw.commons.contributions.ContributionDao.Table.ALL_FIELDS;
|
||||
import static fr.free.nrw.commons.contributions.ContributionsContentProvider.BASE_URI;
|
||||
import static fr.free.nrw.commons.settings.Prefs.UPLOADS_SHOWING;
|
||||
|
||||
|
|
@ -58,6 +57,7 @@ public class ContributionsActivity
|
|||
@Inject MediaWikiApi mediaWikiApi;
|
||||
@Inject SessionManager sessionManager;
|
||||
@Inject @Named("default_preferences") SharedPreferences prefs;
|
||||
@Inject ContributionDao contributionDao;
|
||||
|
||||
private Cursor allContributions;
|
||||
private ContributionsListFragment contributionsList;
|
||||
|
|
@ -65,21 +65,6 @@ public class ContributionsActivity
|
|||
private UploadService uploadService;
|
||||
private boolean isUploadServiceConnected;
|
||||
private ArrayList<DataSetObserver> observersWaitingForLoad = new ArrayList<>();
|
||||
private String CONTRIBUTION_SELECTION = "";
|
||||
|
||||
/*
|
||||
This sorts in the following order:
|
||||
Currently Uploading
|
||||
Failed (Sorted in ascending order of time added - FIFO)
|
||||
Queued to Upload (Sorted in ascending order of time added - FIFO)
|
||||
Completed (Sorted in descending order of time added)
|
||||
|
||||
This is why Contribution.STATE_COMPLETED is -1.
|
||||
*/
|
||||
private String CONTRIBUTION_SORT = Contribution.Table.COLUMN_STATE + " DESC, "
|
||||
+ Contribution.Table.COLUMN_UPLOADED + " DESC , ("
|
||||
+ Contribution.Table.COLUMN_TIMESTAMP + " * "
|
||||
+ Contribution.Table.COLUMN_STATE + ")";
|
||||
|
||||
private CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||
|
||||
|
|
@ -94,7 +79,7 @@ public class ContributionsActivity
|
|||
@Override
|
||||
public void onServiceDisconnected(ComponentName componentName) {
|
||||
// this should never happen
|
||||
throw new RuntimeException("UploadService died but the rest of the process did not!");
|
||||
Timber.e(new RuntimeException("UploadService died but the rest of the process did not!"));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -121,14 +106,13 @@ public class ContributionsActivity
|
|||
@Override
|
||||
protected void onAuthCookieAcquired(String authCookie) {
|
||||
// Do a sync everytime we get here!
|
||||
requestSync(sessionManager.getCurrentAccount(), ContributionsContentProvider.AUTHORITY, new Bundle());
|
||||
requestSync(sessionManager.getCurrentAccount(), ContributionsContentProvider.CONTRIBUTION_AUTHORITY, new Bundle());
|
||||
Intent uploadServiceIntent = new Intent(this, UploadService.class);
|
||||
uploadServiceIntent.setAction(UploadService.ACTION_START_SERVICE);
|
||||
startService(uploadServiceIntent);
|
||||
bindService(uploadServiceIntent, uploadServiceConnection, Context.BIND_AUTO_CREATE);
|
||||
|
||||
allContributions = getContentResolver().query(BASE_URI, ALL_FIELDS,
|
||||
CONTRIBUTION_SELECTION, null, CONTRIBUTION_SORT);
|
||||
allContributions = contributionDao.loadAllContributions();
|
||||
|
||||
getSupportLoaderManager().initLoader(0, null, this);
|
||||
}
|
||||
|
|
@ -186,24 +170,23 @@ public class ContributionsActivity
|
|||
|
||||
public void retryUpload(int i) {
|
||||
allContributions.moveToPosition(i);
|
||||
Contribution c = Contribution.fromCursor(allContributions);
|
||||
Contribution c = contributionDao.fromCursor(allContributions);
|
||||
if (c.getState() == STATE_FAILED) {
|
||||
uploadService.queue(UploadService.ACTION_UPLOAD_FILE, c);
|
||||
Timber.d("Restarting for %s", c.toContentValues());
|
||||
Timber.d("Restarting for %s", c.toString());
|
||||
} else {
|
||||
Timber.d("Skipping re-upload for non-failed %s", c.toContentValues());
|
||||
Timber.d("Skipping re-upload for non-failed %s", c.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteUpload(int i) {
|
||||
allContributions.moveToPosition(i);
|
||||
Contribution c = Contribution.fromCursor(allContributions);
|
||||
Contribution c = contributionDao.fromCursor(allContributions);
|
||||
if (c.getState() == STATE_FAILED) {
|
||||
Timber.d("Deleting failed contrib %s", c.toContentValues());
|
||||
c.setContentProviderClient(getContentResolver().acquireContentProviderClient(AUTHORITY));
|
||||
c.delete();
|
||||
Timber.d("Deleting failed contrib %s", c.toString());
|
||||
contributionDao.delete(c);
|
||||
} else {
|
||||
Timber.d("Skipping deletion for non-failed contrib %s", c.toContentValues());
|
||||
Timber.d("Skipping deletion for non-failed contrib %s", c.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -239,8 +222,8 @@ public class ContributionsActivity
|
|||
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
|
||||
int uploads = prefs.getInt(UPLOADS_SHOWING, 100);
|
||||
return new CursorLoader(this, BASE_URI,
|
||||
ALL_FIELDS, CONTRIBUTION_SELECTION, null,
|
||||
CONTRIBUTION_SORT + "LIMIT " + uploads);
|
||||
ALL_FIELDS, "", null,
|
||||
ContributionDao.CONTRIBUTION_SORT + "LIMIT " + uploads);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -249,7 +232,7 @@ public class ContributionsActivity
|
|||
|
||||
if (contributionsList.getAdapter() == null) {
|
||||
contributionsList.setAdapter(new ContributionsListAdapter(getApplicationContext(),
|
||||
cursor, 0));
|
||||
cursor, 0, contributionDao));
|
||||
} else {
|
||||
((CursorAdapter) contributionsList.getAdapter()).swapCursor(cursor);
|
||||
}
|
||||
|
|
@ -270,7 +253,7 @@ public class ContributionsActivity
|
|||
// not yet ready to return data
|
||||
return null;
|
||||
} else {
|
||||
return Contribution.fromCursor((Cursor) contributionsList.getAdapter().getItem(i));
|
||||
return contributionDao.fromCursor((Cursor) contributionsList.getAdapter().getItem(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ import fr.free.nrw.commons.data.DBOpenHelper;
|
|||
import timber.log.Timber;
|
||||
|
||||
import static android.content.UriMatcher.NO_MATCH;
|
||||
import static fr.free.nrw.commons.contributions.Contribution.Table.ALL_FIELDS;
|
||||
import static fr.free.nrw.commons.contributions.Contribution.Table.TABLE_NAME;
|
||||
import static fr.free.nrw.commons.contributions.ContributionDao.Table.ALL_FIELDS;
|
||||
import static fr.free.nrw.commons.contributions.ContributionDao.Table.TABLE_NAME;
|
||||
|
||||
public class ContributionsContentProvider extends ContentProvider {
|
||||
|
||||
|
|
@ -26,13 +26,13 @@ public class ContributionsContentProvider extends ContentProvider {
|
|||
private static final int CONTRIBUTIONS_ID = 2;
|
||||
private static final String BASE_PATH = "contributions";
|
||||
private static final UriMatcher uriMatcher = new UriMatcher(NO_MATCH);
|
||||
public static final String AUTHORITY = "fr.free.nrw.commons.contributions.contentprovider";
|
||||
public static final String CONTRIBUTION_AUTHORITY = "fr.free.nrw.commons.contributions.contentprovider";
|
||||
|
||||
public static final Uri BASE_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH);
|
||||
public static final Uri BASE_URI = Uri.parse("content://" + CONTRIBUTION_AUTHORITY + "/" + BASE_PATH);
|
||||
|
||||
static {
|
||||
uriMatcher.addURI(AUTHORITY, BASE_PATH, CONTRIBUTIONS);
|
||||
uriMatcher.addURI(AUTHORITY, BASE_PATH + "/#", CONTRIBUTIONS_ID);
|
||||
uriMatcher.addURI(CONTRIBUTION_AUTHORITY, BASE_PATH, CONTRIBUTIONS);
|
||||
uriMatcher.addURI(CONTRIBUTION_AUTHORITY, BASE_PATH + "/#", CONTRIBUTIONS_ID);
|
||||
}
|
||||
|
||||
public static Uri uriForId(int id) {
|
||||
|
|
@ -176,7 +176,7 @@ public class ContributionsContentProvider extends ContentProvider {
|
|||
if (TextUtils.isEmpty(selection)) {
|
||||
rowsUpdated = sqlDB.update(TABLE_NAME,
|
||||
contentValues,
|
||||
Contribution.Table.COLUMN_ID + " = ?",
|
||||
ContributionDao.Table.COLUMN_ID + " = ?",
|
||||
new String[]{String.valueOf(id)});
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
|
|
|
|||
|
|
@ -11,8 +11,11 @@ import fr.free.nrw.commons.R;
|
|||
|
||||
class ContributionsListAdapter extends CursorAdapter {
|
||||
|
||||
public ContributionsListAdapter(Context context, Cursor c, int flags) {
|
||||
private final ContributionDao contributionDao;
|
||||
|
||||
public ContributionsListAdapter(Context context, Cursor c, int flags, ContributionDao contributionDao) {
|
||||
super(context, c, flags);
|
||||
this.contributionDao = contributionDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -26,7 +29,7 @@ class ContributionsListAdapter extends CursorAdapter {
|
|||
@Override
|
||||
public void bindView(View view, Context context, Cursor cursor) {
|
||||
final ContributionViewHolder views = (ContributionViewHolder)view.getTag();
|
||||
final Contribution contribution = Contribution.fromCursor(cursor);
|
||||
final Contribution contribution = contributionDao.fromCursor(cursor);
|
||||
|
||||
views.imageView.setMedia(contribution);
|
||||
views.titleView.setText(contribution.getDisplayTitle());
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ import fr.free.nrw.commons.mwapi.MediaWikiApi;
|
|||
import timber.log.Timber;
|
||||
|
||||
import static fr.free.nrw.commons.contributions.Contribution.STATE_COMPLETED;
|
||||
import static fr.free.nrw.commons.contributions.Contribution.Table.COLUMN_FILENAME;
|
||||
import static fr.free.nrw.commons.contributions.ContributionDao.Table.COLUMN_FILENAME;
|
||||
import static fr.free.nrw.commons.contributions.ContributionsContentProvider.BASE_URI;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
|
|
@ -89,6 +89,7 @@ public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter {
|
|||
LogEventResult result;
|
||||
Boolean done = false;
|
||||
String queryContinue = null;
|
||||
ContributionDao contributionDao = new ContributionDao(() -> contentProviderClient);
|
||||
while (!done) {
|
||||
|
||||
try {
|
||||
|
|
@ -121,7 +122,7 @@ public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter {
|
|||
"", -1, dateUpdated, dateUpdated, user,
|
||||
"", "");
|
||||
contrib.setState(STATE_COMPLETED);
|
||||
imageValues.add(contrib.toContentValues());
|
||||
imageValues.add(contributionDao.toContentValues(contrib));
|
||||
|
||||
if (imageValues.size() % COMMIT_THRESHOLD == 0) {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,276 +0,0 @@
|
|||
package fr.free.nrw.commons.data;
|
||||
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.net.Uri;
|
||||
import android.os.RemoteException;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
|
||||
import fr.free.nrw.commons.category.CategoryContentProvider;
|
||||
|
||||
/**
|
||||
* Represents a category
|
||||
*/
|
||||
public class Category {
|
||||
private Uri contentUri;
|
||||
|
||||
private String name;
|
||||
private Date lastUsed;
|
||||
private int timesUsed;
|
||||
|
||||
// Getters/setters
|
||||
/**
|
||||
* Gets name
|
||||
*
|
||||
* @return name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies name
|
||||
*
|
||||
* @param name Category name
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets last used date
|
||||
*
|
||||
* @return Last used date
|
||||
*/
|
||||
private Date getLastUsed() {
|
||||
// warning: Date objects are mutable.
|
||||
return (Date)lastUsed.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies last used date
|
||||
*
|
||||
* @param lastUsed Category date
|
||||
*/
|
||||
public void setLastUsed(Date lastUsed) {
|
||||
// warning: Date objects are mutable.
|
||||
this.lastUsed = (Date)lastUsed.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates new last used date
|
||||
*/
|
||||
private void touch() {
|
||||
lastUsed = new Date();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets no. of times the category is used
|
||||
*
|
||||
* @return no. of times used
|
||||
*/
|
||||
private int getTimesUsed() {
|
||||
return timesUsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies no. of times used
|
||||
*
|
||||
* @param timesUsed Category used times
|
||||
*/
|
||||
public void setTimesUsed(int timesUsed) {
|
||||
this.timesUsed = timesUsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments timesUsed by 1 and sets last used date as now.
|
||||
*/
|
||||
public void incTimesUsed() {
|
||||
timesUsed++;
|
||||
touch();
|
||||
}
|
||||
|
||||
//region Database/content-provider stuff
|
||||
|
||||
/**
|
||||
* Persist category.
|
||||
* @param client ContentProviderClient to handle DB connection
|
||||
*/
|
||||
public void save(ContentProviderClient client) {
|
||||
try {
|
||||
if (contentUri == null) {
|
||||
contentUri = client.insert(CategoryContentProvider.BASE_URI, this.toContentValues());
|
||||
} else {
|
||||
client.update(contentUri, toContentValues(), null, null);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets content values
|
||||
*
|
||||
* @return Content values
|
||||
*/
|
||||
private ContentValues toContentValues() {
|
||||
ContentValues cv = new ContentValues();
|
||||
cv.put(Table.COLUMN_NAME, getName());
|
||||
cv.put(Table.COLUMN_LAST_USED, getLastUsed().getTime());
|
||||
cv.put(Table.COLUMN_TIMES_USED, getTimesUsed());
|
||||
return cv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets category from cursor
|
||||
* @param cursor Category cursor
|
||||
* @return Category from cursor
|
||||
*/
|
||||
private static Category fromCursor(Cursor cursor) {
|
||||
// Hardcoding column positions!
|
||||
Category c = new Category();
|
||||
c.contentUri = CategoryContentProvider.uriForId(cursor.getInt(0));
|
||||
c.name = cursor.getString(1);
|
||||
c.lastUsed = new Date(cursor.getLong(2));
|
||||
c.timesUsed = cursor.getInt(3);
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find persisted category in database, based on its name.
|
||||
* @param client ContentProviderClient to handle DB connection
|
||||
* @param name Category's name
|
||||
* @return category from database, or null if not found
|
||||
*/
|
||||
public static @Nullable Category find(ContentProviderClient client, String name) {
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = client.query(
|
||||
CategoryContentProvider.BASE_URI,
|
||||
Category.Table.ALL_FIELDS,
|
||||
Category.Table.COLUMN_NAME + "=?",
|
||||
new String[]{name},
|
||||
null);
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
return Category.fromCursor(cursor);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
// This feels lazy, but to hell with checked exceptions. :)
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve recently-used categories, ordered by descending date.
|
||||
* @return a list containing recent categories
|
||||
*/
|
||||
public static @NonNull ArrayList<String> recentCategories(ContentProviderClient client, int limit) {
|
||||
ArrayList<String> items = new ArrayList<>();
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = client.query(
|
||||
CategoryContentProvider.BASE_URI,
|
||||
Category.Table.ALL_FIELDS,
|
||||
null,
|
||||
new String[]{},
|
||||
Category.Table.COLUMN_LAST_USED + " DESC");
|
||||
// fixme add a limit on the original query instead of falling out of the loop?
|
||||
while (cursor != null && cursor.moveToNext()
|
||||
&& cursor.getPosition() < limit) {
|
||||
Category cat = Category.fromCursor(cursor);
|
||||
items.add(cat.getName());
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
public static class Table {
|
||||
public static final String TABLE_NAME = "categories";
|
||||
|
||||
public static final String COLUMN_ID = "_id";
|
||||
public static final String COLUMN_NAME = "name";
|
||||
public static final String COLUMN_LAST_USED = "last_used";
|
||||
public static final String COLUMN_TIMES_USED = "times_used";
|
||||
|
||||
// NOTE! KEEP IN SAME ORDER AS THEY ARE DEFINED UP THERE. HELPS HARD CODE COLUMN INDICES.
|
||||
public static final String[] ALL_FIELDS = {
|
||||
COLUMN_ID,
|
||||
COLUMN_NAME,
|
||||
COLUMN_LAST_USED,
|
||||
COLUMN_TIMES_USED
|
||||
};
|
||||
|
||||
private static final String CREATE_TABLE_STATEMENT = "CREATE TABLE " + TABLE_NAME + " ("
|
||||
+ COLUMN_ID + " INTEGER PRIMARY KEY,"
|
||||
+ COLUMN_NAME + " STRING,"
|
||||
+ COLUMN_LAST_USED + " INTEGER,"
|
||||
+ COLUMN_TIMES_USED + " INTEGER"
|
||||
+ ");";
|
||||
|
||||
/**
|
||||
* Creates new table with provided SQLite database
|
||||
*
|
||||
* @param db Category database
|
||||
*/
|
||||
public static void onCreate(SQLiteDatabase db) {
|
||||
db.execSQL(CREATE_TABLE_STATEMENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes existing table
|
||||
* @param db Category database
|
||||
*/
|
||||
public static void onDelete(SQLiteDatabase db) {
|
||||
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
|
||||
onCreate(db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates given database
|
||||
* @param db Category database
|
||||
* @param from Exiting category id
|
||||
* @param to New category id
|
||||
*/
|
||||
public static void onUpdate(SQLiteDatabase db, int from, int to) {
|
||||
if (from == to) {
|
||||
return;
|
||||
}
|
||||
if (from < 4) {
|
||||
// doesn't exist yet
|
||||
from++;
|
||||
onUpdate(db, from, to);
|
||||
return;
|
||||
}
|
||||
if (from == 4) {
|
||||
// table added in version 5
|
||||
onCreate(db);
|
||||
from++;
|
||||
onUpdate(db, from, to);
|
||||
return;
|
||||
}
|
||||
if (from == 5) {
|
||||
from++;
|
||||
onUpdate(db, from, to);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
//endregion
|
||||
}
|
||||
|
|
@ -4,8 +4,9 @@ import android.content.Context;
|
|||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
|
||||
import fr.free.nrw.commons.contributions.Contribution;
|
||||
import fr.free.nrw.commons.modifications.ModifierSequence;
|
||||
import fr.free.nrw.commons.category.CategoryDao;
|
||||
import fr.free.nrw.commons.contributions.ContributionDao;
|
||||
import fr.free.nrw.commons.modifications.ModifierSequenceDao;
|
||||
|
||||
public class DBOpenHelper extends SQLiteOpenHelper {
|
||||
|
||||
|
|
@ -13,7 +14,8 @@ public class DBOpenHelper extends SQLiteOpenHelper {
|
|||
private static final int DATABASE_VERSION = 6;
|
||||
|
||||
/**
|
||||
* Do not use, please call CommonsApplication.getDBOpenHelper()
|
||||
* Do not use directly - @Inject an instance where it's needed and let
|
||||
* dependency injection take care of managing this as a singleton.
|
||||
*/
|
||||
public DBOpenHelper(Context context) {
|
||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
|
|
@ -21,15 +23,15 @@ public class DBOpenHelper extends SQLiteOpenHelper {
|
|||
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase sqLiteDatabase) {
|
||||
Contribution.Table.onCreate(sqLiteDatabase);
|
||||
ModifierSequence.Table.onCreate(sqLiteDatabase);
|
||||
Category.Table.onCreate(sqLiteDatabase);
|
||||
ContributionDao.Table.onCreate(sqLiteDatabase);
|
||||
ModifierSequenceDao.Table.onCreate(sqLiteDatabase);
|
||||
CategoryDao.Table.onCreate(sqLiteDatabase);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int from, int to) {
|
||||
Contribution.Table.onUpdate(sqLiteDatabase, from, to);
|
||||
ModifierSequence.Table.onUpdate(sqLiteDatabase, from, to);
|
||||
Category.Table.onUpdate(sqLiteDatabase, from, to);
|
||||
ContributionDao.Table.onUpdate(sqLiteDatabase, from, to);
|
||||
ModifierSequenceDao.Table.onUpdate(sqLiteDatabase, from, to);
|
||||
CategoryDao.Table.onUpdate(sqLiteDatabase, from, to);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import fr.free.nrw.commons.auth.LoginActivity;
|
|||
import fr.free.nrw.commons.auth.SignupActivity;
|
||||
import fr.free.nrw.commons.contributions.ContributionsActivity;
|
||||
import fr.free.nrw.commons.nearby.NearbyActivity;
|
||||
import fr.free.nrw.commons.notification.NotificationActivity;
|
||||
import fr.free.nrw.commons.settings.SettingsActivity;
|
||||
import fr.free.nrw.commons.upload.MultipleShareActivity;
|
||||
import fr.free.nrw.commons.upload.ShareActivity;
|
||||
|
|
@ -43,4 +44,6 @@ public abstract class ActivityBuilderModule {
|
|||
@ContributesAndroidInjector
|
||||
abstract NearbyActivity bindNearbyActivity();
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract NotificationActivity bindNotificationActivity();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package fr.free.nrw.commons.di;
|
||||
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v4.util.LruCache;
|
||||
|
|
@ -22,10 +23,14 @@ import fr.free.nrw.commons.nearby.NearbyPlaces;
|
|||
import fr.free.nrw.commons.upload.UploadController;
|
||||
|
||||
import static android.content.Context.MODE_PRIVATE;
|
||||
import static fr.free.nrw.commons.contributions.ContributionsContentProvider.CONTRIBUTION_AUTHORITY;
|
||||
import static fr.free.nrw.commons.modifications.ModificationsContentProvider.MODIFICATIONS_AUTHORITY;
|
||||
|
||||
@Module
|
||||
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||
public class CommonsApplicationModule {
|
||||
public static final String CATEGORY_AUTHORITY = "fr.free.nrw.commons.categories.contentprovider";
|
||||
|
||||
private CommonsApplication application;
|
||||
|
||||
public CommonsApplicationModule(CommonsApplication application) {
|
||||
|
|
@ -37,6 +42,24 @@ public class CommonsApplicationModule {
|
|||
return new AccountUtil(application);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Named("category")
|
||||
public ContentProviderClient provideCategoryContentProviderClient() {
|
||||
return application.getContentResolver().acquireContentProviderClient(CATEGORY_AUTHORITY);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Named("contribution")
|
||||
public ContentProviderClient provideContributionContentProviderClient() {
|
||||
return application.getContentResolver().acquireContentProviderClient(CONTRIBUTION_AUTHORITY);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Named("modification")
|
||||
public ContentProviderClient provideModificationContentProviderClient() {
|
||||
return application.getContentResolver().acquireContentProviderClient(MODIFICATIONS_AUTHORITY);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Named("application_preferences")
|
||||
public SharedPreferences providesApplicationSharedPreferences() {
|
||||
|
|
|
|||
|
|
@ -31,20 +31,36 @@ public class LocationServiceManager implements LocationListener {
|
|||
private final List<LocationUpdateListener> locationListeners = new CopyOnWriteArrayList<>();
|
||||
private boolean isLocationManagerRegistered = false;
|
||||
|
||||
/**
|
||||
* Constructs a new instance of LocationServiceManager.
|
||||
* @param context the context
|
||||
*/
|
||||
public LocationServiceManager(Context context) {
|
||||
this.context = context;
|
||||
this.locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current status of the GPS provider.
|
||||
* @return true if the GPS provider is enabled
|
||||
*/
|
||||
public boolean isProviderEnabled() {
|
||||
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the location permission is granted.
|
||||
* @return true if the location permission is granted
|
||||
*/
|
||||
public boolean isLocationPermissionGranted() {
|
||||
return ContextCompat.checkSelfPermission(context,
|
||||
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests the location permission to be granted.
|
||||
* @param activity the activity
|
||||
*/
|
||||
public void requestPermissions(Activity activity) {
|
||||
if (activity.isFinishing()) {
|
||||
return;
|
||||
|
|
@ -77,6 +93,11 @@ public class LocationServiceManager implements LocationListener {
|
|||
&& requestLocationUpdatesFromProvider(LocationManager.GPS_PROVIDER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests location updates from the specified provider.
|
||||
* @param locationProvider the location provider
|
||||
* @return true if successful
|
||||
*/
|
||||
private boolean requestLocationUpdatesFromProvider(String locationProvider) {
|
||||
try {
|
||||
locationManager.requestLocationUpdates(locationProvider,
|
||||
|
|
@ -93,6 +114,12 @@ public class LocationServiceManager implements LocationListener {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a given location is better than the current best location.
|
||||
* @param location the location to be tested
|
||||
* @param currentBestLocation the current best location
|
||||
* @return true if the given location is better
|
||||
*/
|
||||
protected boolean isBetterLocation(Location location, Location currentBestLocation) {
|
||||
if (currentBestLocation == null) {
|
||||
// A new location is always better than no location
|
||||
|
|
@ -156,12 +183,20 @@ public class LocationServiceManager implements LocationListener {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new listener to the list of location listeners.
|
||||
* @param listener the new listener
|
||||
*/
|
||||
public void addLocationListener(LocationUpdateListener listener) {
|
||||
if (!locationListeners.contains(listener)) {
|
||||
locationListeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a listener from the list of location listeners.
|
||||
* @param listener the listener to be removed
|
||||
*/
|
||||
public void removeLocationListener(LocationUpdateListener listener) {
|
||||
locationListeners.remove(listener);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,20 +16,22 @@ import dagger.android.AndroidInjection;
|
|||
import fr.free.nrw.commons.data.DBOpenHelper;
|
||||
import timber.log.Timber;
|
||||
|
||||
import static fr.free.nrw.commons.modifications.ModifierSequenceDao.Table.TABLE_NAME;
|
||||
|
||||
public class ModificationsContentProvider extends ContentProvider {
|
||||
|
||||
private static final int MODIFICATIONS = 1;
|
||||
private static final int MODIFICATIONS_ID = 2;
|
||||
|
||||
public static final String AUTHORITY = "fr.free.nrw.commons.modifications.contentprovider";
|
||||
private static final String BASE_PATH = "modifications";
|
||||
public static final String MODIFICATIONS_AUTHORITY = "fr.free.nrw.commons.modifications.contentprovider";
|
||||
public static final String BASE_PATH = "modifications";
|
||||
|
||||
public static final Uri BASE_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH);
|
||||
public static final Uri BASE_URI = Uri.parse("content://" + MODIFICATIONS_AUTHORITY + "/" + BASE_PATH);
|
||||
|
||||
private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
|
||||
static {
|
||||
uriMatcher.addURI(AUTHORITY, BASE_PATH, MODIFICATIONS);
|
||||
uriMatcher.addURI(AUTHORITY, BASE_PATH + "/#", MODIFICATIONS_ID);
|
||||
uriMatcher.addURI(MODIFICATIONS_AUTHORITY, BASE_PATH, MODIFICATIONS);
|
||||
uriMatcher.addURI(MODIFICATIONS_AUTHORITY, BASE_PATH + "/#", MODIFICATIONS_ID);
|
||||
}
|
||||
|
||||
public static Uri uriForId(int id) {
|
||||
|
|
@ -47,7 +49,7 @@ public class ModificationsContentProvider extends ContentProvider {
|
|||
@Override
|
||||
public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
|
||||
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
|
||||
queryBuilder.setTables(ModifierSequence.Table.TABLE_NAME);
|
||||
queryBuilder.setTables(TABLE_NAME);
|
||||
|
||||
int uriType = uriMatcher.match(uri);
|
||||
|
||||
|
|
@ -78,7 +80,7 @@ public class ModificationsContentProvider extends ContentProvider {
|
|||
long id = 0;
|
||||
switch (uriType) {
|
||||
case MODIFICATIONS:
|
||||
id = sqlDB.insert(ModifierSequence.Table.TABLE_NAME, null, contentValues);
|
||||
id = sqlDB.insert(TABLE_NAME, null, contentValues);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown URI: " + uri);
|
||||
|
|
@ -94,7 +96,7 @@ public class ModificationsContentProvider extends ContentProvider {
|
|||
switch (uriType) {
|
||||
case MODIFICATIONS_ID:
|
||||
String id = uri.getLastPathSegment();
|
||||
sqlDB.delete(ModifierSequence.Table.TABLE_NAME,
|
||||
sqlDB.delete(TABLE_NAME,
|
||||
"_id = ?",
|
||||
new String[] { id }
|
||||
);
|
||||
|
|
@ -114,7 +116,7 @@ public class ModificationsContentProvider extends ContentProvider {
|
|||
case MODIFICATIONS:
|
||||
for (ContentValues value: values) {
|
||||
Timber.d("Inserting! %s", value);
|
||||
sqlDB.insert(ModifierSequence.Table.TABLE_NAME, null, value);
|
||||
sqlDB.insert(TABLE_NAME, null, value);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
@ -140,7 +142,7 @@ public class ModificationsContentProvider extends ContentProvider {
|
|||
int rowsUpdated = 0;
|
||||
switch (uriType) {
|
||||
case MODIFICATIONS:
|
||||
rowsUpdated = sqlDB.update(ModifierSequence.Table.TABLE_NAME,
|
||||
rowsUpdated = sqlDB.update(TABLE_NAME,
|
||||
contentValues,
|
||||
selection,
|
||||
selectionArgs);
|
||||
|
|
@ -149,9 +151,9 @@ public class ModificationsContentProvider extends ContentProvider {
|
|||
int id = Integer.valueOf(uri.getLastPathSegment());
|
||||
|
||||
if (TextUtils.isEmpty(selection)) {
|
||||
rowsUpdated = sqlDB.update(ModifierSequence.Table.TABLE_NAME,
|
||||
rowsUpdated = sqlDB.update(TABLE_NAME,
|
||||
contentValues,
|
||||
ModifierSequence.Table.COLUMN_ID + " = ?",
|
||||
ModifierSequenceDao.Table.COLUMN_ID + " = ?",
|
||||
new String[] { String.valueOf(id) } );
|
||||
} else {
|
||||
throw new IllegalArgumentException("Parameter `selection` should be empty when updating an ID");
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import javax.inject.Inject;
|
|||
|
||||
import fr.free.nrw.commons.CommonsApplication;
|
||||
import fr.free.nrw.commons.contributions.Contribution;
|
||||
import fr.free.nrw.commons.contributions.ContributionDao;
|
||||
import fr.free.nrw.commons.contributions.ContributionsContentProvider;
|
||||
import fr.free.nrw.commons.mwapi.MediaWikiApi;
|
||||
import timber.log.Timber;
|
||||
|
|
@ -25,6 +26,8 @@ import timber.log.Timber;
|
|||
public class ModificationsSyncAdapter extends AbstractThreadedSyncAdapter {
|
||||
|
||||
@Inject MediaWikiApi mwApi;
|
||||
@Inject ContributionDao contributionDao;
|
||||
@Inject ModifierSequenceDao modifierSequenceDao;
|
||||
|
||||
public ModificationsSyncAdapter(Context context, boolean autoInitialize) {
|
||||
super(context, autoInitialize);
|
||||
|
|
@ -79,11 +82,10 @@ public class ModificationsSyncAdapter extends AbstractThreadedSyncAdapter {
|
|||
|
||||
ContentProviderClient contributionsClient = null;
|
||||
try {
|
||||
contributionsClient = getContext().getContentResolver().acquireContentProviderClient(ContributionsContentProvider.AUTHORITY);
|
||||
contributionsClient = getContext().getContentResolver().acquireContentProviderClient(ContributionsContentProvider.CONTRIBUTION_AUTHORITY);
|
||||
|
||||
while (!allModifications.isAfterLast()) {
|
||||
ModifierSequence sequence = ModifierSequence.fromCursor(allModifications);
|
||||
sequence.setContentProviderClient(contentProviderClient);
|
||||
ModifierSequence sequence = modifierSequenceDao.fromCursor(allModifications);
|
||||
Contribution contrib;
|
||||
|
||||
Cursor contributionCursor;
|
||||
|
|
@ -93,7 +95,7 @@ public class ModificationsSyncAdapter extends AbstractThreadedSyncAdapter {
|
|||
throw new RuntimeException(e);
|
||||
}
|
||||
contributionCursor.moveToFirst();
|
||||
contrib = Contribution.fromCursor(contributionCursor);
|
||||
contrib = contributionDao.fromCursor(contributionCursor);
|
||||
|
||||
if (contrib.getState() == Contribution.STATE_COMPLETED) {
|
||||
String pageContent;
|
||||
|
|
@ -121,7 +123,7 @@ public class ModificationsSyncAdapter extends AbstractThreadedSyncAdapter {
|
|||
// FIXME: Log this somewhere else
|
||||
Timber.d("Non success result! %s", editResult);
|
||||
} else {
|
||||
sequence.delete();
|
||||
modifierSequenceDao.delete(sequence);
|
||||
}
|
||||
}
|
||||
allModifications.moveToNext();
|
||||
|
|
|
|||
|
|
@ -1,14 +1,8 @@
|
|||
package fr.free.nrw.commons.modifications;
|
||||
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.net.Uri;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -17,14 +11,13 @@ public class ModifierSequence {
|
|||
private Uri mediaUri;
|
||||
private ArrayList<PageModifier> modifiers;
|
||||
private Uri contentUri;
|
||||
private ContentProviderClient client;
|
||||
|
||||
public ModifierSequence(Uri mediaUri) {
|
||||
this.mediaUri = mediaUri;
|
||||
modifiers = new ArrayList<>();
|
||||
}
|
||||
|
||||
public ModifierSequence(Uri mediaUri, JSONObject data) {
|
||||
ModifierSequence(Uri mediaUri, JSONObject data) {
|
||||
this(mediaUri);
|
||||
JSONArray modifiersJSON = data.optJSONArray("modifiers");
|
||||
for (int i = 0; i < modifiersJSON.length(); i++) {
|
||||
|
|
@ -32,7 +25,7 @@ public class ModifierSequence {
|
|||
}
|
||||
}
|
||||
|
||||
public Uri getMediaUri() {
|
||||
Uri getMediaUri() {
|
||||
return mediaUri;
|
||||
}
|
||||
|
||||
|
|
@ -40,14 +33,14 @@ public class ModifierSequence {
|
|||
modifiers.add(modifier);
|
||||
}
|
||||
|
||||
public String executeModifications(String pageName, String pageContents) {
|
||||
String executeModifications(String pageName, String pageContents) {
|
||||
for (PageModifier modifier: modifiers) {
|
||||
pageContents = modifier.doModification(pageName, pageContents);
|
||||
}
|
||||
return pageContents;
|
||||
}
|
||||
|
||||
public String getEditSummary() {
|
||||
String getEditSummary() {
|
||||
StringBuilder editSummary = new StringBuilder();
|
||||
for (PageModifier modifier: modifiers) {
|
||||
editSummary.append(modifier.getEditSumary()).append(" ");
|
||||
|
|
@ -56,97 +49,16 @@ public class ModifierSequence {
|
|||
return editSummary.toString();
|
||||
}
|
||||
|
||||
public JSONObject toJSON() {
|
||||
JSONObject data = new JSONObject();
|
||||
try {
|
||||
JSONArray modifiersJSON = new JSONArray();
|
||||
for (PageModifier modifier: modifiers) {
|
||||
modifiersJSON.put(modifier.toJSON());
|
||||
}
|
||||
data.put("modifiers", modifiersJSON);
|
||||
return data;
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
ArrayList<PageModifier> getModifiers() {
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
public ContentValues toContentValues() {
|
||||
ContentValues cv = new ContentValues();
|
||||
cv.put(Table.COLUMN_MEDIA_URI, mediaUri.toString());
|
||||
cv.put(Table.COLUMN_DATA, toJSON().toString());
|
||||
return cv;
|
||||
Uri getContentUri() {
|
||||
return contentUri;
|
||||
}
|
||||
|
||||
public static ModifierSequence fromCursor(Cursor cursor) {
|
||||
// Hardcoding column positions!
|
||||
ModifierSequence ms = null;
|
||||
try {
|
||||
ms = new ModifierSequence(Uri.parse(cursor.getString(1)),
|
||||
new JSONObject(cursor.getString(2)));
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
ms.contentUri = ModificationsContentProvider.uriForId(cursor.getInt(0));
|
||||
|
||||
return ms;
|
||||
void setContentUri(Uri contentUri) {
|
||||
this.contentUri = contentUri;
|
||||
}
|
||||
|
||||
public void save() {
|
||||
try {
|
||||
if (contentUri == null) {
|
||||
contentUri = client.insert(ModificationsContentProvider.BASE_URI, this.toContentValues());
|
||||
} else {
|
||||
client.update(contentUri, toContentValues(), null, null);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
try {
|
||||
client.delete(contentUri, null, null);
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void setContentProviderClient(ContentProviderClient client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public static class Table {
|
||||
public static final String TABLE_NAME = "modifications";
|
||||
|
||||
public static final String COLUMN_ID = "_id";
|
||||
public static final String COLUMN_MEDIA_URI = "mediauri";
|
||||
public static final String COLUMN_DATA = "data";
|
||||
|
||||
// NOTE! KEEP IN SAME ORDER AS THEY ARE DEFINED UP THERE. HELPS HARD CODE COLUMN INDICES.
|
||||
public static final String[] ALL_FIELDS = {
|
||||
COLUMN_ID,
|
||||
COLUMN_MEDIA_URI,
|
||||
COLUMN_DATA
|
||||
};
|
||||
|
||||
private static final String CREATE_TABLE_STATEMENT = "CREATE TABLE " + TABLE_NAME + " ("
|
||||
+ "_id INTEGER PRIMARY KEY,"
|
||||
+ "mediauri STRING,"
|
||||
+ "data STRING"
|
||||
+ ");";
|
||||
|
||||
public static void onCreate(SQLiteDatabase db) {
|
||||
db.execSQL(CREATE_TABLE_STATEMENT);
|
||||
}
|
||||
|
||||
public static void onUpdate(SQLiteDatabase db, int from, int to) {
|
||||
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
|
||||
onCreate(db);
|
||||
}
|
||||
|
||||
public static void onDelete(SQLiteDatabase db) {
|
||||
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
|
||||
onCreate(db);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,124 @@
|
|||
package fr.free.nrw.commons.modifications;
|
||||
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.net.Uri;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
|
||||
public class ModifierSequenceDao {
|
||||
|
||||
private final Provider<ContentProviderClient> clientProvider;
|
||||
|
||||
@Inject
|
||||
public ModifierSequenceDao(@Named("modification") Provider<ContentProviderClient> clientProvider) {
|
||||
this.clientProvider = clientProvider;
|
||||
}
|
||||
|
||||
public void save(ModifierSequence sequence) {
|
||||
ContentProviderClient db = clientProvider.get();
|
||||
try {
|
||||
if (sequence.getContentUri() == null) {
|
||||
sequence.setContentUri(db.insert(ModificationsContentProvider.BASE_URI, toContentValues(sequence)));
|
||||
} else {
|
||||
db.update(sequence.getContentUri(), toContentValues(sequence), null, null);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
db.release();
|
||||
}
|
||||
}
|
||||
|
||||
public void delete(ModifierSequence sequence) {
|
||||
ContentProviderClient db = clientProvider.get();
|
||||
try {
|
||||
db.delete(sequence.getContentUri(), null, null);
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
db.release();
|
||||
}
|
||||
}
|
||||
|
||||
ModifierSequence fromCursor(Cursor cursor) {
|
||||
// Hardcoding column positions!
|
||||
ModifierSequence ms = null;
|
||||
try {
|
||||
ms = new ModifierSequence(Uri.parse(cursor.getString(1)),
|
||||
new JSONObject(cursor.getString(2)));
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
ms.setContentUri( ModificationsContentProvider.uriForId(cursor.getInt(0)));
|
||||
|
||||
return ms;
|
||||
}
|
||||
|
||||
private JSONObject toJSON(ModifierSequence sequence) {
|
||||
JSONObject data = new JSONObject();
|
||||
try {
|
||||
JSONArray modifiersJSON = new JSONArray();
|
||||
for (PageModifier modifier: sequence.getModifiers()) {
|
||||
modifiersJSON.put(modifier.toJSON());
|
||||
}
|
||||
data.put("modifiers", modifiersJSON);
|
||||
return data;
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private ContentValues toContentValues(ModifierSequence sequence) {
|
||||
ContentValues cv = new ContentValues();
|
||||
cv.put(Table.COLUMN_MEDIA_URI, sequence.getMediaUri().toString());
|
||||
cv.put(Table.COLUMN_DATA, toJSON(sequence).toString());
|
||||
return cv;
|
||||
}
|
||||
|
||||
public static class Table {
|
||||
static final String TABLE_NAME = "modifications";
|
||||
|
||||
static final String COLUMN_ID = "_id";
|
||||
static final String COLUMN_MEDIA_URI = "mediauri";
|
||||
static final String COLUMN_DATA = "data";
|
||||
|
||||
// NOTE! KEEP IN SAME ORDER AS THEY ARE DEFINED UP THERE. HELPS HARD CODE COLUMN INDICES.
|
||||
public static final String[] ALL_FIELDS = {
|
||||
COLUMN_ID,
|
||||
COLUMN_MEDIA_URI,
|
||||
COLUMN_DATA
|
||||
};
|
||||
|
||||
static final String DROP_TABLE_STATEMENT = "DROP TABLE IF EXISTS " + TABLE_NAME;
|
||||
|
||||
static final String CREATE_TABLE_STATEMENT = "CREATE TABLE " + TABLE_NAME + " ("
|
||||
+ "_id INTEGER PRIMARY KEY,"
|
||||
+ "mediauri STRING,"
|
||||
+ "data STRING"
|
||||
+ ");";
|
||||
|
||||
public static void onCreate(SQLiteDatabase db) {
|
||||
db.execSQL(CREATE_TABLE_STATEMENT);
|
||||
}
|
||||
|
||||
public static void onUpdate(SQLiteDatabase db, int from, int to) {
|
||||
db.execSQL(DROP_TABLE_STATEMENT);
|
||||
onCreate(db);
|
||||
}
|
||||
|
||||
public static void onDelete(SQLiteDatabase db) {
|
||||
db.execSQL(DROP_TABLE_STATEMENT);
|
||||
onCreate(db);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package fr.free.nrw.commons.notification;
|
||||
|
||||
/**
|
||||
* Created by root on 18.12.2017.
|
||||
*/
|
||||
|
||||
public class Notification {
|
||||
public NotificationType notificationType;
|
||||
public String notificationText;
|
||||
|
||||
|
||||
Notification (NotificationType notificationType, String notificationText) {
|
||||
this.notificationType = notificationType;
|
||||
this.notificationText = notificationText;
|
||||
}
|
||||
|
||||
|
||||
public enum NotificationType {
|
||||
/* Added for test purposes, needs to be rescheduled after implementing
|
||||
fetching notifications from server */
|
||||
edit,
|
||||
mention,
|
||||
message,
|
||||
block;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package fr.free.nrw.commons.notification;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Optional;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.theme.NavigationBaseActivity;
|
||||
|
||||
/**
|
||||
* Created by root on 18.12.2017.
|
||||
*/
|
||||
|
||||
public class NotificationActivity extends NavigationBaseActivity {
|
||||
NotificationAdapterFactory notificationAdapterFactory;
|
||||
|
||||
@Nullable
|
||||
@BindView(R.id.listView) RecyclerView recyclerView;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_notification);
|
||||
ButterKnife.bind(this);
|
||||
initListView();
|
||||
addNotifications();
|
||||
initDrawer();
|
||||
}
|
||||
|
||||
private void initListView() {
|
||||
recyclerView = findViewById(R.id.listView);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
notificationAdapterFactory = new NotificationAdapterFactory(new NotificationRenderer.NotificationClicked() {
|
||||
@Override
|
||||
public void notificationClicked(Notification notification) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void addNotifications() {
|
||||
|
||||
recyclerView.setAdapter(notificationAdapterFactory.create(NotificationController.loadNotifications()));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package fr.free.nrw.commons.notification;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.pedrogomez.renderers.ListAdapteeCollection;
|
||||
import com.pedrogomez.renderers.RVRendererAdapter;
|
||||
import com.pedrogomez.renderers.RendererBuilder;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by root on 19.12.2017.
|
||||
*/
|
||||
|
||||
class NotificationAdapterFactory {
|
||||
private NotificationRenderer.NotificationClicked listener;
|
||||
|
||||
NotificationAdapterFactory(@NonNull NotificationRenderer.NotificationClicked listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public RVRendererAdapter<Notification> create(List<Notification> notifications) {
|
||||
RendererBuilder<Notification> builder = new RendererBuilder<Notification>()
|
||||
.bind(Notification.class, new NotificationRenderer(listener));
|
||||
ListAdapteeCollection<Notification> collection = new ListAdapteeCollection<>(
|
||||
notifications != null ? notifications : Collections.<Notification>emptyList());
|
||||
return new RVRendererAdapter<>(builder, collection);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package fr.free.nrw.commons.notification;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by root on 19.12.2017.
|
||||
*/
|
||||
|
||||
public class NotificationController {
|
||||
|
||||
public static List<Notification> loadNotifications() {
|
||||
List<Notification> notifications = new ArrayList<>();
|
||||
notifications.add(new Notification(Notification.NotificationType.message, "notification 1"));
|
||||
notifications.add(new Notification(Notification.NotificationType.edit, "notification 2"));
|
||||
notifications.add(new Notification(Notification.NotificationType.mention, "notification 3"));
|
||||
notifications.add(new Notification(Notification.NotificationType.message, "notification 4"));
|
||||
notifications.add(new Notification(Notification.NotificationType.edit, "notification 5"));
|
||||
notifications.add(new Notification(Notification.NotificationType.mention, "notification 6"));
|
||||
notifications.add(new Notification(Notification.NotificationType.message, "notification 7"));
|
||||
return notifications;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
package fr.free.nrw.commons.notification;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.pedrogomez.renderers.Renderer;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import fr.free.nrw.commons.R;
|
||||
|
||||
/**
|
||||
* Created by root on 19.12.2017.
|
||||
*/
|
||||
|
||||
public class NotificationRenderer extends Renderer<Notification> {
|
||||
@BindView(R.id.title) TextView title;
|
||||
@BindView(R.id.description) TextView description;
|
||||
@BindView(R.id.time) TextView time;
|
||||
@BindView(R.id.icon) ImageView icon;
|
||||
private NotificationClicked listener;
|
||||
|
||||
|
||||
NotificationRenderer(NotificationClicked listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUpView(View view) { }
|
||||
|
||||
@Override
|
||||
protected void hookListeners(View rootView) {
|
||||
rootView.setOnClickListener(v -> listener.notificationClicked(getContent()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected View inflate(LayoutInflater layoutInflater, ViewGroup viewGroup) {
|
||||
View inflatedView = layoutInflater.inflate(R.layout.item_notification, viewGroup, false);
|
||||
ButterKnife.bind(this, inflatedView);
|
||||
return inflatedView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render() {
|
||||
Notification notification = getContent();
|
||||
title.setText(notification.notificationText);
|
||||
time.setText("3d");
|
||||
description.setText("Example notification description");
|
||||
switch (notification.notificationType) {
|
||||
case edit:
|
||||
icon.setImageResource(R.drawable.ic_edit_black_24dp);
|
||||
break;
|
||||
case message:
|
||||
icon.setImageResource(R.drawable.ic_message_black_24dp);
|
||||
break;
|
||||
case mention:
|
||||
icon.setImageResource(R.drawable.ic_chat_bubble_black_24px);
|
||||
break;
|
||||
default:
|
||||
icon.setImageResource(R.drawable.round_icon_unknown);
|
||||
}
|
||||
}
|
||||
|
||||
public interface NotificationClicked{
|
||||
void notificationClicked(Notification notification);
|
||||
}
|
||||
}
|
||||
|
|
@ -27,6 +27,7 @@ import fr.free.nrw.commons.auth.AccountUtil;
|
|||
import fr.free.nrw.commons.auth.LoginActivity;
|
||||
import fr.free.nrw.commons.contributions.ContributionsActivity;
|
||||
import fr.free.nrw.commons.nearby.NearbyActivity;
|
||||
import fr.free.nrw.commons.notification.NotificationActivity;
|
||||
import fr.free.nrw.commons.settings.SettingsActivity;
|
||||
import timber.log.Timber;
|
||||
|
||||
|
|
@ -143,6 +144,10 @@ public abstract class NavigationBaseActivity extends BaseActivity
|
|||
.setNegativeButton(R.string.no, (dialog, which) -> dialog.cancel())
|
||||
.show();
|
||||
return true;
|
||||
case R.id.action_notifications:
|
||||
drawerLayout.closeDrawer(navigationView);
|
||||
startActivityWithFlags(this, NotificationActivity.class, Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
||||
return true;
|
||||
default:
|
||||
Timber.e("Unknown option [%s] selected from the navigation menu", itemId);
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package fr.free.nrw.commons.upload;
|
|||
|
||||
import android.Manifest;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
|
@ -40,6 +39,7 @@ import fr.free.nrw.commons.media.MediaDetailPagerFragment;
|
|||
import fr.free.nrw.commons.modifications.CategoryModifier;
|
||||
import fr.free.nrw.commons.modifications.ModificationsContentProvider;
|
||||
import fr.free.nrw.commons.modifications.ModifierSequence;
|
||||
import fr.free.nrw.commons.modifications.ModifierSequenceDao;
|
||||
import fr.free.nrw.commons.modifications.TemplateRemoveModifier;
|
||||
import fr.free.nrw.commons.mwapi.MediaWikiApi;
|
||||
import timber.log.Timber;
|
||||
|
|
@ -54,6 +54,7 @@ public class MultipleShareActivity extends AuthenticatedActivity
|
|||
@Inject MediaWikiApi mwApi;
|
||||
@Inject SessionManager sessionManager;
|
||||
@Inject UploadController uploadController;
|
||||
@Inject ModifierSequenceDao modifierSequenceDao;
|
||||
@Inject @Named("default_preferences") SharedPreferences prefs;
|
||||
|
||||
private ArrayList<Contribution> photosList = null;
|
||||
|
|
@ -165,20 +166,18 @@ public class MultipleShareActivity extends AuthenticatedActivity
|
|||
@Override
|
||||
public void onCategoriesSave(List<String> categories) {
|
||||
if (categories.size() > 0) {
|
||||
ContentProviderClient client = getContentResolver().acquireContentProviderClient(ModificationsContentProvider.AUTHORITY);
|
||||
for (Contribution contribution : photosList) {
|
||||
ModifierSequence categoriesSequence = new ModifierSequence(contribution.getContentUri());
|
||||
|
||||
categoriesSequence.queueModifier(new CategoryModifier(categories.toArray(new String[]{})));
|
||||
categoriesSequence.queueModifier(new TemplateRemoveModifier("Uncategorized"));
|
||||
|
||||
categoriesSequence.setContentProviderClient(client);
|
||||
categoriesSequence.save();
|
||||
modifierSequenceDao.save(categoriesSequence);
|
||||
}
|
||||
}
|
||||
// FIXME: Make sure that the content provider is up
|
||||
// This is the wrong place for it, but bleh - better than not having it turned on by default for people who don't go throughl ogin
|
||||
ContentResolver.setSyncAutomatically(sessionManager.getCurrentAccount(), ModificationsContentProvider.AUTHORITY, true); // Enable sync by default!
|
||||
ContentResolver.setSyncAutomatically(sessionManager.getCurrentAccount(), ModificationsContentProvider.MODIFICATIONS_AUTHORITY, true); // Enable sync by default!
|
||||
finish();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ import javax.inject.Inject;
|
|||
import javax.inject.Named;
|
||||
|
||||
import butterknife.ButterKnife;
|
||||
import fr.free.nrw.commons.CommonsApplication;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.auth.AuthenticatedActivity;
|
||||
import fr.free.nrw.commons.auth.SessionManager;
|
||||
|
|
@ -50,8 +49,8 @@ import fr.free.nrw.commons.contributions.Contribution;
|
|||
import fr.free.nrw.commons.modifications.CategoryModifier;
|
||||
import fr.free.nrw.commons.modifications.ModificationsContentProvider;
|
||||
import fr.free.nrw.commons.modifications.ModifierSequence;
|
||||
import fr.free.nrw.commons.modifications.ModifierSequenceDao;
|
||||
import fr.free.nrw.commons.modifications.TemplateRemoveModifier;
|
||||
import fr.free.nrw.commons.mwapi.EventLog;
|
||||
import fr.free.nrw.commons.mwapi.MediaWikiApi;
|
||||
import timber.log.Timber;
|
||||
|
||||
|
|
@ -77,6 +76,7 @@ public class ShareActivity
|
|||
@Inject CacheController cacheController;
|
||||
@Inject SessionManager sessionManager;
|
||||
@Inject UploadController uploadController;
|
||||
@Inject ModifierSequenceDao modifierSequenceDao;
|
||||
@Inject @Named("default_preferences") SharedPreferences prefs;
|
||||
|
||||
private String source;
|
||||
|
|
@ -167,13 +167,12 @@ public class ShareActivity
|
|||
|
||||
categoriesSequence.queueModifier(new CategoryModifier(categories.toArray(new String[]{})));
|
||||
categoriesSequence.queueModifier(new TemplateRemoveModifier("Uncategorized"));
|
||||
categoriesSequence.setContentProviderClient(getContentResolver().acquireContentProviderClient(ModificationsContentProvider.AUTHORITY));
|
||||
categoriesSequence.save();
|
||||
modifierSequenceDao.save(categoriesSequence);
|
||||
}
|
||||
|
||||
// FIXME: Make sure that the content provider is up
|
||||
// This is the wrong place for it, but bleh - better than not having it turned on by default for people who don't go throughl ogin
|
||||
ContentResolver.setSyncAutomatically(sessionManager.getCurrentAccount(), ModificationsContentProvider.AUTHORITY, true); // Enable sync by default!
|
||||
ContentResolver.setSyncAutomatically(sessionManager.getCurrentAccount(), ModificationsContentProvider.MODIFICATIONS_AUTHORITY, true); // Enable sync by default!
|
||||
|
||||
finish();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ public class UploadController {
|
|||
void onUploadStarted(Contribution contribution);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new UploadController.
|
||||
*/
|
||||
public UploadController(SessionManager sessionManager, Context context, SharedPreferences sharedPreferences) {
|
||||
this.sessionManager = sessionManager;
|
||||
this.context = context;
|
||||
|
|
@ -53,10 +56,13 @@ public class UploadController {
|
|||
@Override
|
||||
public void onServiceDisconnected(ComponentName componentName) {
|
||||
// this should never happen
|
||||
throw new RuntimeException("UploadService died but the rest of the process did not!");
|
||||
Timber.e(new RuntimeException("UploadService died but the rest of the process did not!"));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Prepares the upload service.
|
||||
*/
|
||||
public void prepareService() {
|
||||
Intent uploadServiceIntent = new Intent(context, UploadService.class);
|
||||
uploadServiceIntent.setAction(UploadService.ACTION_START_SERVICE);
|
||||
|
|
@ -64,12 +70,25 @@ public class UploadController {
|
|||
context.bindService(uploadServiceIntent, uploadServiceConnection, Context.BIND_AUTO_CREATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects the upload service.
|
||||
*/
|
||||
public void cleanup() {
|
||||
if (isUploadServiceConnected) {
|
||||
context.unbindService(uploadServiceConnection);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a new upload task.
|
||||
* @param title the title of the contribution
|
||||
* @param mediaUri the media URI of the contribution
|
||||
* @param description the description of the contribution
|
||||
* @param mimeType the MIME type of the contribution
|
||||
* @param source the source of the contribution
|
||||
* @param decimalCoords the coordinates in decimal. (e.g. "37.51136|-77.602615")
|
||||
* @param onComplete the progress tracker
|
||||
*/
|
||||
public void startUpload(String title, Uri mediaUri, String description, String mimeType, String source, String decimalCoords, ContributionUploadProgress onComplete) {
|
||||
Contribution contribution;
|
||||
|
||||
|
|
@ -85,6 +104,11 @@ public class UploadController {
|
|||
startUpload(contribution, onComplete);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a new upload task.
|
||||
* @param contribution the contribution object
|
||||
* @param onComplete the progress tracker
|
||||
*/
|
||||
public void startUpload(final Contribution contribution, final ContributionUploadProgress onComplete) {
|
||||
//Set creator, desc, and license
|
||||
if (TextUtils.isEmpty(contribution.getCreator())) {
|
||||
|
|
@ -173,6 +197,12 @@ public class UploadController {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Counts the number of bytes in {@code stream}.
|
||||
* @param stream the stream
|
||||
* @return the number of bytes in {@code stream}
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
private long countBytes(InputStream stream) throws IOException {
|
||||
long count = 0;
|
||||
BufferedInputStream bis = new BufferedInputStream(stream);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import android.annotation.SuppressLint;
|
|||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Intent;
|
||||
|
|
@ -31,6 +30,7 @@ import fr.free.nrw.commons.R;
|
|||
import fr.free.nrw.commons.Utils;
|
||||
import fr.free.nrw.commons.auth.SessionManager;
|
||||
import fr.free.nrw.commons.contributions.Contribution;
|
||||
import fr.free.nrw.commons.contributions.ContributionDao;
|
||||
import fr.free.nrw.commons.contributions.ContributionsActivity;
|
||||
import fr.free.nrw.commons.contributions.ContributionsContentProvider;
|
||||
import fr.free.nrw.commons.modifications.ModificationsContentProvider;
|
||||
|
|
@ -51,9 +51,9 @@ public class UploadService extends HandlerService<Contribution> {
|
|||
@Inject MediaWikiApi mwApi;
|
||||
@Inject SessionManager sessionManager;
|
||||
@Inject @Named("default_preferences") SharedPreferences prefs;
|
||||
@Inject ContributionDao contributionDao;
|
||||
|
||||
private NotificationManager notificationManager;
|
||||
private ContentProviderClient contributionsProviderClient;
|
||||
private NotificationCompat.Builder curProgressNotification;
|
||||
private int toUpload;
|
||||
|
||||
|
|
@ -105,7 +105,7 @@ public class UploadService extends HandlerService<Contribution> {
|
|||
startForeground(NOTIFICATION_UPLOAD_IN_PROGRESS, curProgressNotification.build());
|
||||
|
||||
contribution.setTransferred(transferred);
|
||||
contribution.save();
|
||||
contributionDao.save(contribution);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -113,7 +113,6 @@ public class UploadService extends HandlerService<Contribution> {
|
|||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
contributionsProviderClient.release();
|
||||
Timber.d("UploadService.onDestroy; %s are yet to be uploaded", unfinishedUploads);
|
||||
}
|
||||
|
||||
|
|
@ -122,7 +121,6 @@ public class UploadService extends HandlerService<Contribution> {
|
|||
super.onCreate();
|
||||
|
||||
notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||
contributionsProviderClient = this.getContentResolver().acquireContentProviderClient(ContributionsContentProvider.AUTHORITY);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -144,9 +142,7 @@ public class UploadService extends HandlerService<Contribution> {
|
|||
|
||||
contribution.setState(Contribution.STATE_QUEUED);
|
||||
contribution.setTransferred(0);
|
||||
contribution.setContentProviderClient(contributionsProviderClient);
|
||||
|
||||
contribution.save();
|
||||
contributionDao.save(contribution);
|
||||
toUpload++;
|
||||
if (curProgressNotification != null && toUpload != 1) {
|
||||
curProgressNotification.setContentText(getResources().getQuantityString(R.plurals.uploads_pending_notification_indicator, toUpload, toUpload));
|
||||
|
|
@ -167,11 +163,11 @@ public class UploadService extends HandlerService<Contribution> {
|
|||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
if (intent.getAction().equals(ACTION_START_SERVICE) && freshStart) {
|
||||
ContentValues failedValues = new ContentValues();
|
||||
failedValues.put(Contribution.Table.COLUMN_STATE, Contribution.STATE_FAILED);
|
||||
failedValues.put(ContributionDao.Table.COLUMN_STATE, Contribution.STATE_FAILED);
|
||||
|
||||
int updated = getContentResolver().update(ContributionsContentProvider.BASE_URI,
|
||||
failedValues,
|
||||
Contribution.Table.COLUMN_STATE + " = ? OR " + Contribution.Table.COLUMN_STATE + " = ?",
|
||||
ContributionDao.Table.COLUMN_STATE + " = ? OR " + ContributionDao.Table.COLUMN_STATE + " = ?",
|
||||
new String[]{ String.valueOf(Contribution.STATE_QUEUED), String.valueOf(Contribution.STATE_IN_PROGRESS) }
|
||||
);
|
||||
Timber.d("Set %d uploads to failed", updated);
|
||||
|
|
@ -261,7 +257,7 @@ public class UploadService extends HandlerService<Contribution> {
|
|||
contribution.setImageUrl(uploadResult.getImageUrl());
|
||||
contribution.setState(Contribution.STATE_COMPLETED);
|
||||
contribution.setDateUploaded(uploadResult.getDateUploaded());
|
||||
contribution.save();
|
||||
contributionDao.save(contribution);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Timber.d("I have a network fuckup");
|
||||
|
|
@ -273,7 +269,7 @@ public class UploadService extends HandlerService<Contribution> {
|
|||
toUpload--;
|
||||
if (toUpload == 0) {
|
||||
// Sync modifications right after all uplaods are processed
|
||||
ContentResolver.requestSync(sessionManager.getCurrentAccount(), ModificationsContentProvider.AUTHORITY, new Bundle());
|
||||
ContentResolver.requestSync(sessionManager.getCurrentAccount(), ModificationsContentProvider.MODIFICATIONS_AUTHORITY, new Bundle());
|
||||
stopForeground(true);
|
||||
}
|
||||
}
|
||||
|
|
@ -292,7 +288,7 @@ public class UploadService extends HandlerService<Contribution> {
|
|||
notificationManager.notify(NOTIFICATION_UPLOAD_FAILED, failureNotification);
|
||||
|
||||
contribution.setState(Contribution.STATE_FAILED);
|
||||
contribution.save();
|
||||
contributionDao.save(contribution);
|
||||
}
|
||||
|
||||
private String findUniqueFilename(String fileName) throws IOException {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,11 @@ import timber.log.Timber;
|
|||
|
||||
public class DialogUtil {
|
||||
|
||||
/**
|
||||
* Dismisses a dialog safely.
|
||||
* @param activity the activity
|
||||
* @param dialog the dialog to be dismissed
|
||||
*/
|
||||
public static void dismissSafely(@Nullable Activity activity, @Nullable DialogFragment dialog) {
|
||||
boolean isActivityDestroyed = false;
|
||||
|
||||
|
|
@ -33,6 +38,11 @@ public class DialogUtil {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a dialog safely.
|
||||
* @param activity the activity
|
||||
* @param dialog the dialog to be shown
|
||||
*/
|
||||
public static void showSafely(Activity activity, Dialog dialog) {
|
||||
if (activity == null || dialog == null) {
|
||||
Timber.d("Show called with null activity / dialog. Ignoring.");
|
||||
|
|
@ -54,6 +64,11 @@ public class DialogUtil {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a dialog safely.
|
||||
* @param activity the activity
|
||||
* @param dialog the dialog to be shown
|
||||
*/
|
||||
public static void showSafely(FragmentActivity activity, DialogFragment dialog) {
|
||||
boolean isActivityDestroyed = false;
|
||||
|
||||
|
|
|
|||
9
app/src/main/res/drawable/ic_chat_bubble_black_24px.xml
Normal file
9
app/src/main/res/drawable/ic_chat_bubble_black_24px.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:pathData="M4,2C2.9,2 2,2.9 2,4L2,22L6,18L20,18C21.1,18 22,17.1 22,16L22,4C22,2.9 21.1,2 20,2L4,2zM12.496,4.098C13.408,4.098 14.236,4.273 14.98,4.623C15.725,4.969 16.347,5.47 16.848,6.125C17.153,6.524 17.384,6.956 17.539,7.424C17.698,7.888 17.775,8.376 17.775,8.889C17.775,9.991 17.444,10.849 16.781,11.459C16.118,12.069 15.183,12.375 13.975,12.375L13.736,12.375L13.736,11.434C13.614,11.722 13.417,11.949 13.145,12.111C12.876,12.27 12.559,12.35 12.197,12.35C11.497,12.35 10.928,12.098 10.488,11.594C10.053,11.085 9.836,10.423 9.836,9.609C9.836,8.796 10.055,8.134 10.494,7.625C10.934,7.116 11.501,6.863 12.197,6.863C12.559,6.863 12.876,6.945 13.145,7.107C13.417,7.27 13.614,7.496 13.736,7.785L13.736,6.984L15.012,6.984L15.012,11.215C15.516,11.138 15.912,10.895 16.201,10.488C16.49,10.077 16.635,9.553 16.635,8.914C16.635,8.507 16.575,8.125 16.457,7.771C16.339,7.413 16.16,7.086 15.92,6.789C15.533,6.293 15.051,5.911 14.469,5.643C13.891,5.374 13.263,5.238 12.588,5.238C12.116,5.238 11.664,5.302 11.232,5.428C10.801,5.55 10.403,5.731 10.037,5.971C9.435,6.369 8.965,6.887 8.627,7.521C8.293,8.152 8.127,8.836 8.127,9.572C8.127,10.179 8.234,10.748 8.449,11.281C8.669,11.81 8.986,12.279 9.396,12.686C9.803,13.084 10.268,13.388 10.793,13.596C11.322,13.807 11.886,13.912 12.484,13.912C12.997,13.912 13.511,13.816 14.023,13.625C14.536,13.434 14.972,13.175 15.334,12.85L15.258,14.324C14.96,14.491 14.648,14.63 14.322,14.742C13.724,14.954 13.115,15.061 12.496,15.061C11.743,15.061 11.035,14.925 10.367,14.656C9.7,14.392 9.105,14.007 8.584,13.498C8.063,12.989 7.667,12.4 7.395,11.732C7.122,11.061 6.984,10.341 6.984,9.572C6.984,8.832 7.124,8.126 7.4,7.455C7.677,6.784 8.071,6.194 8.584,5.686C9.097,5.181 9.694,4.79 10.373,4.514C11.057,4.237 11.764,4.098 12.496,4.098zM12.412,7.998C12.054,7.998 11.766,8.143 11.551,8.432C11.339,8.716 11.232,9.105 11.232,9.598C11.232,10.098 11.339,10.492 11.551,10.781C11.766,11.07 12.058,11.215 12.424,11.215C12.786,11.215 13.075,11.07 13.291,10.781C13.507,10.488 13.613,10.094 13.613,9.598C13.613,9.105 13.503,8.716 13.283,8.432C13.068,8.143 12.778,7.998 12.412,7.998z"
|
||||
android:fillColor="#000000"/>
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/ic_edit_black_24dp.xml
Normal file
9
app/src/main/res/drawable/ic_edit_black_24dp.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/ic_message_black_24dp.xml
Normal file
9
app/src/main/res/drawable/ic_message_black_24dp.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M20,2L4,2c-1.1,0 -1.99,0.9 -1.99,2L2,22l4,-4h14c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM18,14L6,14v-2h12v2zM18,11L6,11L6,9h12v2zM18,8L6,8L6,6h12v2z"/>
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z"/>
|
||||
</vector>
|
||||
|
|
@ -8,17 +8,17 @@
|
|||
android:layout_width="400sp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="8dp">
|
||||
android:layout_marginTop="@dimen/small_gap">
|
||||
|
||||
<android.support.v7.widget.CardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="32dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="@dimen/large_gap"
|
||||
android:layout_marginBottom="@dimen/standard_gap"
|
||||
android:layout_marginEnd="@dimen/standard_gap"
|
||||
android:layout_marginLeft="@dimen/standard_gap"
|
||||
android:layout_marginRight="@dimen/standard_gap"
|
||||
android:layout_marginStart="@dimen/standard_gap"
|
||||
app:cardCornerRadius="4dp"
|
||||
app:cardElevation="4dp">
|
||||
|
||||
|
|
@ -34,11 +34,11 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:background="@color/primaryColor"
|
||||
android:gravity="center"
|
||||
android:paddingBottom="32dp"
|
||||
android:paddingTop="32dp"
|
||||
android:paddingBottom="@dimen/large_gap"
|
||||
android:paddingTop="@dimen/large_gap"
|
||||
android:text="@string/login_to_your_account"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="24sp" />
|
||||
android:textSize="@dimen/heading_text_size" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/error_message_container"
|
||||
|
|
@ -52,12 +52,12 @@
|
|||
android:id="@+id/error_message"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:paddingTop="8dp"
|
||||
android:layout_marginEnd="@dimen/standard_gap"
|
||||
android:layout_marginLeft="@dimen/standard_gap"
|
||||
android:layout_marginRight="@dimen/standard_gap"
|
||||
android:layout_marginStart="@dimen/standard_gap"
|
||||
android:paddingBottom="@dimen/small_gap"
|
||||
android:paddingTop="@dimen/small_gap"
|
||||
android:textColor="@color/secondaryDarkColor"
|
||||
tools:text="Check your password, something doesnt look right" />
|
||||
</FrameLayout>
|
||||
|
|
@ -67,12 +67,12 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/error_message_container"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp">
|
||||
android:layout_marginBottom="@dimen/standard_gap"
|
||||
android:layout_marginEnd="@dimen/standard_gap"
|
||||
android:layout_marginLeft="@dimen/standard_gap"
|
||||
android:layout_marginRight="@dimen/standard_gap"
|
||||
android:layout_marginStart="@dimen/standard_gap"
|
||||
android:layout_marginTop="@dimen/standard_gap">
|
||||
|
||||
<android.support.design.widget.TextInputEditText
|
||||
android:id="@+id/loginUsername"
|
||||
|
|
@ -93,11 +93,11 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/username_container"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginBottom="@dimen/standard_gap"
|
||||
android:layout_marginEnd="@dimen/standard_gap"
|
||||
android:layout_marginLeft="@dimen/standard_gap"
|
||||
android:layout_marginRight="@dimen/standard_gap"
|
||||
android:layout_marginStart="@dimen/standard_gap"
|
||||
app:passwordToggleEnabled="false">
|
||||
|
||||
<android.support.design.widget.TextInputEditText
|
||||
|
|
@ -115,11 +115,11 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/password_container"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginBottom="@dimen/standard_gap"
|
||||
android:layout_marginEnd="@dimen/standard_gap"
|
||||
android:layout_marginLeft="@dimen/standard_gap"
|
||||
android:layout_marginRight="@dimen/standard_gap"
|
||||
android:layout_marginStart="@dimen/standard_gap"
|
||||
android:visibility="gone"
|
||||
app:passwordToggleEnabled="false"
|
||||
tools:visibility="visible">
|
||||
|
|
@ -141,11 +141,11 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/two_factor_container"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginStart="16dp">
|
||||
android:layout_marginBottom="@dimen/standard_gap"
|
||||
android:layout_marginEnd="@dimen/standard_gap"
|
||||
android:layout_marginLeft="@dimen/standard_gap"
|
||||
android:layout_marginRight="@dimen/standard_gap"
|
||||
android:layout_marginStart="@dimen/standard_gap">
|
||||
|
||||
<Button
|
||||
android:id="@+id/signupButton"
|
||||
|
|
@ -153,8 +153,8 @@
|
|||
style="@style/Widget.AppCompat.Button.Borderless.Colored"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginEnd="@dimen/small_gap"
|
||||
android:layout_marginRight="@dimen/small_gap"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/signup" />
|
||||
|
||||
|
|
@ -163,35 +163,24 @@
|
|||
android:layout_width="0dp"
|
||||
style="@style/Widget.AppCompat.Button.Colored"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="@dimen/small_gap"
|
||||
android:layout_marginStart="@dimen/small_gap"
|
||||
android:layout_weight="1"
|
||||
android:enabled="false"
|
||||
android:text="@string/login" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
<fr.free.nrw.commons.ui.widget.HtmlTextView
|
||||
android:id="@+id/about_privacy_policy"
|
||||
style="?android:textAppearanceSmall"
|
||||
android:layout_below="@id/buttonFrame"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginStart="16dp">
|
||||
|
||||
<fr.free.nrw.commons.ui.widget.HtmlTextView
|
||||
android:id="@+id/about_privacy_policy"
|
||||
style="?android:textAppearanceSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:text="@string/about_privacy_policy"
|
||||
android:layout_centerHorizontal="true"/>
|
||||
|
||||
</RelativeLayout>
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/standard_gap"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:text="@string/about_privacy_policy"
|
||||
android:layout_centerHorizontal="true"/>
|
||||
|
||||
</RelativeLayout>
|
||||
</android.support.v7.widget.CardView>
|
||||
|
|
|
|||
|
|
@ -5,16 +5,15 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#0c609c"
|
||||
android:gravity="center"
|
||||
>
|
||||
android:gravity="center">
|
||||
|
||||
|
||||
<GridLayout
|
||||
android:layout_width="300dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_marginEnd="@dimen/standard_gap"
|
||||
android:layout_marginRight="@dimen/standard_gap"
|
||||
android:columnCount="2"
|
||||
>
|
||||
|
||||
|
|
@ -69,8 +68,8 @@
|
|||
android:text="@string/tutorial_2_text"
|
||||
android:layout_gravity="center"
|
||||
android:textStyle="bold"
|
||||
android:textSize="@dimen/normal_text"
|
||||
android:textAlignment="center"
|
||||
android:paddingTop="24dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:textColor="@android:color/white"/>
|
||||
|
||||
|
|
@ -81,7 +80,7 @@
|
|||
android:text="@string/tutorial_2_subtext"
|
||||
android:layout_gravity="center"
|
||||
android:textAlignment="textStart"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingTop="@dimen/standard_gap"
|
||||
android:gravity="start"
|
||||
android:textColor="@android:color/white"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -12,24 +12,25 @@
|
|||
android:layout_gravity="center"
|
||||
android:layout_width="240dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginEnd="@dimen/standard_gap"
|
||||
android:layout_marginRight="@dimen/standard_gap"
|
||||
>
|
||||
|
||||
<ImageView
|
||||
android:src="@drawable/selfie_x"
|
||||
android:id="@+id/selfie_x"
|
||||
android:layout_width="110dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:contentDescription="@string/welcome_image_no_selfies"
|
||||
/>
|
||||
|
||||
<ImageView
|
||||
android:src="@drawable/proprietary_x"
|
||||
android:id="@+id/proprietary_x"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginStart="@dimen/standard_gap"
|
||||
android:layout_marginLeft="@dimen/standard_gap"
|
||||
android:layout_width="110dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_toRightOf="@+id/selfie_x"
|
||||
android:contentDescription="@string/welcome_image_proprietary"
|
||||
/>
|
||||
|
|
@ -50,7 +51,7 @@
|
|||
android:layout_gravity="center"
|
||||
android:textStyle="bold"
|
||||
android:textAlignment="center"
|
||||
android:paddingTop="24dp"
|
||||
android:textSize="@dimen/normal_text"
|
||||
android:gravity="center_horizontal"
|
||||
android:textColor="@android:color/white"/>
|
||||
|
||||
|
|
@ -61,7 +62,7 @@
|
|||
android:text="@string/tutorial_3_subtext"
|
||||
android:layout_gravity="center"
|
||||
android:textAlignment="textStart"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingTop="@dimen/standard_gap"
|
||||
android:gravity="start"
|
||||
android:textColor="@android:color/white"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -43,14 +43,15 @@
|
|||
android:text="@string/welcome_final_text"
|
||||
android:layout_gravity="center"
|
||||
android:textStyle="bold"
|
||||
android:textSize="@dimen/normal_text"
|
||||
android:textAlignment="center"
|
||||
android:gravity="center_horizontal"
|
||||
android:textColor="@android:color/white"/>
|
||||
|
||||
<Button
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_height="@dimen/overflow_button_dimen"
|
||||
android:layout_marginTop="@dimen/standard_gap"
|
||||
android:text="@string/welcome_final_button_text"
|
||||
android:id="@+id/welcomeYesButton"
|
||||
android:layout_gravity="center"
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/sydney_opera_house"
|
||||
android:paddingLeft="24dp"
|
||||
android:paddingRight="24dp"
|
||||
android:paddingTop="24dp"
|
||||
android:paddingBottom="24dp"
|
||||
android:paddingLeft="@dimen/large_gap"
|
||||
android:paddingRight="@dimen/standard_gap"
|
||||
android:paddingTop="@dimen/large_gap"
|
||||
android:paddingBottom="@dimen/large_gap"
|
||||
android:adjustViewBounds="true"
|
||||
android:layout_gravity="center"
|
||||
android:contentDescription="@string/welcome_image_sydney_opera_house"
|
||||
|
|
@ -34,7 +34,7 @@
|
|||
android:layout_gravity="center"
|
||||
android:textStyle="bold"
|
||||
android:textAlignment="center"
|
||||
android:paddingTop="24dp"
|
||||
android:textSize="@dimen/normal_text"
|
||||
android:gravity="center_horizontal"
|
||||
android:textColor="@android:color/white"/>
|
||||
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
android:text="@string/tutorial_4_subtext"
|
||||
android:layout_gravity="center"
|
||||
android:textAlignment="textStart"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingTop="@dimen/standard_gap"
|
||||
android:gravity="start"
|
||||
android:textColor="@android:color/white"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/welcome_wikipedia"
|
||||
android:layout_marginEnd="@dimen/standard_gap"
|
||||
android:layout_marginRight="@dimen/standard_gap"
|
||||
android:adjustViewBounds="true"
|
||||
android:contentDescription="@string/welcome_image_welcome_wikipedia"
|
||||
/>
|
||||
|
|
@ -29,8 +31,8 @@
|
|||
android:text="@string/tutorial_1_text"
|
||||
android:layout_gravity="center"
|
||||
android:textStyle="bold"
|
||||
android:textSize="@dimen/normal_text"
|
||||
android:textAlignment="center"
|
||||
android:paddingTop="24dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:textColor="@android:color/white"/>
|
||||
|
||||
|
|
@ -41,7 +43,7 @@
|
|||
android:text="@string/tutorial_1_subtext"
|
||||
android:layout_gravity="center"
|
||||
android:textAlignment="center"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingTop="@dimen/standard_gap"
|
||||
android:gravity="center_horizontal"
|
||||
android:textColor="@android:color/white"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -8,17 +8,17 @@
|
|||
android:layout_width="400sp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="8dp">
|
||||
android:layout_marginTop="@dimen/small_gap">
|
||||
|
||||
<android.support.v7.widget.CardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="32dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="@dimen/large_gap"
|
||||
android:layout_marginBottom="@dimen/standard_gap"
|
||||
android:layout_marginEnd="@dimen/standard_gap"
|
||||
android:layout_marginLeft="@dimen/standard_gap"
|
||||
android:layout_marginRight="@dimen/standard_gap"
|
||||
android:layout_marginStart="@dimen/standard_gap"
|
||||
app:cardCornerRadius="4dp"
|
||||
app:cardElevation="4dp">
|
||||
|
||||
|
|
@ -34,11 +34,11 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:background="@color/primaryColor"
|
||||
android:gravity="center"
|
||||
android:paddingBottom="32dp"
|
||||
android:paddingTop="32dp"
|
||||
android:paddingBottom="@dimen/large_gap"
|
||||
android:paddingTop="@dimen/large_gap"
|
||||
android:text="@string/login_to_your_account"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="24sp" />
|
||||
android:textSize="@dimen/heading_text_size" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/error_message_container"
|
||||
|
|
@ -52,12 +52,12 @@
|
|||
android:id="@+id/error_message"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:paddingTop="8dp"
|
||||
android:layout_marginEnd="@dimen/standard_gap"
|
||||
android:layout_marginLeft="@dimen/standard_gap"
|
||||
android:layout_marginRight="@dimen/standard_gap"
|
||||
android:layout_marginStart="@dimen/standard_gap"
|
||||
android:paddingBottom="@dimen/small_gap"
|
||||
android:paddingTop="@dimen/small_gap"
|
||||
android:textColor="@color/secondaryDarkColor"
|
||||
tools:text="Check your password, something doesnt look right" />
|
||||
</FrameLayout>
|
||||
|
|
@ -67,12 +67,12 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/error_message_container"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp">
|
||||
android:layout_marginBottom="@dimen/standard_gap"
|
||||
android:layout_marginEnd="@dimen/standard_gap"
|
||||
android:layout_marginLeft="@dimen/standard_gap"
|
||||
android:layout_marginRight="@dimen/standard_gap"
|
||||
android:layout_marginStart="@dimen/standard_gap"
|
||||
android:layout_marginTop="@dimen/standard_gap">
|
||||
|
||||
<android.support.design.widget.TextInputEditText
|
||||
android:id="@+id/loginUsername"
|
||||
|
|
@ -93,11 +93,11 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/username_container"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginBottom="@dimen/standard_gap"
|
||||
android:layout_marginEnd="@dimen/standard_gap"
|
||||
android:layout_marginLeft="@dimen/standard_gap"
|
||||
android:layout_marginRight="@dimen/standard_gap"
|
||||
android:layout_marginStart="@dimen/standard_gap"
|
||||
app:passwordToggleEnabled="false">
|
||||
|
||||
<android.support.design.widget.TextInputEditText
|
||||
|
|
@ -115,11 +115,11 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/password_container"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginBottom="@dimen/standard_gap"
|
||||
android:layout_marginEnd="@dimen/standard_gap"
|
||||
android:layout_marginLeft="@dimen/standard_gap"
|
||||
android:layout_marginRight="@dimen/standard_gap"
|
||||
android:layout_marginStart="@dimen/standard_gap"
|
||||
android:visibility="gone"
|
||||
app:passwordToggleEnabled="false"
|
||||
tools:visibility="visible">
|
||||
|
|
@ -141,11 +141,11 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/two_factor_container"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginStart="16dp">
|
||||
android:layout_marginBottom="@dimen/standard_gap"
|
||||
android:layout_marginEnd="@dimen/standard_gap"
|
||||
android:layout_marginLeft="@dimen/standard_gap"
|
||||
android:layout_marginRight="@dimen/standard_gap"
|
||||
android:layout_marginStart="@dimen/standard_gap">
|
||||
|
||||
<Button
|
||||
android:id="@+id/signupButton"
|
||||
|
|
@ -153,8 +153,8 @@
|
|||
style="@style/Widget.AppCompat.Button.Borderless.Colored"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginEnd="@dimen/small_gap"
|
||||
android:layout_marginRight="@dimen/small_gap"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/signup" />
|
||||
|
||||
|
|
@ -163,35 +163,24 @@
|
|||
android:layout_width="0dp"
|
||||
style="@style/Widget.AppCompat.Button.Colored"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="@dimen/small_gap"
|
||||
android:layout_marginStart="@dimen/small_gap"
|
||||
android:layout_weight="1"
|
||||
android:enabled="false"
|
||||
android:text="@string/login" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
<fr.free.nrw.commons.ui.widget.HtmlTextView
|
||||
android:id="@+id/about_privacy_policy"
|
||||
style="?android:textAppearanceSmall"
|
||||
android:layout_below="@id/buttonFrame"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginStart="16dp">
|
||||
|
||||
<fr.free.nrw.commons.ui.widget.HtmlTextView
|
||||
android:id="@+id/about_privacy_policy"
|
||||
style="?android:textAppearanceSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:text="@string/about_privacy_policy"
|
||||
android:layout_centerHorizontal="true"/>
|
||||
|
||||
</RelativeLayout>
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/standard_gap"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:text="@string/about_privacy_policy"
|
||||
android:layout_centerHorizontal="true"/>
|
||||
|
||||
</RelativeLayout>
|
||||
</android.support.v7.widget.CardView>
|
||||
|
|
|
|||
|
|
@ -15,12 +15,14 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/toolbar"
|
||||
android:layout_marginLeft="12dp"
|
||||
android:layout_marginRight="12dp"
|
||||
android:layout_marginLeft="@dimen/activity_margin_horizontal"
|
||||
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
||||
android:layout_marginRight="@dimen/activity_margin_horizontal"
|
||||
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
|
|
@ -47,7 +49,7 @@
|
|||
style="?android:textAppearanceSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginTop="@dimen/standard_gap"
|
||||
android:gravity="center"
|
||||
android:text="@string/about_license" />
|
||||
|
||||
|
|
@ -56,7 +58,7 @@
|
|||
style="?android:textAppearanceSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginTop="@dimen/small_gap"
|
||||
android:gravity="center"
|
||||
android:text="@string/about_improve" />
|
||||
|
||||
|
|
@ -65,7 +67,7 @@
|
|||
style="?android:textAppearanceSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginTop="@dimen/standard_gap"
|
||||
android:gravity="center"
|
||||
android:text="@string/about_privacy_policy" />
|
||||
|
||||
|
|
@ -74,7 +76,7 @@
|
|||
style="?android:textAppearanceSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginTop="@dimen/standard_gap"
|
||||
android:gravity="center"
|
||||
android:text="@string/about_credits" />
|
||||
|
||||
|
|
@ -83,7 +85,7 @@
|
|||
style="?android:textAppearanceSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="32dp"
|
||||
android:layout_marginTop="@dimen/large_gap"
|
||||
android:alpha="0.2"
|
||||
android:gravity="center" />
|
||||
|
||||
|
|
|
|||
|
|
@ -8,17 +8,17 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="8dp">
|
||||
android:layout_marginTop="@dimen/small_gap">
|
||||
|
||||
<android.support.v7.widget.CardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="32dp"
|
||||
android:layout_marginBottom="@dimen/standard_gap"
|
||||
android:layout_marginEnd="@dimen/standard_gap"
|
||||
android:layout_marginLeft="@dimen/standard_gap"
|
||||
android:layout_marginRight="@dimen/standard_gap"
|
||||
android:layout_marginStart="@dimen/standard_gap"
|
||||
android:layout_marginTop="@dimen/large_gap"
|
||||
app:cardCornerRadius="4dp"
|
||||
app:cardElevation="4dp">
|
||||
|
||||
|
|
@ -34,11 +34,11 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:background="@color/primaryColor"
|
||||
android:gravity="center"
|
||||
android:paddingBottom="32dp"
|
||||
android:paddingTop="32dp"
|
||||
android:paddingBottom="@dimen/large_gap"
|
||||
android:paddingTop="@dimen/large_gap"
|
||||
android:text="@string/login_to_your_account"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="24sp" />
|
||||
android:textSize="@dimen/heading_text_size" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/error_message_container"
|
||||
|
|
@ -52,12 +52,12 @@
|
|||
android:id="@+id/error_message"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:paddingTop="8dp"
|
||||
android:layout_marginEnd="@dimen/standard_gap"
|
||||
android:layout_marginLeft="@dimen/standard_gap"
|
||||
android:layout_marginRight="@dimen/standard_gap"
|
||||
android:layout_marginStart="@dimen/standard_gap"
|
||||
android:paddingBottom="@dimen/small_gap"
|
||||
android:paddingTop="@dimen/small_gap"
|
||||
android:textColor="@color/secondaryDarkColor"
|
||||
tools:text="Check your password, something doesnt look right" />
|
||||
</FrameLayout>
|
||||
|
|
@ -67,12 +67,12 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/error_message_container"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp">
|
||||
android:layout_marginBottom="@dimen/standard_gap"
|
||||
android:layout_marginEnd="@dimen/standard_gap"
|
||||
android:layout_marginLeft="@dimen/standard_gap"
|
||||
android:layout_marginRight="@dimen/standard_gap"
|
||||
android:layout_marginStart="@dimen/standard_gap"
|
||||
android:layout_marginTop="@dimen/standard_gap">
|
||||
|
||||
<android.support.design.widget.TextInputEditText
|
||||
android:id="@+id/loginUsername"
|
||||
|
|
@ -93,11 +93,11 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/username_container"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginBottom="@dimen/standard_gap"
|
||||
android:layout_marginEnd="@dimen/standard_gap"
|
||||
android:layout_marginLeft="@dimen/standard_gap"
|
||||
android:layout_marginRight="@dimen/standard_gap"
|
||||
android:layout_marginStart="@dimen/standard_gap"
|
||||
app:passwordToggleEnabled="false">
|
||||
|
||||
<android.support.design.widget.TextInputEditText
|
||||
|
|
@ -115,11 +115,11 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/password_container"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginBottom="@dimen/standard_gap"
|
||||
android:layout_marginEnd="@dimen/standard_gap"
|
||||
android:layout_marginLeft="@dimen/standard_gap"
|
||||
android:layout_marginRight="@dimen/standard_gap"
|
||||
android:layout_marginStart="@dimen/standard_gap"
|
||||
android:visibility="gone"
|
||||
app:passwordToggleEnabled="false"
|
||||
tools:visibility="visible">
|
||||
|
|
@ -141,11 +141,11 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/two_factor_container"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginStart="16dp">
|
||||
android:layout_marginBottom="@dimen/standard_gap"
|
||||
android:layout_marginEnd="@dimen/standard_gap"
|
||||
android:layout_marginLeft="@dimen/standard_gap"
|
||||
android:layout_marginRight="@dimen/standard_gap"
|
||||
android:layout_marginStart="@dimen/standard_gap">
|
||||
|
||||
<Button
|
||||
android:id="@+id/signupButton"
|
||||
|
|
@ -153,8 +153,8 @@
|
|||
style="@style/Widget.AppCompat.Button.Borderless.Colored"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginEnd="@dimen/small_gap"
|
||||
android:layout_marginRight="@dimen/small_gap"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/signup" />
|
||||
|
||||
|
|
@ -163,35 +163,24 @@
|
|||
android:layout_width="0dp"
|
||||
style="@style/Widget.AppCompat.Button.Colored"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="@dimen/small_gap"
|
||||
android:layout_marginStart="@dimen/small_gap"
|
||||
android:layout_weight="1"
|
||||
android:enabled="false"
|
||||
android:text="@string/login" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
<fr.free.nrw.commons.ui.widget.HtmlTextView
|
||||
android:id="@+id/about_privacy_policy"
|
||||
style="?android:textAppearanceSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/buttonFrame"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginStart="16dp">
|
||||
|
||||
<fr.free.nrw.commons.ui.widget.HtmlTextView
|
||||
android:id="@+id/about_privacy_policy"
|
||||
style="?android:textAppearanceSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:text="@string/about_privacy_policy"
|
||||
android:layout_centerHorizontal="true"/>
|
||||
|
||||
</RelativeLayout>
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginBottom="@dimen/standard_gap"
|
||||
android:text="@string/about_privacy_policy" />
|
||||
|
||||
</RelativeLayout>
|
||||
</android.support.v7.widget.CardView>
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/toolbar"
|
||||
android:orientation="vertical"></FrameLayout>
|
||||
android:orientation="vertical" />
|
||||
</RelativeLayout>
|
||||
|
||||
<android.support.design.widget.NavigationView
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
|
|
@ -25,13 +25,12 @@
|
|||
<ProgressBar
|
||||
android:id="@+id/progressBar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true" />
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"></FrameLayout>
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
|
|
|||
34
app/src/main/res/layout/activity_notification.xml
Normal file
34
app/src/main/res/layout/activity_notification.xml
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/drawer_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<include
|
||||
android:id="@+id/toolbar"
|
||||
layout="@layout/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/listView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/toolbar"
|
||||
/>
|
||||
</RelativeLayout>
|
||||
|
||||
<android.support.design.widget.NavigationView
|
||||
android:id="@+id/navigation_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="start"
|
||||
app:headerLayout="@layout/drawer_header"
|
||||
app:menu="@menu/drawer"/>
|
||||
|
||||
</android.support.v4.widget.DrawerLayout>
|
||||
|
|
@ -9,14 +9,13 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
|
||||
<include
|
||||
android:id="@+id/toolbar"
|
||||
layout="@layout/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/toolbar"
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
<com.viewpagerindicator.CirclePageIndicator
|
||||
android:id="@+id/welcomePagerIndicator"
|
||||
android:layout_height="24dp"
|
||||
android:layout_height="@dimen/half_standard_height"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_gravity="bottom" />
|
||||
|
||||
|
|
|
|||
|
|
@ -13,17 +13,17 @@
|
|||
android:background="?attr/subBackground"
|
||||
android:foreground="?attr/selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="48dp"
|
||||
android:padding="12dp"
|
||||
android:minHeight="@dimen/overflow_button_dimen"
|
||||
android:padding="@dimen/quarter_standard_height"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp"
|
||||
app:drawablePadding="6dp"
|
||||
android:textSize="@dimen/description_text_size"
|
||||
app:drawablePadding="@dimen/small_gap"
|
||||
app:drawableStart="@drawable/ic_info_outline_white_24dp"
|
||||
/>
|
||||
|
||||
<fr.free.nrw.commons.media.MediaDetailSpacer
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="8dp"
|
||||
android:layout_height="@dimen/small_gap"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
|||
|
|
@ -41,16 +41,18 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="12dp"
|
||||
android:layout_marginRight="12dp"
|
||||
android:layout_marginLeft="@dimen/quarter_standard_height"
|
||||
android:layout_marginRight="@dimen/quarter_standard_height"
|
||||
android:layout_marginStart="@dimen/quarter_standard_height"
|
||||
android:layout_marginEnd="@dimen/quarter_standard_height"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:fontFamily="serif"
|
||||
android:lineSpacingMultiplier="0.9"
|
||||
android:maxLines="3"
|
||||
android:paddingBottom="4dp"
|
||||
android:paddingBottom="@dimen/tiny_gap"
|
||||
android:textColor="@android:color/black"
|
||||
android:textSize="20sp"
|
||||
android:textSize="@dimen/subheading_text_size"
|
||||
tools:text="Lorem ipsum" />
|
||||
|
||||
<ImageView
|
||||
|
|
@ -58,7 +60,7 @@
|
|||
android:layout_width="@dimen/overflow_button_dimen"
|
||||
android:layout_height="@dimen/overflow_button_dimen"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:padding="12dp"
|
||||
android:padding="@dimen/quarter_standard_height"
|
||||
android:background="@android:color/white"
|
||||
android:contentDescription="@string/abc_action_menu_overflow_description"
|
||||
app:srcCompat="@drawable/ic_more_vert_white_24dp" />
|
||||
|
|
@ -67,8 +69,8 @@
|
|||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0.5dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginLeft="@dimen/standard_gap"
|
||||
android:layout_marginRight="@dimen/standard_gap"
|
||||
android:background="@android:color/black" />
|
||||
|
||||
<TextView
|
||||
|
|
@ -76,11 +78,11 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:lineSpacingMultiplier="1.3"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingLeft="@dimen/standard_gap"
|
||||
android:paddingRight="@dimen/standard_gap"
|
||||
android:paddingTop="@dimen/small_gap"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="16sp"
|
||||
android:textSize="@dimen/normal_text"
|
||||
android:textColor="@android:color/black"
|
||||
tools:text="Lorem ipsum" />
|
||||
|
||||
|
|
@ -103,9 +105,9 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:paddingBottom="16dp"
|
||||
android:paddingTop="16dp"
|
||||
android:text="GET DIRECTIONS"
|
||||
android:paddingBottom="@dimen/standard_gap"
|
||||
android:paddingTop="@dimen/standard_gap"
|
||||
android:text="@string/get_directions"
|
||||
android:textColor="@android:color/black" />
|
||||
|
||||
<TextView
|
||||
|
|
@ -114,9 +116,9 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:paddingBottom="16dp"
|
||||
android:paddingTop="16dp"
|
||||
android:text="READ ARTICLE"
|
||||
android:paddingBottom="@dimen/standard_gap"
|
||||
android:paddingTop="@dimen/standard_gap"
|
||||
android:text="@string/read_article"
|
||||
android:textColor="@android:color/black" />
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
|||
|
|
@ -1,28 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:background="@android:color/darker_gray">
|
||||
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/pictureOfTheDay"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="172dp"
|
||||
android:background="@android:color/darker_gray"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingBottom="5dp"
|
||||
android:src="@drawable/commons_logo_large"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/pictureOfTheDay"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="172dp"
|
||||
android:background="@android:color/darker_gray"
|
||||
android:paddingLeft="@dimen/standard_gap"
|
||||
android:paddingTop="@dimen/standard_gap"
|
||||
android:paddingRight="@dimen/standard_gap"
|
||||
android:paddingBottom="@dimen/small_gap"
|
||||
android:src="@drawable/commons_logo_large"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/username"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextView"
|
||||
tools:text="TextView"
|
||||
android:textColor="@color/item_white_background"
|
||||
android:textSize="22sp"
|
||||
android:textSize="@dimen/subheading_text_size"
|
||||
android:layout_below="@+id/pictureOfTheDay"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:paddingBottom="5dp"/>
|
||||
android:paddingBottom="@dimen/small_gap"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
|
@ -4,12 +4,12 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/fragmentCategorisationBackground"
|
||||
android:paddingBottom="8dip"
|
||||
android:paddingLeft="16dip"
|
||||
android:paddingStart="16dip"
|
||||
android:paddingRight="16dip"
|
||||
android:paddingEnd="16dip"
|
||||
android:paddingTop="8dip"
|
||||
android:paddingBottom="@dimen/small_gap"
|
||||
android:paddingLeft="@dimen/standard_gap"
|
||||
android:paddingStart="@dimen/standard_gap"
|
||||
android:paddingRight="@dimen/standard_gap"
|
||||
android:paddingEnd="@dimen/standard_gap"
|
||||
android:paddingTop="@dimen/small_gap"
|
||||
android:theme="@style/DarkAppTheme"
|
||||
>
|
||||
|
||||
|
|
@ -34,8 +34,8 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true"
|
||||
android:indeterminateOnly="true"
|
||||
android:layout_marginRight="4dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:layout_marginRight="@dimen/tiny_gap"
|
||||
android:layout_marginEnd="@dimen/tiny_gap"
|
||||
android:layout_gravity="center_vertical|right|end"
|
||||
style="?android:progressBarStyleSmall"
|
||||
android:visibility="gone"
|
||||
|
|
@ -54,7 +54,7 @@
|
|||
android:id="@+id/categoriesExplanation"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_marginTop="48dp"
|
||||
android:layout_marginTop="@dimen/huge_gap"
|
||||
android:gravity="center"
|
||||
android:focusable="true"
|
||||
android:text="@string/categories_skip_explanation"
|
||||
|
|
|
|||
|
|
@ -43,29 +43,29 @@
|
|||
<fr.free.nrw.commons.media.MediaDetailSpacer
|
||||
android:id="@+id/mediaDetailSpacer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="16dp" />
|
||||
android:layout_height="@dimen/standard_gap" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/fragmentCategorisationBackground"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
android:padding="@dimen/standard_gap">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/subBackground"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
android:padding="@dimen/standard_gap">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="6dp"
|
||||
android:paddingBottom="@dimen/tiny_gap"
|
||||
android:text="@string/media_detail_title"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="16sp"
|
||||
android:textSize="@dimen/normal_text"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
|
|
@ -74,30 +74,30 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start"
|
||||
android:background="?attr/subBackground"
|
||||
android:padding="12dp"
|
||||
android:padding="@dimen/small_gap"
|
||||
android:text="@string/media_detail_media_title"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
android:textSize="@dimen/description_text_size" />
|
||||
</LinearLayout>
|
||||
|
||||
<fr.free.nrw.commons.media.MediaDetailSpacer
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="8dp" />
|
||||
android:layout_height="@dimen/small_gap" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/subBackground"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
android:padding="@dimen/standard_gap">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="6dp"
|
||||
android:paddingBottom="@dimen/tiny_gap"
|
||||
android:text="@string/media_detail_description"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="16sp"
|
||||
android:textSize="@dimen/normal_text"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
|
|
@ -106,30 +106,30 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start"
|
||||
android:background="?attr/subBackground"
|
||||
android:padding="12dp"
|
||||
android:padding="@dimen/small_gap"
|
||||
android:text="@string/media_detail_description_explanation"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
android:textSize="@dimen/description_text_size" />
|
||||
</LinearLayout>
|
||||
|
||||
<fr.free.nrw.commons.media.MediaDetailSpacer
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="8dp" />
|
||||
android:layout_height="@dimen/small_gap" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/subBackground"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
android:padding="@dimen/standard_gap">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="6dp"
|
||||
android:paddingBottom="@dimen/tiny_gap"
|
||||
android:text="@string/media_detail_license"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="16sp"
|
||||
android:textSize="@dimen/normal_text"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<fr.free.nrw.commons.ui.widget.CompatTextView
|
||||
|
|
@ -140,11 +140,11 @@
|
|||
android:background="?attr/subBackground"
|
||||
android:foreground="?attr/selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:padding="12dp"
|
||||
android:padding="@dimen/small_gap"
|
||||
android:text="@string/media_detail_license"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp"
|
||||
app:drawablePadding="6dp"
|
||||
android:textSize="@dimen/description_text_size"
|
||||
app:drawablePadding="@dimen/tiny_gap"
|
||||
app:drawableStart="@drawable/ic_info_outline_white_24dp"
|
||||
tools:text="License link" />
|
||||
</LinearLayout>
|
||||
|
|
@ -154,15 +154,15 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:background="?attr/subBackground"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
android:padding="@dimen/standard_gap">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="6dp"
|
||||
android:paddingBottom="@dimen/tiny_gap"
|
||||
android:text="@string/media_detail_coordinates"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="16sp"
|
||||
android:textSize="@dimen/normal_text"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<fr.free.nrw.commons.ui.widget.CompatTextView
|
||||
|
|
@ -173,35 +173,35 @@
|
|||
android:background="?attr/subBackground"
|
||||
android:foreground="?attr/selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:padding="12dp"
|
||||
android:padding="@dimen/small_gap"
|
||||
android:text="@string/media_detail_coordinates"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp"
|
||||
app:drawablePadding="6dp"
|
||||
android:textSize="@dimen/description_text_size"
|
||||
app:drawablePadding="@dimen/tiny_gap"
|
||||
app:drawableStart="@drawable/ic_map_white_24dp"
|
||||
tools:text="Coordinates link" />
|
||||
</LinearLayout>
|
||||
|
||||
<fr.free.nrw.commons.media.MediaDetailSpacer
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="8dp" />
|
||||
android:layout_height="@dimen/small_gap" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/subBackground"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
android:padding="@dimen/standard_gap"
|
||||
android:textStyle="bold">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start"
|
||||
android:paddingBottom="6dp"
|
||||
android:paddingBottom="@dimen/tiny_gap"
|
||||
android:text="@string/detail_panel_cats_label"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="16sp"
|
||||
android:textSize="@dimen/normal_text"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<LinearLayout
|
||||
|
|
@ -213,22 +213,22 @@
|
|||
|
||||
<fr.free.nrw.commons.media.MediaDetailSpacer
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="8dp" />
|
||||
android:layout_height="@dimen/small_gap" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/subBackground"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
android:padding="@dimen/standard_gap">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="6dp"
|
||||
android:paddingBottom="@dimen/tiny_gap"
|
||||
android:text="@string/media_detail_uploaded_date"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="16sp"
|
||||
android:textSize="@dimen/normal_text"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
|
|
@ -237,10 +237,10 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start"
|
||||
android:background="?attr/subBackground"
|
||||
android:padding="12dp"
|
||||
android:padding="@dimen/small_gap"
|
||||
android:text="@string/media_detail_uploaded_date"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
android:textSize="@dimen/description_text_size" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:paddingLeft="30dp"
|
||||
android:paddingRight="30dp"
|
||||
android:paddingLeft="@dimen/large_gap"
|
||||
android:paddingRight="@dimen/large_gap"
|
||||
android:text="@string/nearby_needs_permissions"
|
||||
android:textAlignment="center"
|
||||
android:textSize="18sp" />
|
||||
android:textSize="@dimen/subheading_text_size" />
|
||||
|
||||
|
||||
</FrameLayout>
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@
|
|||
android:layout_gravity="fill"
|
||||
android:orientation="vertical"
|
||||
android:background="?attr/fragmentCategorisationBackground"
|
||||
android:paddingBottom="8dip"
|
||||
android:paddingLeft="16dip"
|
||||
android:paddingStart="16dip"
|
||||
android:paddingRight="16dip"
|
||||
android:paddingEnd="16dip"
|
||||
android:paddingTop="8dip"
|
||||
android:paddingBottom="@dimen/small_gap"
|
||||
android:paddingLeft="@dimen/standard_gap"
|
||||
android:paddingStart="@dimen/standard_gap"
|
||||
android:paddingRight="@dimen/standard_gap"
|
||||
android:paddingEnd="@dimen/standard_gap"
|
||||
android:paddingTop="@dimen/small_gap"
|
||||
android:theme="@style/DarkAppTheme"
|
||||
>
|
||||
|
||||
|
|
@ -56,7 +56,7 @@
|
|||
android:text="@string/share_license_summary"
|
||||
android:id="@+id/share_license_summary"
|
||||
android:gravity="center"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginTop="@dimen/standard_gap"
|
||||
/>
|
||||
|
||||
<fr.free.nrw.commons.ui.widget.HtmlTextView
|
||||
|
|
@ -65,7 +65,7 @@
|
|||
android:id="@+id/media_upload_policy"
|
||||
android:text="@string/media_upload_policy"
|
||||
android:gravity="start"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginTop="@dimen/standard_gap"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
|||
70
app/src/main/res/layout/item_notification.xml
Normal file
70
app/src/main/res/layout/item_notification.xml
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:foreground="?selectableItemBackground"
|
||||
android:minHeight="72dp"
|
||||
>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:background="@android:color/white"
|
||||
android:contentDescription="@string/no_image_found"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/empty_photo"
|
||||
android:tint="@color/primaryDarkColor"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
|
||||
tools:text="@string/placeholder_place_distance"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignTop="@id/time"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_toEndOf="@id/icon"
|
||||
android:layout_toLeftOf="@id/time"
|
||||
android:layout_toRightOf="@id/icon"
|
||||
android:layout_toStartOf="@id/time"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="2"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
|
||||
tools:text="@string/placeholder_place_name"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignEnd="@id/time"
|
||||
android:layout_alignLeft="@id/title"
|
||||
android:layout_alignRight="@id/time"
|
||||
android:layout_alignStart="@id/title"
|
||||
android:layout_below="@id/title"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="4"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
tools:text="@string/placeholder_place_description"
|
||||
/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
|
@ -10,9 +10,9 @@
|
|||
android:id="@+id/icon"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginLeft="@dimen/standard_gap"
|
||||
android:layout_marginStart="@dimen/standard_gap"
|
||||
android:layout_marginTop="@dimen/standard_gap"
|
||||
android:background="@android:color/white"
|
||||
android:contentDescription="@string/no_image_found"
|
||||
android:scaleType="centerCrop"
|
||||
|
|
@ -25,9 +25,9 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginLeft="@dimen/standard_gap"
|
||||
android:layout_marginRight="@dimen/standard_gap"
|
||||
android:layout_marginTop="@dimen/standard_gap"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
|
||||
tools:text="@string/placeholder_place_distance"
|
||||
/>
|
||||
|
|
@ -37,8 +37,8 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignTop="@id/distance"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginLeft="@dimen/standard_gap"
|
||||
android:layout_marginStart="@dimen/standard_gap"
|
||||
android:layout_toEndOf="@id/icon"
|
||||
android:layout_toLeftOf="@id/distance"
|
||||
android:layout_toRightOf="@id/icon"
|
||||
|
|
@ -58,7 +58,7 @@
|
|||
android:layout_alignRight="@id/distance"
|
||||
android:layout_alignStart="@id/tvName"
|
||||
android:layout_below="@id/tvName"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginBottom="@dimen/standard_gap"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="4"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
android:checkMark="?android:attr/textCheckMark"
|
||||
android:checked="false"
|
||||
android:gravity="center_vertical"
|
||||
android:padding="4dp"
|
||||
android:padding="@dimen/tiny_gap"
|
||||
android:theme="@style/DarkAppTheme">
|
||||
|
||||
</CheckedTextView>
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
android:layout_gravity="center|bottom"
|
||||
android:background="#AA000000"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp"
|
||||
android:padding="@dimen/small_gap"
|
||||
>
|
||||
<ProgressBar
|
||||
android:id="@+id/contributionProgress"
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center|bottom"
|
||||
android:background="#77000000"
|
||||
android:padding="4dp"
|
||||
android:padding="@dimen/tiny_gap"
|
||||
>
|
||||
|
||||
<TextView
|
||||
|
|
|
|||
|
|
@ -12,8 +12,6 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="240dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:columnCount="2"
|
||||
>
|
||||
|
||||
|
|
@ -62,20 +60,21 @@
|
|||
android:text="@string/tutorial_2_text"
|
||||
android:layout_gravity="center"
|
||||
android:textStyle="bold"
|
||||
android:textSize="@dimen/normal_text"
|
||||
android:textAlignment="center"
|
||||
android:paddingTop="24dp"
|
||||
android:paddingTop="@dimen/standard_gap"
|
||||
android:gravity="center_horizontal"
|
||||
android:textColor="@android:color/white"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="293dp"
|
||||
android:layout_width="295dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxWidth="240dp"
|
||||
android:text="@string/tutorial_2_subtext"
|
||||
android:layout_gravity="center"
|
||||
android:textAlignment="textStart"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingTop="@dimen/standard_gap"
|
||||
android:gravity="start"
|
||||
android:textColor="@android:color/white"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -9,10 +9,9 @@
|
|||
|
||||
<LinearLayout
|
||||
android:gravity="center"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="240dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
>
|
||||
|
||||
<ImageView
|
||||
|
|
@ -26,7 +25,8 @@
|
|||
<ImageView
|
||||
android:src="@drawable/proprietary_x"
|
||||
android:id="@+id/proprietary_x"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginLeft="@dimen/standard_gap"
|
||||
android:layout_marginStart="@dimen/standard_gap"
|
||||
android:layout_width="140dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@string/welcome_image_proprietary"
|
||||
|
|
@ -41,20 +41,21 @@
|
|||
android:text="@string/tutorial_3_text"
|
||||
android:layout_gravity="center"
|
||||
android:textStyle="bold"
|
||||
android:textSize="@dimen/normal_text"
|
||||
android:textAlignment="center"
|
||||
android:paddingTop="24dp"
|
||||
android:paddingTop="@dimen/standard_gap"
|
||||
android:gravity="center_horizontal"
|
||||
android:textColor="@android:color/white"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="278dp"
|
||||
android:layout_width="295dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxWidth="240dp"
|
||||
android:text="@string/tutorial_3_subtext"
|
||||
android:layout_gravity="center"
|
||||
android:textAlignment="textStart"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingTop="@dimen/standard_gap"
|
||||
android:gravity="start"
|
||||
android:textColor="@android:color/white"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -9,10 +9,9 @@
|
|||
|
||||
<LinearLayout
|
||||
android:gravity="center"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_height="180dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
>
|
||||
|
||||
<ImageView
|
||||
|
|
@ -20,7 +19,6 @@
|
|||
android:id="@+id/welcome_wikipedia"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="180dp"
|
||||
android:layout_marginLeft="30dp"
|
||||
android:contentDescription="@string/welcome_image_welcome_wikipedia"
|
||||
/>
|
||||
|
||||
|
|
@ -29,7 +27,8 @@
|
|||
android:layout_width="160dp"
|
||||
android:layout_height="120dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginLeft="@dimen/standard_gap"
|
||||
android:layout_marginStart="@dimen/standard_gap"
|
||||
android:contentDescription="@string/welcome_image_welcome_copyright"
|
||||
/>
|
||||
|
||||
|
|
@ -42,6 +41,7 @@
|
|||
android:text="@string/welcome_final_text"
|
||||
android:layout_gravity="center"
|
||||
android:textStyle="bold"
|
||||
android:textSize="@dimen/normal_text"
|
||||
android:textAlignment="center"
|
||||
android:gravity="center_horizontal"
|
||||
android:textColor="@android:color/white"
|
||||
|
|
@ -49,10 +49,11 @@
|
|||
|
||||
<Button
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_height="@dimen/overflow_button_dimen"
|
||||
android:layout_marginTop="@dimen/standard_gap"
|
||||
android:text="@string/welcome_final_button_text"
|
||||
android:id="@+id/welcomeYesButton"
|
||||
android:textSize="@dimen/normal_text"
|
||||
android:layout_gravity="center"
|
||||
android:background="@android:color/white"
|
||||
android:textColor="#0c609c"
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="24dp"
|
||||
android:paddingRight="24dp"
|
||||
android:paddingLeft="@dimen/large_gap"
|
||||
android:paddingRight="@dimen/large_gap"
|
||||
android:src="@drawable/sydney_opera_house"
|
||||
android:adjustViewBounds="true"
|
||||
android:layout_gravity="center"
|
||||
|
|
@ -25,8 +25,9 @@
|
|||
android:text="@string/tutorial_4_text"
|
||||
android:layout_gravity="center"
|
||||
android:textStyle="bold"
|
||||
android:textSize="@dimen/normal_text"
|
||||
android:textAlignment="center"
|
||||
android:paddingTop="24dp"
|
||||
android:paddingTop="@dimen/standard_gap"
|
||||
android:gravity="center_horizontal"
|
||||
android:textColor="@android:color/white"
|
||||
/>
|
||||
|
|
@ -38,7 +39,7 @@
|
|||
android:text="@string/tutorial_4_subtext"
|
||||
android:layout_gravity="center"
|
||||
android:textAlignment="textStart"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingTop="@dimen/standard_gap"
|
||||
android:gravity="start"
|
||||
android:textColor="@android:color/white"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@
|
|||
android:layout_gravity="center"
|
||||
android:textStyle="bold"
|
||||
android:textAlignment="center"
|
||||
android:paddingTop="24dp"
|
||||
android:textSize="@dimen/normal_text"
|
||||
android:paddingTop="@dimen/standard_gap"
|
||||
android:gravity="center_horizontal"
|
||||
android:textColor="@android:color/white"
|
||||
/>
|
||||
|
|
@ -36,7 +37,7 @@
|
|||
android:text="@string/tutorial_1_subtext"
|
||||
android:layout_gravity="center"
|
||||
android:textAlignment="center"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingTop="@dimen/standard_gap"
|
||||
android:gravity="center_horizontal"
|
||||
android:textColor="@android:color/white"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -35,4 +35,9 @@
|
|||
android:icon="@drawable/ic_exit_to_app_black_24dp"
|
||||
android:title="@string/navigation_item_logout"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_notifications"
|
||||
android:icon="@drawable/ic_notifications_black_24dp"
|
||||
android:title="@string/navigation_item_notification"/>
|
||||
|
||||
</menu>
|
||||
|
|
|
|||
5
app/src/main/res/values-ab/error.xml
Normal file
5
app/src/main/res/values-ab/error.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="crash_dialog_title">Аиҧҟьара</string>
|
||||
<string name="crash_dialog_ok_toast">Иҭабуп!</string>
|
||||
</resources>
|
||||
105
app/src/main/res/values-ab/strings.xml
Normal file
105
app/src/main/res/values-ab/strings.xml
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="menu_settings">Архиарақәа</string>
|
||||
<string name="username">Ахархәаҩ ихьӡ</string>
|
||||
<string name="password">Ажәамаӡа</string>
|
||||
<string name="login">Аҭаларҭа</string>
|
||||
<string name="signup">Иҟаҵатәуп арегистрациа</string>
|
||||
<string name="logging_in_title">Асистемахь аҭаларҭа</string>
|
||||
<string name="logging_in_message">Шәааҧшы ҧыҭрак...</string>
|
||||
<string name="login_success">Аҭалара қәҿиарала имҩаҧысит!</string>
|
||||
<string name="login_failed">Асистемахь аҭалараан агха!</string>
|
||||
<string name="upload_failed">Афаил ҧшаам. Даҽа фаилк шәахәаҧш.</string>
|
||||
<string name="authentication_failed">Аутентификациа агха!</string>
|
||||
<string name="uploading_started">Аҭагалара иалагоуп!</string>
|
||||
<string name="upload_completed_notification_title">%1$s иҭагалоуп!</string>
|
||||
<string name="upload_completed_notification_text">Шәақәыӷәӷәа иҭагалоу афаил ахәаҧшраз</string>
|
||||
<string name="upload_progress_notification_title_start">Аҭагалара %1$s иалагоуп</string>
|
||||
<string name="upload_progress_notification_title_in_progress">%1$s иаҿуп аҭагалара</string>
|
||||
<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>
|
||||
<string name="contribution_state_failed">Аҭагалара агха.</string>
|
||||
<string name="contribution_state_in_progress">Инагӡоуп %1$d%%</string>
|
||||
<string name="contribution_state_starting">Аҭагалара</string>
|
||||
<string name="menu_from_gallery">Агалереиа аҟынтәи</string>
|
||||
<string name="menu_from_camera">Афото ҭыхтәуп</string>
|
||||
<string name="provider_contributions">Сара сҭагаламҭақәа</string>
|
||||
<string name="menu_open_in_browser">Иаарттәуп абраузер аҟны</string>
|
||||
<string name="share_title_hint">Ахьӡ</string>
|
||||
<string name="share_description_hint">Ахҳәаа</string>
|
||||
<string name="login_failed_generic">Асистемахь аҭалара агха!</string>
|
||||
<string name="share_upload_button">Аҭагалара</string>
|
||||
<string name="provider_modifications">Аҧсахрақәа</string>
|
||||
<string name="menu_upload_single">Аҭагалара</string>
|
||||
<string name="categories_search_text_hint">Актегориа алхра</string>
|
||||
<string name="menu_save_categories">Еиқәырхатәуп</string>
|
||||
<string name="refresh_button">Ирҿыцтәуп</string>
|
||||
<string name="gps_disabled">GPS аҿыхуп шәара шәҟны. Ишәҭахума иаҿашәкыр?</string>
|
||||
<string name="enable_gps">Иаҿактәуп GPS</string>
|
||||
<string name="contributions_subtitle_zero">Аҭагаламҭақәа макьана иҟам</string>
|
||||
<string name="categories_activity_title">Акатегориақәа</string>
|
||||
<string name="title_activity_settings">Архиарақәа</string>
|
||||
<string name="title_activity_signup">Арегистрациа ҟаҵатәуп</string>
|
||||
<string name="menu_retry_upload">Еиҭаҟаҵатәуп</string>
|
||||
<string name="menu_cancel_upload">Аҟәыхра</string>
|
||||
<string name="menu_download">Иҭыгатәуп</string>
|
||||
<string name="preference_license">Алицензиа</string>
|
||||
<string name="preference_theme">Уахынлатәи арежим</string>
|
||||
<string name="preference_theme_summary">Ихархәатәуп еиқәаҵәоу атема</string>
|
||||
<string name="license_name_cc_by_sa_four"> Attribution-ShareAlike 4.0</string>
|
||||
<string name="license_name_cc_by_four">Attribution 4.0</string>
|
||||
<string name="license_name_cc_by_sa">Attribution-ShareAlike 3.0</string>
|
||||
<string name="license_name_cc_by">Attribution 3.0</string>
|
||||
<string name="license_name_cc0">CC0</string>
|
||||
<string name="license_name_cc_by_sa_3_0">CC BY-SA 3.0</string>
|
||||
<string name="license_name_cc_by_sa_3_0_at">CC BY-SA 3.0 (Австриа)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_de">CC BY-SA 3.0 (Германиа)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_ee">CC BY-SA 3.0 (Естониа)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_es">CC BY-SA 3.0 (Испаниа)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_hr">CC BY-SA 3.0 (Хорватиа)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_lu">CC-BY-SA 3.0 (Лиуксембург)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_nl">CC-BY-SA 3.0 (Нидерланды)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_no">CC BY-SA 3.0 (Норвегиа)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_pl">CC BY-SA 3.0 (Польша)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_ro">CC BY-SA 3.0 (Румыниа)</string>
|
||||
<string name="license_name_cc_by_3_0">CC BY 3.0</string>
|
||||
<string name="license_name_cc_by_sa_4_0">CC BY-SA 4.0</string>
|
||||
<string name="license_name_cc_by_4_0">CC BY 4.0</string>
|
||||
<string name="license_name_cc_zero">CC Zero</string>
|
||||
<string name="tutorial_4_text">Аҭагалара аҿырҧштәы:</string>
|
||||
<string name="welcome_final_text">Ари шәара еилышәкаама?</string>
|
||||
<string name="welcome_final_button_text">Ааи!</string>
|
||||
<string name="detail_panel_cats_label">Акатегориақәа</string>
|
||||
<string name="detail_panel_cats_loading">Аҭагалара...</string>
|
||||
<string name="detail_panel_cats_none">Акагь алхӡам</string>
|
||||
<string name="detail_description_empty">Иҟам ахҳәаа</string>
|
||||
<string name="detail_license_empty">Идырым алицензиа</string>
|
||||
<string name="menu_refresh">Ирҿыцтәуп</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="warning">Агәаҽанҵара</string>
|
||||
<string name="yes">Ааи</string>
|
||||
<string name="no">Мап</string>
|
||||
<string name="media_detail_title">Ахьӡ</string>
|
||||
<string name="media_detail_description">Ахҳәаа</string>
|
||||
<string name="media_detail_license">Алицензиа</string>
|
||||
<string name="media_detail_coordinates">Акоординатқәа</string>
|
||||
<string name="_2fa_code">2ФА Акод</string>
|
||||
<string name="maximum_limit">Имаксималу алимит</string>
|
||||
<string name="maximum_limit_alert">Иауам 500 иреиҳаны раарҧшра</string>
|
||||
<string name="background_image">Аҿаҧшыратә сахьа</string>
|
||||
<string name="no_image_found">Асахьа ҧшаам</string>
|
||||
<string name="upload_image">Иҭагалатәуп асахьа</string>
|
||||
<string name="welcome_image_mount_zao">Ашьха Зао</string>
|
||||
<string name="welcome_image_tulip">Атиульпан</string>
|
||||
<string name="welcome_image_no_selfies">Аселфи ыҟаӡам</string>
|
||||
<string name="welcome_image_welcome_wikipedia">Бзиала шәаабеит Википедиа ахь</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_upload">Иҭагалатәуп</string>
|
||||
<string name="navigation_item_settings">Архиарақәа</string>
|
||||
<string name="navigation_item_logout">Иҭыҵтәуп</string>
|
||||
<string name="no_description_found">ахҳаа ҧшаам</string>
|
||||
</resources>
|
||||
|
|
@ -120,5 +120,6 @@
|
|||
<string name="navigation_item_about">حول</string>
|
||||
<string name="navigation_item_settings">الإعدادات</string>
|
||||
<string name="navigation_item_logout">تسجيل الخروج</string>
|
||||
<string name="navigation_item_notification">إشعارات</string>
|
||||
<string name="nearby_info_menu_commons_article">صفحة ملف كومنز</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@
|
|||
<string name="tutorial_3_text">NUN xubas:</string>
|
||||
<string name="tutorial_3_subtext">- Selfies o semeyes de los tos amigos\n- Imáxenes que descargasti d\'Internet\n- Imáxenes de pantalla d\'aplicaciones propietaries</string>
|
||||
<string name="tutorial_4_text">Exemplu de carga:</string>
|
||||
<string name="tutorial_4_subtext">- Títulu: Ópera de Sidney\n- Descripción: Teatru de la Ópera de Sidney vistu dende l\'otru llau de la badea\n- Categoríes: Ópera de Sidney, Ópera de Sidney dende l\'oeste, Vistes a distancia de la Ópera de Sidney</string>
|
||||
<string name="tutorial_4_subtext">- Títulu: Ópera de Sidney\n- Descripción: Teatru de la Ópera de Sidney vistu dende l\'otru llau de la badea\n- Categoríes: Ópera de Sidney dende l\'oeste, Vistes a distancia de la Ópera de Sidney</string>
|
||||
<string name="welcome_wikipedia_text">Collabore coles sos imaxes. ¡Ayude a que los artículos de Wikipedia tengan vida!</string>
|
||||
<string name="welcome_wikipedia_subtext">Les imaxes de Wikipedia vienen de\nWikimedia Commons.</string>
|
||||
<string name="welcome_copyright_text">Les sos imaxes ayuden a educar a la xente alredor del mundu.</string>
|
||||
|
|
@ -188,6 +188,7 @@
|
|||
<string name="navigation_item_feedback">La to opinión</string>
|
||||
<string name="navigation_item_logout">Salir</string>
|
||||
<string name="navigation_item_info">Tutorial</string>
|
||||
<string name="navigation_item_notification">Avisos</string>
|
||||
<string name="nearby_needs_permissions">Los sitios cercanos nun pueden amosase ensin los permisos d\'allugamientu</string>
|
||||
<string name="no_description_found">nun s\'atoparon descripciones</string>
|
||||
<string name="nearby_info_menu_commons_article">Páxina del ficheru en Commons</string>
|
||||
|
|
@ -204,4 +205,6 @@
|
|||
<string name="nearby_location_has_not_changed">L\'allugamientu nun camudó.</string>
|
||||
<string name="nearby_location_not_available">L\'allugamientu nun ta disponible.</string>
|
||||
<string name="location_permission_rationale_nearby">Ríquese permisu p\'amosar una llista de llugares cercanos</string>
|
||||
<string name="get_directions">CÓMO LLEGAR</string>
|
||||
<string name="read_article">LLEER L\'ARTÍCULU</string>
|
||||
</resources>
|
||||
|
|
|
|||
7
app/src/main/res/values-b+sr+Latn/error.xml
Normal file
7
app/src/main/res/values-b+sr+Latn/error.xml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="crash_dialog_title">Ostava se srušila</string>
|
||||
<string name="crash_dialog_text">Ups! Nešto je pošlo naopako.</string>
|
||||
<string name="crash_dialog_comment_prompt">Recite nam šta ste radili pa to saznanje podelite s nama, putem e-pošte. Time ćete nam pomoći da rešimo problem!</string>
|
||||
<string name="crash_dialog_ok_toast">Hvala vam!</string>
|
||||
</resources>
|
||||
208
app/src/main/res/values-b+sr+Latn/strings.xml
Normal file
208
app/src/main/res/values-b+sr+Latn/strings.xml
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">Ostava</string>
|
||||
<string name="menu_settings">Podešavanja</string>
|
||||
<string name="username">Korisničko ime</string>
|
||||
<string name="password">Lozinka</string>
|
||||
<string name="login">Prijavi me</string>
|
||||
<string name="signup">Otvori nalog</string>
|
||||
<string name="logging_in_title">Prijavljivanje</string>
|
||||
<string name="logging_in_message">Sačekajte…</string>
|
||||
<string name="login_success">Uspešno ste prijavljeni.</string>
|
||||
<string name="login_failed">Prijavljivanje nije uspelo.</string>
|
||||
<string name="upload_failed">Datoteka nije pronađena. Pokušajte sa drugom datotekom.</string>
|
||||
<string name="authentication_failed">Provera identiteta nije uspela.</string>
|
||||
<string name="uploading_started">Otpremanje je započeto.</string>
|
||||
<string name="upload_completed_notification_title">Datoteka „%1$s“ je otpremljena.</string>
|
||||
<string name="upload_completed_notification_text">Tapnite da biste videli otpremanje</string>
|
||||
<string name="upload_progress_notification_title_start">Počinjem sa otpremanjem datoteke „%1$s“</string>
|
||||
<string name="upload_progress_notification_title_in_progress">Otpremanje datoteke „%1$s“</string>
|
||||
<string name="upload_progress_notification_title_finishing">Završavam sa otpremanjem datoteke „%1$s“</string>
|
||||
<string name="upload_failed_notification_title">Ne mogu da otpremim „%1$s“</string>
|
||||
<string name="upload_failed_notification_subtitle">Tapnite da biste videli</string>
|
||||
<plurals name="uploads_pending_notification_indicator">
|
||||
<item quantity="one">%d datoteka se otprema</item>
|
||||
<item quantity="other">%d datoteke se otpremaju</item>
|
||||
</plurals>
|
||||
<string name="title_activity_contributions">Moja skorašnja otpremanja</string>
|
||||
<string name="contribution_state_queued">Na čekanju</string>
|
||||
<string name="contribution_state_failed">Nije uspelo</string>
|
||||
<string name="contribution_state_in_progress">%1$d%% otpremljeno</string>
|
||||
<string name="contribution_state_starting">Otpremam</string>
|
||||
<string name="menu_from_gallery">Iz galerije</string>
|
||||
<string name="menu_from_camera">Fotografiši</string>
|
||||
<string name="menu_nearby">U blizini</string>
|
||||
<string name="provider_contributions">Moja otpremanja</string>
|
||||
<string name="menu_share">Deli</string>
|
||||
<string name="menu_open_in_browser">Otvori u pregledaču</string>
|
||||
<string name="share_title_hint">Naslov</string>
|
||||
<string name="share_description_hint">Opis</string>
|
||||
<string name="login_failed_network">Ne mogu da vas prijavim – mreža ne radi</string>
|
||||
<string name="login_failed_username">Ne mogu da vas prijavim – proverite svoje korisničko ime</string>
|
||||
<string name="login_failed_password">Ne mogu da vas prijavim – proverite svoju lozinku</string>
|
||||
<string name="login_failed_throttled">Previše neuspešnih pokušaja. Probajte ponovo za nekoliko minuta.</string>
|
||||
<string name="login_failed_blocked">Nažalost, korisnik je blokiran na Ostavi</string>
|
||||
<string name="login_failed_2fa_needed">Morate uneti svoj dvofaktorski kod za autentifikaciju.</string>
|
||||
<string name="login_failed_generic">Prijava nije uspela</string>
|
||||
<string name="share_upload_button">Otpremi</string>
|
||||
<string name="multiple_share_base_title">Dajte ime ovom kompletu</string>
|
||||
<string name="provider_modifications">Izmene</string>
|
||||
<string name="menu_upload_single">Otpremi</string>
|
||||
<string name="categories_search_text_hint">Pretraži kategorije</string>
|
||||
<string name="menu_save_categories">Sačuvaj</string>
|
||||
<string name="refresh_button">Osveži</string>
|
||||
<string name="gps_disabled">GPS je onemogućen na Vašem uređaju. Želite li ga omogućiti?</string>
|
||||
<string name="enable_gps">Omogući GPS</string>
|
||||
<string name="contributions_subtitle_zero">Još uvek nema otpremanja</string>
|
||||
<plurals name="contributions_subtitle">
|
||||
<item quantity="zero">\@string/contributions_subtitle_zero</item>
|
||||
<item quantity="one">%d otpremanje</item>
|
||||
<item quantity="other">%d otpremanja</item>
|
||||
</plurals>
|
||||
<plurals name="starting_multiple_uploads">
|
||||
<item quantity="one">Započni %d otpremanje</item>
|
||||
<item quantity="other">Započni %d otpremanja</item>
|
||||
</plurals>
|
||||
<plurals name="multiple_uploads_title">
|
||||
<item quantity="one">%d otpremanje</item>
|
||||
<item quantity="other">%d otpremanja</item>
|
||||
</plurals>
|
||||
<string name="categories_not_found">Nema kategorija koje odgovaraju %1$s</string>
|
||||
<string name="categories_skip_explanation">Dodajte kategorije na slike da biste olakšali korisnicima njihovo pronalaženje na Ostavi.\n\nDa biste dodali kategoriju, počnite sa pisanjem njenog imena.</string>
|
||||
<string name="categories_activity_title">Kategorije</string>
|
||||
<string name="title_activity_settings">Postavke</string>
|
||||
<string name="title_activity_signup">Otvori nalog</string>
|
||||
<string name="menu_about">O aplikaciji</string>
|
||||
<string name="about_license">Softver otvorenog koda dostupan pod licencom <a href=\"https://github.com/commons-app/apps-android-commons/blob/master/COPYING\">Apache ver. 2</a> Vikimedijina Ostava i njen logo su zaštitni znaci Vikimedijine Fondacije i koriste se sa dozvolom Vikimedijine Fondacine. Mi ne odobravamo ili podržavmo Vikimedijinu Fondaciju.\n\nAplikacija za Vikimedijinu ostavu je aplikacija otvorenog koda koja je napravljena i koja se održava pomoću grantova i volontera Vikimedijine zajednice. Zadužbina Vikimedija nije uključena u stvaranje, razvoj ili održavanje aplikacije.</string>
|
||||
<string name="about_improve"><a href=\"https://github.com/commons-app/apps-android-commons\">Izvorni kôd</a> i <a href=\"https://commons-app.github.io/\">veb-sajt</a> na GitHub-u. Napravite novi <a href=\"https://github.com/commons-app/apps-android-commons/issues\">zahtev na GitHub-u</a> da biste prijavili greške ili dali predloge.</string>
|
||||
<string name="about_privacy_policy"><a href=\"https://github.com/commons-app/apps-android-commons/wiki/Privacy-policy\">Politika privatnosti</a></string>
|
||||
<string name="about_credits"><a href=\"https://github.com/commons-app/apps-android-commons/blob/master/CREDITS\">Zasluge</a></string>
|
||||
<string name="title_activity_about">O aplikaciji</string>
|
||||
<string name="menu_feedback">Pošaljite povratne informacije (putem e-pošte)</string>
|
||||
<string name="no_email_client">Nije instaliran imejl klijent</string>
|
||||
<string name="provider_categories">Nedavno korišćene kategorije</string>
|
||||
<string name="waiting_first_sync">Čekam na prvu sinhronizaciju…</string>
|
||||
<string name="no_uploads_yet">Još niste otpremili nijednu fotografiju.</string>
|
||||
<string name="menu_retry_upload">Pokušaj ponovo</string>
|
||||
<string name="menu_cancel_upload">Otkaži</string>
|
||||
<string name="share_license_summary">Slika će se voditi pod licencom %1$s</string>
|
||||
<string name="media_upload_policy">Slanjem ove slike, ja tvrdim da je u pitanju moj rad, da ne sadrži materijal ili selfije zaštićene autorskim pravima, te da je na ostale načine u skladu sa <a href=\"https://commons.wikimedia.org/wiki/Commons:Policies_and_guidelines\">smernicama Vikimedijine ostave</a>.</string>
|
||||
<string name="menu_download">Preuzmi</string>
|
||||
<string name="preference_license">Licenca</string>
|
||||
<string name="use_previous">Koristi prethodan naslov/opis</string>
|
||||
<string name="allow_gps">Automatski detektuj trenutnu lokaciju</string>
|
||||
<string name="allow_gps_summary">Primi trenutnu lokaciju da bi predložili kategoriju ako slika nije geografski označena</string>
|
||||
<string name="preference_theme">Noćni režim</string>
|
||||
<string name="preference_theme_summary">Koristiti tamnu temu</string>
|
||||
<string name="license_name_cc_by_sa_four">Autorstvo-Deliti pod istim uslovima 4.0</string>
|
||||
<string name="license_name_cc_by_four">Autorstvo 4.0</string>
|
||||
<string name="license_name_cc_by_sa">Autorstvo-Deliti pod istim uslovimau 3.0</string>
|
||||
<string name="license_name_cc_by">Autorstvo 3.0</string>
|
||||
<string name="license_name_cc0">CC0</string>
|
||||
<string name="license_name_cc_by_sa_3_0">CC BY-SA 3.0</string>
|
||||
<string name="license_name_cc_by_sa_3_0_at">CC BY-SA 3.0 (Austrija)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_de">CC BY-SA 3.0 (Nemačka)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_ee">CC BY-SA 3.0 (Estonija)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_es">CC BY-SA 3.0 (Španija)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_hr">CC BY-SA 3.0 (Hrvatska)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_lu">CC BY-SA 3.0 (Luksemburg)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_nl">CC BY-SA 3.0 (Holandija)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_no">CC BY-SA 3.0 (Norveška)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_pl">CC BY-SA 3.0 (Poljska)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_ro">CC BY-SA 3.0 (Rumunija)</string>
|
||||
<string name="license_name_cc_by_3_0">CC BY 3.0</string>
|
||||
<string name="license_name_cc_by_sa_4_0">CC BY-SA 4.0</string>
|
||||
<string name="license_name_cc_by_4_0">CC BY 4.0</string>
|
||||
<string name="license_name_cc_zero">CC Nula</string>
|
||||
<string name="tutorial_1_text">Vikimedijina Ostava sadrži većinu slika koja se koristi na Vikipediji.</string>
|
||||
<string name="tutorial_1_subtext">Vaše slike pomažu u obrazovanju ljudi širom sveta.</string>
|
||||
<string name="tutorial_2_text">Molimo Vas da postavite slike koje ste preuzeli ili kreirali u potpunosti sami:</string>
|
||||
<string name="tutorial_2_subtext">- Prirodne objekte (cveće, životinje, planine)\n- Korisne objekte (bicikle, železničke stanice)\n- Poznate ljude (vaš gradonačelnik, Olimpijce koje ste sreli)</string>
|
||||
<string name="tutorial_3_text">Molimo NE otpremajte:</string>
|
||||
<string name="tutorial_3_subtext">- Selfije i slike tvojih prijatelja\n- Slike koje ste preuzeli sa interneta\n- Skrinšotove iz sopstvenih aplikacija</string>
|
||||
<string name="tutorial_4_text">Primer otpremanja:</string>
|
||||
<string name="tutorial_4_subtext">— Naslov: Sidnejska opera\n— Opis: Sidnejska opera, pogled preko zaliva\n— Kategorije: Sidnejska opera sa zapada, pogledi na Sidnejksu operu iz daljine</string>
|
||||
<string name="welcome_wikipedia_text">Delite svoje slike. Oživite članke na Vikipediji!</string>
|
||||
<string name="welcome_wikipedia_subtext">Slike na Vikipediji dolaze iz Ostave.</string>
|
||||
<string name="welcome_copyright_text">Sa vašim slikama pomažete u obrazovanju ljudi širom sveta.</string>
|
||||
<string name="welcome_copyright_subtext">Izbegavajte materijale koje ste našli na internetu, kao i slike plakata, korica knjiga itd.</string>
|
||||
<string name="welcome_final_text">Jeste li razumeli?</string>
|
||||
<string name="welcome_final_button_text">Jesam!</string>
|
||||
<string name="detail_panel_cats_label">Kategorije</string>
|
||||
<string name="detail_panel_cats_loading">Učitavam…</string>
|
||||
<string name="detail_panel_cats_none">Ništa nije izabrano</string>
|
||||
<string name="detail_description_empty">Nema opisa</string>
|
||||
<string name="detail_license_empty">Nepoznata licenca</string>
|
||||
<string name="menu_refresh">Osveži</string>
|
||||
<string name="read_storage_permission_rationale">Potrebna dozvola: Provera spoljašnje memorije. Aplikacija bez ovoga ne može da funkcioniše.</string>
|
||||
<string name="write_storage_permission_rationale">Neophodna dozvola: Pisanje spoljašnjeg skladišta. Aplikacija ne može da funkcioniše bez ovoga.</string>
|
||||
<string name="location_permission_rationale">Opciona dozvola: Preuzmi trenutnu lokaciju za predloge kategorija</string>
|
||||
<string name="ok">U redu</string>
|
||||
<string name="title_activity_nearby">Mesta u blizini</string>
|
||||
<string name="no_nearby">Nisu pronađena obližnja mesta</string>
|
||||
<string name="warning">Upozorenje</string>
|
||||
<string name="file_exists">Ova datoteka je već dostupna na Ostavi. Da li ste sigurni da želite da nastavite?</string>
|
||||
<string name="yes">Da</string>
|
||||
<string name="no">Ne</string>
|
||||
<string name="media_detail_title">Naslov</string>
|
||||
<string name="media_detail_media_title">Naslov medija</string>
|
||||
<string name="media_detail_description">Opis</string>
|
||||
<string name="media_detail_description_explanation">Opis datoteke ide ovde. Može da bude poprilično dug i prikazivaće se u više redova. Nadamo se da će izgledati lepo.</string>
|
||||
<string name="media_detail_uploaded_date">Datum otpremanja</string>
|
||||
<string name="media_detail_license">Licenca</string>
|
||||
<string name="media_detail_coordinates">Koordinate</string>
|
||||
<string name="media_detail_coordinates_empty">Ništa nije uneto</string>
|
||||
<string name="become_a_tester_title">Postani Beta Tester</string>
|
||||
<string name="become_a_tester_description">Priključite se na naš beta kanal na Gugl pleju i pristupajte novim informacijama i popravkama bagova</string>
|
||||
<string name="use_wikidata">Koristi Vikipodatke</string>
|
||||
<string name="use_wikidata_summary">(Upozorenje: onemogućavanjem ovoga može se izazvati velika potrošnja mobilnih podataka)</string>
|
||||
<string name="_2fa_code">2FA kod</string>
|
||||
<string name="number_of_uploads">Moj limit za skorašnja otpremanja</string>
|
||||
<string name="maximum_limit">Maksimalni limit</string>
|
||||
<string name="maximum_limit_alert">Nije moguće prikazati više od 500</string>
|
||||
<string name="set_limit">Postavi limit za skorašnja otpremanja</string>
|
||||
<string name="login_failed_2fa_not_supported">Dvofaktorska autentifikacija trenutno nije podržana.</string>
|
||||
<string name="logout_verification">Zaista želite da se odjavite?</string>
|
||||
<string name="commons_logo">Logo Ostave</string>
|
||||
<string name="background_image">Pozadinska slika</string>
|
||||
<string name="mediaimage_failed">Medijska slika neuspešna</string>
|
||||
<string name="no_image_found">Slika nije pronađena</string>
|
||||
<string name="upload_image">Otpremi sliku</string>
|
||||
<string name="welcome_image_mount_zao">Planina Zao</string>
|
||||
<string name="welcome_image_llamas">Lame</string>
|
||||
<string name="welcome_image_rainbow_bridge">Dugin most</string>
|
||||
<string name="welcome_image_tulip">Tulipan</string>
|
||||
<string name="welcome_image_no_selfies">Bez selfija</string>
|
||||
<string name="welcome_image_proprietary">Vlasnička slika</string>
|
||||
<string name="welcome_image_welcome_wikipedia">Dobrodošlica Vikipediji</string>
|
||||
<string name="welcome_image_welcome_copyright">Dobrodošlica za autorska prava</string>
|
||||
<string name="welcome_image_sydney_opera_house">Sidnejska opera</string>
|
||||
<string name="cancel">Otkaži</string>
|
||||
<string name="navigation_drawer_open">Otvori</string>
|
||||
<string name="navigation_drawer_close">Zatvori</string>
|
||||
<string name="navigation_item_home">Početna</string>
|
||||
<string name="navigation_item_upload">Otpremanje</string>
|
||||
<string name="navigation_item_nearby">U blizini</string>
|
||||
<string name="navigation_item_about">O nama</string>
|
||||
<string name="navigation_item_settings">Podešavanja</string>
|
||||
<string name="navigation_item_feedback">Povratne informacije</string>
|
||||
<string name="navigation_item_logout">Odjavi me</string>
|
||||
<string name="navigation_item_info">Tutorijal</string>
|
||||
<string name="navigation_item_notification">Obaveštenja</string>
|
||||
<string name="nearby_needs_permissions">Obližnja mesta ne mogu da se prikazuju bez dozvola za lokaciju</string>
|
||||
<string name="no_description_found">opis nije pronađen</string>
|
||||
<string name="nearby_info_menu_commons_article">Stranica datoteke na Ostavi</string>
|
||||
<string name="nearby_info_menu_wikidata_article">Stavka na Vikipodacima</string>
|
||||
<string name="error_while_cache">Greška pri keširanju slika</string>
|
||||
<string name="title_info">Jedinstven opisni naslov za datoteku, koji će biti ime datoteke. Možete da koristite obični jezik sa razmacima. Ne treba unositi ekstenziju datoteke</string>
|
||||
<string name="description_info">Molimo da opišete datoteku koliko je to moguće: Gde je napravljena? Šta prikazuje? Šta je kontekst? Opišite objekte i/ili osobe. Otkrijte informacije koje se ne mogu lako pogoditi, na primer doba dana ako je u pitanju pejzaž. Ako datoteka prikazuje nešto neobično, molimo da objasnite šta je to čini neobičnom.</string>
|
||||
<string name="give_permission">Davanje dozvole</string>
|
||||
<string name="use_external_storage">Upotreba spoljašnjeg skladišta</string>
|
||||
<string name="use_external_storage_summary">Spremanje slika napravljenih kamerom aplikacije na Vašem uređaju</string>
|
||||
<string name="send_log_file">Pošalji dnevničku datoteku</string>
|
||||
<string name="send_log_file_description">Pošalji dnevničku datoteku developerima preko imejla</string>
|
||||
<string name="login_to_your_account">Prijavite se na svoj nalog</string>
|
||||
<string name="nearby_location_has_not_changed">Lokacija nije promenjena.</string>
|
||||
<string name="nearby_location_not_available">Lokacija nije dostupna.</string>
|
||||
<string name="location_permission_rationale_nearby">Potrebna je dozvola za prikazivanje liste lokacija u blizini</string>
|
||||
</resources>
|
||||
|
|
@ -121,7 +121,7 @@
|
|||
<string name="tutorial_3_text">দয়া করে আপলোড করবেন না:</string>
|
||||
<string name="tutorial_3_subtext">u2022 আপনার বন্ধুর সেলফি বা ছবি \nu2022 ইন্টারনেট থেকে ডাউনলোড করা ছবি \nu2022 মালিকানাযুক্ত অ্যাপসমূহের স্ক্রীনশট</string>
|
||||
<string name="tutorial_4_text">আপলোডের উদাহরণ:</string>
|
||||
<string name="tutorial_4_subtext">u2022 শিরোনাম: সিডনি অপেরা হাউস \nu2022 বিবরণ: উপসাগর থেকে দেখা সিডনি অপেরা হাউস\nu2022 বিষয়শ্রেণী: সিডনি অপেরা হাউস, পশ্চিম দিক থেকে সিডনি অপেরা হাউস, সিডনি অপেরা হাউসের দূরবর্তী দৃশ্য</string>
|
||||
<string name="tutorial_4_subtext" fuzzy="true">u2022 শিরোনাম: সিডনি অপেরা হাউস \nu2022 বিবরণ: উপসাগর থেকে দেখা সিডনি অপেরা হাউস\nu2022 বিষয়শ্রেণী: সিডনি অপেরা হাউস, পশ্চিম দিক থেকে সিডনি অপেরা হাউস, সিডনি অপেরা হাউসের দূরবর্তী দৃশ্য</string>
|
||||
<string name="welcome_wikipedia_text">আপনার ছবি দিয়ে অবদান রাখুন। উইকিপিডিয়ার নিবন্ধগুলিকে নতুন রূপ দিতে সাহায্য করুন!</string>
|
||||
<string name="welcome_wikipedia_subtext">উইকিপিডিয়াতে চিত্র উইকিমিডিয়া কমন্স থেকে এসেছে।</string>
|
||||
<string name="welcome_copyright_text">আপনার ছবি সারা বিশ্বের শিক্ষিত মানুষকে সাহায্য করবে।</string>
|
||||
|
|
@ -204,4 +204,6 @@
|
|||
<string name="nearby_location_has_not_changed">অবস্থান পরিবর্তন হয়নি।</string>
|
||||
<string name="nearby_location_not_available">অবস্থান উপলব্ধ নয়।</string>
|
||||
<string name="location_permission_rationale_nearby">কাছাকাছি স্থানসমূহের একটি তালিকা প্রদর্শন করতে অনুমতি প্রয়োজন</string>
|
||||
<string name="get_directions">নির্দেশনা পান</string>
|
||||
<string name="read_article">নিবন্ধ পড়ুন</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@
|
|||
<item quantity="other">%d pellgargadennoù</item>
|
||||
</plurals>
|
||||
<string name="categories_not_found">N\'eus bet kavet rummad ebet o klotañ gant %1$s</string>
|
||||
<string name="categories_skip_explanation" fuzzy="true">Ouzhpennit rummadoù evit ma vo aesoc\'h kavout ho skeudennoù war Wikimedia Commons.\n\nKrogit da ouzhpennañ rummadoù.\nPouezit war ar c\'hemenn-mañ (pe distroit en a-raok) evit mont dreist ar bazenn-mañ.</string>
|
||||
<string name="categories_skip_explanation">Ouzhpennit rummadoù evit ma vo aesoc\'h kavout ho skeudennoù war Wikimedia Commons.\n\nKrogit da skrivañ evit ouzhpennañ rummadoù.</string>
|
||||
<string name="categories_activity_title">Rummadoù</string>
|
||||
<string name="title_activity_settings">Arventennoù</string>
|
||||
<string name="title_activity_signup">En em enskrivañ</string>
|
||||
|
|
@ -120,7 +120,7 @@
|
|||
<string name="tutorial_3_text">ARABAT enporzhiañ :</string>
|
||||
<string name="tutorial_3_subtext">- Emskeudennoù pe skeudennoù eus ho mignoned\n- Skeudennoù pellgarget ganeoc\'h diwar an Internet\n- Tapadennoù-skramm arloadoù prevez</string>
|
||||
<string name="tutorial_4_text">Skouer un enporzhiadenn :</string>
|
||||
<string name="tutorial_4_subtext">- Titl : Ti opera Sydney\n- Desskrivadur : Ti opera Sydney gwelet eus tu all ar bae\n- Rummadoù : Ti opera Sydney, Ti opera Sydney gwelet eus ar c\'hornôg, Gweloù a-bell eus ti opera Sydney</string>
|
||||
<string name="tutorial_4_subtext" fuzzy="true">- Titl : Ti opera Sydney\n- Desskrivadur : Ti opera Sydney gwelet eus tu all ar bae\n- Rummadoù : Ti opera Sydney, Ti opera Sydney gwelet eus ar c\'hornôg, Gweloù a-bell eus ti opera Sydney</string>
|
||||
<string name="welcome_wikipedia_text">Kemerit perzh gant ho skeudennoù. Sikourit pennadoù Wikipedia da zont da vev !</string>
|
||||
<string name="welcome_wikipedia_subtext">Dont a ra skeudennoù Wikipedia eus Wikimedia Commons.</string>
|
||||
<string name="welcome_copyright_text">Ho skeudennoù a sikour an dud da zeskiñ traoù dre ar bed a-bezh.</string>
|
||||
|
|
@ -182,8 +182,11 @@
|
|||
<string name="navigation_item_feedback">Evezhiadennoù</string>
|
||||
<string name="navigation_item_logout">Digevreañ</string>
|
||||
<string name="navigation_item_info">Tutorial</string>
|
||||
<string name="navigation_item_notification">Kemennoù</string>
|
||||
<string name="nearby_needs_permissions">Ne c\'haller ket diskwel al lec\'hioù tost ma ne rannit ket ho lec\'hiadur</string>
|
||||
<string name="no_description_found">N\'eus bet kavet deskrivadur ebet</string>
|
||||
<string name="nearby_info_menu_commons_article" fuzzy="true">Pennad Commons</string>
|
||||
<string name="nearby_info_menu_wikidata_article">Elfenn Wikidata</string>
|
||||
<string name="get_directions">Kaout urzhioù</string>
|
||||
<string name="read_article">Lenn ar pennad</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@
|
|||
<string name="tutorial_3_text">NE postavljajte:</string>
|
||||
<string name="tutorial_3_subtext">– Vlastite slike ili slike svojih prijatelja\n– Slike koje ste preuzeli s interneta\n– Slike ekrana neslobodnih aplikacija</string>
|
||||
<string name="tutorial_4_text">Primjer postavljanja:</string>
|
||||
<string name="tutorial_4_subtext">– Naziv: Sidnejska opera\n– Opis: Pogled na Sidnejsku operu sa zaliva\n– Kategorije: Sidnejska opera, Sidnejska opera sa zapada, Sidnejska opera iz daleka</string>
|
||||
<string name="tutorial_4_subtext" fuzzy="true">– Naziv: Sidnejska opera\n– Opis: Pogled na Sidnejsku operu sa zaliva\n– Kategorije: Sidnejska opera, Sidnejska opera sa zapada, Sidnejska opera iz daleka</string>
|
||||
<string name="welcome_wikipedia_text">Podijelite vaše slike. Pomozite člancima na Wikipediji da zažive!</string>
|
||||
<string name="welcome_wikipedia_subtext">Slike na Wikipediji se uzimaju sa Wikimedia Commonsa.</string>
|
||||
<string name="welcome_copyright_text">Vaše slike pomažu u obrazovanju ljudi širom svijeta.</string>
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@
|
|||
<item quantity="other">%d càrregues</item>
|
||||
</plurals>
|
||||
<string name="categories_not_found">No s\'ha trobat cap categoria que coincideixi amb %1$s</string>
|
||||
<string name="categories_skip_explanation" fuzzy="true">Afegiu categories per fer que les vostres imatges siguin més fàcils de trobar a Wikimedia Commons.</string>
|
||||
<string name="categories_skip_explanation">Afegiu categories per fer que les vostres imatges siguin més fàcils de trobar a Wikimedia Commons.</string>
|
||||
<string name="categories_activity_title">Categories</string>
|
||||
<string name="title_activity_settings">Paràmetres</string>
|
||||
<string name="title_activity_signup">Registre</string>
|
||||
|
|
@ -87,6 +87,7 @@
|
|||
<string name="share_license_summary">Aquesta imatge es llicenciarà sota %1$s</string>
|
||||
<string name="menu_download">Baixa</string>
|
||||
<string name="preference_license">Llicència</string>
|
||||
<string name="use_previous">Utilitza títol i descripció anteriors</string>
|
||||
<string name="preference_theme">Mode nocturn</string>
|
||||
<string name="preference_theme_summary">Utilitza el tema fosc</string>
|
||||
<string name="license_name_cc_by_sa_four">Reconeixement-CompartirIgual 4.0</string>
|
||||
|
|
@ -146,6 +147,8 @@
|
|||
<string name="upload_image">Carrega la imatge</string>
|
||||
<string name="welcome_image_llamas">Llames</string>
|
||||
<string name="welcome_image_proprietary">Imatge privativa</string>
|
||||
<string name="welcome_image_welcome_wikipedia">Benvinguts a la Viquipèdia</string>
|
||||
<string name="welcome_image_sydney_opera_house">Casa d\'Òpera de Sydney</string>
|
||||
<string name="cancel">Cancel·la</string>
|
||||
<string name="navigation_drawer_open">Obre</string>
|
||||
<string name="navigation_drawer_close">Tanca</string>
|
||||
|
|
@ -156,7 +159,19 @@
|
|||
<string name="navigation_item_settings">Paràmetres</string>
|
||||
<string name="navigation_item_feedback">Comentaris</string>
|
||||
<string name="navigation_item_logout">Finalitza la sessió</string>
|
||||
<string name="navigation_item_info">Tutorial</string>
|
||||
<string name="navigation_item_notification">Notificacions</string>
|
||||
<string name="no_description_found">no s\'ha trobat cap descripció</string>
|
||||
<string name="nearby_info_menu_commons_article">Article del fitxer a Commons</string>
|
||||
<string name="nearby_info_menu_wikidata_article">Element del Wikidata</string>
|
||||
<string name="error_while_cache">Error mentre es carregaven les fotografies</string>
|
||||
<string name="give_permission">Dóna permís</string>
|
||||
<string name="use_external_storage">Utilitza l’emmagatzematge extern</string>
|
||||
<string name="send_log_file">Envia log arxiu</string>
|
||||
<string name="send_log_file_description">Envia log a desenvolupadors via correu electrònic</string>
|
||||
<string name="login_to_your_account">Login al vostre compte</string>
|
||||
<string name="nearby_location_has_not_changed">La ubicació no ha canviat.</string>
|
||||
<string name="nearby_location_not_available">La ubicació no és disponible.</string>
|
||||
<string name="get_directions">COM ANAR-HI</string>
|
||||
<string name="read_article">LLEGIU L’ARTICLE</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@
|
|||
<item quantity="other">%d nahrávání</item>
|
||||
</plurals>
|
||||
<string name="categories_not_found">Žádné kategorie neodpovídají „%1$s“</string>
|
||||
<string name="categories_skip_explanation" fuzzy="true">Přidejte kategorie, aby bylo vaše obrázky možno na Wikimedia Commons najít.</string>
|
||||
<string name="categories_skip_explanation">Přidejte kategorie, aby bylo vaše obrázky možno na Wikimedia Commons najít.</string>
|
||||
<string name="categories_activity_title">Kategorie</string>
|
||||
<string name="title_activity_settings">Nastavení</string>
|
||||
<string name="title_activity_signup">Zaregistrovat se</string>
|
||||
|
|
@ -120,7 +120,7 @@
|
|||
<string name="tutorial_3_text">Prosím NENAHRÁVEJTE:</string>
|
||||
<string name="tutorial_3_subtext">- Selfie nebo obrázky vašich přátel\n- Obrázky stažené z Internetu\n- Screenshoty z proprietárních aplikací</string>
|
||||
<string name="tutorial_4_text">Příklad nahraného souboru:</string>
|
||||
<string name="tutorial_4_subtext">- Název: Opera v Sydney\n- Popis: Opera v Sydney, pohled přes záliv\n- Kategorie: Sydney Opera House, Sydney Opera House from the west, Sydney Opera House remote views</string>
|
||||
<string name="tutorial_4_subtext" fuzzy="true">- Název: Opera v Sydney\n- Popis: Opera v Sydney, pohled přes záliv\n- Kategorie: Sydney Opera House, Sydney Opera House from the west, Sydney Opera House remote views</string>
|
||||
<string name="welcome_wikipedia_text">Přispějte svými obrázky. Pomozte oživit články na Wikipedii.</string>
|
||||
<string name="welcome_wikipedia_subtext">Obrázky na Wikipedii pochází \nz Wikimedia Commons.</string>
|
||||
<string name="welcome_copyright_text">Vaše obrázky pomáhají vzdělávat lidi po celém světě.</string>
|
||||
|
|
@ -147,6 +147,8 @@
|
|||
<string name="media_detail_description">Popis</string>
|
||||
<string name="media_detail_description_explanation">Sem patří popis média. Může být potenciálně velmi dlouhý, takže zabere několik řádků. Přesto doufáme, že to vypadá hezky.</string>
|
||||
<string name="media_detail_uploaded_date">Datum nahrání souboru</string>
|
||||
<string name="media_detail_license">Licence</string>
|
||||
<string name="media_detail_coordinates">Souřadnice</string>
|
||||
<string name="become_a_tester_title">Staňte se beta testery</string>
|
||||
<string name="become_a_tester_description">Přihlásit se do našeho beta kanálu na Google Play a dostávat včasný přístup k novinkám a opravám chyb</string>
|
||||
<string name="use_wikidata">Použít Wikidata</string>
|
||||
|
|
@ -160,6 +162,7 @@
|
|||
<string name="logout_verification">Opravdu se chcete odhlásit?</string>
|
||||
<string name="commons_logo">Logo Wikimedia Commons</string>
|
||||
<string name="background_image">Obrázek na pozadí</string>
|
||||
<string name="mediaimage_failed">Obrázek</string>
|
||||
<string name="no_image_found">Nebyl nalezen žádný obrázek</string>
|
||||
<string name="upload_image">Nahrát obrázek</string>
|
||||
<string name="welcome_image_mount_zao">Hora Zao</string>
|
||||
|
|
@ -186,4 +189,12 @@
|
|||
<string name="no_description_found">nebyl nalezen žádný popisek</string>
|
||||
<string name="nearby_info_menu_commons_article">Stránka souboru na Commons</string>
|
||||
<string name="nearby_info_menu_wikidata_article">Položka Wikidat</string>
|
||||
<string name="give_permission">Dát povolení</string>
|
||||
<string name="send_log_file">Odeslat log</string>
|
||||
<string name="send_log_file_description">Odeslat log vývojářům e-mailem</string>
|
||||
<string name="login_to_your_account">Přihlásit se k účtu</string>
|
||||
<string name="nearby_location_has_not_changed">Vaše umístění se nezměnilo.</string>
|
||||
<string name="nearby_location_not_available">Umístění není dostupné.</string>
|
||||
<string name="get_directions">NAVIGOVAT</string>
|
||||
<string name="read_article">PŘEČÍST ČLÁNEK</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@
|
|||
<item quantity="other">%d overførsler</item>
|
||||
</plurals>
|
||||
<string name="categories_not_found">Ingen kategorier matchende %1$s er fundet</string>
|
||||
<string name="categories_skip_explanation" fuzzy="true">Tilføj kategorier for at gøre billederne mere synlig på Wikimedia Commons.</string>
|
||||
<string name="categories_skip_explanation">Tilføj kategorier for at gøre billederne mere synlig på Wikimedia Commons. Tast for at tilføje kategorier.</string>
|
||||
<string name="categories_activity_title">Kategorier</string>
|
||||
<string name="title_activity_settings">Indstillinger</string>
|
||||
<string name="title_activity_signup">Opret konto</string>
|
||||
|
|
@ -121,7 +121,7 @@
|
|||
<string name="tutorial_3_text">Overfør venligst IKKE:</string>
|
||||
<string name="tutorial_3_subtext">- Selvportrætter eller billeder af dine venner\n- Billeder du har hentet fra internettet\n- Skærmbilleder af dine proprietære programmer</string>
|
||||
<string name="tutorial_4_text">Eksempel på overførsel:</string>
|
||||
<string name="tutorial_4_subtext">- Titel: Sydneys Operahus\n- Beskrivelse: Operahuset i Sydney set fra anden siden af bugten\n- Kategorier: Operahuset i Sydney, Operahuset i Sydney fra vest, Operahuset i Sydney udefra</string>
|
||||
<string name="tutorial_4_subtext">- Titel: Sydneys Operahus\n- Beskrivelse: Operahuset i Sydney set fra den anden siden af\n bugten\n- Kategorier: Operahuset i Sydney fra vest, Operahuset i Sydney\n udefra</string>
|
||||
<string name="welcome_wikipedia_text">Bidrag med dine billeder. Hjælp Wikipedias artikler med at komme til live!</string>
|
||||
<string name="welcome_wikipedia_subtext">Billeder på Wikipedia kommer fra Wikimedia Commons.</string>
|
||||
<string name="welcome_copyright_text">Dine billeder hjælper med til at uddanne folk rundt om i verden.</string>
|
||||
|
|
@ -188,6 +188,7 @@
|
|||
<string name="navigation_item_feedback">Tilbagemelding</string>
|
||||
<string name="navigation_item_logout">Log af</string>
|
||||
<string name="navigation_item_info">Øvelse</string>
|
||||
<string name="navigation_item_notification">Påmindelser</string>
|
||||
<string name="nearby_needs_permissions">Steder i nærheden kan ikke vises uden placeringsrettigheder</string>
|
||||
<string name="no_description_found">ingen beskrivelse fundet</string>
|
||||
<string name="nearby_info_menu_commons_article">Commons-filside</string>
|
||||
|
|
@ -204,4 +205,6 @@
|
|||
<string name="nearby_location_has_not_changed">Sted er ikke ændret.</string>
|
||||
<string name="nearby_location_not_available">Sted ikke tilgængeligt.</string>
|
||||
<string name="location_permission_rationale_nearby">Tilladelse kræves for at vise en liste over steder i nærheden</string>
|
||||
<string name="get_directions">FÅ RUTEHJÆLP</string>
|
||||
<string name="read_article">LÆS ARTIKEL</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@
|
|||
<string name="tutorial_3_text">Bitte NICHT hochladen:</string>
|
||||
<string name="tutorial_3_subtext">- Selfies oder Bilder deiner Freunde\n- Bilder, die du aus dem Internet heruntergeladen hast\n- Screenshots von proprietären Softwareanwendungen</string>
|
||||
<string name="tutorial_4_text">Beispiel-Upload:</string>
|
||||
<string name="tutorial_4_subtext">- Titel: Opernhaus von Sydney\n- Beschreibung: Opernhaus von Sydney, von der Bucht aus gesehen\n- Kategorien: Opernhaus von Sydney, Opernhaus von Sydney von Westen, Opernhaus von Sydney (Fernansicht)</string>
|
||||
<string name="tutorial_4_subtext">- Titel: Opernhaus von Sydney\n- Beschreibung: Opernhaus von Sydney, von der Bucht aus gesehen\n- Kategorien: Opernhaus von Sydney von Westen, Opernhaus von Sydney (Fernansicht)</string>
|
||||
<string name="welcome_wikipedia_text">Teile deine Bilder. Erwecke Wikipedia-Artikel zum Leben!</string>
|
||||
<string name="welcome_wikipedia_subtext">Die Bilder auf Wikipedia kommen von Wikimedia Commons.</string>
|
||||
<string name="welcome_copyright_text">Deine Bilder helfen dabei, Menschen auf der ganzen Welt zu bilden.</string>
|
||||
|
|
@ -188,6 +188,7 @@
|
|||
<string name="navigation_item_feedback">Rückmeldungen</string>
|
||||
<string name="navigation_item_logout">Abmelden</string>
|
||||
<string name="navigation_item_info">Anleitung</string>
|
||||
<string name="navigation_item_notification">Benachrichtigungen</string>
|
||||
<string name="nearby_needs_permissions">Orte in der Nähe können ohne Berechtigung zur Standortbestimmung nicht ermittelt werden</string>
|
||||
<string name="no_description_found">Keine Beschreibung gefunden</string>
|
||||
<string name="nearby_info_menu_commons_article">Commons-Dateiseite</string>
|
||||
|
|
@ -204,4 +205,6 @@
|
|||
<string name="nearby_location_has_not_changed">Der Standort hat sich nicht geändert.</string>
|
||||
<string name="nearby_location_not_available">Der Standort ist nicht verfügbar.</string>
|
||||
<string name="location_permission_rationale_nearby">Berechtigung zur Anzeige einer Liste mit Orten in der Nähe erforderlich</string>
|
||||
<string name="get_directions">RICHTUNGEN ABRUFEN</string>
|
||||
<string name="read_article">ARTIKEL LESEN</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -54,21 +54,21 @@
|
|||
<string name="gps_disabled">Το GPS στην συσκευή είναι απενεργοποιημένο. Θέλετε να το ενεργοποιήσετε;</string>
|
||||
<string name="enable_gps"> Ενεργοποιήσετε το GPS</string>
|
||||
<string name="contributions_subtitle_zero">Δεν υπάρχουν ακόμα φορτωμένα αρχεία</string>
|
||||
<plurals name="contributions_subtitle" fuzzy="true">
|
||||
<plurals name="contributions_subtitle">
|
||||
<item quantity="zero">Δεν υπάρχουν επιφορτώσεις ακόμη</item>
|
||||
<item quantity="one">1 επιφόρτωση</item>
|
||||
<item quantity="other">%d επιφορτώσεις</item>
|
||||
</plurals>
|
||||
<plurals name="starting_multiple_uploads" fuzzy="true">
|
||||
<plurals name="starting_multiple_uploads">
|
||||
<item quantity="one">Έναρξη 1 επιφόρτωσης</item>
|
||||
<item quantity="other">Έναρτξη %d επιφορτώσεων</item>
|
||||
</plurals>
|
||||
<plurals name="multiple_uploads_title" fuzzy="true">
|
||||
<plurals name="multiple_uploads_title">
|
||||
<item quantity="one">1 επιφόρτωση</item>
|
||||
<item quantity="other">%d επιφορτώσεις</item>
|
||||
</plurals>
|
||||
<string name="categories_not_found">Δεν βρέθηκαν κατηγορίες που ταιριάζουν %1$s</string>
|
||||
<string name="categories_skip_explanation" fuzzy="true">Προσθέστε κατηγορίες για να κάνετε τις εικόνες σας πιο ανιχνεύσιμες στα Wikimedia Commons.\n\nΑρχίστε να γράφετε για να προσθέσετε κατηγορίες.\nΠατήστε αυτό το μήνυμα (ή πατήστε επιστροφή) για να παραλείψετε αυτό το βήμα.</string>
|
||||
<string name="categories_skip_explanation">Προσθέστε κατηγορίες για να κάνετε τις εικόνες σας πιο ανιχνεύσιμες στα Wikimedia Commons.\n\nΑρχίστε να γράφετε για να προσθέσετε κατηγορίες.\nΠατήστε αυτό το μήνυμα (ή πατήστε επιστροφή) για να παραλείψετε αυτό το βήμα.</string>
|
||||
<string name="categories_activity_title">Κατηγορίες</string>
|
||||
<string name="title_activity_settings">Ρυθμίσεις</string>
|
||||
<string name="title_activity_signup">Εγγραφή</string>
|
||||
|
|
@ -76,7 +76,7 @@
|
|||
<string name="about_license">Λογισμικό ανοικτού κωδικού που κυκλοφορεί υπό την <a href=\"https://github.com/commons-app/apps-android-commons/blob/master/COPYING\">Άδεια Apache v2</a>. Το Wikimedia Commons και το λογότυπο είναι εμπορικά σήματα του Ιδρύματος Wikimedia και χρησιμοποιούνται με άδεια από το Ίδρυμα Wikimedia. Δεν συμμετέχουμε στην δημιουργία, ανάπτυξη ή συντήρηση του Ιδρύματος Wikimedia.</string>
|
||||
<string name="about_improve"><a href=\"https://github.com/commons-app/apps-android-commons\">Πηγή</a> και <a href=\"https://commons-app.github.io/\">ιστοσελίδα</a> στο GitHub. Δημιουργήστε ένα νέο <a href=\"https://github.com/commons-app/apps-android-commons/issues\">GitHub θέμα</a> για αναφορές σφαλμάτων και προτάσεις.</string>
|
||||
<string name="about_privacy_policy"><a href=\"https://wikimediafoundation.org/wiki/Privacy_policy\">Πολιτική Απορρήτου και προσωπικών δεδομένων</a></string>
|
||||
<string name="about_credits" fuzzy="true"><a href=\"https://github.com/commons-app/apps-android-commons/blob/master/CREDITS\">CREDITS</a></string>
|
||||
<string name="about_credits"><a href=\"https://github.com/commons-app/apps-android-commons/blob/master/CREDITS\">CREDITS</a></string>
|
||||
<string name="title_activity_about">Σχετικά</string>
|
||||
<string name="menu_feedback">Αποστολή σχολίων (μέσω Email)</string>
|
||||
<string name="no_email_client">Δεν υπάρχει εγκατεστημένη εφαρμογή ηλεκτρονικού ταχυδρομείου</string>
|
||||
|
|
@ -172,6 +172,7 @@
|
|||
<string name="welcome_image_llamas">Llamas</string>
|
||||
<string name="welcome_image_rainbow_bridge">Γέφυρα Ουρανίου Τόξου</string>
|
||||
<string name="welcome_image_tulip">Τουλίπα</string>
|
||||
<string name="welcome_image_no_selfies">Όχι selfies</string>
|
||||
<string name="welcome_image_proprietary">Ιδιόκτητη Εικόνα</string>
|
||||
<string name="welcome_image_welcome_wikipedia"> Καλωσόρισες Βικιπαίδεια</string>
|
||||
<string name="welcome_image_welcome_copyright">Καλωσορίστε το Δικαίωμα Αντιγραφής</string>
|
||||
|
|
@ -187,6 +188,7 @@
|
|||
<string name="navigation_item_feedback">Σχόλια</string>
|
||||
<string name="navigation_item_logout">Αποσύνδεση</string>
|
||||
<string name="navigation_item_info">Σεμινάριο</string>
|
||||
<string name="navigation_item_notification">Ενημερώσεις</string>
|
||||
<string name="nearby_needs_permissions">Οι κοντινές τοποθεσίες δεν μπορούν να προβληθούν δίχως τις άδειες τοποθεσίας</string>
|
||||
<string name="no_description_found">δεν βρέθηκε περιγραφή</string>
|
||||
<string name="nearby_info_menu_commons_article">Σελίδα φακέλλου κοινής χρήσης</string>
|
||||
|
|
@ -199,6 +201,10 @@
|
|||
<string name="use_external_storage_summary">Αποθηκεύσετε εικόνες που παίρνονται στην κάμερα εφαρμογής στην συσκευή σας</string>
|
||||
<string name="send_log_file">Αποστείλατε τον φάκελλο σύνδεσης</string>
|
||||
<string name="send_log_file_description">Στείλατε τον φάκελλο σύνδεσης στους δημιουργούς μέσω email</string>
|
||||
<string name="login_to_your_account">Συνδεθείτε στο λογαριασμό σας.</string>
|
||||
<string name="nearby_location_has_not_changed">Ο εντοπισμός δεν έχει αλλάξει.</string>
|
||||
<string name="nearby_location_not_available">Ο τόπος δεν είναι διαθέσιμος.</string>
|
||||
<string name="location_permission_rationale_nearby">Απαιτείται άδεια για την εμφάνιση λίστας κοντινών σημείων</string>
|
||||
<string name="get_directions">Λάβετε κατευθύνσεις</string>
|
||||
<string name="read_article">Ανάγνωση άρθρου</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@
|
|||
<string name="tutorial_3_text">NO cargues:</string>
|
||||
<string name="tutorial_3_subtext">- Autorretratos o fotos de tus amigos\n- Imágenes que hayas descargado de Internet\n- Capturas de pantalla de aplicaciones privativas</string>
|
||||
<string name="tutorial_4_text">Ejemplo de carga:</string>
|
||||
<string name="tutorial_4_subtext">- Título: Casa de la Ópera de Sídney\n- Descripción: Casa de la Ópera de Sídney vista desde el otro lado de la bahía\n- Categorías: Casa de la Ópera de Sídney, Casa de la Ópera de Sídney desde el oeste, Vistas a distancia de la Casa de la Ópera de Sídney</string>
|
||||
<string name="tutorial_4_subtext">- Título: Casa de la Ópera de Sídney\n- Descripción: Casa de la Ópera de Sídney vista desde el otro lado de la bahía\n- Categorías: Casa de la Ópera de Sídney desde el oeste, Vistas a distancia de la Casa de la Ópera de Sídney</string>
|
||||
<string name="welcome_wikipedia_text">Contribuye con tus imágenes.\n¡Ayuda a que los artículos de Wikipedia tengan vida!</string>
|
||||
<string name="welcome_wikipedia_subtext">Las imágenes en Wikipedia proceden de\nWikimedia Commons.</string>
|
||||
<string name="welcome_copyright_text">Tus imágenes ayudan a educar a la gente\nalrededor del mundo.</string>
|
||||
|
|
@ -147,13 +147,13 @@
|
|||
<string name="media_detail_title">Título</string>
|
||||
<string name="media_detail_media_title">Título del multimedia</string>
|
||||
<string name="media_detail_description">Descripción</string>
|
||||
<string name="media_detail_description_explanation">Aquí va la descripción del multimedia. Potencialmente, puede ser bastante largo, y deberá agruparse en múltiples líneas. De todas formas, esperamos que se ve bien.</string>
|
||||
<string name="media_detail_description_explanation">Aquí va la descripción del archivo multimedia. Esta puede ser muy extensa, en cuyo caso deberá ajustarse en varios renglones. No obstante, esperamos que se vea bien.</string>
|
||||
<string name="media_detail_uploaded_date">Fecha de subida</string>
|
||||
<string name="media_detail_license">Licencia</string>
|
||||
<string name="media_detail_coordinates">Coordenadas</string>
|
||||
<string name="media_detail_coordinates_empty">No se proporcionaron</string>
|
||||
<string name="become_a_tester_title">Prueba la versión beta</string>
|
||||
<string name="become_a_tester_description">Opta por nuestro canal beta en Google Play y obtén acceso a funcionalidades nuevas y correcciones de errores</string>
|
||||
<string name="become_a_tester_description">Apúntate a nuestro canal beta en Google Play y obtén acceso a funcionalidades nuevas y correcciones de errores</string>
|
||||
<string name="use_wikidata">Utilizar Wikidata</string>
|
||||
<string name="use_wikidata_summary">(Advertencia: desactivar esto puede ocasionar un gran consumo de datos del móvil)</string>
|
||||
<string name="_2fa_code">Código de autenticación de 2 pasos</string>
|
||||
|
|
@ -188,6 +188,7 @@
|
|||
<string name="navigation_item_feedback">Comentarios</string>
|
||||
<string name="navigation_item_logout">Salir</string>
|
||||
<string name="navigation_item_info">Tutorial</string>
|
||||
<string name="navigation_item_notification">Notificaciones</string>
|
||||
<string name="nearby_needs_permissions">Los sitios cercanos no pueden mostrarse sin los permisos de ubicación</string>
|
||||
<string name="no_description_found">no se encontró ninguna descripción</string>
|
||||
<string name="nearby_info_menu_commons_article">Página del archivo en Commons</string>
|
||||
|
|
@ -204,4 +205,6 @@
|
|||
<string name="nearby_location_has_not_changed">La ubicación no ha cambiado.</string>
|
||||
<string name="nearby_location_not_available">La ubicación no está disponible.</string>
|
||||
<string name="location_permission_rationale_nearby">Se necesita permiso para mostrar una lista de lugares cercanos</string>
|
||||
<string name="get_directions">CÓMO LLEGAR</string>
|
||||
<string name="read_article">LEER ARTÍCULO</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -155,4 +155,6 @@
|
|||
<string name="nearby_info_menu_commons_article">Artxibo orrialde komuna</string>
|
||||
<string name="nearby_info_menu_wikidata_article">Wikidata itema</string>
|
||||
<string name="error_while_cache">Argazkiak hartzerakoan sortutako akatsa</string>
|
||||
<string name="get_directions">NORABIDEAK JASO</string>
|
||||
<string name="read_article">IRAKURRI ARTIKULUA</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@
|
|||
<string name="tutorial_3_text">لطفاً بارگذاری نکنید:</string>
|
||||
<string name="tutorial_3_subtext">-سلفی خودتان یا تصویر دوستانتان\n-تصاویری که از اینترنت دانلود کردید\n-نماگرفت از دیگر اپلیکیشنها</string>
|
||||
<string name="tutorial_4_text">نمونه بارگذاری:</string>
|
||||
<string name="tutorial_4_subtext">-عنوان: خانهٔ اپرای سیدنی\n-توضیحات: خانهٔ اپرای سیدنی از آن طرف خلیج\n-ردهها: Sydney Opera House, Sydney Opera House from the west, Sydney Opera House remote views</string>
|
||||
<string name="tutorial_4_subtext" fuzzy="true">-عنوان: خانهٔ اپرای سیدنی\n-توضیحات: خانهٔ اپرای سیدنی از آن طرف خلیج\n-ردهها: Sydney Opera House, Sydney Opera House from the west, Sydney Opera House remote views</string>
|
||||
<string name="welcome_wikipedia_text">عکسهای خود را به اشتراک بگذارید. به ویکیپدیا کمک کنید تا مقالاتش زنده شوند!</string>
|
||||
<string name="welcome_wikipedia_subtext">ویکیپدیا از تصویرهای ویکیانبار استفاده میکند.</string>
|
||||
<string name="welcome_copyright_text">تصویرهای شما به مطالعهٔ مردم در سراسر دنیا کمک میکنند.</string>
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@
|
|||
<item quantity="other">%d tallennusta</item>
|
||||
</plurals>
|
||||
<string name="categories_not_found">Luokkaa %1$s ei löytynyt</string>
|
||||
<string name="categories_skip_explanation" fuzzy="true">Lisää luokkia tehdäksesi kuvistasi helpommin löydettäviä.\n\nAloita kirjoittaminen lisätäksesi luokkia.\nNapauta tätä viestiä (tai paina takaisin) ohittaaksesi tämän vaiheen.</string>
|
||||
<string name="categories_skip_explanation">Lisää luokkia tehdäksesi kuvistasi enemmän löydettäviä Wikimedia Commonssissa.\nAloita kirjoittaminen lisätäksesi luokkia.</string>
|
||||
<string name="categories_activity_title">Luokat</string>
|
||||
<string name="title_activity_settings">Asetukset</string>
|
||||
<string name="title_activity_signup">Rekisteröidy</string>
|
||||
|
|
@ -121,7 +121,7 @@
|
|||
<string name="tutorial_3_text">ÄLÄ tallenna seuraavia:</string>
|
||||
<string name="tutorial_3_subtext">- Selfiet tai kuvat ystävistäsi\n- Netistä ladatut kuvat\n- Kuvakaappaukset kaupallisista sovelluksista</string>
|
||||
<string name="tutorial_4_text">Tallennusesimerkki:</string>
|
||||
<string name="tutorial_4_subtext">- Nimi: Sydneyn operatalo\n- Kuvaus: Sydneyn oopperatalo katsottuna lahden toisella puolella\n- Luokat: Sydneyn oopperatalo, Sydneyn oopperatalo lännestä, Sydneyn oopperatalo remote views</string>
|
||||
<string name="tutorial_4_subtext" fuzzy="true">- Nimi: Sydneyn operatalo\n- Kuvaus: Sydneyn oopperatalo katsottuna lahden toisella puolella\n- Luokat: Sydneyn oopperatalo, Sydneyn oopperatalo lännestä, Sydneyn oopperatalo remote views</string>
|
||||
<string name="welcome_wikipedia_text">Herätä Wikipedia-artikkelit eloon kuvillasi! Tuo kuvasi Wikipediaan.</string>
|
||||
<string name="welcome_wikipedia_subtext">Wikipedian kuvat tulevat Wikimedia Commonsista.</string>
|
||||
<string name="welcome_copyright_text">Kuvasi auttavat useita ihmisiä ympäri maailmaa artikkeleiden ymmärtämisessä.</string>
|
||||
|
|
@ -153,6 +153,7 @@
|
|||
<string name="become_a_tester_title">Ryhdy beetatestaajaksi</string>
|
||||
<string name="use_wikidata">Käytä Wikidataa</string>
|
||||
<string name="use_wikidata_summary">(Varoitus: poiskytkeminen voi aiheuttaa suuren mobiilidatankäytön)</string>
|
||||
<string name="_2fa_code">2FA koodi</string>
|
||||
<string name="maximum_limit">Maksimimäärä</string>
|
||||
<string name="maximum_limit_alert">Ei voida näyttää enempää, kuin 500</string>
|
||||
<string name="login_failed_2fa_not_supported">Kaksivaiheinen tunnistus ei ole vielä tuettu.</string>
|
||||
|
|
@ -162,9 +163,11 @@
|
|||
<string name="no_image_found">Kuvaa ei löytynyt</string>
|
||||
<string name="upload_image">Lataa kuva</string>
|
||||
<string name="welcome_image_mount_zao">Zao-vuori</string>
|
||||
<string name="welcome_image_llamas">Laamat</string>
|
||||
<string name="welcome_image_rainbow_bridge">Sateenkaarisilta</string>
|
||||
<string name="welcome_image_tulip">Tulppaani</string>
|
||||
<string name="welcome_image_no_selfies">Ei selfieitä</string>
|
||||
<string name="welcome_image_proprietary">Patentoitu kuva</string>
|
||||
<string name="welcome_image_welcome_wikipedia">Tervetuloa Wikipediaan</string>
|
||||
<string name="welcome_image_welcome_copyright">Tervetuloa tekijänoikeus</string>
|
||||
<string name="welcome_image_sydney_opera_house">Sydneyn oopperatalo</string>
|
||||
|
|
@ -179,8 +182,17 @@
|
|||
<string name="navigation_item_feedback">Palaute</string>
|
||||
<string name="navigation_item_logout">Kirjaudu ulos</string>
|
||||
<string name="navigation_item_info">Opas</string>
|
||||
<string name="navigation_item_notification">Ilmoitukset</string>
|
||||
<string name="nearby_needs_permissions">Lähellä olevia paikkoja ei voida näyttää ilman sijaintilupaa</string>
|
||||
<string name="nearby_info_menu_commons_article">Commons-tiedostosivu</string>
|
||||
<string name="nearby_info_menu_wikidata_article">Wikidata-kohde</string>
|
||||
<string name="title_info">Tiedoston yksilöllinen ja kuvaava otsikko, jota käytetään tiedostonimenä. Voit käyttää tavallista kieltä välilyönnein. Älä sisällytä tiedoston päätettä.</string>
|
||||
<string name="give_permission">Anna lupa</string>
|
||||
<string name="use_external_storage">Käytä ulkoista tallennustilaa</string>
|
||||
<string name="send_log_file">Lähetä lokitiedosto</string>
|
||||
<string name="send_log_file_description">Lähetä logitiedosto kehittäjille sähköpostin kautta</string>
|
||||
<string name="login_to_your_account">Kirjaudu tilillesi</string>
|
||||
<string name="nearby_location_has_not_changed">Sijainti ei ole muuttunut.</string>
|
||||
<string name="nearby_location_not_available">Sijainti ei käytettävissä.</string>
|
||||
<string name="read_article">LUE ARTIKKELI</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@
|
|||
<string name="tutorial_3_text">Veuillez ne PAS téléverser :</string>
|
||||
<string name="tutorial_3_subtext">- des selfies ou des images de vos amis \n- des images téléchargées sur Internet\n- des copies d’écran d’applications propriétaires</string>
|
||||
<string name="tutorial_4_text">Exemple de téléversement :</string>
|
||||
<string name="tutorial_4_subtext">- Titre : L’opéra de Sydney\n- Description : L’opéra de Sydney vu à travers la baie\n- Catégories : Opéra de Sydney, Opéra de Sydney depuis l’ouest, vues à distance de l’Opéra de Sydney</string>
|
||||
<string name="tutorial_4_subtext">- Titre : Opéra de Sydney\n- Description : L’opéra de Sydney vu à travers la baie\n- Catégories : Opéra de Sydney depuis l’ouest, vues à distance de l’Opéra de Sydney</string>
|
||||
<string name="welcome_wikipedia_text">Contribuez avec vos images. Aidez les articles de Wikipédia à prendre vie !</string>
|
||||
<string name="welcome_wikipedia_subtext">Les images sur Wikipédia viennent de Wikimedia Commons.</string>
|
||||
<string name="welcome_copyright_text">Vos images aident à éduquer les gens dans le monde entier.</string>
|
||||
|
|
@ -188,6 +188,7 @@
|
|||
<string name="navigation_item_feedback">Commentaire</string>
|
||||
<string name="navigation_item_logout">Déconnexion</string>
|
||||
<string name="navigation_item_info">Tutoriel</string>
|
||||
<string name="navigation_item_notification">Notifications</string>
|
||||
<string name="nearby_needs_permissions">Les endroits proches ne peuvent pas être affichés si vous ne partagez pas votre position géographique.</string>
|
||||
<string name="no_description_found">aucune description trouvée</string>
|
||||
<string name="nearby_info_menu_commons_article">Page des fichiers de Commons</string>
|
||||
|
|
@ -204,4 +205,6 @@
|
|||
<string name="nearby_location_has_not_changed">L\'emplacement n\'a pas changé.</string>
|
||||
<string name="nearby_location_not_available">Emplacement non disponible.</string>
|
||||
<string name="location_permission_rationale_nearby">Une permission est requise pour afficher une liste de lieux relatifs</string>
|
||||
<string name="get_directions">OBTENIR DES DIRECTIVES</string>
|
||||
<string name="read_article">LIRE L’ARTICLE</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@
|
|||
<string name="tutorial_3_text">Oober schüür EI huuch:</string>
|
||||
<string name="tutorial_3_subtext">- Selfies of bilen faan din frinjer\n- Bilen, diar dü ütj at internet deellooset heest\n- Bilskirembilen faan ünfrei software</string>
|
||||
<string name="tutorial_4_text">Bispal:</string>
|
||||
<string name="tutorial_4_subtext">- Tiitel: Sydney Opernhüs\n- Beskriiwang: Opernhüs fan Sydney, faan\'t bocht ütj sen\n- Kategoriin: Sydney Opernhüs, Sydney Opernhüs faan waasten, Sydney Opernhüs faan widj wech</string>
|
||||
<string name="tutorial_4_subtext" fuzzy="true">- Tiitel: Sydney Opernhüs\n- Beskriiwang: Opernhüs fan Sydney, faan\'t bocht ütj sen\n- Kategoriin: Sydney Opernhüs, Sydney Opernhüs faan waasten, Sydney Opernhüs faan widj wech</string>
|
||||
<string name="welcome_wikipedia_text">Skaft din bilen. Halep mä an maage artiikler üüb Wikipedia labener!</string>
|
||||
<string name="welcome_wikipedia_subtext">A bilen üüb Wikipedia kem faan Wikimedia Commons.</string>
|
||||
<string name="welcome_copyright_text">Mä din bilen halepst dü minsken üüb a hialer welt.</string>
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@
|
|||
<item quantity="other">%d cargas</item>
|
||||
</plurals>
|
||||
<string name="categories_not_found">Non se atopou ningunha categoría que coincidise con \"%1$s\"</string>
|
||||
<string name="categories_skip_explanation" fuzzy="true">Engada categorías para facer máis accesibles as súas imaxes na Wikimedia Commons.\n\nComece a escribir para engadir categorías.\nPrema nesta mensaxe (ou no botón \"Atrás\") para saltar este paso.</string>
|
||||
<string name="categories_skip_explanation">Engada categorías para facer máis accesibles as súas imaxes na Wikimedia Commons.\nComece a escribir para engadir categorías.</string>
|
||||
<string name="categories_activity_title">Categorías</string>
|
||||
<string name="title_activity_settings">Configuracións</string>
|
||||
<string name="title_activity_signup">Rexistrarse</string>
|
||||
|
|
@ -121,7 +121,7 @@
|
|||
<string name="tutorial_3_text">Por favor, NON subaː</string>
|
||||
<string name="tutorial_3_subtext">- Selfies ou imaxes dos seus amigos\n- Imaxes descargadas de Internet\n- Capturas de pantalla de aplicacións con dereitos de autor</string>
|
||||
<string name="tutorial_4_text">Exemplo de subaː</string>
|
||||
<string name="tutorial_4_subtext">- Título: Ópera de Sydney\n- Descrición: A Ópera de Sydney vista dende a baía\n- Categorías: Sydney Opera House, Sydney Opera House from the west, Sydney Opera House remote views</string>
|
||||
<string name="tutorial_4_subtext">- Título: Ópera de Sydney\n- Descrición: A Ópera de Sydney vista dende a baía\n- Categorías: Sydney Opera House from the west, Sydney Opera House remote views</string>
|
||||
<string name="welcome_wikipedia_text">Achegue as súas imaxes. Axude a que os artigos da Wikipedia cobren vida!</string>
|
||||
<string name="welcome_wikipedia_subtext">As imaxes da Wikipedia veñen da Wikimedia Commons.</string>
|
||||
<string name="welcome_copyright_text">As súas imaxes axudan a educar xente de todo o mundo.</string>
|
||||
|
|
@ -188,6 +188,7 @@
|
|||
<string name="navigation_item_feedback">Comentarios</string>
|
||||
<string name="navigation_item_logout">Saír</string>
|
||||
<string name="navigation_item_info">Titorial</string>
|
||||
<string name="navigation_item_notification">Notificacións</string>
|
||||
<string name="nearby_needs_permissions">Os sitios situados preto non poden visualizarse sen permisos de localización</string>
|
||||
<string name="no_description_found">non se atopou descrición</string>
|
||||
<string name="nearby_info_menu_commons_article">Páxina do ficheiro en Commons</string>
|
||||
|
|
@ -204,4 +205,6 @@
|
|||
<string name="nearby_location_has_not_changed">A localización non cambiou.</string>
|
||||
<string name="nearby_location_not_available">A localización non está dispoñible.</string>
|
||||
<string name="location_permission_rationale_nearby">Precísase permiso para amosar unha lista de lugares preto de aquí</string>
|
||||
<string name="get_directions">OBTER DIRECCIÓNS</string>
|
||||
<string name="read_article">LER ARTIGO</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@
|
|||
<string name="logging_in_title">प्रवेश हो रहा</string>
|
||||
<string name="logging_in_message">प्रतीक्षा करें…</string>
|
||||
<string name="login_success">प्रवेश में सफल हुआ!</string>
|
||||
<string name="login_failed">प्रवेश विफल हुआ</string>
|
||||
<string name="upload_failed">फ़ाइल नहीं मिला, कृपया अन्य फ़ाइल से कोशिश करें।</string>
|
||||
<string name="login_failed">प्रवेश विफल हुआ!</string>
|
||||
<string name="upload_failed">फ़ाइल नहीं मिली, कृपया अन्य फ़ाइल से प्रयास करें।</string>
|
||||
<string name="authentication_failed">प्रमाणीकरण विफल!</string>
|
||||
<string name="uploading_started">अपलोड शुरू हुआ!</string>
|
||||
<string name="uploading_started">अपलोड आरंभ!</string>
|
||||
<string name="upload_completed_notification_title">%1$s अपलोड हुआ!</string>
|
||||
<string name="upload_completed_notification_text">अपना अपलोड देखने के लिए टैप करें</string>
|
||||
<string name="upload_progress_notification_title_start">%1$s का अपलोड शुरू हुआ</string>
|
||||
|
|
@ -72,40 +72,40 @@
|
|||
<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> के अंतर्गत जारी किया गया है। %1$s और इसका लोगो विकिमीडिया संस्था का व्यापारिक चिह्न है और इसके मर्जी से ही उपयोग किया जाना चाहिए। हम किसी भी प्रकार से विकिमीडिया संस्था से जुड़े नहीं हैं।</string>
|
||||
<string name="about_license">विकिमीडिया कॉमन्स एप्प एक मुक्त स्रोत एप्प है जो कि विकिमीडिया समुदाय के अनुदानप्राप्तकर्ताओं व स्वयंसेवकों द्वारा निर्मित एवं प्रबंधित है। विकिमीडिया फॉऊण्डेशन इस एप्प के निर्माण, विकास व प्रबंधन में किसी प्रकार से भी संलग्न नहीं है।</string>
|
||||
<string name="about_improve"><a href=\"https://github.com/commons-app/apps-android-commons\">स्रोत</a> और <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" fuzzy="true"><a href=\"https://wikimediafoundation.org/wiki/Privacy_policy\">गोपनियता नीति</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>
|
||||
<string name="no_email_client">कोई ईमेल साधन स्थापित नहीं</string>
|
||||
<string name="provider_categories">हाल ही उपयोग में ली गयी श्रेणियाँ</string>
|
||||
<string name="waiting_first_sync">पहले सिंक हेतु प्रतीक्षा में…</string>
|
||||
<string name="no_uploads_yet">आपने अब तक कोई फोटो अपलोड नहीं किया है।</string>
|
||||
<string name="menu_retry_upload">फिर प्रयास करें</string>
|
||||
<string name="menu_cancel_upload">रद्द करें</string>
|
||||
<string name="share_license_summary">इस छवि का लाइसेन्स %1$s के अंतर्गत है।</string>
|
||||
<string name="share_license_summary">इस छवि का लाइसेन्स %1$s के अंतर्गत होगा।</string>
|
||||
<string name="media_upload_policy">इस तस्वीर को सबमिट करके, मैं घोषणा करता हूं कि यह मेरा अपना काम है, इसमें कॉपीराइट सामग्री या सेल्फी नहीं है, और अन्यथा <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="allow_gps_summary">यदि छवि पर जियोटैग नहीं है तो श्रेणियों के सुझाव हेतु वर्तमान स्थान ज्ञात करें।</string>
|
||||
<string name="preference_theme">रात्रि मोड</string>
|
||||
<string name="preference_theme_summary">डार्क थीम का प्रयोग करें</string>
|
||||
<string name="license_name_cc_by_sa_four">विशेषता-साझेदारी 4.0</string>
|
||||
<string name="license_name_cc_by_sa_four">एट्रीब्यूशन-शेयरअलाइक 4.0</string>
|
||||
<string name="license_name_cc_by_four">एट्रिब्यूशन 4.0</string>
|
||||
<string name="license_name_cc_by_sa">एट्रीबुसन-शेयरअलाइक 3.0</string>
|
||||
<string name="license_name_cc_by">एट्रीबुसन 3.0</string>
|
||||
<string name="license_name_cc0">CC0</string>
|
||||
<string name="license_name_cc_by_sa_3_0">CC BY-SA 3.0</string>
|
||||
<string name="license_name_cc_by_sa_3_0_at">CC BY-SA 3.0 (ऑस्ट्रीया)</string>
|
||||
<string name="license_name_cc_by_sa">एट्रीब्यूशन-शेयरअलाइक 3.0</string>
|
||||
<string name="license_name_cc_by">एट्रीब्यूशन 3.0</string>
|
||||
<string name="license_name_cc0">सीसी0</string>
|
||||
<string name="license_name_cc_by_sa_3_0">सीसी बाय-एसए 3.0</string>
|
||||
<string name="license_name_cc_by_sa_3_0_at">सीसी बाय-एसए 3.0 (ऑस्ट्रिया)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_de">CC BY-SA 3.0 (जर्मनी)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_ee">CC BY-SA 3.0 (एस्टोनिया)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_es">CC BY-SA 3.0 (स्पेन)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_hr">CC BY-SA 3.0 (क्रोटिया)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_lu">CC BY-SA 3.0 (लुक्सेमबौर्ग)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_nl">CC BY-SA 3.0 (नेदरलैंड)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_hr">CC BY-SA 3.0 (क्रोएशिया)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_lu">CC BY-SA 3.0 (लक्समबर्ग)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_nl">CC BY-SA 3.0 (नीदरलैंड)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_no">CC BY-SA 3.0 (नॉर्वे)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_pl">CC BY-SA 3.0 (पोलैंड)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_ro">CC BY-SA 3.0 (रोमानिया)</string>
|
||||
|
|
@ -113,19 +113,19 @@
|
|||
<string name="license_name_cc_by_sa_4_0">CC BY-SA 4.0</string>
|
||||
<string name="license_name_cc_by_4_0">CC BY 4.0</string>
|
||||
<string name="license_name_cc_zero">CC Zero</string>
|
||||
<string name="tutorial_1_text">विकिपीडिया में उपयोग होने वाले कई चित्रों को होस्ट विकिमीडिया कॉमन्स करता है।</string>
|
||||
<string name="tutorial_1_subtext">आपके लिए चित्र पूरे विश्व के लोगों को शिक्षित करेंगे!</string>
|
||||
<string name="tutorial_2_text">कृपया उन तस्वीरों को डालें, जो आपने ली है या केवल आपके द्वारा बनाई गई है:</string>
|
||||
<string name="tutorial_2_subtext">- प्राकृतिक वस्तुओं (फूल, पशु, पहाड़ों)\n- उपयोगी वस्तुओं (साइकिल, रेलवे स्टेशन)\n- प्रसिद्ध लोगों (आपके महापौर, ओलंपिक एथलीटों जिनसे आप मिले हो)</string>
|
||||
<string name="tutorial_1_text">विकिपीडिया में उपयोग होने वाले अधिकतर चित्र विकिमीडिया कॉमन्स पर रखे जाते है।</string>
|
||||
<string name="tutorial_1_subtext">आपके लिए चित्र पूरे विश्व के लोगों को शिक्षित करने में सहायता करेंगे!</string>
|
||||
<string name="tutorial_2_text">कृपया उन तस्वीरों को डालें, जो केवल आपके द्वारा ली गई या बनाई गई है:</string>
|
||||
<string name="tutorial_2_subtext">- प्राकृतिक वस्तुएँ (फूल, पशु, पहाड़)\n- उपयोगी वस्तुएँ (साइकिल, रेलवे स्टेशन)\n- प्रसिद्ध लोग (आपके महापौर, ओलंपिक एथलीट जिनसे आप मिले हों)</string>
|
||||
<string name="tutorial_3_text">कृपया अपलोड न करें:</string>
|
||||
<string name="tutorial_3_subtext">- सेल्फी या अपने दोस्तों की तस्वीरें\n- इंटरनेट से डाउनलोड की गई तस्वीरें\n- किसी निजी एप का स्क्रीनशॉट</string>
|
||||
<string name="tutorial_4_text">अपलोड का उदाहरण:</string>
|
||||
<string name="tutorial_4_subtext">- शीर्षक: सिडनी ओपेरा हाउस\n- विवरण: सिडनी ओपेरा हाउस खाड़ी के पार से देखा गया\n- श्रेणियाँ: सिडनी ओपेरा हाउस, पश्चिम से सिडनी ओपेरा हाउस, सिडनी ओपेरा हाउस दूर से</string>
|
||||
<string name="welcome_wikipedia_text">अपने छवियों का योगदान करें। विकिपीडिया के लेखों को जीवित करने में सहायता करें।</string>
|
||||
<string name="tutorial_4_subtext">- शीर्षक: सिडनी ओपेरा हाउस\n- विवरण: सिडनी ओपेरा हाउस का खाड़ी के पार से दृश्य\n- श्रेणियाँ: सिडनी ओपेरा हाउस, पश्चिम से सिडनी ओपेरा हाउस, सिडनी ओपेरा हाउस दूर से</string>
|
||||
<string name="welcome_wikipedia_text">अपने लिए चित्रों का योगदान करें। विकिपीडिया के लेखों में जान फूँकने में सहायता करें।</string>
|
||||
<string name="welcome_wikipedia_subtext">विकिपीडिया में छवि विकिमीडिया कॉमन्स से आती है।</string>
|
||||
<string name="welcome_copyright_text">आपके चित्र पूरे विश्व के लोगों को शिक्षित करेंगे।</string>
|
||||
<string name="welcome_copyright_text">आपके चित्र पूरे विश्व के लोगों को शिक्षित करने में सहायता करते हैं।</string>
|
||||
<string name="welcome_copyright_subtext">इंटरनेट से मिली कोई कॉपीराइट सामग्री के साथ साथ पोस्टर, पुस्तक के खड्डे आदि को भी अपलोड करने से बचें।</string>
|
||||
<string name="welcome_final_text">जो आपने सोचा वो मिला?</string>
|
||||
<string name="welcome_final_text">क्या आपको लगता है कि आप समझ गए?</string>
|
||||
<string name="welcome_final_button_text">हाँ!</string>
|
||||
<string name="detail_panel_cats_label">श्रेणियाँ</string>
|
||||
<string name="detail_panel_cats_loading">लोड हो रहा है…</string>
|
||||
|
|
@ -152,9 +152,9 @@
|
|||
<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="become_a_tester_description">गूगल प्ले पर हमारे बीटा चैनल का चयन करें और नई सुविधाओं व त्रुटिसुधारों तक पहले पहुँचे</string>
|
||||
<string name="use_wikidata">विकिडेटा का प्रयोग करें</string>
|
||||
<string name="use_wikidata_summary">(चेतावनी: इसे अक्षम करने से बड़ी मोबाइल डेटा की खपत हो सकती है)</string>
|
||||
<string name="use_wikidata_summary">(चेतावनी: इसे अक्षम करने से मोबाइल डेटा की खपत अधिक हो सकती है)</string>
|
||||
<string name="_2fa_code">2 एफए कोड</string>
|
||||
<string name="number_of_uploads">मेरी हाल ही की अपलोड सीमा</string>
|
||||
<string name="maximum_limit">अधिकतम सीमा</string>
|
||||
|
|
@ -187,6 +187,7 @@
|
|||
<string name="navigation_item_feedback">आपके सुझाव</string>
|
||||
<string name="navigation_item_logout">प्रस्थान करें</string>
|
||||
<string name="navigation_item_info">अनुशिक्षण</string>
|
||||
<string name="navigation_item_notification">सूचनायें</string>
|
||||
<string name="nearby_needs_permissions">आस-पास के स्थान बिना स्थान अनुमतियों के प्रदर्शित नहीं किए जा सकते हैं</string>
|
||||
<string name="no_description_found">कोई विवरण नहीं मिला</string>
|
||||
<string name="nearby_info_menu_commons_article">कॉमन्स फाइल पृष्ठ</string>
|
||||
|
|
@ -194,6 +195,15 @@
|
|||
<string name="error_while_cache">चित्र कैशिंग करते समय त्रुटि</string>
|
||||
<string name="title_info">फ़ाइल के लिए एक अद्वितीय वर्णनात्मक शीर्षक, जो एक फ़ाइल नाम के रूप में काम करेगा। आप रिक्त स्थान के साथ सादे भाषा का उपयोग कर सकते हैं। फ़ाइल विस्तार शामिल न करें</string>
|
||||
<string name="description_info">कृपया मीडिया जितना संभव हो उतना बताएं: यह कहां लिया गया? यह क्या दिखाता है? संदर्भ क्या है? कृपया वस्तुओं या व्यक्तियों का वर्णन करें। ऐसी जानकारी का खुलासा करें जिसे आसानी से अनुमानित नहीं किया जा सकता, उदाहरण के लिए दिन का समय यदि यह परिदृश्य है। अगर मीडिया कुछ असामान्य दिखाता है, तो कृपया बताएं कि इसे क्या असामान्य बनाता है।</string>
|
||||
<string name="give_permission">अनुमति दें</string>
|
||||
<string name="use_external_storage">बाहरी स्टॉरज का पृयोग करे।</string>
|
||||
<string name="use_external_storage_summary">आप अपने डिवाइस के इन-ऐप कैमरा से ली गई तस्वीरों को सहेजें।</string>
|
||||
<string name="send_log_file">लॉग फाइल भेजें</string>
|
||||
<string name="send_log_file_description">डेवेलपर्स को लॉग फाइल ई-मेल से भेजें</string>
|
||||
<string name="login_to_your_account">अपने खाते में प्रवेश करें</string>
|
||||
<string name="nearby_location_has_not_changed">स्थान परिवर्तन नहीं हुआ।</string>
|
||||
<string name="nearby_location_not_available">स्थान उपलब्ध नहीं।</string>
|
||||
<string name="location_permission_rationale_nearby">आसपास के स्थान दिखाने के लिए अनुमति चाहिए</string>
|
||||
<string name="get_directions">दिशा - निर्देश प्राप्त करें</string>
|
||||
<string name="read_article">लेख पढ़ें</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@
|
|||
<item quantity="other">%d feltöltés</item>
|
||||
</plurals>
|
||||
<string name="categories_not_found">Nincs a(z) „%1$s” keresési kifejezésnek megfelelő kategória</string>
|
||||
<string name="categories_skip_explanation" fuzzy="true">Adj kategóriákat a képekhez, hogy könnyebben meg lehessen találni őket a Commonson.\n\nKezdd el beírni a kategória nevét, hogy hozzáadd.\nKattints erre az üzenetre a lépés kihagyásához</string>
|
||||
<string name="categories_skip_explanation">Adj kategóriákat a képekhez, hogy könnyebben meg lehessen találni őket a Commonson.\nKezdd el beírni a kategória nevét, hogy hozzáadd.\nBökj erre az üzenetre (vagy a vissza gombra) a lépés kihagyásához</string>
|
||||
<string name="categories_activity_title">Kategóriák</string>
|
||||
<string name="title_activity_settings">Beállítások</string>
|
||||
<string name="title_activity_signup">Regisztráció</string>
|
||||
|
|
@ -121,7 +121,7 @@
|
|||
<string name="tutorial_3_text">Kérjük, NE tölts fel:</string>
|
||||
<string name="tutorial_3_subtext">- Szelfiket vagy képeket a barátaidról\n- Internetröl letöltött képeket\n- Kereskedelmi alkalmazások képernyőképeit</string>
|
||||
<string name="tutorial_4_text">Példa feltöltés:</string>
|
||||
<string name="tutorial_4_subtext">- Cím: Sydney-i Operaház\n- Leírás: A Sydney-i Operaház az öböl túlpartjáról\n- Kategóriák: Sydney Opera House, Sydney Opera House from the west, Sydney Opera House remote views</string>
|
||||
<string name="tutorial_4_subtext">- Cím: Sydney-i Operaház\n- Leírás: A Sydney-i Operaház az öböl túlpartjáról\n- Kategóriák: Sydney Opera House from the west, Sydney Opera House remote views</string>
|
||||
<string name="welcome_wikipedia_text">Tedd közzé a képeidet! Segíts életre kelteni a Wikipédia-szócikkeket!</string>
|
||||
<string name="welcome_wikipedia_subtext">A Wikipédián található képek a Wikimédia Commonsből származnak.</string>
|
||||
<string name="welcome_copyright_text">A képeid segítenek a világ minden táján élő emberek oktatásában.</string>
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@
|
|||
<string name="license_name_cc_zero">CC Zero</string>
|
||||
<string name="tutorial_1_text">Wikimedia Commons ospita la maggior parte delle immagini che vengono utilizzate in Wikipedia.</string>
|
||||
<string name="tutorial_1_subtext">Le tue immagini aiutano l\'istruzione di persone in tutto il mondo!</string>
|
||||
<string name="tutorial_3_text">Per favore NON caricare:</string>
|
||||
<string name="tutorial_4_text">Esempi di caricamento:</string>
|
||||
<string name="welcome_wikipedia_text">Contribuisci con le tue immagini. Aiuta a rendere vive le voci di Wikipedia!</string>
|
||||
<string name="welcome_wikipedia_subtext">Le immagini su Wikipedia provengono da Wikimedia Commons.</string>
|
||||
|
|
@ -146,11 +147,15 @@
|
|||
<string name="maximum_limit_alert">Non è possibile mostrarne più di 500</string>
|
||||
<string name="login_failed_2fa_not_supported">L\'autenticazione a due fattori non è attualmente supportata.</string>
|
||||
<string name="logout_verification">Vuoi veramente uscire?</string>
|
||||
<string name="commons_logo">Logo di Commons</string>
|
||||
<string name="no_image_found">Nessuna immagine trovata</string>
|
||||
<string name="upload_image">Carica immagine</string>
|
||||
<string name="welcome_image_mount_zao">Monte Zao</string>
|
||||
<string name="welcome_image_rainbow_bridge">Arcobaleno</string>
|
||||
<string name="welcome_image_tulip">Tulipano</string>
|
||||
<string name="welcome_image_no_selfies">No autoscatti (selfie)</string>
|
||||
<string name="welcome_image_welcome_wikipedia">Benvenuto Wikipedia</string>
|
||||
<string name="welcome_image_welcome_copyright">Benvenuto Copyright</string>
|
||||
<string name="welcome_image_sydney_opera_house">Teatro dell\'opera di Sydney</string>
|
||||
<string name="cancel">Annulla</string>
|
||||
<string name="navigation_drawer_open">Apri</string>
|
||||
|
|
@ -163,10 +168,14 @@
|
|||
<string name="navigation_item_feedback">Commenti</string>
|
||||
<string name="navigation_item_logout">Esci</string>
|
||||
<string name="navigation_item_info">Tutorial</string>
|
||||
<string name="navigation_item_notification">Notifiche</string>
|
||||
<string name="no_description_found">nessuna descrizione trovata</string>
|
||||
<string name="nearby_info_menu_commons_article">Pagina di Commons del file</string>
|
||||
<string name="nearby_info_menu_wikidata_article">Elemento Wikidata</string>
|
||||
<string name="give_permission">Dai autorizzazione</string>
|
||||
<string name="login_to_your_account">Accedi alla tua utenza</string>
|
||||
<string name="nearby_location_has_not_changed">La posizione non è cambiata.</string>
|
||||
<string name="nearby_location_not_available">Posizione non disponibile.</string>
|
||||
<string name="get_directions">OTTIENI DIREZIONI</string>
|
||||
<string name="read_article">LEGGI VOCE</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@
|
|||
<string name="tutorial_3_text">נא לא להעלות:</string>
|
||||
<string name="tutorial_3_subtext">- תמונות עצמיות (\"סלפי\") או תמונות של חברים שלכם\n- תמונות שהורדתם מהאינטרנט\n- צילומי מסך של יישומים קנייניים</string>
|
||||
<string name="tutorial_4_text">העלאה לדוגמה:</string>
|
||||
<string name="tutorial_4_subtext">- כותרת: בית האופרה של סידני\n- תיאור: בית האופרה של סידני מהצד השני של המפרץ\n- קטגוריות: Sydney Opera House (בית האופרה של סידני), Sydney Opera House from the west (בית האופרה של סידני מהמערב), Sydney Opera House remote views (מראה מרחוק על בית האופרה של סידני)</string>
|
||||
<string name="tutorial_4_subtext" fuzzy="true">- כותרת: בית האופרה של סידני\n- תיאור: בית האופרה של סידני מהצד השני של המפרץ\n- קטגוריות: Sydney Opera House (בית האופרה של סידני), Sydney Opera House from the west (בית האופרה של סידני מהמערב), Sydney Opera House remote views (מראה מרחוק על בית האופרה של סידני)</string>
|
||||
<string name="welcome_wikipedia_text">תרמו את התמונות שלכם. עזרו לערכים בוויקיפדיה להתעורר לחיים!</string>
|
||||
<string name="welcome_wikipedia_subtext">התמונות בוויקיפדיה מגיעות מ־Wikimedia Commons.</string>
|
||||
<string name="welcome_copyright_text">התמונות שלכם עוזרות להעניק חינוך לאנשים מסביב לעולם.</string>
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@
|
|||
<string name="menu_about">このアプリについて</string>
|
||||
<string name="about_license">ウィキメディア・コモンズ・アプリはウィキメディア・コミュニティの助成金受給者とボランティアによって製作・メンテナンスされているオープンソースソフトウェアです。ウィキメディア財団はこのアプリの製作・開発・メンテナンスに関与していません。</string>
|
||||
<string name="about_improve">ソースは <a href=\"https://github.com/commons-app/apps-android-commons\">GitHub</a> にあります。バグとアイディアは <a href=\"https://github.com/commons-app/apps-android-commons/issues\">Github</a> へ。</string>
|
||||
<string name="about_privacy_policy" fuzzy="true"><a href=\"https://wikimediafoundation.org/wiki/プライバシー・ポリシー\">プライバシー・ポリシー</a></string>
|
||||
<string name="about_privacy_policy"><a href=\"https://github.com/commons-app/apps-android-commons/wiki/プライバシー・ポリシー\">プライバシー・ポリシー</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>
|
||||
|
|
@ -115,7 +115,7 @@
|
|||
<string name="tutorial_3_text">アップロードが《禁止》のもの:</string>
|
||||
<string name="tutorial_3_subtext">- あなたの友人の自撮り写真や画像\n- インターネットからダウンロードした画像\n- 著作権のあるアプリのスクリーンショット</string>
|
||||
<string name="tutorial_4_text">アップロードの例:</string>
|
||||
<string name="tutorial_4_subtext">- 題名: シドニー・オペラハウス\n- 説明: 湾の向こうから見たシドニー・オペラハウス\n- カテゴリ: シドニー・オペラハウス、シドニー・オペラハウスの西側、遠くから見たシドニー・オペラハウス</string>
|
||||
<string name="tutorial_4_subtext">- 題名: シドニー・オペラハウス\n- 説明: 湾の向こうから見たシドニー・オペラハウス\n- カテゴリ: 西側から見たシドニー・オペラハウス、遠くから見たシドニー・オペラハウス</string>
|
||||
<string name="welcome_wikipedia_text">画像を投稿してください。ウィキペディアの記事に彩りを!</string>
|
||||
<string name="welcome_wikipedia_subtext">ウィキペディアの画像はウィキメディア・コモンズに保管されています。</string>
|
||||
<string name="welcome_copyright_text">あなたの画像は世界中の人々が学習する助けになります</string>
|
||||
|
|
@ -155,6 +155,7 @@
|
|||
<string name="set_limit">最近のアップロードファイルに表示する最大件数</string>
|
||||
<string name="login_failed_2fa_not_supported">2段階認証は現在サポートされていません。</string>
|
||||
<string name="logout_verification">ログアウトしてもよろしいですか?</string>
|
||||
<string name="commons_logo">コモンズの商標</string>
|
||||
<string name="background_image">背景画像</string>
|
||||
<string name="no_image_found">画像がありません</string>
|
||||
<string name="upload_image">画像をアップロード</string>
|
||||
|
|
@ -175,6 +176,7 @@
|
|||
<string name="navigation_item_feedback">フィードバック</string>
|
||||
<string name="navigation_item_logout">ログアウト</string>
|
||||
<string name="navigation_item_info">チュートリアル</string>
|
||||
<string name="navigation_item_notification">通知</string>
|
||||
<string name="nearby_needs_permissions">場所の権限がないと、近くの場所を表示できません</string>
|
||||
<string name="no_description_found">説明がありません</string>
|
||||
<string name="nearby_info_menu_wikidata_article">ウィキデータ項目</string>
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@
|
|||
<string name="tutorial_3_text">გთხოვთ არ ატვირთოთ:</string>
|
||||
<string name="tutorial_3_subtext">- სელფი ან მეგობრების სურათები\n- ინტერნეტიდან ჩამოტვირთული ფოტოები\n- არათავისუფალი აპლიკაციების სკრინშოტები</string>
|
||||
<string name="tutorial_4_text">ატვირთვის ნიმუში:</string>
|
||||
<string name="tutorial_4_subtext">- სათაური: სიდნეის ოპერის თეატრი\n- აღწერა: სიდნეის ოპერის თეატრის ხედი უბიდან\n- კატეგორიები: Sydney Opera House, Sydney Opera House from the west, Sydney Opera House remote views</string>
|
||||
<string name="tutorial_4_subtext" fuzzy="true">- სათაური: სიდნეის ოპერის თეატრი\n- აღწერა: სიდნეის ოპერის თეატრის ხედი უბიდან\n- კატეგორიები: Sydney Opera House, Sydney Opera House from the west, Sydney Opera House remote views</string>
|
||||
<string name="welcome_wikipedia_text">ატვირთეთ თქვენი ფოტოები. დაეხმარეთ ვიკიპედიის სტატიებს გაცოცხლებაში!</string>
|
||||
<string name="welcome_wikipedia_subtext">ვიკიპედიის ფოტოები ვიკისაწყობში ინახება.</string>
|
||||
<string name="welcome_copyright_text">თქვენი სურათები ხალხის განათლებას ეხმარება მთელ მსოფლიოში.</string>
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@
|
|||
<string name="tutorial_3_text">UR salay ara:</string>
|
||||
<string name="tutorial_3_subtext">- isilfiyen neɣ tugniwin n yimdakkal-ik \n- tugniwin i d-sidreḍ si Internet\n- inɣal n ugdil n yisnasen yesɛan imawlan</string>
|
||||
<string name="tutorial_4_text">Amedya n usali:</string>
|
||||
<string name="tutorial_4_subtext">- Azwel: Tazqqa Opera n Sydney\n- Aglam : Tazeqqa Opera n Sydney seg ilel\n- Taggayin: Tazeqqa Opera n Sydney, Tazeqqa Opera n Sydney seg umalu, timeẓriyin s lebɛid n Tazeqqa Opera n Sydney.</string>
|
||||
<string name="tutorial_4_subtext">- Azwel: Tazqqa Opera n Sydney\n- Aglam : Tazeqqa Opera n Sydney seg ilel\n- Taggayin: Tazeqqa Opera n Sydney, Tazeqqa Opera n Sydney seg umalu, timeẓriyin s lebɛid n Tazeqqa Opera n Sydney</string>
|
||||
<string name="welcome_wikipedia_text">Ttekki s tugniwin-ik. Snerni imagraden n Wikipedia!</string>
|
||||
<string name="welcome_wikipedia_subtext">Tugniwin ɣef Wikipedia ttasent-d si Wikimedia Commons.</string>
|
||||
<string name="welcome_copyright_text">Tugniwin-ik ad slemdent imdanen deg umaḍal.</string>
|
||||
|
|
@ -204,4 +204,6 @@
|
|||
<string name="nearby_location_has_not_changed">Adeg ur ibeddel ara.</string>
|
||||
<string name="nearby_location_not_available">Ulac adeg</string>
|
||||
<string name="location_permission_rationale_nearby">Ilaq usireg i uskan tabdart n wadigen iqerben</string>
|
||||
<string name="get_directions">AWI IWELLIHEN</string>
|
||||
<string name="read_article">ƔER AMAGRAD</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@
|
|||
<string name="tutorial_3_text">업로드하지 마십시오:</string>
|
||||
<string name="tutorial_3_subtext">- 자기 자신 또는 친구의 사진\n- 인터넷에서 다운로드한 사진\n- 사유 앱의 스크린샷</string>
|
||||
<string name="tutorial_4_text">업로드 예시:</string>
|
||||
<string name="tutorial_4_subtext">- 제목: 시드니 오페라 하우스\n- 설명: 항만에서 바라본 시드니 오페라 하우스\n- 분류: 시드니 오페라 하우스, 서쪽에서 본 시드니 오페라 하우스, 시드니 오페라 하우스 원경</string>
|
||||
<string name="tutorial_4_subtext">- 제목: 시드니 오페라 하우스\n- 설명: 항만 건너편에서 바라본 시드니 오페라 하우스\n- 분류: 시드니 오페라 하우스, 서쪽에서 본 시드니 오페라 하우스, 시드니 오페라 하우스 원경</string>
|
||||
<string name="welcome_wikipedia_text">당신의 그림을 기여하세요. 위키백과 문서의 생명이 오는 데 도와주세요!</string>
|
||||
<string name="welcome_wikipedia_subtext">위키백과의 그림은 위키미디어 공용에서 옵니다.</string>
|
||||
<string name="welcome_copyright_text">당신의 그림은 전 세계 사람들을 교육하는 데 도움이 됩니다.</string>
|
||||
|
|
@ -187,6 +187,7 @@
|
|||
<string name="navigation_item_feedback">피드백</string>
|
||||
<string name="navigation_item_logout">로그아웃</string>
|
||||
<string name="navigation_item_info">강좌</string>
|
||||
<string name="navigation_item_notification">알림</string>
|
||||
<string name="nearby_needs_permissions">위치 권한이 없으면 주변 장소를 표시할 수 없습니다</string>
|
||||
<string name="no_description_found">설명이 없습니다</string>
|
||||
<string name="nearby_info_menu_commons_article">공용 파일 문서</string>
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue