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

Merge pull request #1416 from AllanWang/misc

Misc
This commit is contained in:
Allan Wang 2019-05-01 17:05:22 -07:00 committed by GitHub
commit e7a499f631
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 120 additions and 56 deletions

View File

@ -45,7 +45,9 @@ 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.android.startKoin
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
@ -134,7 +136,12 @@ class FrostApp : Application() {
L.d { "Activity ${activity.localClassName} created" }
}
})
startKoin(this, listOf(FrostDatabase.module(this)))
startKoin {
if (BuildConfig.DEBUG)
androidLogger()
androidContext(this@FrostApp)
modules(FrostDatabase.module(this@FrostApp))
}
}
private fun initBugsnag() {

View File

@ -21,8 +21,8 @@ import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import com.pitchedapps.frost.BuildConfig
import org.koin.dsl.module.module
import org.koin.standalone.StandAloneContext
import org.koin.core.context.GlobalContext
import org.koin.dsl.module
interface FrostPrivateDao {
fun cookieDao(): CookieDao
@ -101,6 +101,6 @@ class FrostDatabase(private val privateDb: FrostPrivateDatabase, private val pub
* Get from koin
* For the most part, you can retrieve directly from other koin components
*/
fun get(): FrostDatabase = StandAloneContext.getKoin().koinContext.get()
fun get(): FrostDatabase = GlobalContext.get().koin.get()
}
}

View File

@ -186,7 +186,8 @@ fun MaterialDialog.Builder.theme(): MaterialDialog.Builder {
}
fun Activity.setFrostTheme(forceTransparent: Boolean = false) {
val isTransparent = (Color.alpha(Prefs.bgColor) != 255) || (Color.alpha(Prefs.headerColor) != 255) || forceTransparent
val isTransparent =
(Color.alpha(Prefs.bgColor) != 255) || (Color.alpha(Prefs.headerColor) != 255) || forceTransparent
if (Prefs.bgColor.isColorDark)
setTheme(if (isTransparent) R.style.FrostTheme_Transparent else R.style.FrostTheme)
else
@ -357,7 +358,7 @@ val dependentSegments = arrayOf(
)
inline val String?.isExplicitIntent
get() = this != null && startsWith("intent://")
get() = this != null && (startsWith("intent://") || startsWith("market://"))
fun Context.frostChangelog() = showChangelog(R.xml.frost_changelog, Prefs.textColor) {
theme()

View File

@ -75,7 +75,6 @@ fun FrostWebView.requestWebOverlay(url: String): Boolean {
}
if (!Prefs.overlayEnabled) return false
if (context is WebOverlayActivityBase) {
L.v { "Check web request from overlay" }
val shouldUseDesktop = url.formattedFbUrl.shouldUseDesktopAgent
//already overlay; manage user agent
if (userAgentString != USER_AGENT_DESKTOP && shouldUseDesktop) {

View File

@ -47,8 +47,8 @@ import com.pitchedapps.frost.services.NotificationContent
import com.pitchedapps.frost.services.NotificationType
import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.toReadableTime
import org.koin.standalone.KoinComponent
import org.koin.standalone.inject
import org.koin.core.KoinComponent
import org.koin.core.inject
class NotificationWidget : AppWidgetProvider() {

View File

@ -9,7 +9,8 @@
<version title="v2.3.0" />
<item text="Converted internals of Facebook data storage; auto migration will only work from 2.2.x to 2.3.x" />
<item text="Added notification widget" />
<item text="" />
<item text="Update theme" />
<item text="Update translations" />
<item text="" />
<item text="" />
<item text="" />

View File

@ -246,6 +246,8 @@ class CoroutineTest {
}
}
class TestException(msg: String) : RuntimeException(msg)
@Test
fun exceptionChecks() {
val mainTag = "main-test"
@ -257,7 +259,7 @@ class CoroutineTest {
val job = SupervisorJob()
val flyweight = Flyweight<Int, Int>(GlobalScope, 200L) {
throw java.lang.RuntimeException("Flyweight exception")
throw TestException("Flyweight exception")
}
suspend fun crash(): Boolean = withContext(Dispatchers.IO) {
@ -266,7 +268,7 @@ class CoroutineTest {
flyweight.fetch(0).await()
}
true
} catch (e: java.lang.Exception) {
} catch (e: TestException) {
false
}
}
@ -282,10 +284,6 @@ class CoroutineTest {
println("B")
channel.offer(1)
}
// launch {
// delay(2000)
// job.cancel()
// }
}
}
}

View File

@ -19,7 +19,7 @@ textarea:not([style*="color: rgb"]), ._24pi, ._4en9, ._1kb, ._5p7j, ._2klz, ._57
div.sharerSelector, .footer, ._4pv_, ._1dbp, ._3kad, ._20zc, ._2i5v, ._2i5w,
a, ._5fpq, ._4gux, ._3bg5 ._52x1, ._3bg5 ._52x2, ._6dsj ._3gin, ._hdn._hdn,
.mentions-input:not([style*="color: rgb"]), .mentions-placeholder:not([style*="color: rgb"]),
.largeStatusBox .placeHolder, .fcw, ._2rgt, ._67i4 ._5hu6 ._59tt,
.largeStatusBox .placeHolder, .fcw, ._2rgt, ._67i4 ._5hu6 ._59tt, ._2bu3, ._2bu4,
._5-7t, .fcl, ._4qas, .thread-title, .title, ._46pa, ._336p, ._1rrd, ._2om4,
._3m1m, ._2om2, ._5n_e, .appListExplanation, ._5yt8, ._8he, ._2luw, ._5rgs,
h1, h2, h3, h4, h5, h6 {

View File

@ -1,34 +1,81 @@
(function () {
let prevented = false;
/**
* Go up at most [depth] times, to retrieve a parent matching the provided predicate
* If one is found, it is returned immediately.
* Otherwise, null is returned.
*/
function _parentEl(el: HTMLElement, depth: number, predicate: (el: HTMLElement) => boolean): HTMLElement | null {
for (let i = 0; i < depth + 1; i++) {
if (predicate(el)) {
return el
}
const parent = el.parentElement;
if (!parent) {
return null
}
el = parent
}
return null
}
/**
* Attempts to find a url entry at most [depth] away
* A url is found if the element has tag 'A', and the url isn't blank
*/
function _parentUrl(el: HTMLElement, depth: number): string | null {
const element = _parentEl(el, depth, (el) => el.tagName === 'A');
if (!element) {
return null;
}
const url = element.getAttribute('href');
if (!url || url === '#') {
return null;
}
return url
}
/**
* Given event and target, return true if handled and false otherwise.
*/
type EventHandler = (e: Event, target: HTMLElement) => Boolean
const _frostGeneral: EventHandler = (e, target) => {
// Notifications are two layers under
const url = _parentUrl(target, 2);
return Frost.loadUrl(url);
};
const _frostLaunchpadClick: EventHandler = (e, target) => {
if (!_parentEl(target, 6, (el) => el.id === 'launchpad')) {
return false
}
console.log('Clicked launchpad');
const url = _parentUrl(target, 5);
return Frost.loadUrl(url);
};
const handlers: EventHandler[] = [_frostLaunchpadClick, _frostGeneral];
const _frostAClick = (e: Event) => {
// check for valid target
if (prevented) {
console.log("Click intercept prevented");
return
}
/*
* Commonality; check for valid target
*/
const target = e.target || e.currentTarget || e.srcElement;
if (!(target instanceof Element)) {
if (!(target instanceof HTMLElement)) {
console.log("No element found");
return
}
let element: Element = target;
// Notifications are two layers under
for (let i = 0; i < 2; i++) {
if (element.tagName !== 'A') {
element = <Element>element.parentElement;
}
}
if (element.tagName === 'A') {
if (!prevented) {
const url = element.getAttribute('href');
if (!url || url === '#') {
return
}
console.log(`Click intercept ${url}`);
// If Frost is injected, check if loading the url through an overlay works
if (Frost.loadUrl(url)) {
e.stopPropagation();
e.preventDefault();
}
} else {
console.log("Click intercept prevented")
for (const h of handlers) {
if (h(e, target)) {
e.stopPropagation();
e.preventDefault();
return
}
}
};

View File

@ -6,6 +6,25 @@
(function () {
let longClick = false;
/**
* Go up at most [depth] times, to retrieve a parent matching the provided predicate
* If one is found, it is returned immediately.
* Otherwise, null is returned.
*/
function _parentEl(el: HTMLElement, depth: number, predicate: (el: HTMLElement) => boolean): HTMLElement | null {
for (let i = 0; i < depth + 1; i++) {
if (predicate(el)) {
return el
}
const parent = el.parentElement;
if (!parent) {
return null
}
el = parent
}
return null
}
/**
* Given event and target, return true if handled and false otherwise.
*/
@ -55,16 +74,8 @@
* Opens image activity for posts with just one image
*/
const _frostImage: EventHandler = (e, target) => {
let element: Element = target;
// Notifications are two layers under
for (let i = 0; i < 2; i++) {
if (element.tagName !== 'A') {
element = <Element>element.parentElement;
} else {
break
}
}
if (element.tagName !== 'A') {
const element = _parentEl(target, 2, (el) => el.tagName === 'A');
if (!element) {
return false;
}
const url = element.getAttribute('href');
@ -92,7 +103,7 @@
return true;
};
const handlers = [_frostImage, _frostCopyComment, _frostCopyPost];
const handlers: EventHandler[] = [_frostImage, _frostCopyComment, _frostCopyPost];
const _frostAContext = (e: Event) => {
Frost.longClick(true);

View File

@ -17,7 +17,7 @@ APP_ID=Frost
APP_GROUP=com.pitchedapps
KAU=4.0.0
KOTLIN=1.3.21
KOTLIN=1.3.31
# https://mvnrepository.com/artifact/com.android.tools.build/gradle?repo=google
ANDROID_GRADLE=3.3.2
@ -41,7 +41,7 @@ DBFLOW=4.2.4
# https://github.com/brianwernick/ExoMedia/releases
EXOMEDIA=4.3.0
# https://github.com/InsertKoinIO/koin/blob/master/CHANGELOG.md
KOIN=1.0.2
KOIN=2.0.0-rc-2
# https://github.com/mockk/mockk/releases
MOCKK=1.9.3
# https://mvnrepository.com/artifact/androidx.core/core-ktx?repo=google
@ -56,10 +56,10 @@ LEAK_CANARY=1.6.2
# https://github.com/zsmb13/MaterialDrawerKt/releases
MATERIAL_DRAWER_KT=2.0.1
# https://github.com/square/okhttp/releases
OKHTTP=3.14.0
# http://robolectric.org/getting-started/
OKHTTP=3.14.1
# https://developer.android.com/jetpack/androidx/releases/room
ROOM=2.1.0-alpha04
# http://robolectric.org/getting-started/
ROBOELECTRIC=4.2
# https://github.com/davemorrissey/subsampling-scale-image-view#quick-start
SCALE_IMAGE_VIEW=3.10.0