Skip to content

Commit e07b9c2

Browse files
authored
Fix #138: Implemented Forem app popup on start (#143)
* Implemented Forem app popup on start * Added bottom bar options * Improved UX * Deep-linking finished * Icon updates
1 parent 3f32520 commit e07b9c2

File tree

15 files changed

+647
-21
lines changed

15 files changed

+647
-21
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ captures/
4848
.idea/**/misc.xml
4949
.idea/**/dictionaries
5050
.idea/**/shelf
51+
.idea/assetWizardSettings.xml
5152
.idea/libraries
5253
.idea/caches
5354
.idea/caches/build_file_checksums.ser
@@ -120,3 +121,7 @@ google-service-account-user.json
120121
fastlane/README.md
121122
fastlane/metadata/
122123
fastlane/*.xml
124+
125+
# Extra
126+
*.DS_Store
127+
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package to.dev.dev_android.activities
2+
3+
import android.app.Activity
4+
import android.content.ActivityNotFoundException
5+
import android.content.Intent
6+
import android.net.Uri
7+
import android.os.Bundle
8+
import android.view.LayoutInflater
9+
import android.view.View
10+
import android.view.ViewGroup
11+
import androidx.constraintlayout.widget.ConstraintLayout
12+
import androidx.fragment.app.DialogFragment
13+
import android.content.pm.PackageManager
14+
import android.widget.ImageView
15+
import android.widget.TextView
16+
import androidx.core.content.ContextCompat
17+
import to.dev.dev_android.R
18+
19+
class ForemAppDialog : DialogFragment() {
20+
21+
companion object {
22+
const val PACKAGE_NAME = "com.forem.android"
23+
private const val FOREM_URL = "ForemAppDialog.url"
24+
25+
fun newInstance(url: String): ForemAppDialog {
26+
val foremAppDialog = ForemAppDialog()
27+
val args = Bundle()
28+
args.putString(FOREM_URL, url)
29+
foremAppDialog.arguments = args
30+
return foremAppDialog
31+
}
32+
33+
fun isForemAppAlreadyInstalled(activity: Activity?): Boolean {
34+
return try {
35+
activity?.packageManager?.getPackageInfo(PACKAGE_NAME, 0)
36+
true
37+
} catch (e: PackageManager.NameNotFoundException) {
38+
false
39+
}
40+
}
41+
42+
fun openForemApp(activity: Activity?, url: String?) {
43+
val packageManager: PackageManager? = activity?.packageManager
44+
val app = packageManager?.getLaunchIntentForPackage(PACKAGE_NAME)
45+
if (!url.isNullOrEmpty()) {
46+
app?.putExtra(Intent.EXTRA_TEXT, url)
47+
}
48+
activity?.startActivity(app)
49+
}
50+
}
51+
52+
lateinit var url: String
53+
54+
override fun onStart() {
55+
super.onStart()
56+
val width = resources.displayMetrics.widthPixels
57+
dialog!!.window?.setLayout(width, ViewGroup.LayoutParams.WRAP_CONTENT)
58+
}
59+
60+
override fun onCreateView(
61+
inflater: LayoutInflater,
62+
container: ViewGroup?,
63+
savedInstanceState: Bundle?
64+
): View? {
65+
val args = arguments
66+
url = args?.getString(FOREM_URL) ?: ""
67+
68+
val view = inflater.inflate(R.layout.forem_app_dialog, container, false)
69+
if (dialog != null && dialog!!.window != null) {
70+
dialog!!.window?.setBackgroundDrawableResource(R.drawable.forem_dialog_fragment_background)
71+
}
72+
val downloadInstallForemAppTextView =
73+
view.findViewById<TextView>(R.id.download_install_forem_app_text_view)
74+
val downloadOpenForemAppImageView =
75+
view.findViewById<ImageView>(R.id.download_open_forem_image_view)
76+
val descriptionTextView =
77+
view.findViewById<TextView>(R.id.forem_app_dialog_description_text_view)
78+
79+
if (isForemAppAlreadyInstalled(activity)) {
80+
downloadInstallForemAppTextView.text = getString(R.string.open_forem_app)
81+
downloadOpenForemAppImageView.setImageDrawable(
82+
ContextCompat.getDrawable(
83+
this.requireContext(),
84+
R.drawable.ic_compass
85+
)
86+
)
87+
descriptionTextView.text = getString(R.string.forem_app_dialog_description_if_installed)
88+
} else {
89+
downloadInstallForemAppTextView.text = getString(R.string.download_forem_app)
90+
downloadOpenForemAppImageView.setImageDrawable(
91+
ContextCompat.getDrawable(
92+
this.requireContext(),
93+
R.drawable.ic_baseline_arrow_downward_24
94+
)
95+
)
96+
descriptionTextView.text = getString(R.string.forem_app_dialog_description)
97+
}
98+
99+
val downloadLayout = view.findViewById<ConstraintLayout>(R.id.download_forem_app_layout)
100+
101+
downloadLayout.setOnClickListener {
102+
openForemAppLink()
103+
}
104+
return view
105+
}
106+
107+
private fun openForemAppLink() {
108+
if (isForemAppAlreadyInstalled(activity)) {
109+
openForemApp(activity, url)
110+
} else {
111+
try {
112+
// Opens Forem app in Play Store, if Play Store app is available.
113+
activity?.startActivity(
114+
Intent(
115+
Intent.ACTION_VIEW,
116+
Uri.parse("market://details?id=$PACKAGE_NAME")
117+
)
118+
)
119+
} catch (e: ActivityNotFoundException) {
120+
// Opens Forem app on Play Store in browser.
121+
activity?.startActivity(
122+
Intent(
123+
Intent.ACTION_VIEW,
124+
Uri.parse("https://play.google.com/store/apps/details?id=$PACKAGE_NAME")
125+
)
126+
)
127+
}
128+
}
129+
this.dismiss()
130+
}
131+
}

app/src/main/java/to/dev/dev_android/activities/MainActivity.kt

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), CustomWebChromeClient.
3939
handleIntent(intent)
4040
PushNotifications.start(applicationContext, BuildConfig.pusherInstanceId)
4141
PushNotifications.addDeviceInterest("broadcast")
42+
43+
binding.showPopupImageView.setOnClickListener {
44+
showForemAppAlert()
45+
}
46+
47+
binding.openForemImageView.setOnClickListener {
48+
val url = binding.webView.url
49+
ForemAppDialog.openForemApp(this, url)
50+
}
4251
}
4352

4453
override fun onResume() {
@@ -50,10 +59,16 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), CustomWebChromeClient.
5059
binding.webView.loadUrl(targetUrl)
5160
}
5261
} catch (e: Exception) {
53-
Log.e(LOG_TAG, e.message)
62+
Log.e(LOG_TAG, "${e.message}")
5463
}
5564
}
5665

66+
if (ForemAppDialog.isForemAppAlreadyInstalled(this)) {
67+
binding.openForemImageView.visibility = View.VISIBLE
68+
} else {
69+
binding.openForemImageView.visibility = View.GONE
70+
}
71+
5772
super.onResume()
5873
webViewClient.observeNetwork()
5974
}
@@ -107,12 +122,23 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), CustomWebChromeClient.
107122
mainActivityScope
108123
) {
109124
binding.splash.visibility = View.GONE
125+
binding.webView.visibility = View.VISIBLE
126+
binding.bottomLayout.visibility = View.VISIBLE
127+
showForemAppAlert()
110128
}
111129
binding.webView.webViewClient = webViewClient
112130
webViewBridge.webViewClient = webViewClient
113131
binding.webView.webChromeClient = CustomWebChromeClient(BuildConfig.baseUrl, this)
114132
}
115133

134+
private fun showForemAppAlert() {
135+
val url: String = binding.webView.url ?: ""
136+
ForemAppDialog.newInstance(url).show(
137+
supportFragmentManager,
138+
"ForemAppDialogFragment"
139+
)
140+
}
141+
116142
private fun restoreState(savedInstanceState: Bundle) {
117143
binding.webView.restoreState(savedInstanceState)
118144
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<inset xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:drawable="@drawable/rounded_dialog"
4+
android:insetLeft="16dp"
5+
android:insetRight="16dp" />
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<vector android:height="24dp" android:tint="#FFFFFF"
2+
android:viewportHeight="24" android:viewportWidth="24"
3+
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
4+
<path android:fillColor="@android:color/white" android:pathData="M20,12l-1.41,-1.41L13,16.17V4h-2v12.17l-5.58,-5.59L4,12l8,8 8,-8z"/>
5+
</vector>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="24dp"
3+
android:height="24dp"
4+
android:viewportWidth="28"
5+
android:viewportHeight="28">
6+
<path
7+
android:pathData="M13.987,28C6.274,28 0,21.714 0,13.987 0,6.275 6.274,0 13.987,0 21.714,0 28,6.275 28,13.987 28,21.714 21.714,28 13.987,28zM13.987,1C6.826,1 1,6.826 1,13.987 1,21.163 6.826,27 13.987,27 21.162,27 27,21.163 27,13.987 27,6.826 21.162,1 13.987,1z"
8+
android:fillColor="#0c0c0c"/>
9+
<path
10+
android:pathData="M6.821,21.179l4.922,-9.436 9.436,-4.923 -4.922,9.436 -9.436,4.923zM12.484,12.485l-3.306,6.336 6.337,-3.306 3.306,-6.336 -6.337,3.306z"
11+
android:fillColor="#0c0c0c"/>
12+
<path
13+
android:pathData="M14,15.499c-0.384,0 -0.769,-0.146 -1.061,-0.438a1.501,1.501 0,0 1,0 -2.121,1.501 1.501,0 0,1 2.121,0 1.501,1.501 0,0 1,0 2.121,1.494 1.494,0 0,1 -1.06,0.438zM14,13.5a0.498,0.498 0,0 0,-0.354 0.853A0.5,0.5 0,1 0,14 13.5z"
14+
android:fillColor="#0c0c0c"/>
15+
</vector>

0 commit comments

Comments
 (0)