Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,7 @@ lint/tmp/
# lint/reports/

# Detekt Reports
reports/
reports/

# Firebase config
app/google-services.json
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ This is the official repository for the [dev.to](https://dev.to/)'s Android app.

## Design ethos

DEV Android is an [WebView](https://developer.android.com/guide/webapps/webview) based application. This application is inspired by [Basecamp's approach](https://m.signalvnoise.com/basecamp-3-for-ios-hybrid-architecture-afc071589c25). We will grow to include more native code over time.
DEV Android is an [WebView](https://developer.android.com/guide/webapps/webview) based application. This application is inspired by [Basecamp's approach](https://m.signalvnoise.com/basecamp-3-for-ios-hybrid-architecture-afc071589c25). We will grow to include more native code over time.

By leveraging webviews as much as possible, we can smoothly sync up with our web dev work. And where it makes sense, we can re-implement certain things fully native, or build entirely native features. Life's a journey, not a destination.
By leveraging webviews as much as possible, we can smoothly sync up with our web dev work. And where it makes sense, we can re-implement certain things fully native, or build entirely native features. Life's a journey, not a destination.

## Contributions

Expand Down Expand Up @@ -43,6 +43,11 @@ To see more detail about a task, run gradlew help --task <task>

```

### Push Notifications

For Push Notification delivery we use [Pusher Beams](https://pusher.com/beams). In order to get the app running locally you'll need a `google-services.json` configuration file from Firebase, otherwise you'll encounter the following error: `File google-services.json is missing. The Google Services Plugin cannot function without it.`

You can [sign up or sign in on Firebase](https://firebase.google.com/) account for free in order to get the app working locally. Steps 1-4 under **Firebase for Android Push Notifications** in our [official docs](https://docs.dev.to/backend/pusher/#mobile-push-notifications) show how to set this up in more detail. Drop the resulting `google-services.json` file in the `app` folder and you'll be good to go.

### How to contribute

Expand Down
5 changes: 5 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ dependencies {
implementation(Libs.kotlin_stdlib_jdk8)
implementation(Libs.browser)

implementation("com.google.firebase:firebase-messaging:18.0.0")
implementation("com.pusher:push-notifications-android:1.6.2")

testImplementation(Libs.junit)
androidTestImplementation(Libs.androidx_test_runner)
androidTestImplementation(Libs.espresso_core)
}

apply(plugin = "com.google.gms.google-services")
5 changes: 3 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true"
tools:ignore="GoogleAppIndexingWarning,UnusedAttribute">
tools:ignore="GoogleAppIndexingWarning,UnusedAttribute"
tools:replace="android:fullBackupContent"
>
<activity
android:name=".view.main.view.MainActivity"
android:screenOrientation="portrait">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import android.webkit.CookieManager
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.browser.customtabs.CustomTabsIntent
import com.pusher.pushnotifications.PushNotifications
import java.lang.Exception

class CustomWebViewClient(
private val context: Context,
Expand All @@ -23,12 +25,32 @@ class CustomWebViewClient(
"github.com/sessions/"
)

private var registeredUserNotifications = false

override fun onPageFinished(view: WebView, url: String?) {
onPageFinish()
view.visibility = View.VISIBLE
super.onPageFinished(view, url)
}

override fun doUpdateVisitedHistory(view: WebView?, url: String?, isReload: Boolean) {
val javascript = "JSON.parse(document.getElementsByTagName('body')[0].getAttribute('data-user')).id"
view?.evaluateJavascript(javascript) { result ->
if (result != "null" && !registeredUserNotifications) {
try {
val userId = result.toString().toInt()
PushNotifications.addDeviceInterest("user-notifications-$userId")
registeredUserNotifications = true
}
catch (e: Exception) {
println(e)
}
}
}

super.doUpdateVisitedHistory(view, url, isReload)
}

override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
if (view.originalUrl == "https://dev.to/signout_confirm" && url == "https://dev.to/") {
view.clearCache(true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import android.view.View
import android.webkit.ValueCallback
import android.webkit.WebView
import to.dev.dev_android.R
import com.pusher.pushnotifications.PushNotifications
import to.dev.dev_android.base.BuildConfig
import to.dev.dev_android.base.activity.BaseActivity
import to.dev.dev_android.databinding.ActivityMainBinding
Expand All @@ -29,6 +30,15 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), CustomWebChromeClient.
setWebViewSettings()
savedInstanceState?.let { restoreState(it) } ?: navigateToHome()
handleIntent(intent)
PushNotifications.start(getApplicationContext(), BuildConfig.pusherInstanceId);
PushNotifications.addDeviceInterest("broadcast");
}

override fun onResume() {
if (intent.extras != null && intent.extras["url"] != null) {
binding.webView.loadUrl(intent.extras["url"].toString())
}
super.onResume()
}

override fun onSaveInstanceState(outState: Bundle) {
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ buildscript {
val agpVersion = findProperty("version.com.android.tools.build..gradle") as String
classpath("com.android.tools.build:gradle:$agpVersion")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")

classpath("com.google.gms:google-services:4.2.0")
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
Expand Down
2 changes: 2 additions & 0 deletions buildSrc/src/main/kotlin/Android.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ fun Project.configureBuildConfig(android: BaseExtension) {
android.buildTypes.all {
resValue("string", "baseUrl", extra.string("chrome.baseUrl"))
buildConfigString("baseUrl", extra.string("chrome.baseUrl"))
resValue("string", "pusherInstanceId", extra.string("pusher.instanceId"))
buildConfigString("pusherInstanceId", extra.string("pusher.instanceId"))
resValue("string", "userAgent", extra.string("chrome.userAgent"))
buildConfigString("userAgent", extra.string("chrome.userAgent"))
}
Expand Down
1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## dev.to configurations
chrome.baseUrl=https://dev.to/
chrome.userAgent=DEV-Native-android
pusher.instanceId=cdaf9857-fad0-4bfb-b360-64c1b2693ef3

# Android release configurations
android.targetSdkVersion=28
Expand Down