diff options
Diffstat (limited to 'app/src/main/kotlin')
38 files changed, 135 insertions, 140 deletions
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt b/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt index ae4360a5..178aa8bb 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt @@ -81,6 +81,13 @@ class FrostApp : Application() { Bugsnag.setAutoCaptureSessions(true) Bugsnag.setUserId(Prefs.frostId) + Bugsnag.beforeNotify { error -> + when { + error.exception is UndeliverableException -> false + error.exception.stackTrace.any { it.className.contains("XposedBridge") } -> false + else -> true + } + } } KL.shouldLog = { BuildConfig.DEBUG } Prefs.verboseLogging = false diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseActivity.kt index 08728ae4..3ac8c6ce 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseActivity.kt @@ -8,7 +8,6 @@ import com.pitchedapps.frost.contracts.VideoViewHolder import com.pitchedapps.frost.utils.setFrostTheme import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.Disposable -import io.reactivex.rxkotlin.addTo /** * Created by Allan Wang on 2017-06-12. diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt index 9ed51652..2fce69a8 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt @@ -52,11 +52,11 @@ import com.pitchedapps.frost.dbflow.loadFbTabs import com.pitchedapps.frost.enums.MainActivityLayout import com.pitchedapps.frost.facebook.FbCookie import com.pitchedapps.frost.facebook.FbItem +import com.pitchedapps.frost.facebook.parsers.FrostSearch +import com.pitchedapps.frost.facebook.parsers.SearchParser import com.pitchedapps.frost.facebook.profilePictureUrl import com.pitchedapps.frost.fragments.BaseFragment import com.pitchedapps.frost.fragments.WebFragment -import com.pitchedapps.frost.facebook.parsers.FrostSearch -import com.pitchedapps.frost.facebook.parsers.SearchParser import com.pitchedapps.frost.utils.* import com.pitchedapps.frost.views.BadgedIcon import com.pitchedapps.frost.views.FrostVideoViewer @@ -308,10 +308,10 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract, else { val data = SearchParser.query(FbCookie.webCookie, query)?.data?.results if (data != null) { - val items = data.map(FrostSearch::toSearchItem).toMutableList() + val items = data.mapTo(mutableListOf(), FrostSearch::toSearchItem) if (items.isNotEmpty()) items.add(SearchItem("${FbItem._SEARCH.url}?q=$query", string(R.string.show_all_results), iicon = null)) - searchViewCache.put(query, items) + searchViewCache[query] = items searchView.results = items } } @@ -352,7 +352,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract, if (requestCode == ACTIVITY_SETTINGS) { if (resultCode and REQUEST_RESTART_APPLICATION > 0) { //completely restart application L.d { "Restart Application Requested" } - val intent = packageManager.getLaunchIntentForPackage(packageName) + val intent = packageManager.getLaunchIntentForPackage(packageName)!! Intent.makeRestartActivityTask(intent.component) Runtime.getRuntime().exit(0) return @@ -378,7 +378,8 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract, override fun onRestoreInstanceState(savedInstanceState: Bundle) { super.onRestoreInstanceState(savedInstanceState) adapter.forcedFallbacks.clear() - adapter.forcedFallbacks.addAll(savedInstanceState.getStringArrayList(STATE_FORCE_FALLBACK)) + adapter.forcedFallbacks.addAll(savedInstanceState.getStringArrayList(STATE_FORCE_FALLBACK) + ?: emptyList()) } override fun onResume() { @@ -416,7 +417,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract, positiveText(R.string.kau_yes) negativeText(R.string.kau_no) onPositive { _, _ -> finish() } - checkBoxPromptRes(R.string.kau_do_not_show_again, false, { _, b -> Prefs.exitConfirmation = !b }) + checkBoxPromptRes(R.string.kau_do_not_show_again, false) { _, b -> Prefs.exitConfirmation = !b } } return true } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/DebugActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/DebugActivity.kt index 30f12c1d..9b1d8e79 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/DebugActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/DebugActivity.kt @@ -63,7 +63,7 @@ class DebugActivity : KauBaseActivity() { fab.visible().setIcon(GoogleMaterial.Icon.gmd_bug_report, Prefs.iconColor) fab.backgroundTintList = ColorStateList.valueOf(Prefs.accentColor) - fab.setOnClickListener { + fab.setOnClickListener { _ -> fab.hide() val parent = baseDir(this) @@ -76,11 +76,11 @@ class DebugActivity : KauBaseActivity() { emitter.onSuccess(it) } }.subscribeOn(AndroidSchedulers.mainThread()) - Single.zip(listOf(rxScreenshot, rxBody), { + Single.zip(listOf(rxScreenshot, rxBody)) { val screenshot = it[0] == true val body = it[1] as? String screenshot to body - }).observeOn(AndroidSchedulers.mainThread()) + }.observeOn(AndroidSchedulers.mainThread()) .subscribe { (screenshot, body), err -> if (err != null) { L.e { "DebugActivity error ${err.message}" } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/IntroActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/IntroActivity.kt index 8be9c847..4b00c242 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/IntroActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/IntroActivity.kt @@ -106,11 +106,14 @@ class IntroActivity : KauBaseActivity(), ViewPager.PageTransformer, ViewPager.On ripple.ripple(blue, x, y, 600) { postDelayed(1000) { finish() } } - arrayOf(skip, indicator, next, fragments.last().view?.find<View>(R.id.intro_title), fragments.last().view?.find<View>(R.id.intro_desc)).forEach { + val lastView: View? = fragments.last().view + arrayOf<View?>(skip, indicator, next, + lastView?.find(R.id.intro_title), + lastView?.find(R.id.intro_desc)).forEach { it?.animate()?.alpha(0f)?.setDuration(600)?.start() } if (Prefs.textColor != Color.WHITE) { - val f = fragments.last().view?.find<ImageView>(R.id.intro_image)?.drawable + val f = lastView?.find<ImageView>(R.id.intro_image)?.drawable if (f != null) ValueAnimator.ofFloat(0f, 1f).apply { addUpdateListener { diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt index 77ca37f3..bf8120de 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt @@ -6,8 +6,6 @@ import android.support.v4.view.ViewPager import com.pitchedapps.frost.facebook.FbItem import com.pitchedapps.frost.views.BadgedIcon import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.disposables.CompositeDisposable -import io.reactivex.rxkotlin.addTo import io.reactivex.schedulers.Schedulers import io.reactivex.subjects.PublishSubject import org.jsoup.Jsoup @@ -15,9 +13,9 @@ import java.util.concurrent.TimeUnit class MainActivity : BaseMainActivity() { - override val fragmentSubject = PublishSubject.create<Int>()!! + override val fragmentSubject = PublishSubject.create<Int>() var lastPosition = -1 - val headerBadgeObservable = PublishSubject.create<String>()!! + val headerBadgeObservable = PublishSubject.create<String>() override fun onNestedCreate(savedInstanceState: Bundle?) { setupTabs() @@ -73,7 +71,7 @@ class MainActivity : BaseMainActivity() { val requests = it.select("[data-sigil*=requests] [data-sigil=count]") val messages = it.select("[data-sigil*=messages] [data-sigil=count]") val notifications = it.select("[data-sigil*=notifications] [data-sigil=count]") - return@map arrayOf(feed, requests, messages, notifications).map { it?.getOrNull(0)?.ownText() } + return@map arrayOf(feed, requests, messages, notifications).map { e -> e?.getOrNull(0)?.ownText() } } .observeOn(AndroidSchedulers.mainThread()) .subscribe { (feed, requests, messages, notifications) -> diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/SelectorActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/SelectorActivity.kt index a9658eb1..58ab3dac 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/SelectorActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/SelectorActivity.kt @@ -39,7 +39,7 @@ class SelectorActivity : BaseActivity() { override fun onClick(v: View, position: Int, fastAdapter: FastAdapter<AccountItem>, item: AccountItem) { if (item.cookie == null) this@SelectorActivity.launchNewTask<LoginActivity>() - else FbCookie.switchUser(item.cookie, { launchNewTask<MainActivity>(cookies()) }) + else FbCookie.switchUser(item.cookie) { launchNewTask<MainActivity>(cookies()) } } }) setFrostColors { diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt index 237780b8..7561dc88 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt @@ -47,7 +47,7 @@ class SettingsActivity : KPrefActivity() { ACTIVITY_REQUEST_DEBUG -> { val url = data?.extras?.getString(DebugActivity.RESULT_URL) if (resultCode == Activity.RESULT_OK && url?.isNotBlank() == true) - sendDebug(url, data.extras.getString(DebugActivity.RESULT_BODY)) + sendDebug(url, data.getStringExtra(DebugActivity.RESULT_BODY)) return } } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt index 3081c463..323a2eb5 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt @@ -75,17 +75,17 @@ class FrostWebActivity : WebOverlayActivityBase(false) { if (intent.action != Intent.ACTION_SEND || intent.type != "text/plain") return true val text = intent.getStringExtra(Intent.EXTRA_TEXT) ?: return true val url = HttpUrl.parse(text)?.toString() - if (url == null) { + return if (url == null) { L.i { "Attempted to share a non-url" } L._i { "Shared text: $text" } copyToClipboard(text, "Text to Share", showToast = false) intent.putExtra(ARG_URL, FbItem.FEED.url) - return false + false } else { L.i { "Sharing url through overlay" } L._i { "Url: $url" } intent.putExtra(ARG_URL, "${FB_URL_BASE}sharer/sharer.php?u=$url") - return true + true } } } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt b/app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt index ca6df366..1182e609 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt @@ -1,6 +1,7 @@ package com.pitchedapps.frost.contracts import com.mikepenz.iconics.typeface.IIcon +import com.pitchedapps.frost.activities.MainActivity import com.pitchedapps.frost.fragments.BaseFragment import io.reactivex.subjects.PublishSubject diff --git a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostUrlData.kt b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostUrlData.kt deleted file mode 100644 index 18467fa4..00000000 --- a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostUrlData.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.pitchedapps.frost.contracts - -import com.pitchedapps.frost.facebook.FbItem - -/** - * Created by Allan Wang on 19/12/17. - */ -interface FrostUrlData { - - /** - * The main (and fallback) url - */ - var baseUrl: String - - /** - * Only base viewpager should pass an enum - */ - var baseEnum: FbItem? - - fun passUrlDataTo(other: FrostUrlData) { - other.baseUrl = baseUrl - other.baseEnum = baseEnum - } - -}
\ No newline at end of file diff --git a/app/src/main/kotlin/com/pitchedapps/frost/debugger/OfflineWebsite.kt b/app/src/main/kotlin/com/pitchedapps/frost/debugger/OfflineWebsite.kt index f5f7463d..6298f1f9 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/debugger/OfflineWebsite.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/debugger/OfflineWebsite.kt @@ -182,7 +182,7 @@ class OfflineWebsite(private val url: String, delete() } - baseDir.listFiles({ _, n -> n != "$name.zip" }).forEach { it.zip() } + baseDir.listFiles { _, n -> n != "$name.zip" }.forEach { it.zip() } assetDir.listFiles().forEach { it.zip("assets/${it.name}") } @@ -208,7 +208,7 @@ class OfflineWebsite(private val url: String, } private fun downloadFiles() = fileQueue.clean().toTypedArray().zip<String, Boolean, Boolean>({ - it.all { it } + it.all { self -> self } }, { it.downloadUrl({ false }) { file, body -> body.byteStream().use { input -> @@ -222,8 +222,8 @@ class OfflineWebsite(private val url: String, private fun downloadCss() = cssQueue.clean().toTypedArray().zip<String, Set<String>, Set<String>>({ it.flatMap { l -> l }.toSet() - }, { - it.downloadUrl({ emptySet() }) { file, body -> + }, { cssUrl -> + cssUrl.downloadUrl({ emptySet() }) { file, body -> var content = body.string() val links = FB_CSS_URL_MATCHER.findAll(content).mapNotNull { it[1] } val absLinks = links.mapNotNull { @@ -303,7 +303,7 @@ class OfflineWebsite(private val url: String, if (newUrl.endsWith(".js")) newUrl = "$newUrl.txt" - urlMapper.put(this, newUrl) + urlMapper[this] = newUrl return newUrl } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbCookie.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbCookie.kt index 38de6150..ab7e165a 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbCookie.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbCookie.kt @@ -29,15 +29,15 @@ object FbCookie { private fun setWebCookie(cookie: String?, callback: (() -> Unit)?) { with(CookieManager.getInstance()) { - removeAllCookies { + removeAllCookies { _ -> if (cookie == null) { callback?.invoke() return@removeAllCookies } L.d { "Setting cookie" } val cookies = cookie.split(";").map { Pair(it, SingleSubject.create<Boolean>()) } - cookies.forEach { (cookie, callback) -> setCookie(FB_URL_BASE, cookie, { callback.onSuccess(it) }) } - Observable.zip<Boolean, Unit>(cookies.map { (_, callback) -> callback.toObservable() }, {}) + cookies.forEach { (cookie, callback) -> setCookie(FB_URL_BASE, cookie) { callback.onSuccess(it) } } + Observable.zip<Boolean, Unit>(cookies.map { (_, callback) -> callback.toObservable() }) {} .observeOn(AndroidSchedulers.mainThread()) .subscribe { callback?.invoke() diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbRegex.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbRegex.kt index cfa2796c..a57ced11 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbRegex.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbRegex.kt @@ -22,7 +22,7 @@ val FB_USER_MATCHER: Regex by lazy { Regex("c_user=([0-9]*);") } val FB_EPOCH_MATCHER: Regex by lazy { Regex(":([0-9]+)") } val FB_NOTIF_ID_MATCHER: Regex by lazy { Regex("notif_([0-9]+)") } -val FB_MESSAGE_NOTIF_ID_MATCHER: Regex by lazy { Regex("[thread|user]_fbid_([0-9]+)") } +val FB_MESSAGE_NOTIF_ID_MATCHER: Regex by lazy { Regex("(?:thread|user)_fbid_([0-9]+)") } val FB_CSS_URL_MATCHER: Regex by lazy { Regex("url\\([\"|']?(.*?)[\"|']?\\)") } val FB_JSON_URL_MATCHER: Regex by lazy { Regex("\"(http.*?)\"") } val FB_IMAGE_ID_MATCHER: Regex by lazy { Regex("fbcdn.*?/[0-9]+_([0-9]+)_") } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/FrostParser.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/FrostParser.kt index 5d023023..3d5c5bce 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/FrostParser.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/FrostParser.kt @@ -104,22 +104,19 @@ internal abstract class FrostParserBase<out T : Any>(private val redirectToText: protected abstract fun parseImpl(doc: Document): T? - // protected abstract fun parse(doc: Document): T? - /** * Attempts to find inner <i> element with some style containing a url * Returns the formatted url, or an empty string if nothing was found */ - protected fun Element.getInnerImgStyle() = + protected fun Element.getInnerImgStyle(): String? = select("i.img[style*=url]").getStyleUrl() - protected fun Elements.getStyleUrl() = + protected fun Elements.getStyleUrl(): String? = FB_CSS_URL_MATCHER.find(attr("style"))[1]?.formattedFbUrl - protected open fun textToDoc(text: String) = if (!redirectToText) - Jsoup.parse(text) - else - throw RuntimeException("${this::class.java.simpleName} requires text redirect but did not implement textToDoc") + protected open fun textToDoc(text: String): Document? = + if (!redirectToText) Jsoup.parse(text) + else throw RuntimeException("${this::class.java.simpleName} requires text redirect but did not implement textToDoc") protected fun parseLink(element: Element?): FrostLink? { val a = element?.getElementsByTag("a")?.first() ?: return null diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/MessageParser.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/MessageParser.kt index f32c3452..a3ebf998 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/MessageParser.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/MessageParser.kt @@ -35,7 +35,7 @@ data class FrostMessages(val threads: List<FrostThread>, }.toString() override fun getUnreadNotifications(data: CookieModel) = - threads.filter(FrostThread::unread).map { + threads.asSequence().filter(FrostThread::unread).map { with(it) { NotificationContent( data = data, @@ -47,7 +47,7 @@ data class FrostMessages(val threads: List<FrostThread>, profileUrl = img ) } - } + }.toList() } /** diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/NotifParser.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/NotifParser.kt index 03b913c7..410a0e84 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/NotifParser.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/NotifParser.kt @@ -24,7 +24,7 @@ data class FrostNotifs( }.toString() override fun getUnreadNotifications(data: CookieModel) = - notifs.filter(FrostNotif::unread).map { + notifs.asSequence().filter(FrostNotif::unread).map { with(it) { NotificationContent( data = data, @@ -36,7 +36,7 @@ data class FrostNotifs( profileUrl = img ) } - } + }.toList() } /** diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/FbRequest.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/FbRequest.kt index a4b0a347..500c4102 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/FbRequest.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/FbRequest.kt @@ -115,8 +115,8 @@ fun String.getAuth(): RequestAuth { .url(FB_URL_BASE) .get() .call() - call.execute().body()?.charStream()?.useLines { - it.forEach { + call.execute().body()?.charStream()?.useLines { lines -> + lines.forEach { val text = StringEscapeUtils.unescapeEcmaScript(it) val fb_dtsg = FB_DTSG_MATCHER.find(text)[1] if (fb_dtsg != null) { @@ -153,8 +153,8 @@ inline fun <T, reified R : Any, O> Array<T>.zip(crossinline mapper: (List<R>) -> fun executeForNoError(call: Call): Boolean { val body = call.execute().body() ?: return false var empty = true - body.charStream().useLines { - it.forEach { + body.charStream().useLines { lines -> + lines.forEach { if (it.contains("error")) return false if (empty && it.isNotEmpty()) empty = false } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Notifications.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Notifications.kt index 82a9364b..0d3926dc 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Notifications.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Notifications.kt @@ -23,5 +23,5 @@ fun RequestAuth.markNotificationRead(notifId: Long): FrostRequest<Boolean> { fun RequestAuth.markNotificationsRead(vararg notifId: Long) = notifId.toTypedArray().zip<Long, Boolean, Boolean>( - { it.all { it } }, + { it.all { self -> self } }, { markNotificationRead(it).invoke() })
\ No newline at end of file diff --git a/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragmentBase.kt b/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragmentBase.kt index e3b8f3d3..4f9133a6 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragmentBase.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragmentBase.kt @@ -47,7 +47,7 @@ abstract class GenericRecyclerFragment<T, Item : IItem<*, *>> : RecyclerFragment abstract fun mapper(data: T): Item - val adapter: ModelAdapter<T, Item> = ModelAdapter(this::mapper) + val adapter: ModelAdapter<T, Item> = ModelAdapter { this.mapper(it) } final override fun bind(recyclerView: FrostRecyclerView) { recyclerView.adapter = getAdapter() diff --git a/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragments.kt b/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragments.kt index 512ea82c..4f597731 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragments.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragments.kt @@ -3,11 +3,11 @@ package com.pitchedapps.frost.fragments import com.mikepenz.fastadapter.IItem import com.pitchedapps.frost.facebook.FbCookie import com.pitchedapps.frost.facebook.FbItem -import com.pitchedapps.frost.facebook.requests.* -import com.pitchedapps.frost.iitems.* import com.pitchedapps.frost.facebook.parsers.FrostNotifs import com.pitchedapps.frost.facebook.parsers.NotifParser import com.pitchedapps.frost.facebook.parsers.ParseResponse +import com.pitchedapps.frost.facebook.requests.* +import com.pitchedapps.frost.iitems.* import com.pitchedapps.frost.utils.frostJsoup import com.pitchedapps.frost.views.FrostRecyclerView import org.jetbrains.anko.doAsync diff --git a/app/src/main/kotlin/com/pitchedapps/frost/iitems/NotificationIItem.kt b/app/src/main/kotlin/com/pitchedapps/frost/iitems/NotificationIItem.kt index 185da4fd..61e8b6c4 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/iitems/NotificationIItem.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/iitems/NotificationIItem.kt @@ -14,9 +14,9 @@ import com.mikepenz.fastadapter.FastAdapter import com.mikepenz.fastadapter.adapters.ItemAdapter import com.mikepenz.fastadapter.commons.utils.DiffCallback import com.pitchedapps.frost.R +import com.pitchedapps.frost.facebook.parsers.FrostNotif import com.pitchedapps.frost.glide.FrostGlide import com.pitchedapps.frost.glide.GlideApp -import com.pitchedapps.frost.facebook.parsers.FrostNotif import com.pitchedapps.frost.services.FrostRunnable import com.pitchedapps.frost.utils.Prefs import com.pitchedapps.frost.utils.launchWebOverlay diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssHider.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssHider.kt index 6981fd1c..5444fad8 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssHider.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssHider.kt @@ -8,9 +8,9 @@ import android.webkit.WebView * List of elements to hide */ enum class CssHider(vararg val items: String) : InjectorContract { - CORE("[data-sigil=m_login_upsell]", "role=progressbar"), - // HEADER("#header", "[data-sigil=MTopBlueBarHeader]", -// "#header-notices", "[data-sigil*=m-promo-jewel-header]"), + CORE("[data-sigil=m_login_upsell]", "[role=progressbar]"), + HEADER("#header", "#mJewelNav", "[data-sigil=MTopBlueBarHeader]", + "#header-notices", "[data-sigil*=m-promo-jewel-header]"), ADS("article[data-xt*=sponsor]", "article[data-store*=sponsor]"), PEOPLE_YOU_MAY_KNOW("article._d2r"), diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt index b4926355..1ab00153 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt @@ -17,7 +17,7 @@ enum class JsActions(body: String) : InjectorContract { BASE_HREF("""document.write("<base href='$FB_URL_BASE'/>");"""), FETCH_BODY("""setTimeout(function(){var e=document.querySelector("main");e||(e=document.querySelector("body")),Frost.handleHtml(e.outerHTML)},1e2);"""), RETURN_BODY("return(document.getElementsByTagName('html')[0].innerHTML);"), - CREATE_POST(clickBySelector("button[name=view_overview]")), + CREATE_POST(clickBySelector("[role=textbox][onclick]")), // CREATE_MSG(clickBySelector("a[rel=dialog]")), /** * Used as a pseudoinjector for maybe functions diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsAssets.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsAssets.kt index 21d660b8..980481a4 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsAssets.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsAssets.kt @@ -3,6 +3,7 @@ package com.pitchedapps.frost.injectors import android.webkit.WebView import ca.allanwang.kau.kotlin.lazyContext import com.pitchedapps.frost.utils.L +import java.io.BufferedReader import java.io.FileNotFoundException import java.util.* @@ -19,7 +20,7 @@ enum class JsAssets : InjectorContract { var file = "${name.toLowerCase(Locale.CANADA)}.js" var injector = lazyContext { try { - val content = it.assets.open("js/$file").bufferedReader().use { it.readText() } + val content = it.assets.open("js/$file").bufferedReader().use(BufferedReader::readText) JsBuilder().js(content).single(name).build() } catch (e: FileNotFoundException) { L.e(e) { "JsAssets file not found" } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt index e45e86b1..acda2d9b 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt @@ -110,6 +110,6 @@ fun FrostWebViewClient.jsInject(vararg injectors: InjectorContract, */ class JsInjector(val function: String) : InjectorContract { override fun inject(webView: WebView, callback: (() -> Unit)?) { - webView.evaluateJavascript(function, { callback?.invoke() }) + webView.evaluateJavascript(function) { callback?.invoke() } } }
\ No newline at end of file diff --git a/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt b/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt index 279b4027..2bb1b5c5 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt @@ -12,6 +12,7 @@ import android.support.v4.app.NotificationCompat import android.support.v4.app.NotificationManagerCompat import ca.allanwang.kau.utils.dpToPx import ca.allanwang.kau.utils.string +import com.pitchedapps.frost.BuildConfig import com.pitchedapps.frost.R import com.pitchedapps.frost.activities.FrostWebActivity import com.pitchedapps.frost.dbflow.CookieModel @@ -19,12 +20,12 @@ import com.pitchedapps.frost.dbflow.NotificationModel import com.pitchedapps.frost.dbflow.lastNotificationTime import com.pitchedapps.frost.enums.OverlayContext import com.pitchedapps.frost.facebook.FbItem -import com.pitchedapps.frost.glide.FrostGlide -import com.pitchedapps.frost.glide.GlideApp import com.pitchedapps.frost.facebook.parsers.FrostParser import com.pitchedapps.frost.facebook.parsers.MessageParser import com.pitchedapps.frost.facebook.parsers.NotifParser import com.pitchedapps.frost.facebook.parsers.ParseNotification +import com.pitchedapps.frost.glide.FrostGlide +import com.pitchedapps.frost.glide.GlideApp import com.pitchedapps.frost.utils.ARG_USER_ID import com.pitchedapps.frost.utils.L import com.pitchedapps.frost.utils.Prefs @@ -99,8 +100,8 @@ enum class NotificationType( L.v { "$name notification data not found" } return -1 } - val notifContents = response.data.getUnreadNotifications(data).filter { - val text = it.text + val notifContents = response.data.getUnreadNotifications(data).filter { notif -> + val text = notif.text Prefs.notificationKeywords.none { text.contains(it, true) } } if (notifContents.isEmpty()) return 0 @@ -120,8 +121,10 @@ enum class NotificationType( if (newLatestEpoch > prevLatestEpoch) putTime(prevNotifTime, newLatestEpoch).save() L.d { "Notif $name new epoch ${getTime(lastNotificationTime(userId))}" } - if (prevLatestEpoch == -1L) + if (prevLatestEpoch == -1L && !BuildConfig.DEBUG) { + L.d { "Skipping first notification fetch" } return 0 // do not notify the first time + } frostEvent("Notifications", "Type" to name, "Count" to notifs.size) if (notifs.size > 1) summaryNotification(context, userId, notifs.size).notify(context) @@ -146,44 +149,43 @@ enum class NotificationType( /** * Create and submit a new notification with the given [content] */ - private fun createNotification(context: Context, content: NotificationContent): FrostNotification { - with(content) { - val intent = Intent(context, FrostWebActivity::class.java) - intent.data = Uri.parse(href) - intent.putExtra(ARG_USER_ID, data.id) - overlayContext.put(intent) - bindRequest(intent, content, data.cookie) + private fun createNotification(context: Context, content: NotificationContent): FrostNotification = + with(content) { + val intent = Intent(context, FrostWebActivity::class.java) + intent.data = Uri.parse(href) + intent.putExtra(ARG_USER_ID, data.id) + overlayContext.put(intent) + bindRequest(intent, content, data.cookie) - val group = "${groupPrefix}_${data.id}" - val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT) - val notifBuilder = context.frostNotification(channelId) - .setContentTitle(title ?: context.string(R.string.frost_name)) - .setContentText(text) - .setContentIntent(pendingIntent) - .setCategory(Notification.CATEGORY_SOCIAL) - .setSubText(data.name) - .setGroup(group) + val group = "${groupPrefix}_${data.id}" + val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT) + val notifBuilder = context.frostNotification(channelId) + .setContentTitle(title ?: context.string(R.string.frost_name)) + .setContentText(text) + .setContentIntent(pendingIntent) + .setCategory(Notification.CATEGORY_SOCIAL) + .setSubText(data.name) + .setGroup(group) - if (timestamp != -1L) notifBuilder.setWhen(timestamp * 1000) - L.v { "Notif load $content" } + if (timestamp != -1L) notifBuilder.setWhen(timestamp * 1000) + L.v { "Notif load $content" } - if (profileUrl != null) { - try { - val profileImg = GlideApp.with(context) - .asBitmap() - .load(profileUrl) - .transform(FrostGlide.circleCrop) - .submit(_40_DP, _40_DP) - .get() - notifBuilder.setLargeIcon(profileImg) - } catch (e: Exception) { - L.e { "Failed to get image $profileUrl" } + if (profileUrl != null) { + try { + val profileImg = GlideApp.with(context) + .asBitmap() + .load(profileUrl) + .transform(FrostGlide.circleCrop) + .submit(_40_DP, _40_DP) + .get() + notifBuilder.setLargeIcon(profileImg) + } catch (e: Exception) { + L.e { "Failed to get image $profileUrl" } + } } - } - return FrostNotification(group, notifId, notifBuilder) - } - } + FrostNotification(group, notifId, notifBuilder) + } /** diff --git a/app/src/main/kotlin/com/pitchedapps/frost/services/FrostRequestService.kt b/app/src/main/kotlin/com/pitchedapps/frost/services/FrostRequestService.kt index 3fd5ee7b..b2ccaea2 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/services/FrostRequestService.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/services/FrostRequestService.kt @@ -104,11 +104,11 @@ object FrostRunnable { } fun propagate(context: Context, intent: Intent?) { - intent?.extras ?: return + val extras = intent?.extras ?: return val command = FrostRequestCommands[intent] ?: return intent.removeExtra(ARG_COMMAND) // reset L.d { "Propagating command ${command.name}" } - val builder = command.propagate(intent.extras) + val builder = command.propagate(extras) schedule(context, command, builder) } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt b/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt index 35dd9571..56ff4db7 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt @@ -69,6 +69,7 @@ class NotificationService : JobService() { notifCount += fetch(jobId, NotificationType.MESSAGE, it) } + L.i { "Sent $notifCount notifications" } if (notifCount == 0 && jobId == NOTIFICATION_JOB_NOW) generalNotification(665, R.string.no_new_notifications, BuildConfig.DEBUG) diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Appearance.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Appearance.kt index 314590e2..9253d926 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Appearance.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Appearance.kt @@ -149,7 +149,10 @@ fun SettingsActivity.getAppearancePrefs(): KPrefAdapterBuilder.() -> Unit = { list.add(KPrefTextSeekbar( KPrefSeekbar.KPrefSeekbarBuilder( globalOptions, - R.string.web_text_scaling, Prefs::webTextScaling, { Prefs.webTextScaling = it; setFrostResult(REQUEST_TEXT_ZOOM) }))) + R.string.web_text_scaling, Prefs::webTextScaling) { + Prefs.webTextScaling = it + setFrostResult(REQUEST_TEXT_ZOOM) + })) checkbox(R.string.enforce_black_media_bg, Prefs::blackMediaBg, { Prefs.blackMediaBg = it diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Feed.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Feed.kt index 5de68e21..402322ad 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Feed.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Feed.kt @@ -20,13 +20,13 @@ fun SettingsActivity.getFeedPrefs(): KPrefAdapterBuilder.() -> Unit = { materialDialogThemed { title(R.string.newsfeed_sort) items(FeedSort.values().map { string(it.textRes) }) - itemsCallbackSingleChoice(item.pref, { _, _, which, _ -> + itemsCallbackSingleChoice(item.pref) { _, _, which, _ -> if (item.pref != which) { item.pref = which shouldRestartMain() } true - }) + } } } textGetter = { string(FeedSort(it).textRes) } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt index 962e60ae..1f9411e4 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt @@ -36,11 +36,11 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = { materialDialogThemed { title(R.string.notification_frequency) items(texts) - itemsCallbackSingleChoice(options.indexOf(item.pref), { _, _, which, _ -> + itemsCallbackSingleChoice(options.indexOf(item.pref)) { _, _, which, _ -> item.pref = options[which] scheduleNotifications(item.pref) true - }) + } } } enabler = { @@ -154,8 +154,8 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = { if (BuildConfig.DEBUG) { plainText(R.string.reset_notif_epoch) { onClick = { - loadFbCookiesAsync { - it.map { NotificationModel(it.id) }.forEach { it.save() } + loadFbCookiesAsync { cookies -> + cookies.map { NotificationModel(it.id) }.forEach { it.save() } } } } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/AdBlocker.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/AdBlocker.kt index 20041370..1bb0449b 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/AdBlocker.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/AdBlocker.kt @@ -23,7 +23,9 @@ open class AdBlocker(val assetPath: String) { fun init(context: Context) { doAsync { - val content = context.assets.open(assetPath).bufferedReader().use { it.readLines().filter { !it.startsWith("#") } } + val content = context.assets.open(assetPath).bufferedReader().use { f -> + f.readLines().filter { !it.startsWith("#") } + } data.addAll(content) L.i { "Initialized adblock for $assetPath with ${data.size} hosts" } } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt index dbd4d0d1..9f068a58 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt @@ -61,9 +61,11 @@ object Prefs : KPref() { get() = t.accentColor inline val accentColorForWhite: Int - get() = if (accentColor.isColorVisibleOn(Color.WHITE)) accentColor - else if (textColor.isColorVisibleOn(Color.WHITE)) textColor - else FACEBOOK_BLUE + get() = when { + accentColor.isColorVisibleOn(Color.WHITE) -> accentColor + textColor.isColorVisibleOn(Color.WHITE) -> textColor + else -> FACEBOOK_BLUE + } inline val nativeBgColor: Int get() = Prefs.bgColor.withAlpha(30) diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/DebugWebView.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/DebugWebView.kt index 4c4e5525..ac62f142 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/web/DebugWebView.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/web/DebugWebView.kt @@ -82,7 +82,7 @@ class DebugWebView @JvmOverloads constructor( if (url.isFacebookUrl) view.jsInject( CssAssets.ROUND_ICONS.maybe(Prefs.showRoundedIcons), - CssHider.CORE, +// CssHider.CORE, CssHider.COMPOSER.maybe(!Prefs.showComposer), CssHider.PEOPLE_YOU_MAY_KNOW.maybe(!Prefs.showSuggestedFriends), CssHider.SUGGESTED_GROUPS.maybe(!Prefs.showSuggestedGroups), diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt index 72e448b9..4e4df027 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt @@ -23,7 +23,7 @@ fun WebView.shouldFrostInterceptRequest(request: WebResourceRequest): WebResourc val host = httpUrl.host() val url = httpUrl.toString() if (host.contains("facebook") || host.contains("fbcdn")) return null - if (FrostPglAdBlock.isAdHost(host)) return blankResource + if (FrostPglAdBlock.isAd(host)) return blankResource // if (!shouldLoadImages && !Prefs.loadMediaOnMeteredNetwork && request.isMedia) return blankResource L.v { "Intercept Request: $host $url" } return null diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostUrlOverlayValidator.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostUrlOverlayValidator.kt index b58f1a16..b83002a3 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostUrlOverlayValidator.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostUrlOverlayValidator.kt @@ -76,7 +76,9 @@ fun FrostWebView.requestWebOverlay(url: String): Boolean { /** * If the url contains any one of the whitelist segments, switch to the chat overlay */ -val messageWhitelist = setOf(FbItem.MESSAGES, FbItem.CHAT, FbItem.FEED_MOST_RECENT, FbItem.FEED_TOP_STORIES).map { it.url }.toSet() +val messageWhitelist: Set<String> = + setOf(FbItem.MESSAGES, FbItem.CHAT, FbItem.FEED_MOST_RECENT, FbItem.FEED_TOP_STORIES) + .mapTo(mutableSetOf(), FbItem::url) val String.shouldUseBasicAgent: Boolean get() { diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt index a1fd594f..8824e635 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt @@ -65,7 +65,8 @@ open class FrostWebViewClient(val web: FrostWebView) : BaseWebViewClient() { if (url.isFacebookUrl) view.jsInject( CssAssets.ROUND_ICONS.maybe(Prefs.showRoundedIcons), - CssHider.CORE, +// CssHider.CORE, + CssHider.HEADER, CssHider.COMPOSER.maybe(!Prefs.showComposer), CssHider.PEOPLE_YOU_MAY_KNOW.maybe(!Prefs.showSuggestedFriends), CssHider.SUGGESTED_GROUPS.maybe(!Prefs.showSuggestedGroups), @@ -76,7 +77,7 @@ open class FrostWebViewClient(val web: FrostWebView) : BaseWebViewClient() { JsAssets.CLICK_A, CssHider.ADS.maybe(!Prefs.showFacebookAds), JsAssets.CONTEXT_A, - JsAssets.HEADER_HIDER, +// JsAssets.HEADER_HIDER, JsAssets.MEDIA) else refresh.onNext(false) |