mirror of
https://github.com/TwidereProject/Twidere-Android
synced 2025-02-17 04:00:48 +01:00
added option to turn chrome custom tab off
This commit is contained in:
parent
f9f058042b
commit
1b19806575
@ -0,0 +1,47 @@
|
||||
package org.mariotaku.twidere.model;
|
||||
|
||||
import org.mariotaku.library.objectcursor.annotation.CursorField;
|
||||
import org.mariotaku.library.objectcursor.annotation.CursorObject;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Filters;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2017/1/9.
|
||||
*/
|
||||
|
||||
@CursorObject(valuesCreator = true, tableInfo = true)
|
||||
public class FiltersSubscription {
|
||||
@CursorField(value = Filters.Subscriptions._ID, excludeWrite = true, type = TwidereDataStore.TYPE_PRIMARY_KEY)
|
||||
public long id;
|
||||
|
||||
@CursorField(Filters.Subscriptions.COMPONENT)
|
||||
public String component;
|
||||
|
||||
@CursorField(Filters.Subscriptions.ARGUMENTS)
|
||||
public String arguments;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
FiltersSubscription that = (FiltersSubscription) o;
|
||||
|
||||
return id == that.id;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (int) (id ^ (id >>> 32));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FiltersSubscription{" +
|
||||
"arguments='" + arguments + '\'' +
|
||||
", id=" + id +
|
||||
", component='" + component + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@ import android.provider.BaseColumns;
|
||||
import org.mariotaku.twidere.model.DraftTableInfo;
|
||||
import org.mariotaku.twidere.model.FiltersData$BaseItemTableInfo;
|
||||
import org.mariotaku.twidere.model.FiltersData$UserItemTableInfo;
|
||||
import org.mariotaku.twidere.model.FiltersSubscriptionTableInfo;
|
||||
import org.mariotaku.twidere.model.ParcelableActivityTableInfo;
|
||||
import org.mariotaku.twidere.model.ParcelableDirectMessageTableInfo;
|
||||
import org.mariotaku.twidere.model.ParcelableStatusTableInfo;
|
||||
@ -621,6 +622,21 @@ public interface TwidereDataStore {
|
||||
|
||||
String[] TYPES = FiltersData$UserItemTableInfo.TYPES;
|
||||
}
|
||||
|
||||
interface Subscriptions extends BaseColumns {
|
||||
String TABLE_NAME = "filters_subscriptions";
|
||||
String CONTENT_PATH_SEGMENT = "subscriptions";
|
||||
String CONTENT_PATH = Filters.CONTENT_PATH + "/" + CONTENT_PATH_SEGMENT;
|
||||
Uri CONTENT_URI = Uri.withAppendedPath(Filters.CONTENT_URI, CONTENT_PATH_SEGMENT);
|
||||
|
||||
String COMPONENT = "component";
|
||||
String ARGUMENTS = "arguments";
|
||||
|
||||
|
||||
String[] COLUMNS = FiltersSubscriptionTableInfo.COLUMNS;
|
||||
|
||||
String[] TYPES = FiltersSubscriptionTableInfo.TYPES;
|
||||
}
|
||||
}
|
||||
|
||||
interface Mentions extends Statuses {
|
||||
@ -964,6 +980,7 @@ public interface TwidereDataStore {
|
||||
String DEFAULT_SORT_ORDER = POSITION + " ASC";
|
||||
}
|
||||
|
||||
|
||||
interface CachedRelationships extends BaseColumns, AccountSupportColumns {
|
||||
|
||||
String TABLE_NAME = "cached_relationships";
|
||||
|
@ -0,0 +1,9 @@
|
||||
package org.mariotaku.twidere.util.filter;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2017/1/9.
|
||||
*/
|
||||
|
||||
public interface FiltersSubscriptionProvider {
|
||||
|
||||
}
|
@ -42,7 +42,6 @@ class GooglePlayInAppPurchaseActivity : AbsExtraFeaturePurchaseActivity(),
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
if (!billingProcessor.handleActivityResult(requestCode, resultCode, data)) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
@ -127,7 +126,7 @@ class GooglePlayInAppPurchaseActivity : AbsExtraFeaturePurchaseActivity(),
|
||||
BILLING_RESPONSE_RESULT_USER_CANCELED -> Activity.RESULT_CANCELED
|
||||
BILLING_RESPONSE_RESULT_SERVICE_UNAVAILABLE -> RESULT_SERVICE_UNAVAILABLE
|
||||
BILLING_RESPONSE_RESULT_ITEM_NOT_OWNED -> RESULT_NOT_PURCHASED
|
||||
BILLING_RESPONSE_RESULT_ERROR -> RESULT_NOT_PURCHASED
|
||||
BILLING_RESPONSE_RESULT_ERROR -> RESULT_INTERNAL_ERROR
|
||||
else -> billingResponse
|
||||
}
|
||||
return resultCode
|
||||
@ -138,6 +137,5 @@ class GooglePlayInAppPurchaseActivity : AbsExtraFeaturePurchaseActivity(),
|
||||
companion object {
|
||||
private const val TAG_PURCHASE_PROCESS = "get_purchase_process"
|
||||
|
||||
const val EXTRA_PRODUCT_ID = "product_id"
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,91 @@
|
||||
package org.mariotaku.twidere.util.sync.dropbox
|
||||
|
||||
import android.content.Context
|
||||
import com.dropbox.core.DbxException
|
||||
import com.dropbox.core.v2.DbxClientV2
|
||||
import com.dropbox.core.v2.files.DeleteArg
|
||||
import com.dropbox.core.v2.files.FileMetadata
|
||||
import com.dropbox.core.v2.files.ListFolderErrorException
|
||||
import com.dropbox.core.v2.files.ListFolderResult
|
||||
import org.mariotaku.twidere.extension.model.filename
|
||||
import org.mariotaku.twidere.extension.model.readMimeMessageFrom
|
||||
import org.mariotaku.twidere.extension.model.writeMimeMessageTo
|
||||
import org.mariotaku.twidere.model.Draft
|
||||
import org.mariotaku.twidere.util.sync.FileBasedDraftsSyncAction
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
|
||||
class DropboxDraftsSyncAction(context: Context, val client: DbxClientV2) : FileBasedDraftsSyncAction<FileMetadata>(context) {
|
||||
@Throws(IOException::class)
|
||||
override fun Draft.saveToRemote(): FileMetadata {
|
||||
try {
|
||||
client.newUploader("/Drafts/$filename", this.timestamp).use {
|
||||
this.writeMimeMessageTo(context, it.outputStream)
|
||||
return it.finish()
|
||||
}
|
||||
} catch (e: DbxException) {
|
||||
throw IOException(e)
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun Draft.loadFromRemote(info: FileMetadata): Boolean {
|
||||
try {
|
||||
client.files().download(info.pathLower).use {
|
||||
val parsed = this.readMimeMessageFrom(context, it.inputStream)
|
||||
if (parsed) {
|
||||
this.timestamp = info.draftTimestamp
|
||||
this.unique_id = info.draftFileName.substringBeforeLast(".eml")
|
||||
}
|
||||
return parsed
|
||||
}
|
||||
} catch (e: DbxException) {
|
||||
throw IOException(e)
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun removeDrafts(list: List<FileMetadata>): Boolean {
|
||||
try {
|
||||
return client.files().deleteBatch(list.map { DeleteArg(it.pathLower) }) != null
|
||||
} catch (e: DbxException) {
|
||||
throw IOException(e)
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun removeDraft(info: FileMetadata): Boolean {
|
||||
try {
|
||||
return client.files().delete(info.pathLower) != null
|
||||
} catch (e: DbxException) {
|
||||
throw IOException(e)
|
||||
}
|
||||
}
|
||||
|
||||
override val FileMetadata.draftTimestamp: Long get() = this.clientModified.time
|
||||
|
||||
override val FileMetadata.draftFileName: String get() = this.name
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun listRemoteDrafts(): List<FileMetadata> {
|
||||
val result = ArrayList<FileMetadata>()
|
||||
try {
|
||||
var listResult: ListFolderResult = client.files().listFolder("/Drafts/")
|
||||
while (true) {
|
||||
// Do something with files
|
||||
listResult.entries.mapNotNullTo(result) { it as? FileMetadata }
|
||||
if (!listResult.hasMore) break
|
||||
listResult = client.files().listFolderContinue(listResult.cursor)
|
||||
}
|
||||
} catch (e: DbxException) {
|
||||
if (e is ListFolderErrorException) {
|
||||
if (e.errorValue?.pathValue?.isNotFound ?: false) {
|
||||
return emptyList()
|
||||
}
|
||||
}
|
||||
throw IOException(e)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package org.mariotaku.twidere.util.sync.dropbox
|
||||
|
||||
import android.content.Context
|
||||
import com.dropbox.core.DbxDownloader
|
||||
import com.dropbox.core.v2.DbxClientV2
|
||||
import com.dropbox.core.v2.files.FileMetadata
|
||||
import com.dropbox.core.v2.files.UploadUploader
|
||||
import org.mariotaku.twidere.extension.model.initFields
|
||||
import org.mariotaku.twidere.extension.model.parse
|
||||
import org.mariotaku.twidere.extension.model.serialize
|
||||
import org.mariotaku.twidere.extension.newPullParser
|
||||
import org.mariotaku.twidere.extension.newSerializer
|
||||
import org.mariotaku.twidere.model.FiltersData
|
||||
import org.mariotaku.twidere.util.sync.FileBasedFiltersDataSyncAction
|
||||
|
||||
internal class DropboxFiltersDataSyncAction(
|
||||
context: Context,
|
||||
val client: DbxClientV2
|
||||
) : FileBasedFiltersDataSyncAction<DbxDownloader<FileMetadata>, DropboxUploadSession<FiltersData>>(context) {
|
||||
override fun DbxDownloader<FileMetadata>.getRemoteLastModified(): Long {
|
||||
return result.clientModified.time
|
||||
}
|
||||
|
||||
private val filePath = "/Common/filters.xml"
|
||||
|
||||
override fun newLoadFromRemoteSession(): DbxDownloader<FileMetadata> {
|
||||
return client.newDownloader(filePath)
|
||||
}
|
||||
|
||||
override fun DbxDownloader<FileMetadata>.loadFromRemote(): FiltersData {
|
||||
val data = FiltersData()
|
||||
data.parse(inputStream.newPullParser(charset = Charsets.UTF_8))
|
||||
data.initFields()
|
||||
return data
|
||||
}
|
||||
|
||||
override fun DropboxUploadSession<FiltersData>.setRemoteLastModified(lastModified: Long) {
|
||||
this.localModifiedTime = lastModified
|
||||
}
|
||||
|
||||
override fun DropboxUploadSession<FiltersData>.saveToRemote(data: FiltersData): Boolean {
|
||||
return this.uploadData(data)
|
||||
}
|
||||
|
||||
override fun newSaveToRemoteSession(): DropboxUploadSession<FiltersData> {
|
||||
return object : DropboxUploadSession<FiltersData>(filePath, client) {
|
||||
override fun performUpload(uploader: UploadUploader, data: FiltersData) {
|
||||
data.serialize(uploader.outputStream.newSerializer(charset = Charsets.UTF_8, indent = true))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package org.mariotaku.twidere.util.sync.dropbox
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import com.dropbox.core.DbxDownloader
|
||||
import com.dropbox.core.v2.DbxClientV2
|
||||
import com.dropbox.core.v2.files.FileMetadata
|
||||
import com.dropbox.core.v2.files.UploadUploader
|
||||
import org.mariotaku.twidere.extension.newPullParser
|
||||
import org.mariotaku.twidere.extension.newSerializer
|
||||
import org.mariotaku.twidere.util.sync.FileBasedPreferencesValuesSyncAction
|
||||
import java.util.*
|
||||
|
||||
internal class DropboxPreferencesValuesSyncAction(
|
||||
context: Context,
|
||||
val client: DbxClientV2,
|
||||
preferences: SharedPreferences,
|
||||
processor: Processor,
|
||||
val filePath: String
|
||||
) : FileBasedPreferencesValuesSyncAction<DbxDownloader<FileMetadata>,
|
||||
DropboxUploadSession<Map<String, String>>>(context, preferences, processor) {
|
||||
override fun DbxDownloader<FileMetadata>.getRemoteLastModified(): Long {
|
||||
return result.clientModified.time
|
||||
}
|
||||
|
||||
override fun DbxDownloader<FileMetadata>.loadFromRemote(): MutableMap<String, String> {
|
||||
val data = HashMap<String, String>()
|
||||
data.parse(inputStream.newPullParser())
|
||||
return data
|
||||
}
|
||||
|
||||
override fun newLoadFromRemoteSession(): DbxDownloader<FileMetadata> {
|
||||
return client.newDownloader(filePath)
|
||||
}
|
||||
|
||||
override fun newSaveToRemoteSession(): DropboxUploadSession<Map<String, String>> {
|
||||
return object : DropboxUploadSession<Map<String, String>>(filePath, client) {
|
||||
override fun performUpload(uploader: UploadUploader, data: Map<String, String>) {
|
||||
data.serialize(uploader.outputStream.newSerializer(charset = Charsets.UTF_8,
|
||||
indent = true))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun DropboxUploadSession<Map<String, String>>.saveToRemote(data: MutableMap<String, String>): Boolean {
|
||||
return this.uploadData(data)
|
||||
}
|
||||
|
||||
override fun DropboxUploadSession<Map<String, String>>.setRemoteLastModified(lastModified: Long) {
|
||||
this.localModifiedTime = lastModified
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package org.mariotaku.twidere.util.sync.dropbox
|
||||
|
||||
import com.dropbox.core.DbxDownloader
|
||||
import com.dropbox.core.DbxException
|
||||
import com.dropbox.core.v2.DbxClientV2
|
||||
import com.dropbox.core.v2.files.DownloadErrorException
|
||||
import com.dropbox.core.v2.files.FileMetadata
|
||||
import com.dropbox.core.v2.files.UploadUploader
|
||||
import com.dropbox.core.v2.files.WriteMode
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2017/1/10.
|
||||
*/
|
||||
|
||||
@Throws(IOException::class)
|
||||
internal fun DbxClientV2.newUploader(path: String, clientModified: Long): UploadUploader {
|
||||
try {
|
||||
return files().uploadBuilder(path).withMode(WriteMode.OVERWRITE).withMute(true)
|
||||
.withClientModified(Date(clientModified)).start()
|
||||
} catch (e: DbxException) {
|
||||
throw IOException(e)
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
internal fun DbxClientV2.newDownloader(path: String): DbxDownloader<FileMetadata> {
|
||||
try {
|
||||
return files().downloadBuilder(path).start()
|
||||
} catch (e: DownloadErrorException) {
|
||||
if (e.errorValue?.pathValue?.isNotFound ?: false) {
|
||||
throw FileNotFoundException(path)
|
||||
}
|
||||
throw IOException(e)
|
||||
} catch (e: DbxException) {
|
||||
throw IOException(e)
|
||||
}
|
||||
}
|
@ -1,27 +1,17 @@
|
||||
package org.mariotaku.twidere.util.sync.dropbox;
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import com.dropbox.core.DbxDownloader
|
||||
import com.dropbox.core.DbxException
|
||||
import com.dropbox.core.DbxRequestConfig
|
||||
import com.dropbox.core.v2.DbxClientV2
|
||||
import com.dropbox.core.v2.files.*
|
||||
import nl.komponents.kovenant.task
|
||||
import nl.komponents.kovenant.ui.failUi
|
||||
import nl.komponents.kovenant.ui.successUi
|
||||
import org.mariotaku.twidere.BuildConfig
|
||||
import org.mariotaku.twidere.extension.model.*
|
||||
import org.mariotaku.twidere.extension.newPullParser
|
||||
import org.mariotaku.twidere.extension.newSerializer
|
||||
import org.mariotaku.twidere.model.Draft
|
||||
import org.mariotaku.twidere.model.FiltersData
|
||||
import org.mariotaku.twidere.util.TaskServiceRunner
|
||||
import org.mariotaku.twidere.util.sync.*
|
||||
import java.io.Closeable
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
import org.mariotaku.twidere.util.sync.ISyncAction
|
||||
import org.mariotaku.twidere.util.sync.SyncTaskRunner
|
||||
import org.mariotaku.twidere.util.sync.UserColorsSyncProcessor
|
||||
import org.mariotaku.twidere.util.sync.UserNicknamesSyncProcessor
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2017/1/6.
|
||||
@ -54,209 +44,4 @@ class DropboxSyncTaskRunner(context: Context, val authToken: String) : SyncTaskR
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
class DropboxDraftsSyncAction(context: Context, val client: DbxClientV2) : FileBasedDraftsSyncAction<FileMetadata>(context) {
|
||||
@Throws(IOException::class)
|
||||
override fun Draft.saveToRemote(): FileMetadata {
|
||||
try {
|
||||
client.newUploader("/Drafts/$filename", this.timestamp).use {
|
||||
this.writeMimeMessageTo(context, it.outputStream)
|
||||
return it.finish()
|
||||
}
|
||||
} catch (e: DbxException) {
|
||||
throw IOException(e)
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun Draft.loadFromRemote(info: FileMetadata): Boolean {
|
||||
try {
|
||||
client.files().download(info.pathLower).use {
|
||||
val parsed = this.readMimeMessageFrom(context, it.inputStream)
|
||||
if (parsed) {
|
||||
this.timestamp = info.draftTimestamp
|
||||
this.unique_id = info.draftFileName.substringBeforeLast(".eml")
|
||||
}
|
||||
return parsed
|
||||
}
|
||||
} catch (e: DbxException) {
|
||||
throw IOException(e)
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun removeDrafts(list: List<FileMetadata>): Boolean {
|
||||
try {
|
||||
return client.files().deleteBatch(list.map { DeleteArg(it.pathLower) }) != null
|
||||
} catch (e: DbxException) {
|
||||
throw IOException(e)
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun removeDraft(info: FileMetadata): Boolean {
|
||||
try {
|
||||
return client.files().delete(info.pathLower) != null
|
||||
} catch (e: DbxException) {
|
||||
throw IOException(e)
|
||||
}
|
||||
}
|
||||
|
||||
override val FileMetadata.draftTimestamp: Long get() = this.clientModified.time
|
||||
|
||||
override val FileMetadata.draftFileName: String get() = this.name
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun listRemoteDrafts(): List<FileMetadata> {
|
||||
val result = ArrayList<FileMetadata>()
|
||||
try {
|
||||
var listResult: ListFolderResult = client.files().listFolder("/Drafts/")
|
||||
while (true) {
|
||||
// Do something with files
|
||||
listResult.entries.mapNotNullTo(result) { it as? FileMetadata }
|
||||
if (!listResult.hasMore) break
|
||||
listResult = client.files().listFolderContinue(listResult.cursor)
|
||||
}
|
||||
} catch (e: DbxException) {
|
||||
if (e is ListFolderErrorException) {
|
||||
if (e.errorValue?.pathValue?.isNotFound ?: false) {
|
||||
return emptyList()
|
||||
}
|
||||
}
|
||||
throw IOException(e)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal class DropboxFiltersDataSyncAction(
|
||||
context: Context,
|
||||
val client: DbxClientV2
|
||||
) : FileBasedFiltersDataSyncAction<DbxDownloader<FileMetadata>, DropboxUploadSession<FiltersData>>(context) {
|
||||
override fun DbxDownloader<FileMetadata>.getRemoteLastModified(): Long {
|
||||
return result.clientModified.time
|
||||
}
|
||||
|
||||
private val filePath = "/Common/filters.xml"
|
||||
|
||||
override fun newLoadFromRemoteSession(): DbxDownloader<FileMetadata> {
|
||||
return client.newDownloader(filePath)
|
||||
}
|
||||
|
||||
override fun DbxDownloader<FileMetadata>.loadFromRemote(): FiltersData {
|
||||
val data = FiltersData()
|
||||
data.parse(inputStream.newPullParser(charset = Charsets.UTF_8))
|
||||
data.initFields()
|
||||
return data
|
||||
}
|
||||
|
||||
override fun DropboxUploadSession<FiltersData>.setRemoteLastModified(lastModified: Long) {
|
||||
this.localModifiedTime = lastModified
|
||||
}
|
||||
|
||||
override fun DropboxUploadSession<FiltersData>.saveToRemote(data: FiltersData): Boolean {
|
||||
return this.uploadData(data)
|
||||
}
|
||||
|
||||
override fun newSaveToRemoteSession(): DropboxUploadSession<FiltersData> {
|
||||
return object : DropboxUploadSession<FiltersData>(filePath, client) {
|
||||
override fun performUpload(uploader: UploadUploader, data: FiltersData) {
|
||||
data.serialize(uploader.outputStream.newSerializer(charset = Charsets.UTF_8, indent = true))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
internal class DropboxPreferencesValuesSyncAction(
|
||||
context: Context,
|
||||
val client: DbxClientV2,
|
||||
preferences: SharedPreferences,
|
||||
processor: Processor,
|
||||
val filePath: String
|
||||
) : FileBasedPreferencesValuesSyncAction<DbxDownloader<FileMetadata>,
|
||||
DropboxUploadSession<Map<String, String>>>(context, preferences, processor) {
|
||||
override fun DbxDownloader<FileMetadata>.getRemoteLastModified(): Long {
|
||||
return result.clientModified.time
|
||||
}
|
||||
|
||||
override fun DbxDownloader<FileMetadata>.loadFromRemote(): MutableMap<String, String> {
|
||||
val data = HashMap<String, String>()
|
||||
data.parse(inputStream.newPullParser())
|
||||
return data
|
||||
}
|
||||
|
||||
override fun newLoadFromRemoteSession(): DbxDownloader<FileMetadata> {
|
||||
return client.newDownloader(filePath)
|
||||
}
|
||||
|
||||
override fun newSaveToRemoteSession(): DropboxUploadSession<Map<String, String>> {
|
||||
return object : DropboxUploadSession<Map<String, String>>(filePath, client) {
|
||||
override fun performUpload(uploader: UploadUploader, data: Map<String, String>) {
|
||||
data.serialize(uploader.outputStream.newSerializer(charset = Charsets.UTF_8,
|
||||
indent = true))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun DropboxUploadSession<Map<String, String>>.saveToRemote(data: MutableMap<String, String>): Boolean {
|
||||
return this.uploadData(data)
|
||||
}
|
||||
|
||||
override fun DropboxUploadSession<Map<String, String>>.setRemoteLastModified(lastModified: Long) {
|
||||
this.localModifiedTime = lastModified
|
||||
}
|
||||
}
|
||||
|
||||
abstract internal class DropboxUploadSession<in Data>(val fileName: String, val client: DbxClientV2) : Closeable {
|
||||
private var uploader: UploadUploader? = null
|
||||
|
||||
var localModifiedTime: Long = 0
|
||||
|
||||
override fun close() {
|
||||
uploader?.close()
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
abstract fun performUpload(uploader: UploadUploader, data: Data)
|
||||
|
||||
fun uploadData(data: Data): Boolean {
|
||||
uploader = client.newUploader(fileName, localModifiedTime).apply {
|
||||
performUpload(this, data)
|
||||
this.finish()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
|
||||
@Throws(IOException::class)
|
||||
private fun DbxClientV2.newUploader(path: String, clientModified: Long): UploadUploader {
|
||||
try {
|
||||
return files().uploadBuilder(path).withMode(WriteMode.OVERWRITE).withMute(true)
|
||||
.withClientModified(Date(clientModified)).start()
|
||||
} catch (e: DbxException) {
|
||||
throw IOException(e)
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
private fun DbxClientV2.newDownloader(path: String): DbxDownloader<FileMetadata> {
|
||||
try {
|
||||
return files().downloadBuilder(path).start()
|
||||
} catch (e: DownloadErrorException) {
|
||||
if (e.errorValue?.pathValue?.isNotFound ?: false) {
|
||||
throw FileNotFoundException(path)
|
||||
}
|
||||
throw IOException(e)
|
||||
} catch (e: DbxException) {
|
||||
throw IOException(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,28 @@
|
||||
package org.mariotaku.twidere.util.sync.dropbox
|
||||
|
||||
import com.dropbox.core.v2.DbxClientV2
|
||||
import com.dropbox.core.v2.files.UploadUploader
|
||||
import java.io.Closeable
|
||||
import java.io.IOException
|
||||
|
||||
abstract internal class DropboxUploadSession<in Data>(val fileName: String, val client: DbxClientV2) : Closeable {
|
||||
private var uploader: UploadUploader? = null
|
||||
|
||||
var localModifiedTime: Long = 0
|
||||
|
||||
override fun close() {
|
||||
uploader?.close()
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
abstract fun performUpload(uploader: UploadUploader, data: Data)
|
||||
|
||||
fun uploadData(data: Data): Boolean {
|
||||
uploader = client.newUploader(fileName, localModifiedTime).apply {
|
||||
performUpload(this, data)
|
||||
this.finish()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
@ -58,7 +58,7 @@ val themeKey = KStringKey(KEY_THEME, VALUE_THEME_NAME_LIGHT)
|
||||
val themeColorKey = KIntKey(KEY_THEME_COLOR, 0)
|
||||
val filterUnavailableQuoteStatusesKey = KBooleanKey("filter_unavailable_quote_statuses", false)
|
||||
val filterPossibilitySensitiveStatusesKey = KBooleanKey("filter_possibility_sensitive_statuses", false)
|
||||
|
||||
val chromeCustomTabKey = KBooleanKey("chrome_custom_tab", true)
|
||||
object themeBackgroundAlphaKey : KSimpleKey<Int>(KEY_THEME_BACKGROUND_ALPHA, 0xFF) {
|
||||
override fun read(preferences: SharedPreferences): Int {
|
||||
return preferences.getInt(KEY_THEME_BACKGROUND_ALPHA, DEFAULT_THEME_BACKGROUND_ALPHA)
|
||||
|
@ -0,0 +1,19 @@
|
||||
package org.mariotaku.twidere.extension.model
|
||||
|
||||
import android.content.Context
|
||||
import org.mariotaku.twidere.model.FiltersSubscription
|
||||
import org.mariotaku.twidere.util.filter.FiltersSubscriptionProvider
|
||||
import org.mariotaku.twidere.util.filter.LocalFiltersSubscriptionProvider
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2017/1/9.
|
||||
*/
|
||||
|
||||
fun FiltersSubscription.instantiateComponent(context: Context): FiltersSubscriptionProvider? {
|
||||
val component = this.component ?: return null
|
||||
if (component.startsWith(":")) {
|
||||
// Load builtin service
|
||||
return LocalFiltersSubscriptionProvider.forName(context, component.substringAfter(":"))
|
||||
}
|
||||
return null
|
||||
}
|
@ -36,6 +36,7 @@ import org.mariotaku.twidere.activity.WebLinkHandlerActivity
|
||||
import org.mariotaku.twidere.annotation.Referral
|
||||
import org.mariotaku.twidere.app.TwidereApplication
|
||||
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT_KEY
|
||||
import org.mariotaku.twidere.constant.chromeCustomTabKey
|
||||
import org.mariotaku.twidere.constant.newDocumentApiKey
|
||||
import org.mariotaku.twidere.model.UserKey
|
||||
import org.mariotaku.twidere.model.util.ParcelableMediaUtils
|
||||
@ -161,15 +162,26 @@ open class OnLinkClickHandler(
|
||||
|
||||
protected open fun openLink(link: String) {
|
||||
if (manager != null && manager.isActive) return
|
||||
val uri = Uri.parse(link)
|
||||
if (!preferences[chromeCustomTabKey]) {
|
||||
val viewIntent = Intent(Intent.ACTION_VIEW, uri)
|
||||
viewIntent.addCategory(Intent.CATEGORY_BROWSABLE)
|
||||
try {
|
||||
return context.startActivity(viewIntent)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
// Ignore
|
||||
}
|
||||
return
|
||||
}
|
||||
val builder = CustomTabsIntent.Builder()
|
||||
(ChameleonUtils.getActivity(context) as? Chameleon.Themeable)?.overrideTheme?.let { theme ->
|
||||
builder.setToolbarColor(theme.colorToolbar)
|
||||
}
|
||||
val intent = builder.build()
|
||||
try {
|
||||
intent.launchUrl(context, Uri.parse(link))
|
||||
intent.launchUrl(context, uri)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
// TODO
|
||||
// Ignore
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,20 @@
|
||||
package org.mariotaku.twidere.util.filter
|
||||
|
||||
import android.content.Context
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2017/1/9.
|
||||
*/
|
||||
|
||||
abstract class LocalFiltersSubscriptionProvider(val context: Context) : FiltersSubscriptionProvider {
|
||||
companion object {
|
||||
fun forName(context: Context, name: String): FiltersSubscriptionProvider? {
|
||||
when (name) {
|
||||
"url" -> {
|
||||
return UrlFiltersSubscriptionProvider(context)
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package org.mariotaku.twidere.util.filter;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2017/1/9.
|
||||
*/
|
||||
|
||||
public class UrlFiltersSubscriptionProvider extends LocalFiltersSubscriptionProvider {
|
||||
public UrlFiltersSubscriptionProvider(@NotNull Context context) {
|
||||
super(context);
|
||||
}
|
||||
}
|
@ -894,4 +894,6 @@
|
||||
<string name="message_sync_disconnect_from_name_confirm">Disconnect from <xliff:g example="ownCloud" id="name">%s</xliff:g>?</string>
|
||||
<string name="message_sync_last_synced_time">Last synced: <xliff:g example="2017/1/1 12:00" id="time">%s</xliff:g></string>
|
||||
<string name="action_purchase_features_pack">Buy features pack</string>
|
||||
<string name="preference_title_chrome_custom_tab">Chrome custom tab</string>
|
||||
<string name="preference_summary_chrome_custom_tab">Open links in Chrome custom tab</string>
|
||||
</resources>
|
@ -71,6 +71,12 @@
|
||||
android:summary="@string/preference_multitasking_summary"
|
||||
android:title="@string/preference_multitasking"/>
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="chrome_custom_tab"
|
||||
android:summary="@string/preference_summary_chrome_custom_tab"
|
||||
android:title="@string/preference_title_chrome_custom_tab"/>
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
|
Loading…
x
Reference in New Issue
Block a user