aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/kotlin
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/kotlin')
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt26
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/LoginActivity.kt81
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/MainActivity.kt108
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt19
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/WebOverlayActivity.kt7
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt24
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/dbflow/FbTabsDb.kt3
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/events/FbAccountEvent.kt66
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/events/WebEvent.kt22
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/events/WebLaunchEvent.kt11
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/FbConst.kt8
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/FbCookie.kt39
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/FbTab.kt (renamed from app/src/main/kotlin/com/pitchedapps/frost/facebook/FbTabs.kt)16
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/UsernameFetcher.kt36
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/fragments/WebFragment.kt20
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt16
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt3
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/GlideUtils.kt26
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt2
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/views/ViewUtils.kt11
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt13
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebView.kt7
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt18
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewCore.kt12
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt101
25 files changed, 561 insertions, 134 deletions
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt b/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
index 068cf739..4c34ccfc 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
@@ -1,16 +1,23 @@
package com.pitchedapps.frost
import android.app.Application
+import android.content.Context
+import android.graphics.drawable.Drawable
+import android.net.Uri
+import android.widget.ImageView
+import com.bumptech.glide.Glide
+import com.bumptech.glide.request.RequestOptions
+import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader
+import com.mikepenz.materialdrawer.util.DrawerImageLoader
+import com.mikepenz.materialdrawer.util.DrawerUIUtils
import com.pitchedapps.frost.facebook.FbCookie
import com.pitchedapps.frost.utils.CrashReportingTree
-import com.pitchedapps.frost.utils.GlideUtils
import com.pitchedapps.frost.utils.Prefs
import com.raizlabs.android.dbflow.config.FlowConfig
import com.raizlabs.android.dbflow.config.FlowManager
import timber.log.Timber
import timber.log.Timber.DebugTree
-
/**
* Created by Allan Wang on 2017-05-28.
*/
@@ -21,9 +28,22 @@ class FrostApp : Application() {
else Timber.plant(CrashReportingTree())
FlowManager.init(FlowConfig.Builder(this).build())
Prefs(this)
- GlideUtils(this)
FbCookie()
super.onCreate()
+
+ //Drawer profile loading logic
+ DrawerImageLoader.init(object : AbstractDrawerImageLoader() {
+ override fun set(imageView: ImageView, uri: Uri, placeholder: Drawable, tag: String) {
+ Glide.with(imageView.context).load(uri).apply(RequestOptions().placeholder(placeholder)).into(imageView)
+ }
+
+ override fun placeholder(ctx: Context, tag: String): Drawable {
+ when (tag) {
+ DrawerImageLoader.Tags.PROFILE.name, DrawerImageLoader.Tags.ACCOUNT_HEADER.name -> DrawerUIUtils.getPlaceHolder(ctx)
+ }
+ return super.placeholder(ctx, tag);
+ }
+ })
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/LoginActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/LoginActivity.kt
new file mode 100644
index 00000000..03c40aaf
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/LoginActivity.kt
@@ -0,0 +1,81 @@
+package com.pitchedapps.frost
+
+import android.content.Context
+import android.content.Intent
+import android.graphics.drawable.Drawable
+import android.os.Bundle
+import android.support.v4.app.ActivityOptionsCompat
+import android.support.v4.content.ContextCompat
+import android.support.v4.widget.SwipeRefreshLayout
+import android.support.v7.app.AppCompatActivity
+import android.support.v7.widget.AppCompatTextView
+import android.support.v7.widget.Toolbar
+import android.widget.ImageView
+import butterknife.ButterKnife
+import com.bumptech.glide.Glide
+import com.bumptech.glide.load.DataSource
+import com.bumptech.glide.load.engine.GlideException
+import com.bumptech.glide.request.RequestListener
+import com.bumptech.glide.request.target.Target
+import com.pitchedapps.frost.dbflow.CookieModel
+import com.pitchedapps.frost.facebook.PROFILE_PICTURE_URL
+import com.pitchedapps.frost.utils.bindView
+import com.pitchedapps.frost.web.LoginWebView
+import io.reactivex.android.schedulers.AndroidSchedulers
+import io.reactivex.subjects.BehaviorSubject
+import io.reactivex.subjects.SingleSubject
+
+
+/**
+ * Created by Allan Wang on 2017-06-01.
+ */
+class LoginActivity : AppCompatActivity() {
+
+ val toolbar: Toolbar by bindView(R.id.toolbar)
+ val web: LoginWebView by bindView(R.id.login_webview)
+ val refresh: SwipeRefreshLayout by bindView(R.id.swipe_refresh)
+ val textview: AppCompatTextView by bindView(R.id.textview)
+ val profile: ImageView by bindView(R.id.profile)
+
+ val loginObservable = SingleSubject.create<CookieModel>()
+ val progressObservable = BehaviorSubject.create<Int>()
+
+ companion object {
+ fun newInstance(context: Context) {
+ val intent = Intent(context, LoginActivity::class.java)
+ val bundle = ActivityOptionsCompat.makeCustomAnimation(context, R.anim.slide_in_right, R.anim.slide_out_right).toBundle()
+ ContextCompat.startActivity(context, intent, bundle)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_login)
+ ButterKnife.bind(this)
+ setSupportActionBar(toolbar)
+ web.loginObservable = loginObservable
+ web.progressObservable = progressObservable
+ loginObservable.observeOn(AndroidSchedulers.mainThread()).subscribe {
+ cookieModel ->
+ Glide.with(this@LoginActivity).load(PROFILE_PICTURE_URL(cookieModel.id)).listener(object : RequestListener<Drawable> {
+ override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
+ return false
+ }
+
+ override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
+ return false
+ }
+
+ }).into(profile)
+ }
+ progressObservable.observeOn(AndroidSchedulers.mainThread()).subscribe {
+ val loading = it != 100
+ if (loading) refresh.isEnabled = true
+ refresh.isRefreshing = loading
+ if (!loading) refresh.isEnabled = false
+ }
+ web.loadLogin()
+ }
+
+
+} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/MainActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/MainActivity.kt
index c167dfdb..8b01e0c3 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/MainActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/MainActivity.kt
@@ -1,5 +1,7 @@
package com.pitchedapps.frost
+import android.app.Activity
+import android.content.Intent
import android.os.Bundle
import android.support.design.widget.FloatingActionButton
import android.support.design.widget.Snackbar
@@ -11,15 +13,29 @@ import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.Toolbar
import android.view.Menu
import android.view.MenuItem
-import android.view.ViewTreeObserver
import butterknife.ButterKnife
+import co.zsmb.materialdrawerkt.builders.Builder
+import co.zsmb.materialdrawerkt.builders.accountHeader
+import co.zsmb.materialdrawerkt.builders.drawer
+import co.zsmb.materialdrawerkt.draweritems.badgeable.primaryItem
+import co.zsmb.materialdrawerkt.draweritems.profile.profile
+import com.mikepenz.materialdrawer.AccountHeader
import com.mikepenz.materialdrawer.Drawer
+import com.pitchedapps.frost.dbflow.CookieModel
import com.pitchedapps.frost.dbflow.loadFbTabs
import com.pitchedapps.frost.dbflow.saveAsync
+import com.pitchedapps.frost.events.FbAccountEvent
+import com.pitchedapps.frost.facebook.FbCookie.switchUser
import com.pitchedapps.frost.facebook.FbTab
+import com.pitchedapps.frost.facebook.PROFILE_PICTURE_URL
import com.pitchedapps.frost.fragments.BaseFragment
import com.pitchedapps.frost.fragments.WebFragment
-import com.pitchedapps.frost.utils.*
+import com.pitchedapps.frost.utils.Changelog
+import com.pitchedapps.frost.utils.bindView
+import com.pitchedapps.frost.utils.toDrawable
+import org.greenrobot.eventbus.EventBus
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
class MainActivity : AppCompatActivity() {
@@ -29,15 +45,25 @@ class MainActivity : AppCompatActivity() {
val fab: FloatingActionButton by bindView(R.id.fab)
val tabs: TabLayout by bindView(R.id.tabs)
lateinit var drawer: Drawer
+ lateinit var drawerHeader: AccountHeader
+ lateinit var cookies: ArrayList<CookieModel>
+
+ companion object {
+ const val EXTRA_COOKIES = "extra_cookies"
+ fun launch(activity: Activity, cookies: List<CookieModel>) {
+ val intent = (Intent(activity, MainActivity::class.java))
+ intent.putParcelableArrayListExtra(EXTRA_COOKIES, ArrayList(cookies))
+ activity.startActivity(intent)
+ activity.finish()
+ }
+ }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
-// SwipeBackHelper.onCreate(this)
-// SwipeBackHelper.getCurrentPage(this).setSwipeBackEnable(false)
setContentView(R.layout.activity_main)
ButterKnife.bind(this)
setSupportActionBar(toolbar)
-
+ cookies = intent.extras.getParcelableArrayList<CookieModel>(EXTRA_COOKIES)
adapter = SectionsPagerAdapter(supportFragmentManager, loadFbTabs())
viewPager.adapter = adapter
viewPager.offscreenPageLimit = 5
@@ -56,42 +82,63 @@ class MainActivity : AppCompatActivity() {
}
})
setupTabs()
+ setupDrawer(savedInstanceState)
fab.setOnClickListener { view ->
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
}
-
- override fun onPostCreate(savedInstanceState: Bundle?) {
- super.onPostCreate(savedInstanceState)
-// SwipeBackHelper.onPostCreate(this)
- }
-
- override fun onDestroy() {
- super.onDestroy()
-// SwipeBackHelper.onDestroy(this)
- }
-
fun setupTabs() {
-
viewPager.addOnPageChangeListener(TabLayout.TabLayoutOnPageChangeListener(tabs))
tabs.addOnTabSelectedListener(TabLayout.ViewPagerOnTabSelectedListener(viewPager))
-// tabs.setupWithViewPager(viewPager)
adapter.pages.forEach { tabs.addTab(tabs.newTab().setIcon(it.icon.toDrawable(this))) }
}
+ fun setupDrawer(savedInstanceState: Bundle?) {
+ drawer = drawer {
+ toolbar = this@MainActivity.toolbar
+ savedInstance = savedInstanceState
+ translucentStatusBar = false
+ drawerHeader = accountHeader {
+ cookies.forEach {
+ profile(name = it.name ?: "") {
+ iconUrl = PROFILE_PICTURE_URL(it.id)
+ }
+ }
+ onProfileChanged { _, profile, current ->
+ if (current) WebOverlayActivity.newInstance(this@MainActivity, FbTab.PROFILE)
+ else switchUser(profile.name.text, -1)
+ false
+ }
+ }
+// profile("a") {
+//
+// }
+// if (Prefs.userId != Prefs.userIdDefault) {
+// profile("a")
+// }
+ primaryItem(FbTab.ACTIVITY_LOG)
+ primaryItem(FbTab.PHOTOS)
+ primaryItem(FbTab.GROUPS)
+ }
+ }
+
+ fun Builder.primaryItem(item: FbTab) = this.primaryItem(item.titleId) {
+ iicon = item.icon
+ identifier = item.titleId.toLong()
+ onClick { _ ->
+ WebOverlayActivity.newInstance(this@MainActivity, item.url)
+ false
+ }
+ }
override fun onCreateOptionsMenu(menu: Menu): Boolean {
- // Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.menu_main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
- // Handle action bar item clicks here. The action bar will
- // automatically handle clicks on the Home/Up button, so long
- // as you specify a parent activity in AndroidManifest.xml.
when (item.itemId) {
R.id.action_settings -> {
// startActivity(Intent(this, LoginActivity::class.java))
@@ -119,10 +166,6 @@ class MainActivity : AppCompatActivity() {
val currentFragment: BaseFragment
get() = supportFragmentManager.findFragmentByTag("android:switcher:${R.id.container}:${viewPager.currentItem}") as BaseFragment
- /**
- * A [FragmentPagerAdapter] that returns a fragment corresponding to
- * one of the sections/tabs/pages.
- */
inner class SectionsPagerAdapter(fm: FragmentManager, val pages: List<FbTab>) : FragmentPagerAdapter(fm) {
override fun getItem(position: Int) = WebFragment.newInstance(position, pages[position].url)
@@ -131,4 +174,17 @@ class MainActivity : AppCompatActivity() {
override fun getPageTitle(position: Int): CharSequence = getString(pages[position].titleId)
}
+
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ fun accountEvent(event: FbAccountEvent) = event.execute(drawerHeader)
+
+ override fun onStart() {
+ super.onStart();
+ EventBus.getDefault().register(this);
+ }
+
+ override fun onStop() {
+ EventBus.getDefault().unregister(this);
+ super.onStop();
+ }
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt
index e8c65be3..5d7d145f 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt
@@ -1,8 +1,10 @@
package com.pitchedapps.frost
-import android.content.Intent
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
+import com.pitchedapps.frost.dbflow.loadFbCookiesAsync
+import com.pitchedapps.frost.utils.L
+import com.pitchedapps.frost.utils.Prefs
/**
* Created by Allan Wang on 2017-05-28.
@@ -11,7 +13,18 @@ class StartActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- startActivity(Intent(this, MainActivity::class.java))
- finish()
+
+ L.d("Load cookies ${System.currentTimeMillis()}")
+ loadFbCookiesAsync {
+ cookies ->
+ L.d("Cookies loaded ${System.currentTimeMillis()} $cookies")
+ val sorted = cookies.toMutableList()
+ val current = cookies.filter { it.id == Prefs.userId }
+ if (current.isNotEmpty()) {
+ sorted.remove(current[0])
+ sorted.add(0, current[0])
+ }
+ MainActivity.launch(this, sorted)
+ }
}
} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/WebOverlayActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/WebOverlayActivity.kt
index fafcf7ae..9f6169cf 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/WebOverlayActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/WebOverlayActivity.kt
@@ -5,14 +5,13 @@ import android.content.Intent
import android.os.Bundle
import android.support.v4.app.ActivityOptionsCompat
import android.support.v4.content.ContextCompat
-import android.support.v4.widget.SwipeRefreshLayout
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.Toolbar
import butterknife.ButterKnife
import com.jude.swipbackhelper.SwipeBackHelper
+import com.pitchedapps.frost.facebook.FbTab
import com.pitchedapps.frost.utils.bindView
import com.pitchedapps.frost.web.FrostWebView
-import com.pitchedapps.frost.web.FrostWebViewCore
/**
@@ -21,7 +20,7 @@ import com.pitchedapps.frost.web.FrostWebViewCore
class WebOverlayActivity : AppCompatActivity() {
val toolbar: Toolbar by bindView(R.id.toolbar)
- val frostWeb:FrostWebView by bindView(R.id.frost_webview)
+ val frostWeb: FrostWebView by bindView(R.id.frost_webview)
companion object {
private const val ARG_URL = "arg_url"
@@ -31,6 +30,8 @@ class WebOverlayActivity : AppCompatActivity() {
val bundle = ActivityOptionsCompat.makeCustomAnimation(context, R.anim.slide_in_right, R.anim.slide_out_right).toBundle()
ContextCompat.startActivity(context, intent, bundle)
}
+
+ fun newInstance(context: Context, url: FbTab) = newInstance(context, url.url)
}
override fun onCreate(savedInstanceState: Bundle?) {
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt
index 12443cf1..28ad0800 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt
@@ -1,5 +1,7 @@
package com.pitchedapps.frost.dbflow
+import android.os.Parcel
+import android.os.Parcelable
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.Prefs
import com.raizlabs.android.dbflow.annotation.ConflictAction
@@ -8,6 +10,7 @@ import com.raizlabs.android.dbflow.annotation.PrimaryKey
import com.raizlabs.android.dbflow.annotation.Table
import com.raizlabs.android.dbflow.kotlinextensions.*
import com.raizlabs.android.dbflow.structure.BaseModel
+import paperparcel.PaperParcel
/**
* Created by Allan Wang on 2017-05-30.
@@ -16,16 +19,29 @@ import com.raizlabs.android.dbflow.structure.BaseModel
@Database(name = CookiesDb.NAME, version = CookiesDb.VERSION)
object CookiesDb {
const val NAME = "Cookies"
- const val VERSION = 1
+ const val VERSION = 2
}
+@PaperParcel
@Table(database = CookiesDb::class, allFields = true, primaryKeyConflict = ConflictAction.REPLACE)
-data class CookieModel(@PrimaryKey var id: Long = Prefs.userIdDefault, var cookie: String? = null) : BaseModel()
+data class CookieModel(@PrimaryKey var id: Long = Prefs.userIdDefault, var name: String? = null, var cookie: String? = null) : BaseModel(), Parcelable {
+ companion object {
+ @JvmField val CREATOR = PaperParcelCookieModel.CREATOR
+ }
+
+ override fun describeContents() = 0
+ override fun writeToParcel(dest: Parcel, flags: Int) = PaperParcelCookieModel.writeToParcel(this, dest, flags)
+}
fun loadFbCookie(id: Long): CookieModel? = (select from CookieModel::class where (CookieModel_Table.id eq id)).querySingle()
+fun loadFbCookie(name: String): CookieModel? = (select from CookieModel::class where (CookieModel_Table.name eq name)).querySingle()
+
+fun loadFbCookiesAsync(callback: (cookies: List<CookieModel>) -> Unit) {
+ (select from CookieModel::class).async().queryListResultCallback { _, tResult -> callback.invoke(tResult) }.execute()
+}
-fun saveFbCookie(id: Long, cookie: String?) {
- CookieModel(id, cookie).async save {
+fun saveFbCookie(cookie: CookieModel) {
+ cookie.async save {
L.d("Fb cookie saved")
}
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/FbTabsDb.kt b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/FbTabsDb.kt
index bed50527..2182f9ff 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/FbTabsDb.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/FbTabsDb.kt
@@ -2,6 +2,7 @@ package com.pitchedapps.frost.dbflow
import android.content.Context
import com.pitchedapps.frost.facebook.FbTab
+import com.pitchedapps.frost.facebook.defaultTabs
import com.pitchedapps.frost.utils.L
import com.raizlabs.android.dbflow.annotation.Database
import com.raizlabs.android.dbflow.annotation.PrimaryKey
@@ -32,7 +33,7 @@ fun loadFbTabs(): List<FbTab> {
val tabs: List<FbTabModel>? = SQLite.select().from(FbTabModel::class).orderBy(FbTabModel_Table.position, true).queryList()
if (tabs?.isNotEmpty() ?: false) return tabs!!.map { it.tab }
L.d("No tabs; loading default")
- return listOf(FbTab.FEED, FbTab.MESSAGES, FbTab.FRIENDS, FbTab.NOTIFICATIONS)
+ return defaultTabs()
}
fun List<FbTab>.saveAsync(c: Context) {
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/events/FbAccountEvent.kt b/app/src/main/kotlin/com/pitchedapps/frost/events/FbAccountEvent.kt
new file mode 100644
index 00000000..538a7919
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/events/FbAccountEvent.kt
@@ -0,0 +1,66 @@
+package com.pitchedapps.frost.events
+
+import com.mikepenz.materialdrawer.AccountHeader
+import com.mikepenz.materialdrawer.model.ProfileDrawerItem
+import com.pitchedapps.frost.dbflow.CookieModel
+import com.pitchedapps.frost.facebook.PROFILE_PICTURE_URL
+import com.pitchedapps.frost.facebook.UsernameFetcher
+import com.pitchedapps.frost.utils.L
+import com.pitchedapps.frost.web.FrostWebViewCore
+
+/**
+ * Created by Allan Wang on 2017-06-02.
+ *
+ * An emitter for whenever a change occurs relating to the active facebook account
+ * All subscribers will call one of the execute methods below so the logic is handled within this class
+ * [data] [CookieModel] content
+ * [sender] Webview position that sent the event; or -1 otherwise
+ * [flag] See companion object
+ */
+class FbAccountEvent(val data: CookieModel, val sender: Int, val flag: Int) {
+
+ init {
+ L.d(toString())
+ }
+
+ companion object {
+ const val FLAG_LOGOUT = -2
+ const val FLAG_RESET = -1
+ const val FLAG_NEW = 0
+ const val FLAG_SWITCH = 1
+ const val FLAG_USER_NAME = 2
+ }
+
+ fun execute(webView: FrostWebViewCore) {
+ if (sender != -1 && sender == webView.position) return
+ when (flag) {
+ FLAG_LOGOUT, FLAG_RESET, FLAG_NEW, FLAG_SWITCH -> webView.loadBaseUrl()
+ }
+ }
+
+ /**
+ * If new user id is found; create an account header and fetch the username
+ * If the username is found and the current account is nameless, set the name
+ * Ignore other flags
+ */
+ fun execute(accountHeader: AccountHeader) {
+ when (flag) {
+ FLAG_NEW -> {
+ val profile = ProfileDrawerItem()
+ .withName(data.name)
+ .withIcon(PROFILE_PICTURE_URL(data.id))
+ accountHeader.addProfile(profile, 0)
+ accountHeader.setActiveProfile(profile, true)
+ if (data.name == null)
+ UsernameFetcher.fetch(data, sender)
+ }
+ FLAG_USER_NAME -> {
+ if (accountHeader.activeProfile.name == null)
+ accountHeader.activeProfile.withName(data.name)
+ }
+ FLAG_LOGOUT -> {
+
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/events/WebEvent.kt b/app/src/main/kotlin/com/pitchedapps/frost/events/WebEvent.kt
deleted file mode 100644
index a2eb6907..00000000
--- a/app/src/main/kotlin/com/pitchedapps/frost/events/WebEvent.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.pitchedapps.frost.events
-
-import com.pitchedapps.frost.web.FrostWebViewCore
-
-/**
- * Created by Allan Wang on 2017-05-31.
- */
-class WebEvent(val key: Int, val urlMatch: String? = null) {
-
- companion object {
- const val REFRESH = 0
- const val REFRESH_BASE = 1
- }
-
- fun execute(webView: FrostWebViewCore) {
- if (urlMatch != null && !webView.url.contains(urlMatch)) return
- when (key) {
- REFRESH -> webView.reload()
- REFRESH_BASE -> webView.loadUrl(webView.baseUrl)
- }
- }
-} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/events/WebLaunchEvent.kt b/app/src/main/kotlin/com/pitchedapps/frost/events/WebLaunchEvent.kt
new file mode 100644
index 00000000..e32c01ae
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/events/WebLaunchEvent.kt
@@ -0,0 +1,11 @@
+package com.pitchedapps.frost.events
+
+import android.content.Context
+import com.pitchedapps.frost.WebOverlayActivity
+
+/**
+ * Created by Allan Wang on 2017-06-01.
+ */
+class WebLaunchEvent(val url: String) {
+ fun execute(context: Context) = WebOverlayActivity.newInstance(context, url)
+} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbConst.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbConst.kt
new file mode 100644
index 00000000..59d76954
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbConst.kt
@@ -0,0 +1,8 @@
+package com.pitchedapps.frost.facebook
+
+/**
+ * Created by Allan Wang on 2017-06-01.
+ */
+const val FACEBOOK_COM = "facebook.com"
+const val FB_URL_BASE = "https://m.facebook.com/"
+fun PROFILE_PICTURE_URL(id: Long) = "https://graph.facebook.com/$id/picture?type=large" \ No newline at end of file
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 e44b872a..7829998f 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbCookie.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbCookie.kt
@@ -1,11 +1,11 @@
package com.pitchedapps.frost.facebook
import android.webkit.CookieManager
+import com.pitchedapps.frost.dbflow.CookieModel
import com.pitchedapps.frost.dbflow.loadFbCookie
import com.pitchedapps.frost.dbflow.removeCookie
import com.pitchedapps.frost.dbflow.saveFbCookie
-import com.pitchedapps.frost.events.WebEvent
-import com.pitchedapps.frost.utils.GlideUtils
+import com.pitchedapps.frost.events.FbAccountEvent
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.Prefs
import org.greenrobot.eventbus.EventBus
@@ -34,48 +34,55 @@ object FbCookie {
private val userMatcher: Regex by lazy { Regex("c_user=([0-9]*);") }
- fun checkUserId(url: String, cookie: String?) {
- if (Prefs.userId != Prefs.userIdDefault || cookie == null) return
+ fun hasLoggedIn(url: String, cookie: String?):Boolean {
+ if (cookie == null || !url.contains("facebook") || !cookie.contains(userMatcher)) return false
L.d("Checking cookie for $url\n\t$cookie")
- if (!url.contains("facebook") || !cookie.contains(userMatcher)) return
val id = userMatcher.find(cookie)?.groups?.get(1)?.value
if (id != null) {
try {
- save(id.toLong())
+ save(id.toLong(), -1)
+ return true
} catch (e: NumberFormatException) {
//todo send report that id has changed
}
}
+ return false
}
- fun save(id: Long) {
+ fun save(id: Long, sender: Int) {
L.d("New cookie found for $id")
Prefs.userId = id
CookieManager.getInstance().flush()
- EventBus.getDefault().post(WebEvent(WebEvent.REFRESH_BASE))
- saveFbCookie(Prefs.userId, webCookie)
- GlideUtils.downloadProfile(id)
+ val cookie = CookieModel(Prefs.userId, "", webCookie)
+ EventBus.getDefault().post(FbAccountEvent(cookie, sender, FbAccountEvent.FLAG_NEW))
+ saveFbCookie(cookie)
}
//TODO reset when new account is added; reset and clear when account is logged out
- fun reset() {
+ fun reset(loggedOut: Boolean = false, sender: Int) {
Prefs.userId = Prefs.userIdDefault
with(CookieManager.getInstance()) {
removeAllCookies(null)
flush()
}
+ EventBus.getDefault().post(FbAccountEvent(CookieModel(), sender, if (loggedOut) FbAccountEvent.FLAG_LOGOUT else FbAccountEvent.FLAG_RESET))
}
- fun switchUser(id: Long) {
- val cookie = loadFbCookie(id) ?: return
- Prefs.userId = id
+ fun switchUser(id: Long, sender: Int) = switchUser(loadFbCookie(id), sender)
+
+ fun switchUser(name: String, sender: Int) = switchUser(loadFbCookie(name), sender)
+
+ fun switchUser(cookie: CookieModel?, sender: Int) {
+ if (cookie == null) return
+ Prefs.userId = cookie.id
dbCookie = cookie.cookie
webCookie = dbCookie
+ EventBus.getDefault().post(FbAccountEvent(cookie, sender, FbAccountEvent.FLAG_SWITCH))
}
- fun logout() {
+ fun logout(sender: Int) {
L.d("Logging out user ${Prefs.userId}")
removeCookie(Prefs.userId)
- reset()
+ reset(true, sender)
}
} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbTabs.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbTab.kt
index d391d20f..6b4a2f35 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbTabs.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbTab.kt
@@ -1,6 +1,5 @@
package com.pitchedapps.frost.facebook
-import android.content.Context
import android.support.annotation.StringRes
import com.mikepenz.community_material_typeface_library.CommunityMaterial
import com.mikepenz.google_material_typeface_library.GoogleMaterial
@@ -9,16 +8,23 @@ import com.mikepenz.material_design_iconic_typeface_library.MaterialDesignIconic
import com.pitchedapps.frost.R
enum class FbTab(@StringRes val titleId: Int, val icon: IIcon, relativeUrl: String) {
-// LOGIN(R.string.feed, CommunityMaterial.Icon.cmd_newspaper, "https://www.facebook.com/v2.9/dialog/oauth?client_id=${FB_KEY}&redirect_uri=https://touch.facebook.com/&response_type=token,granted_scopes"),
FEED(R.string.feed, CommunityMaterial.Icon.cmd_newspaper, ""),
PROFILE(R.string.profile, CommunityMaterial.Icon.cmd_account, "me"),
EVENTS(R.string.events, GoogleMaterial.Icon.gmd_event, "events/upcoming"),
FRIENDS(R.string.friends, GoogleMaterial.Icon.gmd_people, "friends/center/requests"),
MESSAGES(R.string.messages, MaterialDesignIconic.Icon.gmi_comments, "messages?disable_interstitial=1&rdr"),
- NOTIFICATIONS(R.string.notifications, MaterialDesignIconic.Icon.gmi_globe, "notifications");
+ NOTIFICATIONS(R.string.notifications, MaterialDesignIconic.Icon.gmi_globe, "notifications"),
+ ACTIVITY_LOG(R.string.activity_log, GoogleMaterial.Icon.gmd_list, "me/allactivity"),
+ PAGES(R.string.pages, GoogleMaterial.Icon.gmd_flag, "pages"),
+ GROUPS(R.string.groups, GoogleMaterial.Icon.gmd_group, "groups"),
+ SAVED(R.string.saved, GoogleMaterial.Icon.gmd_bookmark, "saved"),
+ BIRTHDAYS(R.string.birthdays, GoogleMaterial.Icon.gmd_cake, "events/birthdays"),
+ CHAT(R.string.chat, GoogleMaterial.Icon.gmd_chat, "buddylist"),
+ PHOTOS(R.string.photos, GoogleMaterial.Icon.gmd_photo, "me/photos"),
+ ;
val url = "$FB_URL_BASE$relativeUrl"
}
-const val FACEBOOK_COM = "facebook.com"
-const val FB_URL_BASE = "https://m.facebook.com/" \ No newline at end of file
+fun defaultTabs():List<FbTab> = listOf(FbTab.FEED, FbTab.MESSAGES, FbTab.FRIENDS, FbTab.NOTIFICATIONS)
+fun defaultDrawers():List<FbTab> = listOf(FbTab.ACTIVITY_LOG, FbTab.PAGES, FbTab.GROUPS, FbTab.SAVED) \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/UsernameFetcher.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/UsernameFetcher.kt
new file mode 100644
index 00000000..da244ba3
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/UsernameFetcher.kt
@@ -0,0 +1,36 @@
+package com.pitchedapps.frost.facebook
+
+import com.pitchedapps.frost.dbflow.CookieModel
+import com.pitchedapps.frost.dbflow.saveFbCookie
+import com.pitchedapps.frost.events.FbAccountEvent
+import com.pitchedapps.frost.utils.L
+import org.greenrobot.eventbus.EventBus
+import org.jsoup.Jsoup
+import kotlin.concurrent.thread
+
+/**
+ * Created by Allan Wang on 2017-06-02.
+ */
+object UsernameFetcher {
+
+ fun fetch(data: CookieModel, sender: Int) {
+ thread {
+ try {
+ val title = Jsoup.connect(FbTab.PROFILE.url)
+ .cookie(FACEBOOK_COM, data.cookie)
+ .get().title()
+ L.d("User name found: $title")
+ data.name = title
+ } catch (e: Exception) {
+ L.e("User name fetching failed: ${e.message}")
+ data.name = ""
+ } finally {
+ if (data.name != null) {
+ saveFbCookie(data)
+ EventBus.getDefault().post(FbAccountEvent(data, sender, FbAccountEvent.FLAG_USER_NAME))
+ }
+ }
+ }
+ }
+
+} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/fragments/WebFragment.kt b/app/src/main/kotlin/com/pitchedapps/frost/fragments/WebFragment.kt
index 21d019e7..39c93b01 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/fragments/WebFragment.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/WebFragment.kt
@@ -5,6 +5,7 @@ import android.support.v4.widget.SwipeRefreshLayout
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.putString
import com.pitchedapps.frost.web.FrostWebView
import com.pitchedapps.frost.web.FrostWebViewCore
@@ -25,6 +26,7 @@ class WebFragment : BaseFragment() {
val web: FrostWebViewCore by lazy { frostWebView.web }
lateinit var url: String
lateinit private var frostWebView: FrostWebView
+ private var firstLoad = true
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -34,9 +36,27 @@ class WebFragment : BaseFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
super.onCreateView(inflater, container, savedInstanceState)
frostWebView = FrostWebView(context)
+ frostWebView.position = position
frostWebView.baseUrl = url
return frostWebView
}
+ override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ firstLoad()
+ }
+
+ override fun setUserVisibleHint(isVisibleToUser: Boolean) {
+ super.setUserVisibleHint(isVisibleToUser)
+ firstLoad()
+ }
+
+ fun firstLoad() {
+ if (userVisibleHint && isVisible && firstLoad) {
+ web.loadBaseUrl()
+ firstLoad = false
+ }
+ }
+
override fun onBackPressed() = frostWebView.onBackPressed()
} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt
index 0482fdc9..5433be60 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt
@@ -5,19 +5,21 @@ import com.pitchedapps.frost.utils.L
/**
* Created by Allan Wang on 2017-05-31.
+ * Mapping of the available assets
+ * The enum name must match the css file name
+ * //TODO add folder mapping using Prefs
*/
-enum class CssAssets(f: String) {
- BASE("facebook");
+enum class CssAssets {
+ HEADER, LOGIN
+ ;
- var file = "$f.compact.css"
- var content: String? = null
+ var file = "${name.toLowerCase()}.compact.css"
var injector: JsInjector? = null
fun inject(webView: WebView, callback: ((String) -> Unit)?) {
if (injector == null) {
- if (content == null)
- content = webView.context.assets.open(file).bufferedReader().use { it.readText() }
- injector = JsBuilder().css(content!!).build()
+ val content = webView.context.assets.open("core/$file").bufferedReader().use { it.readText() }
+ injector = JsBuilder().css(content).build()
}
injector!!.inject(webView, callback)
L.d("CSS ${injector!!.function}")
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 c7b4eaf8..4ab48bdb 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt
@@ -64,7 +64,8 @@ class JsBuilder {
}
if (css.isNotBlank()) {
val name = v.next
- builder.append("var $name=document.createElement('style');$name.innerHTML='$css';document.head.appendChild($name);")
+ val cssMin = css.replace(Regex("\\s+"), "")
+ builder.append("var $name=document.createElement('style');$name.innerHTML='$cssMin';document.head.appendChild($name);")
}
return builder.append("}()").toString()
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/GlideUtils.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/GlideUtils.kt
deleted file mode 100644
index 6fbcced1..00000000
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/GlideUtils.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.pitchedapps.frost.utils
-
-import android.content.Context
-import com.bumptech.glide.Glide
-
-/**
- * Created by Allan Wang on 2017-05-31.
- */
-object GlideUtils {
-
- lateinit var applicationContext: Context
-
- operator fun invoke(applicationContext: Context) {
- this.applicationContext = applicationContext
- }
-
- fun downloadForLater(url: String) {
- Glide.with(applicationContext).download(url)
- }
-
- fun downloadProfile(id: Long) {
- L.d("Downloading profile photo")
- downloadForLater("http://graph.facebook.com/$id/picture?type=large")
- }
-
-} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt
index 49cc2f9b..2465980d 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt
@@ -11,6 +11,8 @@ object L {
const val TAG = "Frost: %s"
fun e(s: String) = Timber.e(TAG, s)
fun d(s: String) = Timber.d(TAG, s)
+ fun i(s: String) = Timber.i(TAG, s)
+ fun v(s: String) = Timber.v(TAG, s)
}
internal class CrashReportingTree : Timber.Tree() {
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/ViewUtils.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/ViewUtils.kt
index 01a49f7e..8dc3f01f 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/views/ViewUtils.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/views/ViewUtils.kt
@@ -1,9 +1,10 @@
package com.pitchedapps.frost.views
import android.content.res.ColorStateList
-import android.graphics.PorterDuff
import android.support.annotation.ColorInt
import android.support.annotation.ColorRes
+import android.support.annotation.StringRes
+import android.support.design.widget.Snackbar
import android.support.v4.content.ContextCompat
import android.view.View
import android.view.ViewGroup
@@ -27,4 +28,12 @@ fun ProgressBar.tint(@ColorInt color: Int) {
progressTintList = sl
secondaryProgressTintList = sl
indeterminateTintList = sl
+}
+
+fun View.snackbar(text: String, duration: Int = Snackbar.LENGTH_LONG) {
+ Snackbar.make(this, text, duration).show()
+}
+
+fun View.snackbar(@StringRes textId: Int, duration: Int = Snackbar.LENGTH_LONG) {
+ Snackbar.make(this, textId, duration).show()
} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt
new file mode 100644
index 00000000..8be4e278
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt
@@ -0,0 +1,13 @@
+package com.pitchedapps.frost.web
+
+import android.webkit.JavascriptInterface
+import com.pitchedapps.frost.events.WebLaunchEvent
+import org.greenrobot.eventbus.EventBus
+
+/**
+ * Created by Allan Wang on 2017-06-01.
+ */
+class FrostJSI {
+ @JavascriptInterface
+ fun loadUrl(url: String) = EventBus.getDefault().post(WebLaunchEvent(url))
+} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebView.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebView.kt
index a9cf0559..087e9174 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebView.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebView.kt
@@ -9,7 +9,6 @@ import android.widget.FrameLayout
import android.widget.ProgressBar
import butterknife.ButterKnife
import com.pitchedapps.frost.R
-import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.bindView
import io.reactivex.android.schedulers.AndroidSchedulers
@@ -22,11 +21,15 @@ class FrostWebView @JvmOverloads constructor(context: Context, attrs: AttributeS
get() = web.baseUrl
set(value) {
web.baseUrl = value
- if (value != null) web.loadUrl(value)
}
val refresh: SwipeRefreshLayout by bindView(R.id.swipe_refresh)
val web: FrostWebViewCore by bindView(R.id.frost_webview_core)
val progress: ProgressBar by bindView(R.id.progressBar)
+ var position: Int
+ get() = web.position
+ set(value) {
+ web.position = value
+ }
init {
inflate(getContext(), R.layout.swipe_webview, this)
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt
index 143c9f5a..4dcf0d9e 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt
@@ -9,12 +9,11 @@ import com.pitchedapps.frost.injectors.CssAssets
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.views.circularReveal
import com.pitchedapps.frost.views.fadeOut
-import io.reactivex.subjects.Subject
/**
* Created by Allan Wang on 2017-05-31.
*/
-class FrostWebViewClient : WebViewClient() {
+class FrostWebViewClient(val position: () -> Int) : WebViewClient() {
companion object {
//Collections of jewels mapped with url match -> id
@@ -27,17 +26,17 @@ class FrostWebViewClient : WebViewClient() {
override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
- L.d("FWV Loading $url")
+ L.i("FWV Loading $url")
if (!url.contains(FACEBOOK_COM)) return
- if (url.contains("logout.php")) FbCookie.logout()
+ if (url.contains("logout.php")) FbCookie.logout(position.invoke())
view.fadeOut(duration = 200L)
}
override fun onPageFinished(view: WebView, url: String) {
super.onPageFinished(view, url)
if (!url.contains(FACEBOOK_COM)) return
- FbCookie.checkUserId(url, CookieManager.getInstance().getCookie(url))
- CssAssets.BASE.inject(view, {
+ FbCookie.checkUserId(url, CookieManager.getInstance().getCookie(url), position.invoke())
+ CssAssets.HEADER.inject(view, {
view.circularReveal(offset = 150L)
})
}
@@ -48,23 +47,22 @@ class FrostWebViewClient : WebViewClient() {
}
override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
- L.d("Hi")
L.d("Url Loading ${request.url?.path}")
return super.shouldOverrideUrlLoading(view, request)
}
override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse? {
if (!request.url.host.contains(FACEBOOK_COM)) return super.shouldInterceptRequest(view, request)
- L.d("Url intercept ${request.url.path}")
+ L.v("Url intercept ${request.url.path}")
return super.shouldInterceptRequest(view, request)
}
override fun onLoadResource(view: WebView, url: String) {
if (!url.contains(FACEBOOK_COM)) return super.onLoadResource(view, url)
- L.d("Resource $url")
+ L.v("Resource $url")
FrostWebOverlay.values.forEach {
if (url.contains(it.match))
- L.d("Loaded $it")
+ L.d("Resource Loaded $it")
}
super.onLoadResource(view, url)
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewCore.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewCore.kt
index 03659908..b2260b6f 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewCore.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewCore.kt
@@ -10,12 +10,13 @@ import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.webkit.WebView
-import com.pitchedapps.frost.events.WebEvent
+import com.pitchedapps.frost.events.FbAccountEvent
import com.pitchedapps.frost.utils.ObservableContainer
import io.reactivex.subjects.BehaviorSubject
import io.reactivex.subjects.Subject
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
/**
* Created by Allan Wang on 2017-05-29.
@@ -35,6 +36,7 @@ class FrostWebViewCore @JvmOverloads constructor(
private var nestedOffsetY: Int = 0
override val progressObservable: Subject<Int> //TODO see if we need this
var baseUrl: String? = null
+ var position: Int = -1
init {
isNestedScrollingEnabled = true
@@ -47,7 +49,7 @@ class FrostWebViewCore @JvmOverloads constructor(
settings.javaScriptEnabled = true
settings.domStorageEnabled = true
setLayerType(View.LAYER_TYPE_HARDWARE, null)
- setWebViewClient(FrostWebViewClient())
+ setWebViewClient(FrostWebViewClient({position}))
setWebChromeClient(FrostChromeClient(progressObservable))
}
@@ -56,6 +58,8 @@ class FrostWebViewCore @JvmOverloads constructor(
super.loadUrl(url)
}
+ fun loadBaseUrl() = loadUrl(baseUrl)
+
override fun onTouchEvent(ev: MotionEvent): Boolean {
val event = MotionEvent.obtain(ev)
val action = MotionEventCompat.getActionMasked(event)
@@ -106,8 +110,8 @@ class FrostWebViewCore @JvmOverloads constructor(
super.onDetachedFromWindow()
}
- @Subscribe
- fun webEvent(event: WebEvent) = event.execute(this)
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ fun webEvent(event: FbAccountEvent) = event.execute(this)
// Nested Scroll implements
override fun setNestedScrollingEnabled(enabled: Boolean) {
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt
new file mode 100644
index 00000000..6e0cf201
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt
@@ -0,0 +1,101 @@
+package com.pitchedapps.frost.web
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.util.AttributeSet
+import android.view.View
+import android.webkit.*
+import com.pitchedapps.frost.dbflow.CookieModel
+import com.pitchedapps.frost.facebook.FACEBOOK_COM
+import com.pitchedapps.frost.facebook.FbCookie
+import com.pitchedapps.frost.injectors.CssAssets
+import com.pitchedapps.frost.utils.L
+import com.pitchedapps.frost.views.circularReveal
+import com.pitchedapps.frost.views.snackbar
+import io.reactivex.subjects.PublishSubject
+import io.reactivex.subjects.SingleSubject
+import io.reactivex.subjects.Subject
+
+/**
+ * Created by Allan Wang on 2017-05-29.
+ *
+ * Courtesy of takahirom
+ *
+ * https://github.com/takahirom/webview-in-coordinatorlayout/blob/master/app/src/main/java/com/github/takahirom/webview_in_coodinator_layout/NestedWebView.java
+ */
+
+
+class LoginWebView @JvmOverloads constructor(
+ context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+) : WebView(context, attrs, defStyleAttr) {
+
+ companion object {
+ const val LOGIN_URL = "https://touch.facebook.com/login"
+ private val userMatcher: Regex by lazy { Regex("c_user=([0-9]*);") }
+ }
+
+ val cookieObservable = PublishSubject.create<Pair<String, String?>>()
+ lateinit var loginObservable: SingleSubject<CookieModel>
+ lateinit var progressObservable: Subject<Int>
+
+ init {
+ cookieObservable.filter { (_, cookie) -> cookie?.contains(userMatcher) ?: false }
+ .subscribe {
+ (url, cookie) ->
+ L.d("Checking cookie for $url\n\t$cookie")
+ val id = userMatcher.find(cookie!!)?.groups?.get(1)?.value
+ if (id != null) {
+ try {
+ FbCookie.save(id.toLong(), -1)
+ //TODO proceed to next view
+ cookieObservable.onComplete()
+ } catch (e: NumberFormatException) {
+ //todo send report that id has changed
+ }
+ }
+ }
+ setupWebview()
+ }
+
+ @SuppressLint("SetJavaScriptEnabled")
+ fun setupWebview() {
+ settings.javaScriptEnabled = true
+ setLayerType(View.LAYER_TYPE_HARDWARE, null)
+ setWebViewClient(LoginClient())
+ setWebChromeClient(LoginChromeClient())
+ }
+
+ fun loadLogin() {
+ loadUrl(LOGIN_URL)
+ }
+
+
+ inner class LoginClient : WebViewClient() {
+
+ override fun onPageFinished(view: WebView, url: String) {
+ super.onPageFinished(view, url)
+ if (!url.contains(FACEBOOK_COM)) {
+ view.snackbar("No longer under facebook; refreshing...")
+ loadLogin()
+ return
+ }
+ CssAssets.LOGIN.inject(view, {
+ if (view.visibility == View.INVISIBLE)
+ view.circularReveal(offset = 150L)
+ })
+ cookieObservable.onNext(Pair(url, CookieManager.getInstance().getCookie(url)))
+ }
+ }
+
+ inner class LoginChromeClient : WebChromeClient() {
+ override fun onConsoleMessage(consoleMessage: ConsoleMessage): Boolean {
+ L.d("Login Console ${consoleMessage.lineNumber()}: ${consoleMessage.message()}")
+ return super.onConsoleMessage(consoleMessage)
+ }
+
+ override fun onProgressChanged(view: WebView, newProgress: Int) {
+ super.onProgressChanged(view, newProgress)
+ progressObservable.onNext(newProgress)
+ }
+ }
+} \ No newline at end of file