1
0
mirror of https://github.com/AllanWang/Frost-for-Facebook.git synced 2024-11-10 04:52:38 +01:00

Merge branch 'dev' into theme

This commit is contained in:
Allan Wang 2019-09-08 00:51:13 -07:00
commit 8cf499946b
No known key found for this signature in database
GPG Key ID: C93E3F9C679D7A56
66 changed files with 100 additions and 392 deletions

View File

@ -277,11 +277,6 @@ dependencies {
debugImplementation "com.squareup.leakcanary:leakcanary-android:${Versions.leakCanary}"
// testImplementation "com.squareup.leakcanary:leakcanary-android-no-op:${Versions.leakCanary}"
implementation "com.github.Raizlabs.DBFlow:dbflow:${Versions.dbflow}"
implementation "com.github.Raizlabs.DBFlow:dbflow-core:${Versions.dbflow}"
kapt "com.github.Raizlabs.DBFlow:dbflow-processor:${Versions.dbflow}"
implementation "com.github.Raizlabs.DBFlow:dbflow-kotlinextensions:${Versions.dbflow}"
//Icons
implementation kau.Dependencies.iconicsMaterial
implementation kau.Dependencies.iconicsCommunity

View File

@ -1,6 +1,5 @@
-ignorewarnings
-dontwarn kotlin.**
-keep class * extends com.raizlabs.android.dbflow.config.DatabaseHolder { *; }
-keepattributes *Annotation*
# Enums
#-keepclassmembers class * extends java.lang.Enum {

View File

@ -59,13 +59,6 @@
android:label="@string/frost_name"
android:launchMode="singleTop"
android:theme="@style/FrostTheme.Overlay.Slide" />
<activity
android:name=".activities.WebOverlayDesktopActivity"
android:configChanges="orientation|screenSize|locale"
android:hardwareAccelerated="true"
android:label="@string/frost_web"
android:launchMode="singleTop"
android:theme="@style/FrostTheme.Overlay.Slide" />
<activity
android:name=".activities.FrostWebActivity"
android:autoRemoveFromRecents="true"
@ -197,11 +190,6 @@
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
<provider
android:name="com.raizlabs.android.dbflow.runtime.StubContentProvider"
android:authorities="${applicationId}.dbflow.provider"
android:exported="false" />
<meta-data
android:name="com.bugsnag.android.API_KEY"
android:value="83cf680ed01a6fda10fe497d1c0962bb" />

View File

@ -30,10 +30,7 @@ import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.signature.ApplicationVersionSignature
import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader
import com.mikepenz.materialdrawer.util.DrawerImageLoader
import com.pitchedapps.frost.db.CookiesDb
import com.pitchedapps.frost.db.FbTabsDb
import com.pitchedapps.frost.db.FrostDatabase
import com.pitchedapps.frost.db.NotificationDb
import com.pitchedapps.frost.glide.GlideApp
import com.pitchedapps.frost.services.scheduleNotificationsFromPrefs
import com.pitchedapps.frost.services.setupNotificationChannels
@ -42,15 +39,10 @@ import com.pitchedapps.frost.utils.FrostPglAdBlock
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.Showcase
import com.raizlabs.android.dbflow.config.DatabaseConfig
import com.raizlabs.android.dbflow.config.FlowConfig
import com.raizlabs.android.dbflow.config.FlowManager
import com.raizlabs.android.dbflow.runtime.ContentResolverNotifier
import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidLogger
import org.koin.core.context.startKoin
import java.util.Random
import kotlin.reflect.KClass
/**
* Created by Allan Wang on 2017-05-28.
@ -63,27 +55,12 @@ class FrostApp : Application() {
// lateinit var refWatcher: RefWatcher
private fun FlowConfig.Builder.withDatabase(name: String, klass: KClass<*>) =
addDatabaseConfig(
DatabaseConfig.builder(klass.java)
.databaseName(name)
.modelNotifier(ContentResolverNotifier("${BuildConfig.APPLICATION_ID}.dbflow.provider"))
.build()
)
override fun onCreate() {
if (!buildIsLollipopAndUp) { // not supported
super.onCreate()
return
}
FlowManager.init(
FlowConfig.Builder(this)
.withDatabase(CookiesDb.NAME, CookiesDb::class)
.withDatabase(FbTabsDb.NAME, FbTabsDb::class)
.withDatabase(NotificationDb.NAME, NotificationDb::class)
.build()
)
// if (LeakCanary.isInAnalyzerProcess(this)) return
// refWatcher = LeakCanary.install(this)
initPrefs()

View File

@ -34,12 +34,7 @@ import com.pitchedapps.frost.activities.MainActivity
import com.pitchedapps.frost.activities.SelectorActivity
import com.pitchedapps.frost.db.CookieDao
import com.pitchedapps.frost.db.CookieEntity
import com.pitchedapps.frost.db.CookieModel
import com.pitchedapps.frost.db.FbTabModel
import com.pitchedapps.frost.db.GenericDao
import com.pitchedapps.frost.db.getTabs
import com.pitchedapps.frost.db.save
import com.pitchedapps.frost.db.saveTabs
import com.pitchedapps.frost.db.selectAll
import com.pitchedapps.frost.facebook.FbCookie
import com.pitchedapps.frost.utils.BiometricUtils
@ -48,11 +43,7 @@ import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.launchNewTask
import com.pitchedapps.frost.utils.loadAssets
import com.raizlabs.android.dbflow.kotlinextensions.from
import com.raizlabs.android.dbflow.kotlinextensions.select
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.android.ext.android.inject
import java.util.ArrayList
@ -82,7 +73,6 @@ class StartActivity : KauBaseActivity() {
launch {
val authDefer = BiometricUtils.authenticate(this@StartActivity)
try {
migrate()
FbCookie.switchBackUser()
val cookies = ArrayList(cookieDao.selectAll())
L.i { "Cookies loaded at time ${System.currentTimeMillis()}" }
@ -111,27 +101,6 @@ class StartActivity : KauBaseActivity() {
}
}
/**
* Migrate from dbflow to room
* TODO delete dbflow data
*/
private suspend fun migrate() = withContext(Dispatchers.IO) {
if (cookieDao.selectAll().isNotEmpty()) return@withContext
val cookies = (select from CookieModel::class).queryList()
.map { CookieEntity(it.id, it.name, it.cookie) }
if (cookies.isNotEmpty()) {
cookieDao.save(cookies)
L._d { "Migrated cookies ${cookieDao.selectAll()}" }
}
val tabs = (select from FbTabModel::class).queryList().map(FbTabModel::tab)
if (tabs.isNotEmpty()) {
genericDao.saveTabs(tabs)
L._d { "Migrated tabs ${genericDao.getTabs()}" }
}
deleteDatabase("Cookies.db")
deleteDatabase("FrostTabs.db")
}
private fun showInvalidWebView() =
showInvalidView(R.string.error_webview)

View File

@ -68,7 +68,6 @@ class AboutActivity : AboutActivityBase(null, {
val include = arrayOf(
"AboutLibraries",
"AndroidIconics",
"dbflow",
"fastadapter",
"glide",
"Jsoup",

View File

@ -16,7 +16,6 @@
*/
package com.pitchedapps.frost.activities
import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.PointF
import android.net.Uri
@ -60,7 +59,6 @@ import com.pitchedapps.frost.enums.OverlayContext
import com.pitchedapps.frost.facebook.FB_URL_BASE
import com.pitchedapps.frost.facebook.FbCookie
import com.pitchedapps.frost.facebook.FbItem
import com.pitchedapps.frost.facebook.USER_AGENT_DESKTOP
import com.pitchedapps.frost.facebook.formattedFbUrl
import com.pitchedapps.frost.kotlin.subscribeDuringJob
import com.pitchedapps.frost.services.FrostRunnable
@ -94,7 +92,7 @@ import okhttp3.HttpUrl
* Going back will bring you back to the previous app
*/
@UseExperimental(ExperimentalCoroutinesApi::class)
class FrostWebActivity : WebOverlayActivityBase(false) {
class FrostWebActivity : WebOverlayActivityBase() {
override fun onCreate(savedInstanceState: Bundle?) {
val requiresAction = !parseActionSend()
@ -142,20 +140,13 @@ class FrostWebActivity : WebOverlayActivityBase(false) {
}
}
/**
* Variant that forces a desktop user agent. This is largely internal,
* and is only necessary when we are launching from an existing [WebOverlayActivityBase]
*/
class WebOverlayDesktopActivity : WebOverlayActivityBase(true)
/**
* Internal overlay for the app; this is tied with the main task and is singleTop as opposed to singleInstance
*/
class WebOverlayActivity : WebOverlayActivityBase(false)
class WebOverlayActivity : WebOverlayActivityBase()
@SuppressLint("Registered")
@UseExperimental(ExperimentalCoroutinesApi::class)
open class WebOverlayActivityBase(private val forceDesktopAgent: Boolean) : BaseActivity(),
abstract class WebOverlayActivityBase : BaseActivity(),
ActivityContract, FrostContentContainer,
VideoViewHolder, FileChooserContract by FileChooserDelegate() {
@ -217,8 +208,6 @@ open class WebOverlayActivityBase(private val forceDesktopAgent: Boolean) : Base
}
with(web) {
if (forceDesktopAgent) //todo check; the webview already adds it dynamically
userAgentString = USER_AGENT_DESKTOP
Prefs.prevId = Prefs.userId
launch {
val authDefer = BiometricUtils.authenticate(this@WebOverlayActivityBase)

View File

@ -24,11 +24,6 @@ import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.pitchedapps.frost.utils.Prefs
import com.raizlabs.android.dbflow.annotation.ConflictAction
import com.raizlabs.android.dbflow.annotation.Database
import com.raizlabs.android.dbflow.annotation.PrimaryKey
import com.raizlabs.android.dbflow.annotation.Table
import com.raizlabs.android.dbflow.structure.BaseModel
import kotlinx.android.parcel.Parcelize
/**
@ -74,21 +69,3 @@ suspend fun CookieDao.save(cookie: CookieEntity) = dao { _save(cookie) }
suspend fun CookieDao.save(cookies: List<CookieEntity>) = dao { _save(cookies) }
suspend fun CookieDao.deleteById(id: Long) = dao { _deleteById(id) }
suspend fun CookieDao.currentCookie() = selectById(Prefs.userId)
@Database(version = CookiesDb.VERSION)
object CookiesDb {
const val NAME = "Cookies"
const val VERSION = 2
}
@Parcelize
@Table(database = CookiesDb::class, allFields = true, primaryKeyConflict = ConflictAction.REPLACE)
data class CookieModel(
@PrimaryKey var id: Long = -1L,
var name: String? = null,
var cookie: String? = null
) :
BaseModel(), Parcelable {
override fun toString(): String = "CookieModel(${hashCode()})"
}

View File

@ -1,39 +0,0 @@
/*
* Copyright 2018 Allan Wang
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.pitchedapps.frost.db
import com.pitchedapps.frost.facebook.FbItem
import com.raizlabs.android.dbflow.annotation.Database
import com.raizlabs.android.dbflow.annotation.PrimaryKey
import com.raizlabs.android.dbflow.annotation.Table
import com.raizlabs.android.dbflow.structure.BaseModel
/**
* Created by Allan Wang on 2017-05-30.
*/
const val TAB_COUNT = 4
@Database(version = FbTabsDb.VERSION)
object FbTabsDb {
const val NAME = "FrostTabs"
const val VERSION = 1
}
@Table(database = FbTabsDb::class, allFields = true)
data class FbTabModel(@PrimaryKey var position: Int = -1, var tab: FbItem = FbItem.FEED) :
BaseModel()

View File

@ -56,6 +56,8 @@ interface GenericDao {
}
}
const val TAB_COUNT = 4
suspend fun GenericDao.saveTabs(tabs: List<FbItem>) = dao {
val content = tabs.joinToString(",") { it.name }
_save(GenericEntity(GenericDao.TYPE_TABS, content))

View File

@ -26,22 +26,8 @@ import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Transaction
import com.pitchedapps.frost.services.NOTIF_CHANNEL_GENERAL
import com.pitchedapps.frost.services.NOTIF_CHANNEL_MESSAGES
import com.pitchedapps.frost.services.NotificationContent
import com.pitchedapps.frost.utils.L
import com.raizlabs.android.dbflow.annotation.ConflictAction
import com.raizlabs.android.dbflow.annotation.Database
import com.raizlabs.android.dbflow.annotation.Migration
import com.raizlabs.android.dbflow.annotation.PrimaryKey
import com.raizlabs.android.dbflow.annotation.Table
import com.raizlabs.android.dbflow.kotlinextensions.eq
import com.raizlabs.android.dbflow.kotlinextensions.from
import com.raizlabs.android.dbflow.kotlinextensions.select
import com.raizlabs.android.dbflow.kotlinextensions.where
import com.raizlabs.android.dbflow.sql.SQLiteType
import com.raizlabs.android.dbflow.sql.migration.AlterTableMigration
import com.raizlabs.android.dbflow.structure.BaseModel
@Entity(
tableName = "notifications",
@ -164,46 +150,5 @@ suspend fun NotificationDao.saveNotifications(
}
suspend fun NotificationDao.latestEpoch(userId: Long, type: String): Long = dao {
_selectEpoch(userId, type) ?: lastNotificationTime(userId).let {
when (type) {
NOTIF_CHANNEL_GENERAL -> it.epoch
NOTIF_CHANNEL_MESSAGES -> it.epochIm
else -> -1L
}
}
_selectEpoch(userId, type) ?: -1L
}
/**
* Created by Allan Wang on 2017-05-30.
*/
@Database(version = NotificationDb.VERSION)
object NotificationDb {
const val NAME = "Notifications"
const val VERSION = 2
}
@Migration(version = 2, database = NotificationDb::class)
class NotificationMigration2(modelClass: Class<NotificationModel>) :
AlterTableMigration<NotificationModel>(modelClass) {
override fun onPreMigrate() {
super.onPreMigrate()
addColumn(SQLiteType.INTEGER, "epochIm")
L.d { "Added column" }
}
}
@Table(
database = NotificationDb::class,
allFields = true,
primaryKeyConflict = ConflictAction.REPLACE
)
data class NotificationModel(
@PrimaryKey var id: Long = -1L,
var epoch: Long = -1L,
var epochIm: Long = -1L
) : BaseModel()
internal fun lastNotificationTime(id: Long): NotificationModel =
(select from NotificationModel::class where (NotificationModel_Table.id eq id)).querySingle()
?: NotificationModel(id = id)

View File

@ -19,7 +19,7 @@ package com.pitchedapps.frost.debugger
import ca.allanwang.kau.logging.KauLoggerExtension
import ca.allanwang.kau.utils.copyFromInputStream
import com.pitchedapps.frost.facebook.FB_CSS_URL_MATCHER
import com.pitchedapps.frost.facebook.USER_AGENT_DESKTOP
import com.pitchedapps.frost.facebook.USER_AGENT
import com.pitchedapps.frost.facebook.get
import com.pitchedapps.frost.facebook.requests.call
import com.pitchedapps.frost.utils.createFreshDir
@ -59,7 +59,7 @@ class OfflineWebsite(
* Directory that holds all the files
*/
val baseDir: File,
private val userAgent: String = USER_AGENT_DESKTOP
private val userAgent: String = USER_AGENT
) {
/**

View File

@ -28,6 +28,13 @@ fun profilePictureUrl(id: Long) = "https://graph.facebook.com/$id/picture?type=l
const val FB_LOGIN_URL = "${FB_URL_BASE}login"
const val FB_HOME_URL = "${FB_URL_BASE}home.php"
/*
* User agent candidates.
* For those building from source, you can feel free to set the used agent to one of these options.
* Following https://github.com/AllanWang/Frost-for-Facebook/pull/1531, we do not support multiple
* agents per login session.
*/
// Default user agent
private const val USER_AGENT_MOBILE_CONST =
"Mozilla/5.0 (Linux; Android 8.0.0; ONEPLUS A3000) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.90 Mobile Safari/537.36"
@ -35,8 +42,7 @@ private const val USER_AGENT_MOBILE_CONST =
private const val USER_AGENT_DESKTOP_CONST =
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.90 Safari/537.36"
const val USER_AGENT_MOBILE = USER_AGENT_DESKTOP_CONST
const val USER_AGENT_DESKTOP = USER_AGENT_DESKTOP_CONST
const val USER_AGENT = USER_AGENT_DESKTOP_CONST
/**
* Animation transition delay, just to ensure that the styles

View File

@ -137,7 +137,20 @@ class FbUrlFormatter(url: String) {
*
* acontext is not required for "friends interested in" notifications
*/
val discardableQueries = arrayOf("ref", "refid", "SharedWith", "fbclid")
val discardableQueries = arrayOf(
"ref",
"refid",
"SharedWith",
"fbclid",
"_ft_",
"_tn_",
"_xt_",
"bacr",
"frefs",
"hc_ref",
"loc_ref",
"pn_ref"
)
val converter = listOf(
"\\3C " to "%3C", "\\3E " to "%3E", "\\23 " to "%23", "\\25 " to "%25",

View File

@ -22,7 +22,7 @@ import com.pitchedapps.frost.facebook.FB_JSON_URL_MATCHER
import com.pitchedapps.frost.facebook.FB_REV_MATCHER
import com.pitchedapps.frost.facebook.FB_URL_BASE
import com.pitchedapps.frost.facebook.FB_USER_MATCHER
import com.pitchedapps.frost.facebook.USER_AGENT_DESKTOP
import com.pitchedapps.frost.facebook.USER_AGENT
import com.pitchedapps.frost.facebook.get
import com.pitchedapps.frost.kotlin.Flyweight
import com.pitchedapps.frost.utils.L
@ -97,7 +97,7 @@ internal fun List<Pair<String, Any?>>.withEmptyData(vararg key: String): List<Pa
internal fun String?.requestBuilder(): Request.Builder {
val builder = Request.Builder()
.header("User-Agent", USER_AGENT_DESKTOP)
.header("User-Agent", USER_AGENT)
if (this != null)
builder.header("Cookie", this)
// .cacheControl(CacheControl.FORCE_NETWORK)

View File

@ -67,7 +67,7 @@ abstract class BaseFragment : Fragment(), CoroutineScope, FragmentContract, Dyna
data: FbItem,
position: Int
): BaseFragment {
val fragment = if (useFallback || Prefs.webOnly) WebFragment() else base()
val fragment = if (useFallback || !Prefs.nativeUi) WebFragment() else base()
val d = if (data == FbItem.FEED) FeedSort(Prefs.feedSort).item else data
fragment.withArguments(
ARG_URL to d.url,

View File

@ -144,7 +144,6 @@ enum class NotificationType(
if (notifContents.isEmpty()) return 0
val userId = data.id
// Legacy, remove with dbflow
val prevLatestEpoch = notifDao.latestEpoch(userId, channelId)
L.v { "Notif $name prev epoch $prevLatestEpoch" }

View File

@ -163,8 +163,8 @@ class FrostRequestService : BaseJobService() {
override fun onStartJob(params: JobParameters?): Boolean {
super.onStartJob(params)
if (Prefs.webOnly) {
L.i { "Web only; skipping request service" }
if (!Prefs.authRequests) {
L.i { "Auth requests disabled; skipping request service" }
return false
}
val bundle = params?.extras

View File

@ -72,10 +72,6 @@ class NotificationService : BaseJobService() {
override fun onStartJob(params: JobParameters?): Boolean {
super.onStartJob(params)
L.i { "Fetching notifications" }
if (Prefs.webOnly) {
L.i { "Web only mode; skipping notification service" }
return false
}
launch {
try {
sendNotifications(params)

View File

@ -79,6 +79,13 @@ fun SettingsActivity.getBehaviourPrefs(): KPrefAdapterBuilder.() -> Unit = {
}
}
checkbox(R.string.native_ui, Prefs::nativeUi, {
Prefs.nativeUi = it
shouldRestartMain()
}) {
descRes = R.string.native_ui_desc
}
checkbox(R.string.exit_confirmation, Prefs::exitConfirmation, { Prefs.exitConfirmation = it }) {
descRes = R.string.exit_confirmation_desc
}

View File

@ -23,7 +23,6 @@ import com.pitchedapps.frost.R
import com.pitchedapps.frost.activities.SettingsActivity
import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.REQUEST_RESTART_APPLICATION
import com.pitchedapps.frost.utils.Showcase
/**
* Created by Allan Wang on 2017-06-29.
@ -34,20 +33,10 @@ fun SettingsActivity.getExperimentalPrefs(): KPrefAdapterBuilder.() -> Unit = {
descRes = R.string.experimental_disclaimer_info
}
checkbox(
R.string.experimental_by_default,
Showcase::experimentalDefault,
{ Showcase.experimentalDefault = it }) {
descRes = R.string.experimental_by_default_desc
}
// Experimental content starts here ------------------
checkbox(R.string.web_only, Prefs::webOnly, {
Prefs.webOnly = it
shouldRestartMain()
}) {
descRes = R.string.web_only_desc
checkbox(R.string.auth_requests, Prefs::authRequests, { Prefs.authRequests = it }) {
descRes = R.string.auth_requests_desc
}
// Experimental content ends here --------------------

View File

@ -22,7 +22,6 @@ import android.media.RingtoneManager
import android.os.Build
import android.provider.Settings
import ca.allanwang.kau.kpref.activity.KPrefAdapterBuilder
import ca.allanwang.kau.kpref.activity.KPrefItemActions
import ca.allanwang.kau.kpref.activity.items.KPrefText
import ca.allanwang.kau.utils.materialDialog
import ca.allanwang.kau.utils.minuteToText
@ -48,25 +47,11 @@ import kotlinx.coroutines.launch
*/
val Prefs.hasNotifications: Boolean
get() = !webOnly && (notificationsGeneral || notificationsInstantMessages)
get() = notificationsGeneral || notificationsInstantMessages
@SuppressLint("InlinedApi")
fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
fun KPrefItemActions.leaveWebOnlyDialog() {
if (Prefs.webOnly) {
materialDialog {
title(R.string.leave_web_only_title)
message(R.string.leave_web_only_desc)
positiveButton(R.string.kau_yes) {
Prefs.webOnly = false
reload()
}
negativeButton(R.string.kau_no)
}
}
}
text(
R.string.notification_frequency,
Prefs::notificationFreq,
@ -86,9 +71,6 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
}
}
}
onDisabledClick = {
leaveWebOnlyDialog()
}
enabler = { Prefs.hasNotifications }
textGetter = { minuteToText(it) }
}
@ -114,19 +96,12 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
reloadByTitle(R.string.notification_frequency)
}) {
descRes = R.string.notification_general_desc
enabler = { !Prefs.webOnly }
onDisabledClick = {
leaveWebOnlyDialog()
}
}
checkbox(R.string.notification_general_all_accounts, Prefs::notificationAllAccounts,
{ Prefs.notificationAllAccounts = it }) {
descRes = R.string.notification_general_all_accounts_desc
enabler = { !Prefs.webOnly && Prefs.notificationsGeneral }
onDisabledClick = {
leaveWebOnlyDialog()
}
enabler = { Prefs.notificationsGeneral }
}
checkbox(R.string.notification_messages, Prefs::notificationsInstantMessages,
@ -137,19 +112,12 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = {
reloadByTitle(R.string.notification_frequency)
}) {
descRes = R.string.notification_messages_desc
enabler = { !Prefs.webOnly }
onDisabledClick = {
leaveWebOnlyDialog()
}
}
checkbox(R.string.notification_messages_all_accounts, Prefs::notificationsImAllAccounts,
{ Prefs.notificationsImAllAccounts = it }) {
descRes = R.string.notification_messages_all_accounts_desc
enabler = { !Prefs.webOnly && Prefs.notificationsInstantMessages }
onDisabledClick = {
leaveWebOnlyDialog()
}
enabler = { Prefs.notificationsInstantMessages }
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

View File

@ -31,7 +31,7 @@ import ca.allanwang.kau.utils.string
import ca.allanwang.kau.utils.toast
import com.pitchedapps.frost.R
import com.pitchedapps.frost.db.CookieEntity
import com.pitchedapps.frost.facebook.USER_AGENT_DESKTOP
import com.pitchedapps.frost.facebook.USER_AGENT
/**
* Created by Allan Wang on 2017-08-04.
@ -41,7 +41,7 @@ import com.pitchedapps.frost.facebook.USER_AGENT_DESKTOP
fun Context.frostDownload(
cookie: CookieEntity,
url: String?,
userAgent: String = USER_AGENT_DESKTOP,
userAgent: String = USER_AGENT,
contentDisposition: String? = null,
mimeType: String? = null,
contentLength: Long = 0L
@ -53,7 +53,7 @@ fun Context.frostDownload(
fun Context.frostDownload(
cookie: CookieEntity,
uri: Uri?,
userAgent: String = USER_AGENT_DESKTOP,
userAgent: String = USER_AGENT,
contentDisposition: String? = null,
mimeType: String? = null,
contentLength: Long = 0L

View File

@ -191,7 +191,9 @@ object Prefs : KPref() {
var showCreateFab: Boolean by kpref("show_create_fab", true)
var webOnly: Boolean by kpref("web_only", false)
var authRequests: Boolean by kpref("web_requests", false)
var nativeUi: Boolean by kpref("native_ui", true)
inline val mainActivityLayout: MainActivityLayout
get() = MainActivityLayout(mainActivityLayoutType)

View File

@ -30,8 +30,5 @@ object Showcase : KPref() {
val intro: Boolean by kprefSingle("intro_pages")
//not a showcase but cannot be in the same file as Prefs
var experimentalDefault: Boolean by kpref("experimental_by_default", false)
override fun deleteKeys() = arrayOf("shown_release")
override fun deleteKeys() = arrayOf("shown_release", "experimental_by_default")
}

View File

@ -57,14 +57,13 @@ import com.pitchedapps.frost.activities.SettingsActivity
import com.pitchedapps.frost.activities.TabCustomizerActivity
import com.pitchedapps.frost.activities.WebOverlayActivity
import com.pitchedapps.frost.activities.WebOverlayActivityBase
import com.pitchedapps.frost.activities.WebOverlayDesktopActivity
import com.pitchedapps.frost.db.CookieEntity
import com.pitchedapps.frost.facebook.FACEBOOK_COM
import com.pitchedapps.frost.facebook.FBCDN_NET
import com.pitchedapps.frost.facebook.FbCookie
import com.pitchedapps.frost.facebook.FbItem
import com.pitchedapps.frost.facebook.FbUrlFormatter.Companion.VIDEO_REDIRECT
import com.pitchedapps.frost.facebook.USER_AGENT_DESKTOP
import com.pitchedapps.frost.facebook.USER_AGENT
import com.pitchedapps.frost.facebook.formattedFbUri
import com.pitchedapps.frost.facebook.formattedFbUrl
import com.pitchedapps.frost.injectors.CssAssets
@ -75,6 +74,7 @@ import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import org.apache.commons.text.StringEscapeUtils
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import java.io.File
import java.io.IOException
@ -138,9 +138,6 @@ private inline fun <reified T : WebOverlayActivityBase> Context.launchWebOverlay
fun Context.launchWebOverlay(url: String) = launchWebOverlayImpl<WebOverlayActivity>(url)
fun Context.launchWebOverlayDesktop(url: String) =
launchWebOverlayImpl<WebOverlayDesktopActivity>(url)
private fun Context.fadeBundle() = ActivityOptions.makeCustomAnimation(
this,
android.R.anim.fade_in, android.R.anim.fade_out
@ -392,13 +389,13 @@ fun EmailBuilder.addFrostDetails() {
addItem("Locale", Locale.getDefault().displayName)
}
fun frostJsoup(url: String) = frostJsoup(FbCookie.webCookie, url)
fun frostJsoup(url: String): Document = frostJsoup(FbCookie.webCookie, url)
fun frostJsoup(cookie: String?, url: String) =
fun frostJsoup(cookie: String?, url: String): Document =
Jsoup.connect(url).run {
if (cookie.isNullOrBlank()) this
else cookie(FACEBOOK_COM, cookie)
}.userAgent(USER_AGENT_DESKTOP).get()!!
}.userAgent(USER_AGENT).get()
fun Element.first(vararg select: String): Element? {
select.forEach {

View File

@ -31,9 +31,7 @@ import com.pitchedapps.frost.contracts.FrostContentParent
import com.pitchedapps.frost.db.FrostDatabase
import com.pitchedapps.frost.db.currentCookie
import com.pitchedapps.frost.facebook.FB_HOME_URL
import com.pitchedapps.frost.facebook.FbItem
import com.pitchedapps.frost.facebook.USER_AGENT_DESKTOP
import com.pitchedapps.frost.facebook.USER_AGENT_MOBILE
import com.pitchedapps.frost.facebook.USER_AGENT
import com.pitchedapps.frost.fragments.WebFragment
import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.ctxCoroutine
@ -42,7 +40,6 @@ import com.pitchedapps.frost.web.FrostChromeClient
import com.pitchedapps.frost.web.FrostJSI
import com.pitchedapps.frost.web.FrostWebViewClient
import com.pitchedapps.frost.web.NestedWebView
import com.pitchedapps.frost.web.shouldUseDesktopAgent
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min
@ -72,9 +69,7 @@ class FrostWebView @JvmOverloads constructor(
@SuppressLint("SetJavaScriptEnabled")
override fun bind(container: FrostContentContainer): View {
userAgentString =
if (parent.baseEnum == FbItem.MESSAGES || parent.baseUrl.shouldUseDesktopAgent) USER_AGENT_DESKTOP
else USER_AGENT_MOBILE
userAgentString = USER_AGENT
with(settings) {
javaScriptEnabled = true
mediaPlaybackRequiresUserGesture = false // TODO check if we need this

View File

@ -24,7 +24,7 @@ import android.util.AttributeSet
import android.view.View
import android.webkit.WebView
import ca.allanwang.kau.utils.withAlpha
import com.pitchedapps.frost.facebook.USER_AGENT_MOBILE
import com.pitchedapps.frost.facebook.USER_AGENT
import com.pitchedapps.frost.injectors.CssHider
import com.pitchedapps.frost.injectors.jsInject
import com.pitchedapps.frost.utils.L
@ -55,7 +55,7 @@ class DebugWebView @JvmOverloads constructor(
@SuppressLint("SetJavaScriptEnabled")
private fun setupWebview() {
settings.javaScriptEnabled = true
settings.userAgentString = USER_AGENT_MOBILE
settings.userAgentString = USER_AGENT
setLayerType(View.LAYER_TYPE_HARDWARE, null)
webViewClient = DebugClient()
@Suppress("DEPRECATION")

View File

@ -22,7 +22,6 @@ import com.pitchedapps.frost.activities.WebOverlayActivityBase
import com.pitchedapps.frost.contracts.VideoViewHolder
import com.pitchedapps.frost.facebook.FbCookie
import com.pitchedapps.frost.facebook.FbItem
import com.pitchedapps.frost.facebook.USER_AGENT_DESKTOP
import com.pitchedapps.frost.facebook.formattedFbUrl
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.Prefs
@ -32,7 +31,6 @@ import com.pitchedapps.frost.utils.isIndirectImageUrl
import com.pitchedapps.frost.utils.isVideoUrl
import com.pitchedapps.frost.utils.launchImageActivity
import com.pitchedapps.frost.utils.launchWebOverlay
import com.pitchedapps.frost.utils.launchWebOverlayDesktop
import com.pitchedapps.frost.views.FrostWebView
/**
@ -74,22 +72,7 @@ fun FrostWebView.requestWebOverlay(url: String): Boolean {
return false
}
if (!Prefs.overlayEnabled) return false
if (context is WebOverlayActivityBase) {
val shouldUseDesktop = url.formattedFbUrl.shouldUseDesktopAgent
//already overlay; manage user agent
if (userAgentString != USER_AGENT_DESKTOP && shouldUseDesktop) {
L._i { "Switch to desktop agent overlay" }
context.launchWebOverlayDesktop(url)
return true
}
if (userAgentString == USER_AGENT_DESKTOP && !shouldUseDesktop) {
L._i { "Switch from desktop agent" }
context.launchWebOverlay(url)
return true
}
L._i { "return false switch" }
return false
}
if (context is WebOverlayActivityBase) return false
L.v { "Request web overlay passed" }
context.launchWebOverlay(url)
return true
@ -102,6 +85,7 @@ val messageWhitelist: Set<String> =
setOf(FbItem.MESSAGES, FbItem.CHAT, FbItem.FEED_MOST_RECENT, FbItem.FEED_TOP_STORIES)
.mapTo(mutableSetOf(), FbItem::url)
@Deprecated(message = "Should not be used in production as we only support one user agent at a time.")
val String.shouldUseDesktopAgent: Boolean
get() = when {
contains("story.php") -> false // do not use desktop for comment section

View File

@ -33,7 +33,7 @@ import com.pitchedapps.frost.db.CookieEntity
import com.pitchedapps.frost.facebook.FB_LOGIN_URL
import com.pitchedapps.frost.facebook.FB_USER_MATCHER
import com.pitchedapps.frost.facebook.FbCookie
import com.pitchedapps.frost.facebook.USER_AGENT_MOBILE
import com.pitchedapps.frost.facebook.USER_AGENT
import com.pitchedapps.frost.facebook.get
import com.pitchedapps.frost.injectors.CssHider
import com.pitchedapps.frost.injectors.jsInject
@ -58,7 +58,7 @@ class LoginWebView @JvmOverloads constructor(
@SuppressLint("SetJavaScriptEnabled")
private fun setupWebview() {
settings.javaScriptEnabled = true
settings.userAgentString = USER_AGENT_MOBILE
settings.userAgentString = USER_AGENT
setLayerType(View.LAYER_TYPE_HARDWARE, null)
webViewClient = LoginClient()
webChromeClient = LoginChromeClient()

View File

@ -1,10 +1,3 @@
v2.3.2
v2.4.0
* Disable auto feed refresh by default and add setting to re-enable it
* Update theme
* Disable bugsnag completely when opting out of analytics
* Filter urls before sending to other apps
* Allow hiding main fab (see settings > newsfeed)
* Add some experimental options to debug login problems (settings > experimental)
* Enforce desktop user agent for now
* Obfuscate js tags
* Removed web only mode for auth requests. Marking notifications as read is now disabled by default to deal with phishing accusations.

View File

@ -2,8 +2,6 @@
<!--Generated by crowdin.com-->
<resources>
<string name="experimental_disclaimer_info">الميزات التجريبية قد تكون غير مستقرة، وقد لا تصل إلى الإنتاج. استخدمها على مسؤوليتك الخاصة وإرسل ردود الفعل، ولا تتردد في تعطيلها إذا كانت لا تعمل بشكل جيد.</string>
<string name="experimental_by_default">التجريبي بشكل افتراضي</string>
<string name="experimental_by_default_desc">هل تشعر بالخطر أو تريد فقط المساعدة في تصحيح الأخطاء؟ سيؤدي التحقق من ذلك إلى تمكين الوظائف التجريبية المستقبلية بشكل افتراضي.</string>
<string name="verbose_logging">التسجيل المطول</string>
<string name="verbose_logging_desc">تمكين خاصية التسجيل المطول للمساعدة في تقارير الأعطال. سترسل التسجيلات فقط عند حدوث أخطاء، لهذا كرر الخطأ لإخطار المطور. سيتم تلقائياً تعطيلها إذا تمت إعادة تشغيل التطبيق.</string>
<string name="restart_frost">إعادة تشغيل Frost</string>

View File

@ -2,8 +2,6 @@
<!--Generated by crowdin.com-->
<resources>
<string name="experimental_disclaimer_info">Experimentální nastavení mohou způsobovat problémy a být bez varování odstraněna. Povolte je jen na vlastní nebezpečí a dejte vědět vývojářům jak fungují.</string>
<string name="experimental_by_default">Povolit experimentální nastavení ve výchozím režimu</string>
<string name="experimental_by_default_desc">Chcete pomoct vývojářům s laděním? Povolit všechna, i budoucí experimentální nastavení.</string>
<string name="verbose_logging">Rozšířené logování</string>
<string name="verbose_logging_desc">Povolit detailní protokolování v hlášeních o pádu aplikace. Pošle vývojářům hlášení chyby při jejím výskytu. Toto nastavení se automaticky vypne při restartu aplikace.</string>
<string name="restart_frost">Restartovat Frost</string>

View File

@ -2,8 +2,6 @@
<!--Generated by crowdin.com-->
<resources>
<string name="experimental_disclaimer_info">Eksperimentelle funktioner kan være ustabile og bliver muligvis aldrig sat i produktion. Brug foregår på eget ansvar, send feedback og deaktivér dem endelig, hvis de ikke fungerer godt.</string>
<string name="experimental_by_default">Eksperimentel som standard</string>
<string name="experimental_by_default_desc">Føler du dig dristig eller vil du bare gerne hjælpe med fejlfinding? Aktivér denne for automatisk at bruge alle fremtidige eksperimentelle funktioner som standard.</string>
<string name="verbose_logging">Detaljeret logføring</string>
<string name="verbose_logging_desc">Aktivér detaljeret logføring for at hjælpe med nedbrudsrapporter. Log-filer vil kun blive sent ved fejl, så gentag den fejlen for at underrette udvikleren. Dette bliver automatisk deaktiveret, når app\'en genstartes.</string>
<string name="restart_frost">Genstart Frost</string>

View File

@ -2,8 +2,6 @@
<!--Generated by crowdin.com-->
<resources>
<string name="experimental_disclaimer_info">Experimentelle Funktionen sind möglicherweise instabil und schaffen es eventuell nie in die App. Auf eigenes Risiko verwenden! Senden Sie Ihr Feedback und zögern Sie nicht, diese zu deaktivieren, wenn sie nicht gut funktionieren.</string>
<string name="experimental_by_default">Standartmäßig Experimentell</string>
<string name="experimental_by_default_desc">Sie fühlen sich mutig oder wollen einfach helfen bei der Fehlersuche? Beim Aktivieren dieser Option werden zukünftige, experimentelle Funktionen standardmäßig eingeschaltet.</string>
<string name="verbose_logging">Ausführliche Protokollierung</string>
<string name="verbose_logging_desc">Aktivieren Sie die ausführliche Protokollierung um bei Crash-Berichten zu helfen. Die Protokollierung wird erst dann gesendet, wenn ein Fehler auftritt. Wiederhole das Problem um den Entwickler zu Informieren. Dies wird automatisch deaktiviert, wenn die App neustartet.</string>
<string name="restart_frost">Starte Frost neu</string>

View File

@ -2,8 +2,6 @@
<!--Generated by crowdin.com-->
<resources>
<string name="experimental_disclaimer_info">Las características experimentales pueden ser inestables y nunca entrar en vigencia. Úsalas bajo tu propio riesgo. Envía un informe y no dudes en desactivarlas si no funcionan correctamente.</string>
<string name="experimental_by_default">Experimental por Defecto</string>
<string name="experimental_by_default_desc">¿Notas algún error o deseas ayudar a depurar? Las futuras funciones experimentales se habilitarán por defecto.</string>
<string name="verbose_logging">Registro detallado</string>
<string name="verbose_logging_desc">Habilita los registros detallados para ayudar con los informes de errores. El registro sólo será enviado una vez se detecte el error, debes repetir el fallo para notificar al desarrollador. Esta función quedará desactivada una vez se reinicie la app.</string>
<string name="restart_frost">Reiniciar Frost</string>

View File

@ -2,8 +2,6 @@
<!--Generated by crowdin.com-->
<resources>
<string name="experimental_disclaimer_info">Les fonctionnalités expérimentales peuvent être instables et peuvent ne jamais se rendre à la production. Utiliser à vos risques et périls, envoyer vos commentaires et nhésitez pas à les désactiver si elles ne fonctionnent pas bien.</string>
<string name="experimental_by_default">Expérimentale par défaut</string>
<string name="experimental_by_default_desc">Vous vous sentez risqué ou vous souhaitez simplement aider avec le débogage? Cocher ceci permettra aux futures fonctions expérimentales d\'être activées par défaut.</string>
<string name="verbose_logging">Logs détaillés</string>
<string name="verbose_logging_desc">Activer les logs détaillés pour aider avec les rapports d\'incidents. Les logs seront seulement envoyés lorsqu\'un erreur est rencontré, alors répétez le problème pour aviser le développeur. Ceci sera automatiquement désactivé si l\'application redémarre.</string>
<string name="restart_frost">Redémarrer Frost</string>

View File

@ -2,8 +2,6 @@
<!--Generated by crowdin.com-->
<resources>
<string name="experimental_disclaimer_info">As funcionalidades en proba ou experimentais poden resultar inestables e mesmo poden non funcionar. Utilízaas baixo a túa responsabilidade, envíanos comentarios acerca delas e sempre poderás deshabilitalas se non funcionan ben.</string>
<string name="experimental_by_default">Experimentar predefinido</string>
<string name="experimental_by_default_desc">Gústache o risco ou simplemente é que queres axudar coa depuración? Ao marcares esta opción, as funcionalidades experimentais activaranse por defecto.</string>
<string name="verbose_logging">Rexistros detallados</string>
<string name="verbose_logging_desc">Activa os rexistros detallados o cal resultará de axuda cos informes de erros. Os informes enviaranse de cada vez que se atope un erro, de modo que ao se repetir o problema notificarase ao desenvolvedor. Esta función quedará deshabilitada unha vez que se reinicie a aplicación.</string>
<string name="restart_frost">Reiniciar Frost</string>

View File

@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="experimental_disclaimer_info">Πειραματικά χαρακτηριστικά μπορεί να είναι ασταθή και να μην ολοκληρωθούν ποτέ. Χρησιμοποιήστε τα με δικό σας ρίσκο, αποστείλτε δεδομένα ανάδρασης , και μην διστάσετε να τα απενεργοποιήσετε αν δεν λειτουργούν σωστά.</string>
<string name="experimental_by_default">Προκαθορισμένα Πειραματικό</string>
<string name="experimental_by_default_desc">Νιώθετε ρισκαδόροι ή απλά θέλετε να βοηθήσετε με τη διόρθωση σφαλμάτων; Ελέγχοντας το αυτό θα οδηγήσει μελλοντικές πειραματικές λειτουργίες να είναι προκαθορισμένες.</string>
<string name="verbose_logging">Σύνθετη Καταγραφή</string>
<string name="verbose_logging_desc">Ενεργοποίησε την Σύνθετη Καταγραφή για να βοηθήσεις σε αναφορές σφαλμάτων. Η Καταγραφή θα αποσταλλεί μόνο όταν προκύψει ένα σφάλμα, οπότε ενεργοποιήστε την για να ενημερώνετε τον προγραμματιστή. Αυτόματα θα απενεργοποιηθεί όταν η εφαρμογή επανεκκινηθεί.</string>

View File

@ -2,8 +2,6 @@
<!--Generated by crowdin.com-->
<resources>
<string name="experimental_disclaimer_info">A kísérleti funkciók instabilak lehetnek, és talán sosem kerülnek forgalomba. Használd saját felelősségre, küldj visszajelzést, és nyugodtan tiltsd le őket, ha nem működnek jól.</string>
<string name="experimental_by_default">Kísérletek alapértelmezetten</string>
<string name="experimental_by_default_desc">Szereted a kockázatot, vagy csak segítenél a hibák elhárításában? Ezt bekapcsolva a jövőbeli kísérleti funkciók is engedélyezve lesznek.</string>
<string name="verbose_logging">Verbose Logging</string>
<string name="verbose_logging_desc">Részletes naplózás engedélyezése a hibajelentések segítésére. A napló csak akkor lesz elküldve, ha hiba lép fel, ezért ismételd meg a problémát, hogy értesítsd a fejlesztőt. Ez automatikusan le lesz tiltva, ha az alkalmazás újraindul.</string>
<string name="restart_frost">Frost újraindítása</string>

View File

@ -2,8 +2,6 @@
<!--Generated by crowdin.com-->
<resources>
<string name="experimental_disclaimer_info">Fitur eksperimental mungkin tidak stabil dan mungkin tidak pernah sampai ke produksi. Gunakan dengan resiko Anda sendiri, kirim umpan balik, dan jangan ragu untuk menonaktifkan jika tidak bekerja dengan baik.</string>
<string name="experimental_by_default">Eksperimental secara standar</string>
<string name="experimental_by_default_desc">Merasa berisiko atau hanya ingin membantu kesalahan? Memeriksa ini akan mengaktifkan fungsi eksperimental masa depan menjadi standar.</string>
<string name="verbose_logging">Mencatat banyak kata</string>
<string name="verbose_logging_desc">Aktifkan mencatat banyak kata untuk membantu laporan kerusakan. Pencatatan hanya akan dikirim setelah terjadi kesalahan, jadi ulangi masalahnya untuk memberitahukan dev. Ini akan secara otomatis dinonaktifkan jika mengulang kembali aplikasi.</string>
<string name="restart_frost">Mengulang kembali Frost</string>

View File

@ -2,8 +2,6 @@
<!--Generated by crowdin.com-->
<resources>
<string name="experimental_disclaimer_info">Le funzioni sperimentali potrebbero essere instabili e potrebbero non arrivare mai al rilascio. Usale a tuo rischio e pericolo, manda il tuo feedback e sentiti libero di disabilitarle se non funzionano bene.</string>
<string name="experimental_by_default">Funzioni Sperimentali di Default</string>
<string name="experimental_by_default_desc">Ti senti temerario o vuoi solo aiutarci con il debugging? Attivandolo abiliterai le funzioni sperimentali di default.</string>
<string name="verbose_logging">Log Dettagliati</string>
<string name="verbose_logging_desc">Abilita log dettagliati per aiutare con il rapporto dei crash. Il log verrà mandato solamente quando verrà riscontrato un errore, quindi ricrea la situazione per notificare gli sviluppatori. Verrà automaticamente disattivato se si riavvia l\'applicazione.</string>
<string name="restart_frost">Riavvia Frost</string>

View File

@ -2,8 +2,6 @@
<!--Generated by crowdin.com-->
<resources>
<string name="experimental_disclaimer_info">실험적 기능은 불안정하거나 출시로 이어지지 않을 수 있습니다. 이를 사용함으로써 발생하는 일의 책임은 당신에게 있으며, 피드백을 보내시거나 제대로 작동하지 않으면 비활성화 하시기 바랍니다.</string>
<string name="experimental_by_default">실험적 기능 항상 사용</string>
<string name="experimental_by_default_desc">위험을 감수하거나 디버그에 도움을 주고 싶나요? 이를 활성화하면 앞으로도 기본적으로 실험적 기능이 활성화 됩니다.</string>
<string name="verbose_logging">자세한 로그</string>
<string name="verbose_logging_desc">충돌 보고서에 도움을 주기 위해 자세한 로그를 켭니다. 로그는 에러가 발생했을 때 한번만 보내지며, 문제를 개발자에게 알리려면 문제를 재현하세요. 앱이 재시작되면 이 옵션은 자동으로 꺼집니다.</string>
<string name="restart_frost">Frost 재시작</string>

View File

@ -2,8 +2,6 @@
<!--Generated by crowdin.com-->
<resources>
<string name="experimental_disclaimer_info">Experimentele functies kunnen instabiliteit veroorzaken en zullen mogelijk nooit volledig worden geïmplementeerd. Gebruik de functies op eigen verantwoordelijkheid, stuur feedback en wees vrij om ze uit te schakelen bij problemen.</string>
<string name="experimental_by_default">Experimentele functies standaard inschakelen</string>
<string name="experimental_by_default_desc">Wees een waaghals en activeer nieuwe experimentele functies automatisch.</string>
<string name="verbose_logging">Uitgebreide logging</string>
<string name="verbose_logging_desc">Schakel uitgebreide logging in om te helpen met crashrapporten. Logs worden alleen doorgestuurd bij fouten, dus herhaal de stappen die het probleem veroorzaken om de ontwikkelaar op de hoogte te brengen. Deze optie wordt automatisch uitgeschakeld bij een herstart van de app.</string>
<string name="restart_frost">Frost herstarten</string>

View File

@ -2,8 +2,6 @@
<!--Generated by crowdin.com-->
<resources>
<string name="experimental_disclaimer_info">Eksperimentelle funksjonene kan være ustabile. Bruk på eget ansvar og du må gjerne deaktivere dem om de ikke fungerer.</string>
<string name="experimental_by_default">Eksperimentell som standard</string>
<string name="experimental_by_default_desc">Føles det risikabelt eller bare ønsker å hjelpe til med feilsøking? Å velge dette vil aktivere fremtidige eksperimentelle funksjonene som standard.</string>
<string name="verbose_logging">Detaljert logging</string>
<string name="verbose_logging_desc">Aktiver detaljert logging for å hjelpe med feilrapporter. Logging sendes bare når en feil oppstår, så fremtving feil for å varsle utvikler. Dette vil automatisk bli deaktivert hvis programmet startes på nytt.</string>
<string name="restart_frost">Start Frost på nytt</string>

View File

@ -2,8 +2,6 @@
<!--Generated by crowdin.com-->
<resources>
<string name="experimental_disclaimer_info">Funkcje eksperymentalne mogą być niestabilne i mogą nigdy nie być wprowadzone. Używaj na własne ryzyko, wyślij opinię i wyłącz je jeśli nie działają dobrze.</string>
<string name="experimental_by_default">Eksperymentalne domyślnie</string>
<string name="experimental_by_default_desc">Lubisz ryzyko lub po prostu chcesz pomóc z debugowaniem? Zaznaczenie tej opcji, będzie domyślnie włączać eksperymentalne funkcje.</string>
<string name="verbose_logging">Pełne zbieranie logów</string>
<string name="verbose_logging_desc">Włącz pełne zbieranie logów żeby pomóc z raportami o awariach. Logi będą wysłane tylko kiedy błąd wystąpi, więc odtwórz problem, aby powiadomić dewelopera. Ta opcja zostanie automatycznie wyłączona po restarcie aplikacji.</string>
<string name="restart_frost">Uruchom ponownie Frost</string>

View File

@ -2,8 +2,6 @@
<!--Generated by crowdin.com-->
<resources>
<string name="experimental_disclaimer_info">As funções experimentais podem ser instáveis e podem não funcionar. Use a seu próprio risco, envie comentários e sinta-se livre para desativá-los se eles não funcionarem bem.</string>
<string name="experimental_by_default">Experimental por Padrão</string>
<string name="experimental_by_default_desc">Deseja arriscar-se ou simplesmente quer ajudar com a depuração? Ativando isso, as futuras funções experimentais serão ativadas como padrão.</string>
<string name="verbose_logging">Relatório Detalhado</string>
<string name="verbose_logging_desc">Habilite o relatório detalhado para ajudar com relatórios de falhas. O relatório só será enviado quando um erro for encontrado, então repita o problema para notificar o desenvolvedor. Isso será automaticamente desabilitado se o aplicativo for reiniciado.</string>
<string name="restart_frost">Reiniciar o Frost</string>

View File

@ -2,8 +2,6 @@
<!--Generated by crowdin.com-->
<resources>
<string name="experimental_disclaimer_info">As funcionalidades experimentais podem ser instáveis e podem nem sequer ser incluídas na versão final. Utilize-as por sua conta e risco e submeta os relatório com os erros encontrados. Pode desativar esta opção sempre que quiser.</string>
<string name="experimental_by_default">Experimental por defeito</string>
<string name="experimental_by_default_desc">Está a sentir-se com sorte ou apenas quer ajudar com a depuração? Tenha noção que com esta função permitirá que funções futuras experimentais sejam padrão.</string>
<string name="verbose_logging">Registo detalhado</string>
<string name="verbose_logging_desc">Ativar o registo detalhado para nos ajudar com os erros. Os registos apenas serão enviados se for encontrado um erro. Esta opção será desativada automaticamente se reiniciar a aplicação.</string>
<string name="restart_frost">Reiniciar</string>

View File

@ -2,8 +2,6 @@
<!--Generated by crowdin.com-->
<resources>
<string name="experimental_disclaimer_info">Caracteristici experimentale pot fi instabile. Folosește-le pe propriul tău risc, trimite feedback-ul şi nu ezita să le dezactivaţi dacă nu funcţionează bine.</string>
<string name="experimental_by_default">Experimental implicit</string>
<string name="experimental_by_default_desc">Esti aventuros sau doar vrei sa ajuți? Încearcând asta vei activa viitoare funcții experimentale în mod prestabilit.</string>
<string name="verbose_logging">Logări abuzive</string>
<string name="verbose_logging_desc">Activează logări repetate să ajuți cu report-uri ale erorilor. Logarile vor fi trimise când o eroare este prezentă, așadar repetă problema să anunți dezvoltatorii. Acesta va fi dezactivat când repornești.</string>
<string name="restart_frost">Reporniţi Frost</string>

View File

@ -2,8 +2,6 @@
<!--Generated by crowdin.com-->
<resources>
<string name="experimental_disclaimer_info">Экспериментальные функции может быть нестабильным и никогда не может сделать его в производство. Используйте на свой страх и риск, обратная связь и не стесняйтесь отключить их, если они не работают хорошо.</string>
<string name="experimental_by_default">Экспериментальный по умолчанию</string>
<string name="experimental_by_default_desc">Чувствуя рискованным или просто хотите, чтобы помочь с отладкой? Проверка, что это позволит будущим экспериментальные функции быть по умолчанию.</string>
<string name="verbose_logging">Подробная информация</string>
<string name="verbose_logging_desc">Включите ведение подробного журнала, чтобы помочь с падениях. Протоколирование будет отправлено только после того, как возникает ошибка, так повторить вопрос уведомления dev. Это будет автоматически отключается, если приложение перезапускается.</string>
<string name="restart_frost">Перезапустить Frost</string>

View File

@ -2,9 +2,6 @@
<!--Generated by crowdin.com-->
<resources>
<string name="experimental_disclaimer_info">Експерименталне функције су нестабилне и можда никада неће бити уврштене у апликацију. Користите на сопствени ризик, пошаљите рецензију, слободно их искључите уколико не функционишу како треба.</string>
<string name="experimental_by_default">Подразумевано коришћење експерименталних функција</string>
<string name="experimental_by_default_desc">Желите да помогнете у отклањању грешака?
Штиклирањем ове опције подесићете експерименталне функције као подразумеване.</string>
<string name="verbose_logging">Потпуна евиденција</string>
<string name="verbose_logging_desc">Укључите потпуну евиденцију и помозите нам у отклањању грешака. Евиденција ће бити послата само уколико дође до грешке, зато поновите грешку да би помогли програмерима. Оција ће бити искључена уколико се апликација рестартује.</string>
<string name="restart_frost">Рестартујте Фрост</string>

View File

@ -2,8 +2,6 @@
<!--Generated by crowdin.com-->
<resources>
<string name="experimental_disclaimer_info">Experimentella funktioner kan vara ostabila och kanske aldrig implementeras i slutprodukten. Använd dessa på egen risk, skicka feedback, och stäng gärna av dem om de inte fungerar bra.</string>
<string name="experimental_by_default">Experimentell som standard</string>
<string name="experimental_by_default_desc">Känner du dig riskfylld eller bara vill hjälpa till? Att markera den här kommer att aktivera alla framtida experimentella funktioner som standard.</string>
<string name="verbose_logging">Detaljerad loggning</string>
<string name="verbose_logging_desc">Aktivera utförlig loggning för att hjälpa till med felrapporter. Loggar skickas endast när ett fel påträffas, så upprepa problemet i appen för att skicka informationen till utvecklaren. Detta inaktiveras automatiskt om appen startas om.</string>
<string name="restart_frost">Starta om Frost</string>

View File

@ -2,8 +2,6 @@
<!--Generated by crowdin.com-->
<resources>
<string name="experimental_disclaimer_info">คุณสัมบัติทดลองอาจไม่เสถียนและอาจจะไม่ได้อยู่ถาวร ยอมรับความเสี่ยงเองถ้าคุณใช้มัน, ส่งข้อเสนอแนะ หรือ ปิดมันไปเลยก็ได้ถ้ามันไม่ทำงาน</string>
<string name="experimental_by_default">คุณสัมบัติทดลอง โดยค่าเริ่มต้น</string>
<string name="experimental_by_default_desc">ชอบความเสี่ยงหรือแค่อยากจะช่วยหาของข้อผิดพลาด? สามารถทำได้โดยการเปิด คุณสัมบัติทดลอง เป็นค่าเริ่มต้น</string>
<string name="verbose_logging">การบันทึกทั่วไป</string>
<string name="verbose_logging_desc">เปิดบันทิกทั่วไปและรายงานข้อผิดพลาด บันทึกจะส่งเมื่อเจอข้อผิดพลาด ดังนั้นกรุณาทำให้เกิดข้อผิดพลาดอีกครั้งนึง ตัวเลือกนี้จะปิดเองเมื่อแอพเริ่มต้นใหม่</string>
<string name="restart_frost">เริ่ม Frost ใหม่</string>

View File

@ -2,8 +2,6 @@
<!--Generated by crowdin.com-->
<resources>
<string name="experimental_disclaimer_info">Ang tampok na pageekspiremento ay hindi siguradong matatag at hindi kailanman ito gagawin sa produksyon. Gamitin sa iyong sariling kapahamakan, ipadala ang feedback, at malaya kang i-disable sila kapag hindi ito nagawa ng maayos.</string>
<string name="experimental_by_default">Ang pageekspiremento ayon sa Default</string>
<string name="experimental_by_default_desc">Ang pakiramdam na parang nasa pilegro o gusto lang tumulong sa pagdi-debug? Tignan kung ito ay naka-enable sa hinaharap na pageekspiremento at ang mga paggawa ay default.</string>
<string name="verbose_logging">Ang pagsasalita ay logging</string>
<string name="verbose_logging_desc">I-enable ang logging na pagsasalita para matulongan ang mga ulat pagbangga. Ang logging ay pinapadala lamang kapag may mali na naranasan, kaya ulitin ang isyu para masabihan ang taga-gawa. Ito ay awtomatikong idi-disable kapag ang aplikasyon ay nirestart.</string>
<string name="restart_frost">I-restart ang Frost</string>

View File

@ -2,8 +2,6 @@
<!--Generated by crowdin.com-->
<resources>
<string name="experimental_disclaimer_info">Deneysel özellikler dengesiz olabilir ve asla üretime neden olmayabilir. Kendi sorumluluğunuzdadır kullanın, geri bildirim gönderin ve iyi çalışmazlarsa onları devre dışı bırakmaktan çekinmeyin.</string>
<string name="experimental_by_default">Varsayılan deneysel</string>
<string name="experimental_by_default_desc">Hata ayıklamayla yardım etmek mi istiyorsunuz? Bunu kontrol ederseniz, gelecek deneysel işlevlerin varsayılan olmasını sağlayabilirsiniz.</string>
<string name="verbose_logging">Ayrıntılı günlüğe kaydetme</string>
<string name="verbose_logging_desc">Kilitlenme raporlarıyla yardımcı olmak için ayrıntılı günlüğü etkinleştirin. Günlüğe kaydetme yalnızca bir hata ile karşılaştığında gönderilir, bu nedenle devi bilgilendirmek için sorunu tekrarlayın. Uygulama yeniden başlatılırsa, bu otomatik olarak devre dışı bırakılacaktır.</string>
<string name="restart_frost">Frostu yeniden başlatın</string>

View File

@ -2,8 +2,6 @@
<!--Generated by crowdin.com-->
<resources>
<string name="experimental_disclaimer_info">Експериментальні функції можуть бути нестабільними і можуть ніколи не бути впроваджені. Використовуйте на свій страх і ризик, надішліть відгук і можете вимкнути їх, якщо вони не працюють добре.</string>
<string name="experimental_by_default">Експериментальний режим за замовчуванням</string>
<string name="experimental_by_default_desc">Почуваєшся ризиковано або просто хочеш допомогти з налагодженням? Перевірка цього параметра дозволить використовувати майбутні експериментальні функції за умовчанням.</string>
<string name="verbose_logging">Докладне ведення журналу</string>
<string name="verbose_logging_desc">Увімкнути докладне ведення журналу, щоб допомогти з повідомленнями про аварійне завершення роботи. Журнал буде відправлений тільки після виявлення помилки, тому повторіть цю проблему, щоб повідомити про це розробника. Це буде автоматично вимкнено, якщо додаток перезавантажиться.</string>
<string name="restart_frost">Перезавантажити Frost</string>

View File

@ -2,8 +2,6 @@
<!--Generated by crowdin.com-->
<resources>
<string name="experimental_disclaimer_info">Các tính năng thử nghiệm có thể không ổn định và có thể không bao giờ thành hiện thực. Bạn chấp nhận rủi ro khi dùng, hãy tắt nó đi nếu bạn thấy không hoạt động tốt.</string>
<string name="experimental_by_default">Thử nghiệm theo mặc định</string>
<string name="experimental_by_default_desc">Muốn thử hay chỉ đơn giản muốn giúp soát lỗi? Đánh dấu ở đây sẽ bật các tính năng thử nghiệm tương lai theo mặc định.</string>
<string name="verbose_logging">Nhật ký chi tiết</string>
<string name="verbose_logging_desc">Bật nhật ký chi tiết để giúp báo cáo lỗi. Các ghi chép sẽ chỉ được gửi khi phát sinh lỗi, nên hãy lặc lại lỗi để báo cho tác giả. Tính năng này sẽ tự động tắt khi khởi động lại ứng dụng.</string>
<string name="restart_frost">Khởi động lại Frost</string>

View File

@ -2,8 +2,6 @@
<!--Generated by crowdin.com-->
<resources>
<string name="experimental_disclaimer_info">实验性的功能可能不稳定,也许都不会正式使用。选择使用您自己的风险。如果有发生崩溃, 发送反馈,并禁用它们。</string>
<string name="experimental_by_default">默认情况下实验</string>
<string name="experimental_by_default_desc">感觉有风险或只是想要帮助进行调试?检查这将使未来的实验功能是默认类型。</string>
<string name="verbose_logging">Verbose Logging</string>
<string name="verbose_logging_desc">启用详细日志记录以帮助崩溃报告。所以一旦遇到错误时,才会发送日志记录重复问题通知行业的发展现状如果应用程序重新启动,这将自动禁用。</string>
<string name="restart_frost">重启Frost</string>

View File

@ -4,8 +4,6 @@
<string name="experimental_disclaimer_info">實驗性的特性可能不穩定, 可能永遠無法生產。選擇使用您自己的風險, 發回饋, 並隨時禁用他們
实验性的功能可能不稳定,也许都不会正式使用。选择使用您自己的风险。如果有发生崩溃, 发送反馈,并禁用它们。</string>
<string name="experimental_by_default">預設實驗</string>
<string name="experimental_by_default_desc">感覺有風險還是只是幫助想説明調試?檢查這將使未來的實驗功能是預設的。</string>
<string name="verbose_logging">Verbose 記錄</string>
<string name="verbose_logging_desc">啟用Verbose記錄以幫助崩潰報告。只有在遇到錯誤後才會發送日誌記錄, 因此重複此問題以通知我們。如果應用程式重新啟動, 會自動禁用此功能。</string>
<string name="restart_frost">重啟 Frost</string>

View File

@ -17,6 +17,8 @@
<string name="search_bar_desc">Enable the search bar instead of a search overlay</string>
<string name="force_message_bottom">Force Message Bottom</string>
<string name="force_message_bottom_desc">When loading a message thread, trigger a scroll to the bottom of the page rather than loading the page as is.</string>
<string name="native_ui">Native UI</string>
<string name="native_ui_desc">Enables native UI for certain options in the main activity. Done through parsing.</string>
<string name="enable_pip">Enable PIP</string>
<string name="enable_pip_desc">Enable picture in picture videos</string>
<string name="autoplay_settings">Autoplay Settings</string>

View File

@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="experimental_disclaimer_info">Experimental features may be unstable and may never make it to production. Use at your own risk, send feedback, and feel free to disable them if they don\'t work well.</string>
<string name="experimental_by_default">Experimental by Default</string>
<string name="experimental_by_default_desc">Feeling risky or just want to help with debugging? Checking this will enable future experimental functions be default.</string>
<string name="verbose_logging">Verbose Logging</string>
<string name="verbose_logging_desc">Enable verbose logging to help with crash reports. Logging will only be sent once an error is encountered, so repeat the issue to notify the dev. This will automatically be disabled if the app restarts.</string>
@ -10,8 +8,6 @@
<string name="restart_frost_desc">Launch a cold restart for the application.</string>
<!-- Debugging phishing warnings -->
<string name="web_only" translatable="false">Web Only</string>
<string name="web_only_desc" translatable="false">Having troubles? Enable to use web exclusive features. All parsing and background services will be disabled.</string>
<string name="leave_web_only_title" translatable="false">Leave web only mode</string>
<string name="leave_web_only_desc" translatable="false">Currently in web only mode. Would you like to disable it to continue?</string>
<string name="auth_requests" translatable="false">Auth Requests</string>
<string name="auth_requests_desc" translatable="false">Enables post features such as marking notifications as read. Known to potentially cause phishing responses.</string>
</resources>

View File

@ -6,6 +6,10 @@
<item text="" />
-->
<version title="v2.4.0" />
<item text="Removed web only mode for auth requests. Marking notifications as read is now disabled by default to deal with phishing accusations." />
<item text="" />
<item text="" />
<version title="v2.3.2" />
<item text="Disable auto feed refresh by default and add setting to re-enable it" />

View File

@ -31,7 +31,11 @@ class FbUrlTest {
@Suppress("NOTHING_TO_INLINE")
inline fun assertFbFormat(expected: String, url: String) {
val fbUrl = FbUrlFormatter(url)
assertEquals(expected, fbUrl.toString(), "FbUrl Mismatch:\n${fbUrl.toLogList().joinToString("\n\t")}")
assertEquals(
expected,
fbUrl.toString(),
"FbUrl Mismatch:\n${fbUrl.toLogList().joinToString("\n\t")}"
)
}
@Test
@ -65,8 +69,10 @@ class FbUrlTest {
@Test
fun ampersand() {
val url = "https://scontent-yyz1-1.xx.fbcdn.net/v/t31.0-8/fr/cp0/e15/q65/123.jpg?_nc_cat=0&amp;efg=asdf"
val formattedUrl = "https://scontent-yyz1-1.xx.fbcdn.net/v/t31.0-8/fr/cp0/e15/q65/123.jpg?_nc_cat=0&efg=asdf"
val url =
"https://scontent-yyz1-1.xx.fbcdn.net/v/t31.0-8/fr/cp0/e15/q65/123.jpg?_nc_cat=0&amp;efg=asdf"
val formattedUrl =
"https://scontent-yyz1-1.xx.fbcdn.net/v/t31.0-8/fr/cp0/e15/q65/123.jpg?_nc_cat=0&efg=asdf"
assertFbFormat(formattedUrl, url)
}
@ -101,7 +107,7 @@ class FbUrlTest {
val url =
"/video_redirect/?src=https%3A%2F%2Fvideo-yyz1-1.xx.fbcdn.net%2Fv%2Ft42.1790-2%2F2349078999904_n.mp4%3Fefg%3DeyJ87J9%26oh%3Df5777784%26oe%3D56FD4&source=media_collage&id=1735049&refid=8&_ft_=qid.6484464%3Amf_story_key.-43172431214%3Atop_level_post_id.102773&__tn__=FEH-R"
val expected =
"https://video-yyz1-1.xx.fbcdn.net/v/t42.1790-2/2349078999904_n.mp4?efg=eyJ87J9&oh=f5777784&oe=56FD4&source=media_collage&id=1735049&_ft_=qid.6484464:mf_story_key.-43172431214:top_level_post_id.102773&__tn__=FEH-R"
"https://video-yyz1-1.xx.fbcdn.net/v/t42.1790-2/2349078999904_n.mp4?efg=eyJ87J9&oh=f5777784&oe=56FD4&source=media_collage&id=1735049&__tn__=FEH-R"
assertFbFormat(expected, url)
}
@ -138,10 +144,18 @@ class FbUrlTest {
@Test
fun viewFullImage() {
val url = "https://scontent-yyz1-1.xx.fbcdn.net/v/t1.0-9/fr/cp0/e15/q65/asdf_n.jpg?efg=asdf&oh=asdf&oe=asdf"
val url =
"https://scontent-yyz1-1.xx.fbcdn.net/v/t1.0-9/fr/cp0/e15/q65/asdf_n.jpg?efg=asdf&oh=asdf&oe=asdf"
assertFbFormat(url, "#!$url")
}
@Test
fun queryFt() {
val url = "${FB_URL_BASE}sample/photos/a.12346/?source=48&_ft_=xxx"
val expected = "${FB_URL_BASE}sample/photos/a.12346/?source=48"
assertFbFormat(expected, url)
}
// @Test
// fun viewFullImageIndirect() {
// val urlBase = "photo/view_full_size/?fbid=1234&ref_component=mbasic_photo_permalink&ref_page=%2Fwap%2Fphoto.php&refid=13&_ft_=qid.1234%3Amf_story_key.1234%3Atop_level_post_id"

View File

@ -65,6 +65,7 @@ class FbRequestTest {
}
@Test
@Ignore("Post requests are now experimental")
fun markNotification() {
val notifId = 1514443903880
AUTH.markNotificationRead(notifId).call.assertNoError()

View File

@ -7,8 +7,6 @@ object Versions {
// https://mvnrepository.com/artifact/org.apache.commons/commons-text
// Updates blocked due to javax.script dependency
const val apacheCommonsText = "1.4"
// https://github.com/Raizlabs/DBFlow/releases
const val dbflow = "4.2.4"
// https://github.com/brianwernick/ExoMedia/releases
const val exoMedia = "4.3.0"
// https://github.com/InsertKoinIO/koin/blob/master/CHANGELOG.md

View File

@ -1,5 +1,8 @@
# Changelog
## v2.4.0
* Removed web only mode for auth requests. Marking notifications as read is now disabled by default to deal with phishing accusations.
## v2.3.2
* Disable auto feed refresh by default and add setting to re-enable it
* Update theme