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/FbActivity.kt21
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt10
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/LoginActivity.kt64
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/MainActivity.kt6
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt2
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/FbToken.kt13
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/UrlData.kt3
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/retro/FrostApi.kt52
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/retro/FrostData.kt8
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/retro/FrostInterceptor.kt29
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/retro/IFrost.kt16
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt32
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt8
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/views/FrostWebView.kt1
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/views/LoginWebView.kt78
15 files changed, 321 insertions, 22 deletions
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/FbActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/FbActivity.kt
new file mode 100644
index 00000000..0132a4db
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/FbActivity.kt
@@ -0,0 +1,21 @@
+package com.pitchedapps.frost
+
+import android.os.Bundle
+import android.support.annotation.CallSuper
+import android.support.v7.app.AppCompatActivity
+import com.facebook.AccessToken
+import com.pitchedapps.frost.utils.L
+
+/**
+ * Created by Allan Wang on 2017-05-29.
+ */
+open class FbActivity : AppCompatActivity() {
+ var accessToken: AccessToken? = null
+
+ @CallSuper
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ accessToken = AccessToken.getCurrentAccessToken()
+ L.e("Access ${accessToken?.token}")
+ }
+} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt b/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
index e050f285..0fb4e7db 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
@@ -1,6 +1,8 @@
package com.pitchedapps.frost
import android.app.Application
+import com.pitchedapps.frost.facebook.retro.FrostApi
+import com.pitchedapps.frost.facebook.retro.IFrost
import com.pitchedapps.frost.utils.CrashReportingTree
import com.pitchedapps.frost.utils.Prefs
import io.realm.Realm
@@ -13,15 +15,11 @@ import timber.log.Timber.DebugTree
*/
class FrostApp : Application() {
- companion object {
- lateinit var prefs: Prefs
- }
-
override fun onCreate() {
if (BuildConfig.DEBUG) Timber.plant(DebugTree())
else Timber.plant(CrashReportingTree())
-
- prefs = Prefs(applicationContext)
+ Prefs(applicationContext)
+ FrostApi(applicationContext)
Realm.init(applicationContext)
super.onCreate()
}
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..8ef60991
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/LoginActivity.kt
@@ -0,0 +1,64 @@
+package com.pitchedapps.frost
+
+import android.content.Intent
+import android.content.pm.PackageInstaller
+import android.os.Bundle
+import android.widget.Button
+import com.facebook.CallbackManager
+import com.facebook.FacebookCallback
+import com.facebook.FacebookException
+import com.facebook.login.LoginBehavior
+import com.facebook.login.LoginManager
+import com.facebook.login.LoginResult
+import com.facebook.login.widget.LoginButton
+import com.pitchedapps.frost.utils.L
+import java.util.*
+
+
+/**
+ * Created by Allan Wang on 2017-05-29.
+ */
+class LoginActivity : FbActivity() {
+ lateinit var callback: CallbackManager
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.login_teest)
+ val loginButton = findViewById(R.id.login_button) as LoginButton
+ loginButton.loginBehavior = LoginBehavior.WEB_VIEW_ONLY
+ loginButton.setReadPermissions("email")
+ val switchh = findViewById(R.id.switchh) as Button
+ switchh.setOnClickListener {
+ startActivity(Intent(this, MainActivity::class.java))
+ finish()
+ }
+ // If using in a fragment
+// loginButton.setFragment(this)
+ // Other app specific specialization
+
+ // Callback registration
+ callback = CallbackManager.Factory.create()
+ loginButton.registerCallback(callback, object : FacebookCallback<LoginResult> {
+ override fun onSuccess(loginResult: LoginResult) {
+ L.e("Success")
+ L.e("Success ${loginResult.accessToken.token}")
+ }
+
+ override fun onCancel() {
+ // App code
+ L.e("Cancel")
+ }
+
+ override fun onError(exception: FacebookException) {
+ // App code
+ L.e("Error")
+ }
+ })
+
+// LoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("public_profile"));
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+ callback.onActivityResult(requestCode, resultCode, data)
+ }
+} \ 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 0db5ee72..deb4f5d6 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/MainActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/MainActivity.kt
@@ -1,5 +1,6 @@
package com.pitchedapps.frost
+import android.content.Intent
import android.os.Bundle
import android.support.design.widget.FloatingActionButton
import android.support.design.widget.Snackbar
@@ -69,7 +70,10 @@ class MainActivity : AppCompatActivity(), KeyPairObservable {
// 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 -> return true
+ R.id.action_settings -> {
+ startActivity(Intent(this, LoginActivity::class.java))
+ finish()
+ }
R.id.action_changelog -> Changelog.show(this)
else -> return super.onOptionsItemSelected(item)
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt
index e8c65be3..390efb1a 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt
@@ -11,7 +11,7 @@ class StartActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- startActivity(Intent(this, MainActivity::class.java))
+ startActivity(Intent(this, LoginActivity::class.java))
finish()
}
} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbToken.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbToken.kt
new file mode 100644
index 00000000..22dc25f7
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbToken.kt
@@ -0,0 +1,13 @@
+package com.pitchedapps.frost.facebook
+
+import com.facebook.AccessToken
+
+/**
+ * Created by Allan Wang on 2017-05-30.
+ */
+val token: String?
+ get() = AccessToken.getCurrentAccessToken()?.token
+
+fun setToken() {
+
+} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/UrlData.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/UrlData.kt
index 80972050..d5f9db6e 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/UrlData.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/UrlData.kt
@@ -18,6 +18,7 @@ import io.realm.annotations.PrimaryKey
* Created by Allan Wang on 2017-05-29.
*/
enum class FbUrl(@StringRes val titleId: Int, val icon: IIcon, val url: 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, "https://touch.facebook.com/"),
PROFILE(R.string.profile, CommunityMaterial.Icon.cmd_account, "https://touch.facebook.com/me/"),
EVENTS(R.string.events, GoogleMaterial.Icon.gmd_event, "https://touch.facebook.com/events/upcoming"),
@@ -60,6 +61,6 @@ fun loadFbTab(c: Context): List<FbTab> {
val realmList = mutableListOf<FbTabRealm>()
realm(RealmFiles.TABS, Realm.Transaction { it.copyFromRealm(realmList) })
if (realmList.isNotEmpty()) return realmList.map { FbTab(it) }
- return FbUrl.values().map { it.tabInfo(c) }
+ return listOf(FbUrl.FEED, FbUrl.MESSAGES, FbUrl.NOTIFICATIONS).map { it.tabInfo(c) }
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/retro/FrostApi.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/retro/FrostApi.kt
new file mode 100644
index 00000000..746bf0df
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/retro/FrostApi.kt
@@ -0,0 +1,52 @@
+package com.pitchedapps.frost.facebook.retro
+
+import android.content.Context
+import com.facebook.stetho.okhttp3.StethoInterceptor
+import com.google.gson.GsonBuilder
+import com.pitchedapps.frost.BuildConfig
+import io.reactivex.schedulers.Schedulers
+import okhttp3.Cache
+import okhttp3.OkHttpClient
+import okhttp3.logging.HttpLoggingInterceptor
+import retrofit2.Retrofit
+import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
+import retrofit2.converter.gson.GsonConverterFactory
+import java.io.File
+
+/**
+ * Created by Allan Wang on 2017-05-30.
+ *
+ * API for data retrieval
+ */
+object FrostApi {
+
+ internal lateinit var frostApi: IFrost
+
+ operator fun invoke(context: Context) {
+ val cacheDir = File(context.cacheDir, "responses")
+ val cacheSize = 5L * 1024 * 1024 //10MiB
+ val cache = Cache(cacheDir, cacheSize)
+
+ val client = OkHttpClient.Builder()
+ .addInterceptor(FrostInterceptor(context))
+ .cache(cache)
+
+
+ //add logger and stetho last
+
+ if (BuildConfig.DEBUG || BuildConfig.BUILD_TYPE == "releaseTest") { //log if not full release
+ client.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BASIC))
+ client.addNetworkInterceptor(StethoInterceptor())
+ }
+
+ val gson = GsonBuilder().setLenient()
+
+ val retrofit = Retrofit.Builder()
+ .baseUrl("https://graph.facebook.com/")
+ .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
+ .addConverterFactory(GsonConverterFactory.create(gson.create()))
+ .client(client.build())
+ .build();
+ frostApi = retrofit.create(IFrost::class.java)
+ }
+} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/retro/FrostData.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/retro/FrostData.kt
new file mode 100644
index 00000000..07d686a7
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/retro/FrostData.kt
@@ -0,0 +1,8 @@
+package com.pitchedapps.frost.facebook.retro
+
+/**
+ * Created by Allan Wang on 2017-05-30.
+ *
+ * Collection of Graph API outputs
+ */
+data class Me(val name: String, val id: String) \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/retro/FrostInterceptor.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/retro/FrostInterceptor.kt
new file mode 100644
index 00000000..f745aedf
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/retro/FrostInterceptor.kt
@@ -0,0 +1,29 @@
+package com.pitchedapps.frost.facebook.retro
+
+import android.content.Context
+import com.pitchedapps.frost.facebook.token
+import com.pitchedapps.frost.utils.Utils
+import okhttp3.Interceptor
+import okhttp3.Response
+
+/**
+ * Created by Allan Wang on 2017-05-30.
+ */
+private val maxStale = 60 * 60 * 24 * 28 //maxAge to get from cache if online (4 weeks)
+const val ACCESS_TOKEN = "access_token"
+
+class FrostInterceptor(val context: Context) : Interceptor {
+
+ override fun intercept(chain: Interceptor.Chain): Response? {
+ val request = chain.request()
+ val requestBuilder = request.newBuilder()
+ val urlBase = request.url()
+ val urlWithToken = urlBase.newBuilder()
+ if (urlBase.queryParameter(ACCESS_TOKEN) == null && token != null)
+ urlWithToken.addQueryParameter(ACCESS_TOKEN, token)
+ requestBuilder.url(urlWithToken.build())
+ if (!Utils.isNetworkAvailable(context)) requestBuilder.addHeader("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
+ return chain.proceed(requestBuilder.build())
+ }
+
+} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/retro/IFrost.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/retro/IFrost.kt
new file mode 100644
index 00000000..6c50fa74
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/retro/IFrost.kt
@@ -0,0 +1,16 @@
+package com.pitchedapps.frost.facebook.retro
+
+import com.pitchedapps.frost.facebook.token
+import retrofit2.Call
+import retrofit2.http.GET
+import retrofit2.http.Query
+
+/**
+ * Created by Allan Wang on 2017-05-30.
+ */
+interface IFrost {
+
+ @GET("me")
+ fun me(@Query(ACCESS_TOKEN) accessToken: String? = token): Call<Me>
+
+} \ No newline at end of file
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 fc2e9d1c..ad222145 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt
@@ -1,30 +1,36 @@
package com.pitchedapps.frost.utils
-import com.pitchedapps.frost.FrostApp
+import android.content.Context
+import android.content.SharedPreferences
/**
* Created by Allan Wang on 2017-05-28.
*/
-val prefs: Prefs by lazy { FrostApp.prefs }
-class Prefs(c: android.content.Context) {
- private companion object {
- val PREFERENCE_NAME = "${com.pitchedapps.frost.BuildConfig.APPLICATION_ID}.prefs"
- val LAST_ACTIVE = "last_active"
+private val PREFERENCE_NAME = "${com.pitchedapps.frost.BuildConfig.APPLICATION_ID}.prefs"
+private val LAST_ACTIVE = "last_active"
+
+object Prefs {
+
+ val prefs: Prefs by lazy { this }
+
+ lateinit private var c: Context
+ operator fun invoke(c: Context) {
+ this.c = c
}
- private val prefs: android.content.SharedPreferences by lazy { c.getSharedPreferences(com.pitchedapps.frost.utils.Prefs.Companion.PREFERENCE_NAME, android.content.Context.MODE_PRIVATE) }
+ private val sp: SharedPreferences by lazy { c.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE) }
var lastActive: Long
- get() = prefs.getLong(com.pitchedapps.frost.utils.Prefs.Companion.LAST_ACTIVE, -1)
- set(value) = set(com.pitchedapps.frost.utils.Prefs.Companion.LAST_ACTIVE, System.currentTimeMillis())
+ get() = sp.getLong(LAST_ACTIVE, -1)
+ set(value) = set(LAST_ACTIVE, System.currentTimeMillis())
init {
lastActive = 0
}
- private fun set(key: String, value: Boolean) = prefs.edit().putBoolean(key, value).apply()
- private fun set(key: String, value: Int) = prefs.edit().putInt(key, value).apply()
- private fun set(key: String, value: Long) = prefs.edit().putLong(key, value).apply()
- private fun set(key: String, value: String) = prefs.edit().putString(key, value).apply()
+ private fun set(key: String, value: Boolean) = sp.edit().putBoolean(key, value).apply()
+ private fun set(key: String, value: Int) = sp.edit().putInt(key, value).apply()
+ private fun set(key: String, value: Long) = sp.edit().putLong(key, value).apply()
+ private fun set(key: String, value: String) = sp.edit().putString(key, value).apply()
} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt
index bbf0e1f0..d5bb2502 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt
@@ -1,6 +1,8 @@
package com.pitchedapps.frost.utils
+import android.content.Context
import android.content.res.Resources
+import android.net.ConnectivityManager
/**
* Created by Allan Wang on 2017-05-28.
@@ -8,4 +10,10 @@ import android.content.res.Resources
object Utils {
fun dpToPx(dp: Int) = (dp * android.content.res.Resources.getSystem().displayMetrics.density).toInt()
fun pxToDp(px:Int) = (px / android.content.res.Resources.getSystem().displayMetrics.density).toInt()
+
+ fun isNetworkAvailable(context: Context): Boolean {
+ val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
+ val activeNetworkInfo = connectivityManager.activeNetworkInfo
+ return activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting
+ }
} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostWebView.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostWebView.kt
index 62115276..f09887d8 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostWebView.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostWebView.kt
@@ -68,6 +68,7 @@ class FrostWebView @JvmOverloads constructor(
super.onPageFinished(view, url)
observable.onNext(WebStatus.LOADED)
// CookieManager.getInstance().flush()
+ L.d("Loaded $url")
}
})
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/LoginWebView.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/LoginWebView.kt
new file mode 100644
index 00000000..7d1948fe
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/views/LoginWebView.kt
@@ -0,0 +1,78 @@
+package com.pitchedapps.frost.views
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.graphics.Bitmap
+import android.net.UrlQuerySanitizer
+import android.util.AttributeSet
+import android.view.View
+import android.webkit.WebResourceError
+import android.webkit.WebResourceRequest
+import android.webkit.WebView
+import android.webkit.WebViewClient
+import com.facebook.AccessToken
+import com.pitchedapps.frost.facebook.FB_KEY
+import com.pitchedapps.frost.facebook.retro.FrostApi.frostApi
+import com.pitchedapps.frost.facebook.retro.Me
+import com.pitchedapps.frost.utils.L
+import retrofit2.Call
+import retrofit2.Callback
+import retrofit2.Response
+
+/**
+ * Created by Allan Wang on 2017-05-29.
+ */
+class LoginWebView @JvmOverloads constructor(
+ context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+) : WebView(context, attrs, defStyleAttr) {
+
+ init {
+ setupWebview()
+ }
+
+ @SuppressLint("SetJavaScriptEnabled")
+ fun setupWebview() {
+ settings.javaScriptEnabled = true
+ setLayerType(View.LAYER_TYPE_HARDWARE, null)
+ setWebViewClient(object : WebViewClient() {
+ override fun onReceivedError(view: WebView?, request: WebResourceRequest?, error: WebResourceError?) {
+ super.onReceivedError(view, request, error)
+ L.e("Error ${request}")
+ }
+
+ override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
+ super.onPageStarted(view, url, favicon)
+ L.d("Loading $url")
+ }
+
+ override fun onPageFinished(view: WebView?, url: String?) {
+ super.onPageFinished(view, url)
+ if (url == null) return
+ val sanitizer = UrlQuerySanitizer(url)
+ val accessToken = sanitizer.getValue("access_token")
+ val expiresIn = sanitizer.getValue("expires_in")
+ val grantedScopes = sanitizer.getValue("granted_scopes")
+ val deniedScopes = sanitizer.getValue("deniedScopes")
+
+
+ L.d("Loaded $url")
+ }
+ })
+ }
+
+ fun saveAccessToken(accessToken: String, expiresIn: String, grantedScopes: String?, deniedScopes: String?) {
+ L.d("Granted $grantedScopes")
+ L.d("Denied $deniedScopes")
+ frostApi.me(accessToken).enqueue(object : Callback<Me> {
+ override fun onFailure(call: Call<Me>?, t: Throwable?) {
+ TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+ }
+
+ override fun onResponse(call: Call<Me>, response: Response<Me>) {
+ AccessToken.setCurrentAccessToken(AccessToken(accessToken, FB_KEY.toString(), response.body().id, null, null, null, null, null))
+ }
+ })
+
+ }
+
+}