Switch to the Java 8 Date/Time API.
This commit is contained in:
parent
7dd317e530
commit
c745b845c5
|
@ -5,31 +5,35 @@ import androidx.room.TypeConverter;
|
||||||
import org.schabi.newpipe.extractor.stream.StreamType;
|
import org.schabi.newpipe.extractor.stream.StreamType;
|
||||||
import org.schabi.newpipe.local.subscription.FeedGroupIcon;
|
import org.schabi.newpipe.local.subscription.FeedGroupIcon;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.time.Instant;
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
|
|
||||||
public final class Converters {
|
public final class Converters {
|
||||||
private Converters() { }
|
private Converters() { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a long value to a date.
|
* Convert a long value to a {@link OffsetDateTime}.
|
||||||
*
|
*
|
||||||
* @param value the long value
|
* @param value the long value
|
||||||
* @return the date
|
* @return the {@code OffsetDateTime}
|
||||||
*/
|
*/
|
||||||
@TypeConverter
|
@TypeConverter
|
||||||
public static Date fromTimestamp(final Long value) {
|
public static OffsetDateTime offsetDateTimeFromTimestamp(final Long value) {
|
||||||
return value == null ? null : new Date(value);
|
return value == null ? null : OffsetDateTime.ofInstant(Instant.ofEpochMilli(value),
|
||||||
|
ZoneOffset.UTC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a date to a long value.
|
* Convert a {@link OffsetDateTime} to a long value.
|
||||||
*
|
*
|
||||||
* @param date the date
|
* @param offsetDateTime the {@code OffsetDateTime}
|
||||||
* @return the long value
|
* @return the long value
|
||||||
*/
|
*/
|
||||||
@TypeConverter
|
@TypeConverter
|
||||||
public static Long dateToTimestamp(final Date date) {
|
public static Long offsetDateTimeToTimestamp(final OffsetDateTime offsetDateTime) {
|
||||||
return date == null ? null : date.getTime();
|
return offsetDateTime == null ? null : offsetDateTime.withOffsetSameInstant(ZoneOffset.UTC)
|
||||||
|
.toInstant().toEpochMilli();
|
||||||
}
|
}
|
||||||
|
|
||||||
@TypeConverter
|
@TypeConverter
|
||||||
|
|
|
@ -7,7 +7,7 @@ import androidx.room.Query
|
||||||
import androidx.room.Transaction
|
import androidx.room.Transaction
|
||||||
import androidx.room.Update
|
import androidx.room.Update
|
||||||
import io.reactivex.Flowable
|
import io.reactivex.Flowable
|
||||||
import java.util.Date
|
import java.time.OffsetDateTime
|
||||||
import org.schabi.newpipe.database.feed.model.FeedEntity
|
import org.schabi.newpipe.database.feed.model.FeedEntity
|
||||||
import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity
|
import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity
|
||||||
import org.schabi.newpipe.database.stream.model.StreamEntity
|
import org.schabi.newpipe.database.stream.model.StreamEntity
|
||||||
|
@ -58,10 +58,10 @@ abstract class FeedDAO {
|
||||||
INNER JOIN feed f
|
INNER JOIN feed f
|
||||||
ON s.uid = f.stream_id
|
ON s.uid = f.stream_id
|
||||||
|
|
||||||
WHERE s.upload_date < :date
|
WHERE s.upload_date < :offsetDateTime
|
||||||
)
|
)
|
||||||
""")
|
""")
|
||||||
abstract fun unlinkStreamsOlderThan(date: Date)
|
abstract fun unlinkStreamsOlderThan(offsetDateTime: OffsetDateTime)
|
||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
DELETE FROM feed
|
DELETE FROM feed
|
||||||
|
@ -106,10 +106,10 @@ abstract class FeedDAO {
|
||||||
INNER JOIN feed_group_subscription_join fgs
|
INNER JOIN feed_group_subscription_join fgs
|
||||||
ON fgs.subscription_id = lu.subscription_id AND fgs.group_id = :groupId
|
ON fgs.subscription_id = lu.subscription_id AND fgs.group_id = :groupId
|
||||||
""")
|
""")
|
||||||
abstract fun oldestSubscriptionUpdate(groupId: Long): Flowable<List<Date>>
|
abstract fun oldestSubscriptionUpdate(groupId: Long): Flowable<List<OffsetDateTime>>
|
||||||
|
|
||||||
@Query("SELECT MIN(last_updated) FROM feed_last_updated")
|
@Query("SELECT MIN(last_updated) FROM feed_last_updated")
|
||||||
abstract fun oldestSubscriptionUpdateFromAll(): Flowable<List<Date>>
|
abstract fun oldestSubscriptionUpdateFromAll(): Flowable<List<OffsetDateTime>>
|
||||||
|
|
||||||
@Query("SELECT COUNT(*) FROM feed_last_updated WHERE last_updated IS NULL")
|
@Query("SELECT COUNT(*) FROM feed_last_updated WHERE last_updated IS NULL")
|
||||||
abstract fun notLoadedCount(): Flowable<Long>
|
abstract fun notLoadedCount(): Flowable<Long>
|
||||||
|
@ -135,7 +135,7 @@ abstract class FeedDAO {
|
||||||
|
|
||||||
WHERE lu.last_updated IS NULL OR lu.last_updated < :outdatedThreshold
|
WHERE lu.last_updated IS NULL OR lu.last_updated < :outdatedThreshold
|
||||||
""")
|
""")
|
||||||
abstract fun getAllOutdated(outdatedThreshold: Date): Flowable<List<SubscriptionEntity>>
|
abstract fun getAllOutdated(outdatedThreshold: OffsetDateTime): Flowable<List<SubscriptionEntity>>
|
||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
SELECT s.* FROM subscriptions s
|
SELECT s.* FROM subscriptions s
|
||||||
|
@ -148,5 +148,5 @@ abstract class FeedDAO {
|
||||||
|
|
||||||
WHERE lu.last_updated IS NULL OR lu.last_updated < :outdatedThreshold
|
WHERE lu.last_updated IS NULL OR lu.last_updated < :outdatedThreshold
|
||||||
""")
|
""")
|
||||||
abstract fun getAllOutdatedForGroup(groupId: Long, outdatedThreshold: Date): Flowable<List<SubscriptionEntity>>
|
abstract fun getAllOutdatedForGroup(groupId: Long, outdatedThreshold: OffsetDateTime): Flowable<List<SubscriptionEntity>>
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import androidx.room.ColumnInfo
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.ForeignKey
|
import androidx.room.ForeignKey
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import java.util.Date
|
import java.time.OffsetDateTime
|
||||||
import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity.Companion.FEED_LAST_UPDATED_TABLE
|
import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity.Companion.FEED_LAST_UPDATED_TABLE
|
||||||
import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity.Companion.SUBSCRIPTION_ID
|
import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity.Companion.SUBSCRIPTION_ID
|
||||||
import org.schabi.newpipe.database.subscription.SubscriptionEntity
|
import org.schabi.newpipe.database.subscription.SubscriptionEntity
|
||||||
|
@ -25,9 +25,8 @@ data class FeedLastUpdatedEntity(
|
||||||
var subscriptionId: Long,
|
var subscriptionId: Long,
|
||||||
|
|
||||||
@ColumnInfo(name = LAST_UPDATED)
|
@ColumnInfo(name = LAST_UPDATED)
|
||||||
var lastUpdated: Date? = null
|
var lastUpdated: OffsetDateTime? = null
|
||||||
) {
|
) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val FEED_LAST_UPDATED_TABLE = "feed_last_updated"
|
const val FEED_LAST_UPDATED_TABLE = "feed_last_updated"
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import androidx.room.Ignore;
|
||||||
import androidx.room.Index;
|
import androidx.room.Index;
|
||||||
import androidx.room.PrimaryKey;
|
import androidx.room.PrimaryKey;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.time.OffsetDateTime;
|
||||||
|
|
||||||
import static org.schabi.newpipe.database.history.model.SearchHistoryEntry.SEARCH;
|
import static org.schabi.newpipe.database.history.model.SearchHistoryEntry.SEARCH;
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ public class SearchHistoryEntry {
|
||||||
private long id;
|
private long id;
|
||||||
|
|
||||||
@ColumnInfo(name = CREATION_DATE)
|
@ColumnInfo(name = CREATION_DATE)
|
||||||
private Date creationDate;
|
private OffsetDateTime creationDate;
|
||||||
|
|
||||||
@ColumnInfo(name = SERVICE_ID)
|
@ColumnInfo(name = SERVICE_ID)
|
||||||
private int serviceId;
|
private int serviceId;
|
||||||
|
@ -32,7 +32,8 @@ public class SearchHistoryEntry {
|
||||||
@ColumnInfo(name = SEARCH)
|
@ColumnInfo(name = SEARCH)
|
||||||
private String search;
|
private String search;
|
||||||
|
|
||||||
public SearchHistoryEntry(final Date creationDate, final int serviceId, final String search) {
|
public SearchHistoryEntry(final OffsetDateTime creationDate, final int serviceId,
|
||||||
|
final String search) {
|
||||||
this.serviceId = serviceId;
|
this.serviceId = serviceId;
|
||||||
this.creationDate = creationDate;
|
this.creationDate = creationDate;
|
||||||
this.search = search;
|
this.search = search;
|
||||||
|
@ -46,11 +47,11 @@ public class SearchHistoryEntry {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Date getCreationDate() {
|
public OffsetDateTime getCreationDate() {
|
||||||
return creationDate;
|
return creationDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCreationDate(final Date creationDate) {
|
public void setCreationDate(final OffsetDateTime creationDate) {
|
||||||
this.creationDate = creationDate;
|
this.creationDate = creationDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import androidx.room.Index;
|
||||||
|
|
||||||
import org.schabi.newpipe.database.stream.model.StreamEntity;
|
import org.schabi.newpipe.database.stream.model.StreamEntity;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.time.OffsetDateTime;
|
||||||
|
|
||||||
import static androidx.room.ForeignKey.CASCADE;
|
import static androidx.room.ForeignKey.CASCADE;
|
||||||
import static org.schabi.newpipe.database.history.model.StreamHistoryEntity.JOIN_STREAM_ID;
|
import static org.schabi.newpipe.database.history.model.StreamHistoryEntity.JOIN_STREAM_ID;
|
||||||
|
@ -37,12 +37,12 @@ public class StreamHistoryEntity {
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@ColumnInfo(name = STREAM_ACCESS_DATE)
|
@ColumnInfo(name = STREAM_ACCESS_DATE)
|
||||||
private Date accessDate;
|
private OffsetDateTime accessDate;
|
||||||
|
|
||||||
@ColumnInfo(name = STREAM_REPEAT_COUNT)
|
@ColumnInfo(name = STREAM_REPEAT_COUNT)
|
||||||
private long repeatCount;
|
private long repeatCount;
|
||||||
|
|
||||||
public StreamHistoryEntity(final long streamUid, @NonNull final Date accessDate,
|
public StreamHistoryEntity(final long streamUid, @NonNull final OffsetDateTime accessDate,
|
||||||
final long repeatCount) {
|
final long repeatCount) {
|
||||||
this.streamUid = streamUid;
|
this.streamUid = streamUid;
|
||||||
this.accessDate = accessDate;
|
this.accessDate = accessDate;
|
||||||
|
@ -50,7 +50,7 @@ public class StreamHistoryEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore
|
@Ignore
|
||||||
public StreamHistoryEntity(final long streamUid, @NonNull final Date accessDate) {
|
public StreamHistoryEntity(final long streamUid, @NonNull final OffsetDateTime accessDate) {
|
||||||
this(streamUid, accessDate, 1);
|
this(streamUid, accessDate, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,11 +62,12 @@ public class StreamHistoryEntity {
|
||||||
this.streamUid = streamUid;
|
this.streamUid = streamUid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Date getAccessDate() {
|
@NonNull
|
||||||
|
public OffsetDateTime getAccessDate() {
|
||||||
return accessDate;
|
return accessDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAccessDate(@NonNull final Date accessDate) {
|
public void setAccessDate(@NonNull final OffsetDateTime accessDate) {
|
||||||
this.accessDate = accessDate;
|
this.accessDate = accessDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ package org.schabi.newpipe.database.history.model
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
import androidx.room.Embedded
|
import androidx.room.Embedded
|
||||||
import java.util.Date
|
import java.time.OffsetDateTime
|
||||||
import org.schabi.newpipe.database.stream.model.StreamEntity
|
import org.schabi.newpipe.database.stream.model.StreamEntity
|
||||||
|
|
||||||
data class StreamHistoryEntry(
|
data class StreamHistoryEntry(
|
||||||
|
@ -13,7 +13,7 @@ data class StreamHistoryEntry(
|
||||||
val streamId: Long,
|
val streamId: Long,
|
||||||
|
|
||||||
@ColumnInfo(name = StreamHistoryEntity.STREAM_ACCESS_DATE)
|
@ColumnInfo(name = StreamHistoryEntity.STREAM_ACCESS_DATE)
|
||||||
val accessDate: Date,
|
val accessDate: OffsetDateTime,
|
||||||
|
|
||||||
@ColumnInfo(name = StreamHistoryEntity.STREAM_REPEAT_COUNT)
|
@ColumnInfo(name = StreamHistoryEntity.STREAM_REPEAT_COUNT)
|
||||||
val repeatCount: Long
|
val repeatCount: Long
|
||||||
|
@ -25,6 +25,6 @@ data class StreamHistoryEntry(
|
||||||
|
|
||||||
fun hasEqualValues(other: StreamHistoryEntry): Boolean {
|
fun hasEqualValues(other: StreamHistoryEntry): Boolean {
|
||||||
return this.streamEntity.uid == other.streamEntity.uid && streamId == other.streamId &&
|
return this.streamEntity.uid == other.streamEntity.uid && streamId == other.streamId &&
|
||||||
accessDate.compareTo(other.accessDate) == 0
|
accessDate.isEqual(other.accessDate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package org.schabi.newpipe.database.stream
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
import androidx.room.Embedded
|
import androidx.room.Embedded
|
||||||
import java.util.Date
|
import java.time.OffsetDateTime
|
||||||
import org.schabi.newpipe.database.LocalItem
|
import org.schabi.newpipe.database.LocalItem
|
||||||
import org.schabi.newpipe.database.history.model.StreamHistoryEntity
|
import org.schabi.newpipe.database.history.model.StreamHistoryEntity
|
||||||
import org.schabi.newpipe.database.stream.model.StreamEntity
|
import org.schabi.newpipe.database.stream.model.StreamEntity
|
||||||
|
@ -16,12 +16,11 @@ class StreamStatisticsEntry(
|
||||||
val streamId: Long,
|
val streamId: Long,
|
||||||
|
|
||||||
@ColumnInfo(name = STREAM_LATEST_DATE)
|
@ColumnInfo(name = STREAM_LATEST_DATE)
|
||||||
val latestAccessDate: Date,
|
val latestAccessDate: OffsetDateTime,
|
||||||
|
|
||||||
@ColumnInfo(name = STREAM_WATCH_COUNT)
|
@ColumnInfo(name = STREAM_WATCH_COUNT)
|
||||||
val watchCount: Long
|
val watchCount: Long
|
||||||
) : LocalItem {
|
) : LocalItem {
|
||||||
|
|
||||||
fun toStreamInfoItem(): StreamInfoItem {
|
fun toStreamInfoItem(): StreamInfoItem {
|
||||||
val item = StreamInfoItem(streamEntity.serviceId, streamEntity.url, streamEntity.title, streamEntity.streamType)
|
val item = StreamInfoItem(streamEntity.serviceId, streamEntity.url, streamEntity.title, streamEntity.streamType)
|
||||||
item.duration = streamEntity.duration
|
item.duration = streamEntity.duration
|
||||||
|
|
|
@ -7,7 +7,7 @@ import androidx.room.OnConflictStrategy
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import androidx.room.Transaction
|
import androidx.room.Transaction
|
||||||
import io.reactivex.Flowable
|
import io.reactivex.Flowable
|
||||||
import java.util.Date
|
import java.time.OffsetDateTime
|
||||||
import org.schabi.newpipe.database.BasicDAO
|
import org.schabi.newpipe.database.BasicDAO
|
||||||
import org.schabi.newpipe.database.stream.model.StreamEntity
|
import org.schabi.newpipe.database.stream.model.StreamEntity
|
||||||
import org.schabi.newpipe.database.stream.model.StreamEntity.Companion.STREAM_ID
|
import org.schabi.newpipe.database.stream.model.StreamEntity.Companion.STREAM_ID
|
||||||
|
@ -129,7 +129,7 @@ abstract class StreamDAO : BasicDAO<StreamEntity> {
|
||||||
var textualUploadDate: String? = null,
|
var textualUploadDate: String? = null,
|
||||||
|
|
||||||
@ColumnInfo(name = StreamEntity.STREAM_UPLOAD_DATE)
|
@ColumnInfo(name = StreamEntity.STREAM_UPLOAD_DATE)
|
||||||
var uploadDate: Date? = null,
|
var uploadDate: OffsetDateTime? = null,
|
||||||
|
|
||||||
@ColumnInfo(name = StreamEntity.STREAM_IS_UPLOAD_DATE_APPROXIMATION)
|
@ColumnInfo(name = StreamEntity.STREAM_IS_UPLOAD_DATE_APPROXIMATION)
|
||||||
var isUploadDateApproximation: Boolean? = null,
|
var isUploadDateApproximation: Boolean? = null,
|
||||||
|
|
|
@ -6,8 +6,7 @@ import androidx.room.Ignore
|
||||||
import androidx.room.Index
|
import androidx.room.Index
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
import java.util.Calendar
|
import java.time.OffsetDateTime
|
||||||
import java.util.Date
|
|
||||||
import org.schabi.newpipe.database.stream.model.StreamEntity.Companion.STREAM_SERVICE_ID
|
import org.schabi.newpipe.database.stream.model.StreamEntity.Companion.STREAM_SERVICE_ID
|
||||||
import org.schabi.newpipe.database.stream.model.StreamEntity.Companion.STREAM_TABLE
|
import org.schabi.newpipe.database.stream.model.StreamEntity.Companion.STREAM_TABLE
|
||||||
import org.schabi.newpipe.database.stream.model.StreamEntity.Companion.STREAM_URL
|
import org.schabi.newpipe.database.stream.model.StreamEntity.Companion.STREAM_URL
|
||||||
|
@ -55,18 +54,17 @@ data class StreamEntity(
|
||||||
var textualUploadDate: String? = null,
|
var textualUploadDate: String? = null,
|
||||||
|
|
||||||
@ColumnInfo(name = STREAM_UPLOAD_DATE)
|
@ColumnInfo(name = STREAM_UPLOAD_DATE)
|
||||||
var uploadDate: Date? = null,
|
var uploadDate: OffsetDateTime? = null,
|
||||||
|
|
||||||
@ColumnInfo(name = STREAM_IS_UPLOAD_DATE_APPROXIMATION)
|
@ColumnInfo(name = STREAM_IS_UPLOAD_DATE_APPROXIMATION)
|
||||||
var isUploadDateApproximation: Boolean? = null
|
var isUploadDateApproximation: Boolean? = null
|
||||||
) : Serializable {
|
) : Serializable {
|
||||||
|
|
||||||
@Ignore
|
@Ignore
|
||||||
constructor(item: StreamInfoItem) : this(
|
constructor(item: StreamInfoItem) : this(
|
||||||
serviceId = item.serviceId, url = item.url, title = item.name,
|
serviceId = item.serviceId, url = item.url, title = item.name,
|
||||||
streamType = item.streamType, duration = item.duration, uploader = item.uploaderName,
|
streamType = item.streamType, duration = item.duration, uploader = item.uploaderName,
|
||||||
thumbnailUrl = item.thumbnailUrl, viewCount = item.viewCount,
|
thumbnailUrl = item.thumbnailUrl, viewCount = item.viewCount,
|
||||||
textualUploadDate = item.textualUploadDate, uploadDate = item.uploadDate?.date()?.time,
|
textualUploadDate = item.textualUploadDate, uploadDate = item.uploadDate?.offsetDateTime(),
|
||||||
isUploadDateApproximation = item.uploadDate?.isApproximation
|
isUploadDateApproximation = item.uploadDate?.isApproximation
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -75,7 +73,7 @@ data class StreamEntity(
|
||||||
serviceId = info.serviceId, url = info.url, title = info.name,
|
serviceId = info.serviceId, url = info.url, title = info.name,
|
||||||
streamType = info.streamType, duration = info.duration, uploader = info.uploaderName,
|
streamType = info.streamType, duration = info.duration, uploader = info.uploaderName,
|
||||||
thumbnailUrl = info.thumbnailUrl, viewCount = info.viewCount,
|
thumbnailUrl = info.thumbnailUrl, viewCount = info.viewCount,
|
||||||
textualUploadDate = info.textualUploadDate, uploadDate = info.uploadDate?.date()?.time,
|
textualUploadDate = info.textualUploadDate, uploadDate = info.uploadDate?.offsetDateTime(),
|
||||||
isUploadDateApproximation = info.uploadDate?.isApproximation
|
isUploadDateApproximation = info.uploadDate?.isApproximation
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -95,8 +93,7 @@ data class StreamEntity(
|
||||||
if (viewCount != null) item.viewCount = viewCount as Long
|
if (viewCount != null) item.viewCount = viewCount as Long
|
||||||
item.textualUploadDate = textualUploadDate
|
item.textualUploadDate = textualUploadDate
|
||||||
item.uploadDate = uploadDate?.let {
|
item.uploadDate = uploadDate?.let {
|
||||||
DateWrapper(Calendar.getInstance().apply { time = it }, isUploadDateApproximation
|
DateWrapper(it, isUploadDateApproximation ?: false)
|
||||||
?: false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return item
|
return item
|
||||||
|
|
|
@ -1527,7 +1527,7 @@ public class VideoDetailFragment
|
||||||
|
|
||||||
if (info.getUploadDate() != null) {
|
if (info.getUploadDate() != null) {
|
||||||
videoUploadDateView.setText(Localization
|
videoUploadDateView.setText(Localization
|
||||||
.localizeUploadDate(activity, info.getUploadDate().date().getTime()));
|
.localizeUploadDate(activity, info.getUploadDate().offsetDateTime()));
|
||||||
videoUploadDateView.setVisibility(View.VISIBLE);
|
videoUploadDateView.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
videoUploadDateView.setText(null);
|
videoUploadDateView.setText(null);
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package org.schabi.newpipe.ktx
|
||||||
|
|
||||||
|
import java.time.OffsetDateTime
|
||||||
|
import java.time.ZoneId
|
||||||
|
import java.util.Calendar
|
||||||
|
import java.util.GregorianCalendar
|
||||||
|
|
||||||
|
fun OffsetDateTime.toCalendar(zoneId: ZoneId = ZoneId.systemDefault()): Calendar {
|
||||||
|
return GregorianCalendar.from(if (zoneId != offset) atZoneSameInstant(zoneId) else toZonedDateTime())
|
||||||
|
}
|
|
@ -26,7 +26,8 @@ import org.schabi.newpipe.util.FallbackViewHolder;
|
||||||
import org.schabi.newpipe.util.Localization;
|
import org.schabi.newpipe.util.Localization;
|
||||||
import org.schabi.newpipe.util.OnClickGesture;
|
import org.schabi.newpipe.util.OnClickGesture;
|
||||||
|
|
||||||
import java.text.DateFormat;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.format.FormatStyle;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -69,7 +70,7 @@ public class LocalItemListAdapter extends RecyclerView.Adapter<RecyclerView.View
|
||||||
private final LocalItemBuilder localItemBuilder;
|
private final LocalItemBuilder localItemBuilder;
|
||||||
private final ArrayList<LocalItem> localItems;
|
private final ArrayList<LocalItem> localItems;
|
||||||
private final HistoryRecordManager recordManager;
|
private final HistoryRecordManager recordManager;
|
||||||
private final DateFormat dateFormat;
|
private final DateTimeFormatter dateTimeFormatter;
|
||||||
|
|
||||||
private boolean showFooter = false;
|
private boolean showFooter = false;
|
||||||
private boolean useGridVariant = false;
|
private boolean useGridVariant = false;
|
||||||
|
@ -80,8 +81,8 @@ public class LocalItemListAdapter extends RecyclerView.Adapter<RecyclerView.View
|
||||||
recordManager = new HistoryRecordManager(context);
|
recordManager = new HistoryRecordManager(context);
|
||||||
localItemBuilder = new LocalItemBuilder(context);
|
localItemBuilder = new LocalItemBuilder(context);
|
||||||
localItems = new ArrayList<>();
|
localItems = new ArrayList<>();
|
||||||
dateFormat = DateFormat.getDateInstance(DateFormat.SHORT,
|
dateTimeFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)
|
||||||
Localization.getPreferredLocale(context));
|
.withLocale(Localization.getPreferredLocale(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSelectedListener(final OnClickGesture<LocalItem> listener) {
|
public void setSelectedListener(final OnClickGesture<LocalItem> listener) {
|
||||||
|
@ -303,7 +304,7 @@ public class LocalItemListAdapter extends RecyclerView.Adapter<RecyclerView.View
|
||||||
}
|
}
|
||||||
|
|
||||||
((LocalItemHolder) holder)
|
((LocalItemHolder) holder)
|
||||||
.updateFromItem(localItems.get(position), recordManager, dateFormat);
|
.updateFromItem(localItems.get(position), recordManager, dateTimeFormatter);
|
||||||
} else if (holder instanceof HeaderFooterHolder && position == 0 && header != null) {
|
} else if (holder instanceof HeaderFooterHolder && position == 0 && header != null) {
|
||||||
((HeaderFooterHolder) holder).view = header;
|
((HeaderFooterHolder) holder).view = header;
|
||||||
} else if (holder instanceof HeaderFooterHolder && position == sizeConsideringHeader()
|
} else if (holder instanceof HeaderFooterHolder && position == sizeConsideringHeader()
|
||||||
|
|
|
@ -7,8 +7,9 @@ import io.reactivex.Flowable
|
||||||
import io.reactivex.Maybe
|
import io.reactivex.Maybe
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.schedulers.Schedulers
|
import io.reactivex.schedulers.Schedulers
|
||||||
import java.util.Calendar
|
import java.time.LocalDate
|
||||||
import java.util.Date
|
import java.time.OffsetDateTime
|
||||||
|
import java.time.ZoneOffset
|
||||||
import org.schabi.newpipe.MainActivity.DEBUG
|
import org.schabi.newpipe.MainActivity.DEBUG
|
||||||
import org.schabi.newpipe.NewPipeDatabase
|
import org.schabi.newpipe.NewPipeDatabase
|
||||||
import org.schabi.newpipe.database.feed.model.FeedEntity
|
import org.schabi.newpipe.database.feed.model.FeedEntity
|
||||||
|
@ -29,13 +30,8 @@ class FeedDatabaseManager(context: Context) {
|
||||||
/**
|
/**
|
||||||
* Only items that are newer than this will be saved.
|
* Only items that are newer than this will be saved.
|
||||||
*/
|
*/
|
||||||
val FEED_OLDEST_ALLOWED_DATE: Calendar = Calendar.getInstance().apply {
|
val FEED_OLDEST_ALLOWED_DATE: OffsetDateTime = LocalDate.now().minusWeeks(13)
|
||||||
add(Calendar.WEEK_OF_YEAR, -13)
|
.atStartOfDay().atOffset(ZoneOffset.UTC)
|
||||||
set(Calendar.HOUR_OF_DAY, 0)
|
|
||||||
set(Calendar.MINUTE, 0)
|
|
||||||
set(Calendar.SECOND, 0)
|
|
||||||
set(Calendar.MILLISECOND, 0)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun groups() = feedGroupTable.getAll()
|
fun groups() = feedGroupTable.getAll()
|
||||||
|
@ -55,7 +51,7 @@ class FeedDatabaseManager(context: Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun outdatedSubscriptions(outdatedThreshold: Date) = feedTable.getAllOutdated(outdatedThreshold)
|
fun outdatedSubscriptions(outdatedThreshold: OffsetDateTime) = feedTable.getAllOutdated(outdatedThreshold)
|
||||||
|
|
||||||
fun notLoadedCount(groupId: Long = FeedGroupEntity.GROUP_ALL_ID): Flowable<Long> {
|
fun notLoadedCount(groupId: Long = FeedGroupEntity.GROUP_ALL_ID): Flowable<Long> {
|
||||||
return when (groupId) {
|
return when (groupId) {
|
||||||
|
@ -64,7 +60,7 @@ class FeedDatabaseManager(context: Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun outdatedSubscriptionsForGroup(groupId: Long = FeedGroupEntity.GROUP_ALL_ID, outdatedThreshold: Date) =
|
fun outdatedSubscriptionsForGroup(groupId: Long = FeedGroupEntity.GROUP_ALL_ID, outdatedThreshold: OffsetDateTime) =
|
||||||
feedTable.getAllOutdatedForGroup(groupId, outdatedThreshold)
|
feedTable.getAllOutdatedForGroup(groupId, outdatedThreshold)
|
||||||
|
|
||||||
fun markAsOutdated(subscriptionId: Long) = feedTable
|
fun markAsOutdated(subscriptionId: Long) = feedTable
|
||||||
|
@ -73,7 +69,7 @@ class FeedDatabaseManager(context: Context) {
|
||||||
fun upsertAll(
|
fun upsertAll(
|
||||||
subscriptionId: Long,
|
subscriptionId: Long,
|
||||||
items: List<StreamInfoItem>,
|
items: List<StreamInfoItem>,
|
||||||
oldestAllowedDate: Date = FEED_OLDEST_ALLOWED_DATE.time
|
oldestAllowedDate: OffsetDateTime = FEED_OLDEST_ALLOWED_DATE
|
||||||
) {
|
) {
|
||||||
val itemsToInsert = ArrayList<StreamInfoItem>()
|
val itemsToInsert = ArrayList<StreamInfoItem>()
|
||||||
loop@ for (streamItem in items) {
|
loop@ for (streamItem in items) {
|
||||||
|
@ -81,7 +77,7 @@ class FeedDatabaseManager(context: Context) {
|
||||||
|
|
||||||
itemsToInsert += when {
|
itemsToInsert += when {
|
||||||
uploadDate == null && streamItem.streamType == StreamType.LIVE_STREAM -> streamItem
|
uploadDate == null && streamItem.streamType == StreamType.LIVE_STREAM -> streamItem
|
||||||
uploadDate != null && uploadDate.date().time >= oldestAllowedDate -> streamItem
|
uploadDate != null && uploadDate.offsetDateTime() >= oldestAllowedDate -> streamItem
|
||||||
else -> continue@loop
|
else -> continue@loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,10 +92,11 @@ class FeedDatabaseManager(context: Context) {
|
||||||
feedTable.insertAll(feedEntities)
|
feedTable.insertAll(feedEntities)
|
||||||
}
|
}
|
||||||
|
|
||||||
feedTable.setLastUpdatedForSubscription(FeedLastUpdatedEntity(subscriptionId, Calendar.getInstance().time))
|
feedTable.setLastUpdatedForSubscription(FeedLastUpdatedEntity(subscriptionId,
|
||||||
|
OffsetDateTime.now(ZoneOffset.UTC)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeOrphansOrOlderStreams(oldestAllowedDate: Date = FEED_OLDEST_ALLOWED_DATE.time) {
|
fun removeOrphansOrOlderStreams(oldestAllowedDate: OffsetDateTime = FEED_OLDEST_ALLOWED_DATE) {
|
||||||
feedTable.unlinkStreamsOlderThan(oldestAllowedDate)
|
feedTable.unlinkStreamsOlderThan(oldestAllowedDate)
|
||||||
streamTable.deleteOrphans()
|
streamTable.deleteOrphans()
|
||||||
}
|
}
|
||||||
|
@ -159,7 +156,7 @@ class FeedDatabaseManager(context: Context) {
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun oldestSubscriptionUpdate(groupId: Long): Flowable<List<Date>> {
|
fun oldestSubscriptionUpdate(groupId: Long): Flowable<List<OffsetDateTime>> {
|
||||||
return when (groupId) {
|
return when (groupId) {
|
||||||
FeedGroupEntity.GROUP_ALL_ID -> feedTable.oldestSubscriptionUpdateFromAll()
|
FeedGroupEntity.GROUP_ALL_ID -> feedTable.oldestSubscriptionUpdateFromAll()
|
||||||
else -> feedTable.oldestSubscriptionUpdate(groupId)
|
else -> feedTable.oldestSubscriptionUpdate(groupId)
|
||||||
|
|
|
@ -9,11 +9,11 @@ import io.reactivex.Flowable
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.functions.Function4
|
import io.reactivex.functions.Function4
|
||||||
import io.reactivex.schedulers.Schedulers
|
import io.reactivex.schedulers.Schedulers
|
||||||
import java.util.Calendar
|
import java.time.OffsetDateTime
|
||||||
import java.util.Date
|
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import org.schabi.newpipe.database.feed.model.FeedGroupEntity
|
import org.schabi.newpipe.database.feed.model.FeedGroupEntity
|
||||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem
|
import org.schabi.newpipe.extractor.stream.StreamInfoItem
|
||||||
|
import org.schabi.newpipe.ktx.toCalendar
|
||||||
import org.schabi.newpipe.local.feed.service.FeedEventManager
|
import org.schabi.newpipe.local.feed.service.FeedEventManager
|
||||||
import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.ErrorResultEvent
|
import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.ErrorResultEvent
|
||||||
import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.IdleEvent
|
import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.IdleEvent
|
||||||
|
@ -41,7 +41,7 @@ class FeedViewModel(applicationContext: Context, val groupId: Long = FeedGroupEn
|
||||||
feedDatabaseManager.notLoadedCount(groupId),
|
feedDatabaseManager.notLoadedCount(groupId),
|
||||||
feedDatabaseManager.oldestSubscriptionUpdate(groupId),
|
feedDatabaseManager.oldestSubscriptionUpdate(groupId),
|
||||||
|
|
||||||
Function4 { t1: FeedEventManager.Event, t2: List<StreamInfoItem>, t3: Long, t4: List<Date> ->
|
Function4 { t1: FeedEventManager.Event, t2: List<StreamInfoItem>, t3: Long, t4: List<OffsetDateTime> ->
|
||||||
return@Function4 CombineResultHolder(t1, t2, t3, t4.firstOrNull())
|
return@Function4 CombineResultHolder(t1, t2, t3, t4.firstOrNull())
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -51,8 +51,7 @@ class FeedViewModel(applicationContext: Context, val groupId: Long = FeedGroupEn
|
||||||
.subscribe {
|
.subscribe {
|
||||||
val (event, listFromDB, notLoadedCount, oldestUpdate) = it
|
val (event, listFromDB, notLoadedCount, oldestUpdate) = it
|
||||||
|
|
||||||
val oldestUpdateCalendar =
|
val oldestUpdateCalendar = oldestUpdate?.toCalendar()
|
||||||
oldestUpdate?.let { Calendar.getInstance().apply { time = it } }
|
|
||||||
|
|
||||||
mutableStateLiveData.postValue(when (event) {
|
mutableStateLiveData.postValue(when (event) {
|
||||||
is IdleEvent -> FeedState.LoadedState(listFromDB, oldestUpdateCalendar, notLoadedCount)
|
is IdleEvent -> FeedState.LoadedState(listFromDB, oldestUpdateCalendar, notLoadedCount)
|
||||||
|
@ -71,5 +70,5 @@ class FeedViewModel(applicationContext: Context, val groupId: Long = FeedGroupEn
|
||||||
combineDisposable.dispose()
|
combineDisposable.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class CombineResultHolder(val t1: FeedEventManager.Event, val t2: List<StreamInfoItem>, val t3: Long, val t4: Date?)
|
private data class CombineResultHolder(val t1: FeedEventManager.Event, val t2: List<StreamInfoItem>, val t3: Long, val t4: OffsetDateTime?)
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,8 @@ import io.reactivex.functions.Function
|
||||||
import io.reactivex.processors.PublishProcessor
|
import io.reactivex.processors.PublishProcessor
|
||||||
import io.reactivex.schedulers.Schedulers
|
import io.reactivex.schedulers.Schedulers
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.util.Calendar
|
import java.time.OffsetDateTime
|
||||||
|
import java.time.ZoneOffset
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
|
@ -172,9 +173,7 @@ class FeedLoadService : Service() {
|
||||||
private fun startLoading(groupId: Long = FeedGroupEntity.GROUP_ALL_ID, useFeedExtractor: Boolean, thresholdOutdatedSeconds: Int) {
|
private fun startLoading(groupId: Long = FeedGroupEntity.GROUP_ALL_ID, useFeedExtractor: Boolean, thresholdOutdatedSeconds: Int) {
|
||||||
feedResultsHolder = ResultsHolder()
|
feedResultsHolder = ResultsHolder()
|
||||||
|
|
||||||
val outdatedThreshold = Calendar.getInstance().apply {
|
val outdatedThreshold = OffsetDateTime.now(ZoneOffset.UTC).minusSeconds(thresholdOutdatedSeconds.toLong())
|
||||||
add(Calendar.SECOND, -thresholdOutdatedSeconds)
|
|
||||||
}.time
|
|
||||||
|
|
||||||
val subscriptions = when (groupId) {
|
val subscriptions = when (groupId) {
|
||||||
FeedGroupEntity.GROUP_ALL_ID -> feedDatabaseManager.outdatedSubscriptions(outdatedThreshold)
|
FeedGroupEntity.GROUP_ALL_ID -> feedDatabaseManager.outdatedSubscriptions(outdatedThreshold)
|
||||||
|
|
|
@ -44,9 +44,10 @@ import org.schabi.newpipe.extractor.InfoItem;
|
||||||
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
||||||
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
|
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
|
||||||
|
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import io.reactivex.Completable;
|
import io.reactivex.Completable;
|
||||||
|
@ -85,7 +86,7 @@ public class HistoryRecordManager {
|
||||||
return Maybe.empty();
|
return Maybe.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
final Date currentTime = new Date();
|
final OffsetDateTime currentTime = OffsetDateTime.now(ZoneOffset.UTC);
|
||||||
return Maybe.fromCallable(() -> database.runInTransaction(() -> {
|
return Maybe.fromCallable(() -> database.runInTransaction(() -> {
|
||||||
final long streamId = streamTable.upsert(new StreamEntity(info));
|
final long streamId = streamTable.upsert(new StreamEntity(info));
|
||||||
final StreamHistoryEntity latestEntry = streamHistoryTable.getLatestEntry(streamId);
|
final StreamHistoryEntity latestEntry = streamHistoryTable.getLatestEntry(streamId);
|
||||||
|
@ -161,7 +162,7 @@ public class HistoryRecordManager {
|
||||||
return Maybe.empty();
|
return Maybe.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
final Date currentTime = new Date();
|
final OffsetDateTime currentTime = OffsetDateTime.now(ZoneOffset.UTC);
|
||||||
final SearchHistoryEntry newEntry = new SearchHistoryEntry(currentTime, serviceId, search);
|
final SearchHistoryEntry newEntry = new SearchHistoryEntry(currentTime, serviceId, search);
|
||||||
|
|
||||||
return Maybe.fromCallable(() -> database.runInTransaction(() -> {
|
return Maybe.fromCallable(() -> database.runInTransaction(() -> {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import org.schabi.newpipe.database.LocalItem;
|
||||||
import org.schabi.newpipe.local.LocalItemBuilder;
|
import org.schabi.newpipe.local.LocalItemBuilder;
|
||||||
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
||||||
|
|
||||||
import java.text.DateFormat;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Created by Christian Schabesberger on 12.02.17.
|
* Created by Christian Schabesberger on 12.02.17.
|
||||||
|
@ -41,7 +41,7 @@ public abstract class LocalItemHolder extends RecyclerView.ViewHolder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void updateFromItem(LocalItem item, HistoryRecordManager historyRecordManager,
|
public abstract void updateFromItem(LocalItem item, HistoryRecordManager historyRecordManager,
|
||||||
DateFormat dateFormat);
|
DateTimeFormatter dateTimeFormatter);
|
||||||
|
|
||||||
public void updateState(final LocalItem localItem,
|
public void updateState(final LocalItem localItem,
|
||||||
final HistoryRecordManager historyRecordManager) { }
|
final HistoryRecordManager historyRecordManager) { }
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.schabi.newpipe.local.history.HistoryRecordManager;
|
||||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
import org.schabi.newpipe.util.ImageDisplayConstants;
|
||||||
import org.schabi.newpipe.util.Localization;
|
import org.schabi.newpipe.util.Localization;
|
||||||
|
|
||||||
import java.text.DateFormat;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
public class LocalPlaylistItemHolder extends PlaylistItemHolder {
|
public class LocalPlaylistItemHolder extends PlaylistItemHolder {
|
||||||
public LocalPlaylistItemHolder(final LocalItemBuilder infoItemBuilder, final ViewGroup parent) {
|
public LocalPlaylistItemHolder(final LocalItemBuilder infoItemBuilder, final ViewGroup parent) {
|
||||||
|
@ -25,7 +25,7 @@ public class LocalPlaylistItemHolder extends PlaylistItemHolder {
|
||||||
@Override
|
@Override
|
||||||
public void updateFromItem(final LocalItem localItem,
|
public void updateFromItem(final LocalItem localItem,
|
||||||
final HistoryRecordManager historyRecordManager,
|
final HistoryRecordManager historyRecordManager,
|
||||||
final DateFormat dateFormat) {
|
final DateTimeFormatter dateTimeFormatter) {
|
||||||
if (!(localItem instanceof PlaylistMetadataEntry)) {
|
if (!(localItem instanceof PlaylistMetadataEntry)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,6 @@ public class LocalPlaylistItemHolder extends PlaylistItemHolder {
|
||||||
itemBuilder.displayImage(item.thumbnailUrl, itemThumbnailView,
|
itemBuilder.displayImage(item.thumbnailUrl, itemThumbnailView,
|
||||||
ImageDisplayConstants.DISPLAY_PLAYLIST_OPTIONS);
|
ImageDisplayConstants.DISPLAY_PLAYLIST_OPTIONS);
|
||||||
|
|
||||||
super.updateFromItem(localItem, historyRecordManager, dateFormat);
|
super.updateFromItem(localItem, historyRecordManager, dateTimeFormatter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ import org.schabi.newpipe.util.ImageDisplayConstants;
|
||||||
import org.schabi.newpipe.util.Localization;
|
import org.schabi.newpipe.util.Localization;
|
||||||
import org.schabi.newpipe.views.AnimatedProgressBar;
|
import org.schabi.newpipe.views.AnimatedProgressBar;
|
||||||
|
|
||||||
import java.text.DateFormat;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ public class LocalPlaylistStreamItemHolder extends LocalItemHolder {
|
||||||
@Override
|
@Override
|
||||||
public void updateFromItem(final LocalItem localItem,
|
public void updateFromItem(final LocalItem localItem,
|
||||||
final HistoryRecordManager historyRecordManager,
|
final HistoryRecordManager historyRecordManager,
|
||||||
final DateFormat dateFormat) {
|
final DateTimeFormatter dateTimeFormatter) {
|
||||||
if (!(localItem instanceof PlaylistStreamEntry)) {
|
if (!(localItem instanceof PlaylistStreamEntry)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ import org.schabi.newpipe.util.ImageDisplayConstants;
|
||||||
import org.schabi.newpipe.util.Localization;
|
import org.schabi.newpipe.util.Localization;
|
||||||
import org.schabi.newpipe.views.AnimatedProgressBar;
|
import org.schabi.newpipe.views.AnimatedProgressBar;
|
||||||
|
|
||||||
import java.text.DateFormat;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@ -71,10 +71,10 @@ public class LocalStatisticStreamItemHolder extends LocalItemHolder {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getStreamInfoDetailLine(final StreamStatisticsEntry entry,
|
private String getStreamInfoDetailLine(final StreamStatisticsEntry entry,
|
||||||
final DateFormat dateFormat) {
|
final DateTimeFormatter dateTimeFormatter) {
|
||||||
final String watchCount = Localization
|
final String watchCount = Localization
|
||||||
.shortViewCount(itemBuilder.getContext(), entry.getWatchCount());
|
.shortViewCount(itemBuilder.getContext(), entry.getWatchCount());
|
||||||
final String uploadDate = dateFormat.format(entry.getLatestAccessDate());
|
final String uploadDate = dateTimeFormatter.format(entry.getLatestAccessDate());
|
||||||
final String serviceName = NewPipe.getNameOfService(entry.getStreamEntity().getServiceId());
|
final String serviceName = NewPipe.getNameOfService(entry.getStreamEntity().getServiceId());
|
||||||
return Localization.concatenateStrings(watchCount, uploadDate, serviceName);
|
return Localization.concatenateStrings(watchCount, uploadDate, serviceName);
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ public class LocalStatisticStreamItemHolder extends LocalItemHolder {
|
||||||
@Override
|
@Override
|
||||||
public void updateFromItem(final LocalItem localItem,
|
public void updateFromItem(final LocalItem localItem,
|
||||||
final HistoryRecordManager historyRecordManager,
|
final HistoryRecordManager historyRecordManager,
|
||||||
final DateFormat dateFormat) {
|
final DateTimeFormatter dateTimeFormatter) {
|
||||||
if (!(localItem instanceof StreamStatisticsEntry)) {
|
if (!(localItem instanceof StreamStatisticsEntry)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,7 @@ public class LocalStatisticStreamItemHolder extends LocalItemHolder {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (itemAdditionalDetails != null) {
|
if (itemAdditionalDetails != null) {
|
||||||
itemAdditionalDetails.setText(getStreamInfoDetailLine(item, dateFormat));
|
itemAdditionalDetails.setText(getStreamInfoDetailLine(item, dateTimeFormatter));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default thumbnail is shown on error, while loading and if the url is empty
|
// Default thumbnail is shown on error, while loading and if the url is empty
|
||||||
|
|
|
@ -9,7 +9,7 @@ import org.schabi.newpipe.database.LocalItem;
|
||||||
import org.schabi.newpipe.local.LocalItemBuilder;
|
import org.schabi.newpipe.local.LocalItemBuilder;
|
||||||
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
||||||
|
|
||||||
import java.text.DateFormat;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
public abstract class PlaylistItemHolder extends LocalItemHolder {
|
public abstract class PlaylistItemHolder extends LocalItemHolder {
|
||||||
public final ImageView itemThumbnailView;
|
public final ImageView itemThumbnailView;
|
||||||
|
@ -34,7 +34,7 @@ public abstract class PlaylistItemHolder extends LocalItemHolder {
|
||||||
@Override
|
@Override
|
||||||
public void updateFromItem(final LocalItem localItem,
|
public void updateFromItem(final LocalItem localItem,
|
||||||
final HistoryRecordManager historyRecordManager,
|
final HistoryRecordManager historyRecordManager,
|
||||||
final DateFormat dateFormat) {
|
final DateTimeFormatter dateTimeFormatter) {
|
||||||
itemView.setOnClickListener(view -> {
|
itemView.setOnClickListener(view -> {
|
||||||
if (itemBuilder.getOnItemSelectedListener() != null) {
|
if (itemBuilder.getOnItemSelectedListener() != null) {
|
||||||
itemBuilder.getOnItemSelectedListener().selected(localItem);
|
itemBuilder.getOnItemSelectedListener().selected(localItem);
|
||||||
|
|
|
@ -11,7 +11,7 @@ import org.schabi.newpipe.local.history.HistoryRecordManager;
|
||||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
import org.schabi.newpipe.util.ImageDisplayConstants;
|
||||||
import org.schabi.newpipe.util.Localization;
|
import org.schabi.newpipe.util.Localization;
|
||||||
|
|
||||||
import java.text.DateFormat;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
public class RemotePlaylistItemHolder extends PlaylistItemHolder {
|
public class RemotePlaylistItemHolder extends PlaylistItemHolder {
|
||||||
public RemotePlaylistItemHolder(final LocalItemBuilder infoItemBuilder,
|
public RemotePlaylistItemHolder(final LocalItemBuilder infoItemBuilder,
|
||||||
|
@ -27,7 +27,7 @@ public class RemotePlaylistItemHolder extends PlaylistItemHolder {
|
||||||
@Override
|
@Override
|
||||||
public void updateFromItem(final LocalItem localItem,
|
public void updateFromItem(final LocalItem localItem,
|
||||||
final HistoryRecordManager historyRecordManager,
|
final HistoryRecordManager historyRecordManager,
|
||||||
final DateFormat dateFormat) {
|
final DateTimeFormatter dateTimeFormatter) {
|
||||||
if (!(localItem instanceof PlaylistRemoteEntity)) {
|
if (!(localItem instanceof PlaylistRemoteEntity)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,6 @@ public class RemotePlaylistItemHolder extends PlaylistItemHolder {
|
||||||
itemBuilder.displayImage(item.getThumbnailUrl(), itemThumbnailView,
|
itemBuilder.displayImage(item.getThumbnailUrl(), itemThumbnailView,
|
||||||
ImageDisplayConstants.DISPLAY_PLAYLIST_OPTIONS);
|
ImageDisplayConstants.DISPLAY_PLAYLIST_OPTIONS);
|
||||||
|
|
||||||
super.updateFromItem(localItem, historyRecordManager, dateFormat);
|
super.updateFromItem(localItem, historyRecordManager, dateTimeFormatter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,11 +23,13 @@ import org.schabi.newpipe.extractor.localization.ContentCountry;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import java.text.DateFormat;
|
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.format.FormatStyle;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
@ -139,13 +141,16 @@ public final class Localization {
|
||||||
return nf.format(number);
|
return nf.format(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String formatDate(final Date date, final Context context) {
|
public static String formatDate(final OffsetDateTime offsetDateTime, final Context context) {
|
||||||
return DateFormat.getDateInstance(DateFormat.MEDIUM, getAppLocale(context)).format(date);
|
return DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)
|
||||||
|
.withLocale(getAppLocale(context)).format(offsetDateTime
|
||||||
|
.atZoneSameInstant(ZoneId.systemDefault()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("StringFormatInvalid")
|
@SuppressLint("StringFormatInvalid")
|
||||||
public static String localizeUploadDate(final Context context, final Date date) {
|
public static String localizeUploadDate(final Context context,
|
||||||
return context.getString(R.string.upload_date_text, formatDate(date, context));
|
final OffsetDateTime offsetDateTime) {
|
||||||
|
return context.getString(R.string.upload_date_text, formatDate(offsetDateTime, context));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String localizeViewCount(final Context context, final long viewCount) {
|
public static String localizeViewCount(final Context context, final long viewCount) {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<suppressions>
|
<suppressions>
|
||||||
<suppress checks="FinalParameters"
|
<suppress checks="FinalParameters"
|
||||||
files="LocalItemListAdapter.java"
|
files="LocalItemListAdapter.java"
|
||||||
lines="220,292"/>
|
lines="221,293"/>
|
||||||
|
|
||||||
<suppress checks="FinalParameters"
|
<suppress checks="FinalParameters"
|
||||||
files="InfoListAdapter.java"
|
files="InfoListAdapter.java"
|
||||||
|
|
Loading…
Reference in New Issue