mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Merge branch '2.10-release' into 2.10-release-fork
This commit is contained in:
commit
0a894dc415
11 changed files with 237 additions and 82 deletions
|
|
@ -27,7 +27,8 @@ dependencies {
|
|||
implementation 'com.jakewharton.rxbinding2:rxbinding-appcompat-v7:2.1.1'
|
||||
implementation 'com.jakewharton.rxbinding2:rxbinding-design:2.1.1'
|
||||
implementation 'com.facebook.fresco:fresco:1.10.0'
|
||||
|
||||
implementation 'com.drewnoakes:metadata-extractor:2.11.0'
|
||||
|
||||
// UI
|
||||
implementation 'fr.avianey.com.viewpagerindicator:library:2.4.1.1@aar'
|
||||
implementation 'com.github.chrisbanes:PhotoView:2.0.0'
|
||||
|
|
|
|||
|
|
@ -3,25 +3,33 @@ package fr.free.nrw.commons.contributions;
|
|||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
import android.support.annotation.IntDef;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.StringDef;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import fr.free.nrw.commons.BuildConfig;
|
||||
import fr.free.nrw.commons.CommonsApplication;
|
||||
import fr.free.nrw.commons.Media;
|
||||
import fr.free.nrw.commons.filepicker.UploadableFile;
|
||||
import fr.free.nrw.commons.settings.Prefs;
|
||||
import fr.free.nrw.commons.utils.ConfigUtils;
|
||||
import fr.free.nrw.commons.utils.StringUtils;
|
||||
|
||||
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
||||
|
||||
public class Contribution extends Media {
|
||||
|
||||
//{{According to EXIF data|2009-01-09}}
|
||||
private static final String TEMPLATE_DATE_ACC_TO_EXIF = "|date={{According to EXIF data|%s}}";
|
||||
|
||||
//{{date|2009|1|9}} → 9 January 2009
|
||||
private static final String TEMPLATE_DATA_OTHER_SOURCE = "{{date|%d|%d|%d}}";
|
||||
|
||||
public static Creator<Contribution> CREATOR = new Creator<Contribution>() {
|
||||
@Override
|
||||
public Contribution createFromParcel(Parcel parcel) {
|
||||
|
|
@ -57,6 +65,7 @@ public class Contribution extends Media {
|
|||
private boolean isMultiple;
|
||||
private String wikiDataEntityId;
|
||||
private Uri contentProviderUri;
|
||||
private String dateCreatedSource;
|
||||
|
||||
public Contribution(Uri contentUri, String filename, Uri localUri, String imageUrl, Date dateCreated,
|
||||
int state, long dataLength, Date dateUploaded, long transferred,
|
||||
|
|
@ -71,6 +80,7 @@ public class Contribution extends Media {
|
|||
this.width = width;
|
||||
this.height = height;
|
||||
this.license = license;
|
||||
this.dateCreatedSource = "";
|
||||
}
|
||||
|
||||
public Contribution(Uri localUri, String imageUrl, String filename, String description, long dataLength,
|
||||
|
|
@ -78,6 +88,7 @@ public class Contribution extends Media {
|
|||
super(localUri, imageUrl, filename, description, dataLength, dateCreated, dateUploaded, creator);
|
||||
this.decimalCoords = decimalCoords;
|
||||
this.editSummary = editSummary;
|
||||
this.dateCreatedSource = "";
|
||||
}
|
||||
|
||||
public Contribution(Parcel in) {
|
||||
|
|
@ -99,7 +110,13 @@ public class Contribution extends Media {
|
|||
parcel.writeInt(isMultiple ? 1 : 0);
|
||||
}
|
||||
|
||||
public String getDateCreatedSource() {
|
||||
return dateCreatedSource;
|
||||
}
|
||||
|
||||
public void setDateCreatedSource(String dateCreatedSource) {
|
||||
this.dateCreatedSource = dateCreatedSource;
|
||||
}
|
||||
|
||||
public boolean getMultiple() {
|
||||
return isMultiple;
|
||||
|
|
@ -143,20 +160,19 @@ public class Contribution extends Media {
|
|||
|
||||
public String getPageContents(Context applicationContext) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
|
||||
|
||||
buffer
|
||||
.append("== {{int:filedesc}} ==\n")
|
||||
.append("{{Information\n")
|
||||
.append("|description=").append(getDescription()).append("\n")
|
||||
.append("|source=").append("{{own}}\n")
|
||||
.append("|author=[[User:").append(creator).append("|").append(creator).append("]]\n");
|
||||
if (dateCreated != null) {
|
||||
buffer
|
||||
.append("|date={{According to EXIF data|").append(isoFormat.format(dateCreated)).append("}}\n");
|
||||
|
||||
String templatizedCreatedDate = getTemplatizedCreatedDate();
|
||||
if (!StringUtils.isNullOrWhiteSpace(templatizedCreatedDate)) {
|
||||
buffer.append("|date=").append(templatizedCreatedDate);
|
||||
}
|
||||
buffer
|
||||
.append("}}").append("\n");
|
||||
|
||||
buffer.append("}}").append("\n");
|
||||
|
||||
//Only add Location template (e.g. {{Location|37.51136|-77.602615}} ) if coords is not null
|
||||
if (decimalCoords != null) {
|
||||
|
|
@ -178,6 +194,28 @@ public class Contribution extends Media {
|
|||
return buffer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns upload date in either TEMPLATE_DATE_ACC_TO_EXIF or TEMPLATE_DATA_OTHER_SOURCE
|
||||
* @return
|
||||
*/
|
||||
private String getTemplatizedCreatedDate() {
|
||||
if (dateCreated != null) {
|
||||
if (UploadableFile.DateTimeWithSource.EXIF_SOURCE.equals(dateCreatedSource)) {
|
||||
SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
|
||||
return String.format(Locale.ENGLISH, TEMPLATE_DATE_ACC_TO_EXIF, isoFormat.format(dateCreated)) + "\n";
|
||||
} else {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(dateCreated);
|
||||
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
return String.format(Locale.ENGLISH, TEMPLATE_DATA_OTHER_SOURCE,
|
||||
calendar.get(Calendar.YEAR),
|
||||
calendar.get(Calendar.MONTH),
|
||||
calendar.get(Calendar.DAY_OF_MONTH)) + "\n";
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFilename(String filename) {
|
||||
this.filename = filename;
|
||||
|
|
|
|||
|
|
@ -300,7 +300,7 @@ public class ContributionDao {
|
|||
onUpdate(db, from, to);
|
||||
return;
|
||||
}
|
||||
if (from == 8) {
|
||||
if (from > 5) {
|
||||
// Added place field
|
||||
db.execSQL(ADD_WIKI_DATA_ENTITY_ID_FIELD);
|
||||
from++;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,16 @@ import android.net.Uri;
|
|||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.drew.imaging.ImageMetadataReader;
|
||||
import com.drew.imaging.ImageProcessingException;
|
||||
import com.drew.metadata.Metadata;
|
||||
import com.drew.metadata.exif.ExifSubIFDDirectory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import fr.free.nrw.commons.upload.FileUtils;
|
||||
|
||||
|
|
@ -62,16 +71,32 @@ public class UploadableFile implements Parcelable {
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* First try to get the file creation date from EXIF else fall back to CP
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
@Nullable
|
||||
public DateTimeWithSource getFileCreatedDate(Context context) {
|
||||
DateTimeWithSource dateTimeFromExif = getDateTimeFromExif();
|
||||
if (dateTimeFromExif == null) {
|
||||
return getFileCreatedDateFromCP(context);
|
||||
} else {
|
||||
return dateTimeFromExif;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get filePath creation date from uri from all possible content providers
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public long getFileCreatedDate(Context context) {
|
||||
private DateTimeWithSource getFileCreatedDateFromCP(Context context) {
|
||||
try {
|
||||
Cursor cursor = context.getContentResolver().query(contentUri, null, null, null, null);
|
||||
if (cursor == null) {
|
||||
return -1;//Could not fetch last_modified
|
||||
return null;//Could not fetch last_modified
|
||||
}
|
||||
//Content provider contracts for opening gallery from the app and that by sharing from gallery from outside are different and we need to handle both the cases
|
||||
int lastModifiedColumnIndex = cursor.getColumnIndex("last_modified");//If gallery is opened from in app
|
||||
|
|
@ -80,18 +105,69 @@ public class UploadableFile implements Parcelable {
|
|||
}
|
||||
//If both the content providers do not give the data, lets leave it to Jesus
|
||||
if (lastModifiedColumnIndex == -1) {
|
||||
return -1l;
|
||||
return null;
|
||||
}
|
||||
cursor.moveToFirst();
|
||||
return cursor.getLong(lastModifiedColumnIndex);
|
||||
return new DateTimeWithSource(cursor.getLong(lastModifiedColumnIndex), DateTimeWithSource.CP_SOURCE);
|
||||
} catch (Exception e) {
|
||||
return -1;////Could not fetch last_modified
|
||||
return null;////Could not fetch last_modified
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get filePath creation date from uri from EXIF
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private DateTimeWithSource getDateTimeFromExif() {
|
||||
Metadata metadata;
|
||||
try {
|
||||
metadata = ImageMetadataReader.readMetadata(file);
|
||||
ExifSubIFDDirectory directory = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);
|
||||
if (directory!=null && directory.containsTag(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL)) {
|
||||
Date date = directory.getDate(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL);
|
||||
return new DateTimeWithSource(date, DateTimeWithSource.EXIF_SOURCE);
|
||||
}
|
||||
} catch (ImageProcessingException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int i) {
|
||||
parcel.writeParcelable(contentUri, 0);
|
||||
parcel.writeSerializable(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* This class contains the epochDate along with the source from which it was extracted
|
||||
*/
|
||||
public class DateTimeWithSource {
|
||||
public static final String CP_SOURCE = "contentProvider";
|
||||
public static final String EXIF_SOURCE = "exif";
|
||||
|
||||
private final long epochDate;
|
||||
private final String source;
|
||||
|
||||
public DateTimeWithSource(long epochDate, String source) {
|
||||
this.epochDate = epochDate;
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public DateTimeWithSource(Date date, String source) {
|
||||
this.epochDate = date.getTime();
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public long getEpochDate() {
|
||||
return epochDate;
|
||||
}
|
||||
|
||||
public String getSource() {
|
||||
return source;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package fr.free.nrw.commons.mwapi;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class UploadResult {
|
||||
|
|
@ -34,12 +36,13 @@ public class UploadResult {
|
|||
this.imageUrl = imageUrl;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UploadResult{" +
|
||||
"errorCode='" + errorCode + '\'' +
|
||||
", resultStatus='" + resultStatus + '\'' +
|
||||
", dateUploaded='" + dateUploaded.toString() + '\'' +
|
||||
", dateUploaded='" + (dateUploaded == null ? "" : dateUploaded.toString()) + '\'' +
|
||||
", imageUrl='" + imageUrl + '\'' +
|
||||
", canonicalFilename='" + canonicalFilename + '\'' +
|
||||
'}';
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ import android.widget.ProgressBar;
|
|||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
|
||||
import com.pedrogomez.renderers.RVRendererAdapter;
|
||||
|
||||
|
|
@ -52,10 +51,9 @@ public class NotificationActivity extends NavigationBaseActivity {
|
|||
RelativeLayout relativeLayout;
|
||||
@BindView(R.id.no_notification_background)
|
||||
RelativeLayout no_notification;
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
/* @BindView(R.id.swipe_bg)
|
||||
TextView swipe_bg;*/
|
||||
@BindView(R.id.no_notification_text)
|
||||
TextView noNotificationText;
|
||||
|
||||
@Inject
|
||||
NotificationController controller;
|
||||
|
||||
|
|
@ -63,8 +61,7 @@ public class NotificationActivity extends NavigationBaseActivity {
|
|||
private NotificationWorkerFragment mNotificationWorkerFragment;
|
||||
private RVRendererAdapter<Notification> adapter;
|
||||
private List<Notification> notificationList;
|
||||
MenuItem notificationmenuitem;
|
||||
TextView nonotificationtext;
|
||||
MenuItem notificationMenuItem;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
|
@ -75,7 +72,6 @@ public class NotificationActivity extends NavigationBaseActivity {
|
|||
.findFragmentByTag(TAG_NOTIFICATION_WORKER_FRAGMENT);
|
||||
initListView();
|
||||
initDrawer();
|
||||
nonotificationtext = (TextView)this.findViewById(R.id.no_notification_text);
|
||||
setPageTitle();
|
||||
}
|
||||
|
||||
|
|
@ -160,7 +156,7 @@ public class NotificationActivity extends NavigationBaseActivity {
|
|||
no_notification.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
setAdapter(notificationList);
|
||||
} if (notificationmenuitem != null) {
|
||||
} if (notificationMenuItem != null) {
|
||||
}
|
||||
progressBar.setVisibility(View.GONE);
|
||||
}, throwable -> {
|
||||
|
|
@ -178,7 +174,7 @@ public class NotificationActivity extends NavigationBaseActivity {
|
|||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.menu_notifications, menu);
|
||||
notificationmenuitem = menu.findItem(R.id.archived);
|
||||
notificationMenuItem = menu.findItem(R.id.archived);
|
||||
setMenuItemTitle();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -262,18 +258,18 @@ public class NotificationActivity extends NavigationBaseActivity {
|
|||
|
||||
private void setEmptyView() {
|
||||
if (getIntent().getStringExtra("title").equals("read")) {
|
||||
nonotificationtext.setText(R.string.no_archived_notification);
|
||||
noNotificationText.setText(R.string.no_archived_notification);
|
||||
}else {
|
||||
nonotificationtext.setText(R.string.no_notification);
|
||||
noNotificationText.setText(R.string.no_notification);
|
||||
}
|
||||
}
|
||||
|
||||
private void setMenuItemTitle() {
|
||||
if (getIntent().getStringExtra("title").equals("read")) {
|
||||
notificationmenuitem.setTitle(R.string.menu_option_unread);
|
||||
notificationMenuItem.setTitle(R.string.menu_option_unread);
|
||||
|
||||
}else {
|
||||
notificationmenuitem.setTitle(R.string.menu_option_archived);
|
||||
notificationMenuItem.setTitle(R.string.menu_option_archived);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,11 +7,13 @@ import android.view.View;
|
|||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.daimajia.swipe.SwipeLayout;
|
||||
import com.nineoldandroids.view.ViewHelper;
|
||||
import com.pedrogomez.renderers.Renderer;
|
||||
import com.daimajia.swipe.SwipeLayout;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
|
|
@ -33,6 +35,8 @@ public class NotificationRenderer extends Renderer<Notification> {
|
|||
SwipeLayout swipeLayout;
|
||||
@BindView(R.id.bottom)
|
||||
LinearLayout bottomLayout;
|
||||
@BindView(R.id.notification_view)
|
||||
RelativeLayout notificationView;
|
||||
|
||||
private NotificationClicked listener;
|
||||
private boolean isarchivedvisible = false;
|
||||
|
|
@ -42,19 +46,27 @@ public class NotificationRenderer extends Renderer<Notification> {
|
|||
this.listener = listener;
|
||||
this.isarchivedvisible = isarchivedvisible;
|
||||
}
|
||||
|
||||
@OnClick(R.id.notification_view)
|
||||
void onNotificationClicked() {
|
||||
listener.notificationClicked(getContent());
|
||||
}
|
||||
|
||||
@OnClick(R.id.bottom)
|
||||
void onBottomLayoutClicked(){
|
||||
Notification notification = getContent();
|
||||
Timber.d("NotificationID: %s", notification.notificationId);
|
||||
listener.markNotificationAsRead(notification);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUpView(View rootView) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void hookListeners(View rootView) {
|
||||
rootView.setOnClickListener(v -> listener.notificationClicked(getContent()));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ public class ImageProcessingService {
|
|||
|
||||
/**
|
||||
* Checks for image geolocation
|
||||
* returns IMAGE_OK if the place is null or if the file doesn't contain a geolocation
|
||||
* @param filePath file to be checked
|
||||
* @return IMAGE_GEOLOCATION_DIFFERENT or IMAGE_OK
|
||||
*/
|
||||
|
|
@ -127,6 +128,11 @@ public class ImageProcessingService {
|
|||
}
|
||||
return Single.fromCallable(() -> filePath)
|
||||
.map(fileUtilsWrapper::getGeolocationOfFile)
|
||||
.flatMap(geoLocation -> imageUtilsWrapper.checkImageGeolocationIsDifferent(geoLocation, place.getLocation()));
|
||||
.flatMap(geoLocation -> {
|
||||
if (StringUtils.isNullOrWhiteSpace(geoLocation)) {
|
||||
return Single.just(ImageUtils.IMAGE_OK);
|
||||
}
|
||||
return imageUtilsWrapper.checkImageGeolocationIsDifferent(geoLocation, place.getLocation());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ public class UploadModel {
|
|||
"",
|
||||
GPSExtractor.DUMMY,
|
||||
null,
|
||||
-1L) {
|
||||
-1L, "") {
|
||||
};
|
||||
private final BasicKvStore basicKvStore;
|
||||
private final List<String> licenses;
|
||||
|
|
@ -99,10 +99,16 @@ public class UploadModel {
|
|||
String source,
|
||||
SimilarImageInterface similarImageInterface) {
|
||||
fileProcessor.initFileDetails(Objects.requireNonNull(uploadableFile.getFilePath()), context.getContentResolver());
|
||||
long fileCreatedDate = uploadableFile.getFileCreatedDate(context);
|
||||
UploadableFile.DateTimeWithSource dateTimeWithSource = uploadableFile.getFileCreatedDate(context);
|
||||
long fileCreatedDate = -1;
|
||||
String createdTimestampSource = "";
|
||||
if (dateTimeWithSource != null) {
|
||||
fileCreatedDate = dateTimeWithSource.getEpochDate();
|
||||
createdTimestampSource = dateTimeWithSource.getSource();
|
||||
}
|
||||
Timber.d("File created date is %d", fileCreatedDate);
|
||||
GPSExtractor gpsExtractor = fileProcessor.processFileCoordinates(similarImageInterface);
|
||||
return new UploadItem(Uri.parse(uploadableFile.getFilePath()), uploadableFile.getMimeType(context), source, gpsExtractor, place, fileCreatedDate);
|
||||
return new UploadItem(Uri.parse(uploadableFile.getFilePath()), uploadableFile.getMimeType(context), source, gpsExtractor, place, fileCreatedDate, createdTimestampSource);
|
||||
}
|
||||
|
||||
void onItemsProcessed(Place place, List<UploadItem> uploadItems) {
|
||||
|
|
@ -284,11 +290,13 @@ public class UploadModel {
|
|||
contribution.setTag("mimeType", item.mimeType);
|
||||
contribution.setSource(item.source);
|
||||
contribution.setContentProviderUri(item.mediaUri);
|
||||
|
||||
Timber.d("Created timestamp while building contribution is %s, %s",
|
||||
item.getCreatedTimestamp(),
|
||||
new Date(item.getCreatedTimestamp()));
|
||||
if (item.createdTimestamp != -1L) {
|
||||
contribution.setDateCreated(new Date(item.getCreatedTimestamp()));
|
||||
contribution.setDateCreatedSource(item.getCreatedTimestampSource());
|
||||
//Set the date only if you have it, else the upload service is gonna try it the other way
|
||||
}
|
||||
return contribution;
|
||||
|
|
@ -332,10 +340,15 @@ public class UploadModel {
|
|||
private boolean visited;
|
||||
private boolean error;
|
||||
private long createdTimestamp;
|
||||
private String createdTimestampSource;
|
||||
private BehaviorSubject<Integer> imageQuality;
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
UploadItem(Uri mediaUri, String mimeType, String source, GPSExtractor gpsCoords, @Nullable Place place, long createdTimestamp) {
|
||||
UploadItem(Uri mediaUri, String mimeType, String source, GPSExtractor gpsCoords,
|
||||
@Nullable Place place,
|
||||
long createdTimestamp,
|
||||
String createdTimestampSource) {
|
||||
this.createdTimestampSource = createdTimestampSource;
|
||||
title = new Title();
|
||||
descriptions = new ArrayList<>();
|
||||
descriptions.add(new Description());
|
||||
|
|
@ -348,6 +361,10 @@ public class UploadModel {
|
|||
imageQuality = BehaviorSubject.createDefault(ImageUtils.IMAGE_WAIT);
|
||||
}
|
||||
|
||||
public String getCreatedTimestampSource() {
|
||||
return createdTimestampSource;
|
||||
}
|
||||
|
||||
public String getMimeType() {
|
||||
return mimeType;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:foreground="?selectableItemBackground"
|
||||
android:minHeight="72dp">
|
||||
<com.daimajia.swipe.SwipeLayout android:layout_height="match_parent"
|
||||
|
|
@ -27,52 +28,53 @@
|
|||
android:layout_height="20dp" />
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/notification_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.v7.widget.AppCompatImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:background="@android:color/white"
|
||||
android:scaleType="centerCrop"
|
||||
app:srcCompat="@drawable/ic_message_black_24dp"
|
||||
|
||||
<android.support.v7.widget.AppCompatImageView
|
||||
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:scaleType="centerCrop"
|
||||
app:srcCompat="@drawable/ic_message_black_24dp"
|
||||
/>
|
||||
|
||||
/>
|
||||
<!--app: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"
|
||||
/>
|
||||
<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_marginTop="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
|
||||
tools:text="2 June" />
|
||||
|
||||
<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:layout_alignParentTop="true"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
|
||||
android:padding="12dp"
|
||||
/>
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignTop="@id/time"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_toStartOf="@id/time"
|
||||
android:layout_toLeftOf="@id/time"
|
||||
android:layout_toEndOf="@id/icon"
|
||||
android:layout_toRightOf="@id/icon"
|
||||
android:ellipsize="end"
|
||||
android:padding="12dp"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
|
||||
tools:text="You just made your tenth edit" />
|
||||
</RelativeLayout>
|
||||
</com.daimajia.swipe.SwipeLayout>
|
||||
</RelativeLayout>
|
||||
|
|
@ -108,15 +108,19 @@ class ContributionDaoTest {
|
|||
@Test
|
||||
fun migrateTableVersionFrom_v6_to_v7() {
|
||||
Table.onUpdate(database, 6, 7)
|
||||
// Table didn't change in version 7
|
||||
verifyZeroInteractions(database)
|
||||
// Table has changed in version 7
|
||||
inOrder(database) {
|
||||
verify<SQLiteDatabase>(database).execSQL(Table.ADD_WIKI_DATA_ENTITY_ID_FIELD)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun migrateTableVersionFrom_v7_to_v8() {
|
||||
Table.onUpdate(database, 7, 8)
|
||||
// Table didn't change in version 8
|
||||
verifyZeroInteractions(database)
|
||||
// Table has changed in version 8
|
||||
inOrder(database) {
|
||||
verify<SQLiteDatabase>(database).execSQL(Table.ADD_WIKI_DATA_ENTITY_ID_FIELD)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -355,4 +359,4 @@ class ContributionDaoTest {
|
|||
contribution.wikiDataEntityId = "Q1"
|
||||
return contribution
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue