Commit 24107a8d authored by Aayush Gupta's avatar Aayush Gupta
Browse files

Apps: Bump to v1.3.0

parent 6374a3af
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-android-extensions'
id 'kotlin-kapt'
id 'kotlin-parcelize'
}
android {
compileSdkVersion 29
buildToolsVersion '29.0.2'
compileSdkVersion 30
buildToolsVersion '30.0.3'
defaultConfig {
applicationId "foundation.e.apps"
minSdkVersion 25
targetSdkVersion 29
versionCode 10
versionName "1.2.0"
versionName "1.3.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
}
signingConfigs {
......@@ -47,9 +46,7 @@ android {
lintOptions {
lintConfig file("lint.xml")
disable 'MissingTranslation'
}
androidExtensions {
experimental = true
disable 'NullSafeMutableLiveData'
}
aaptOptions {
additionalParameters '-I', 'app/e-ui-sdk.jar'
......@@ -81,41 +78,25 @@ dependencies {
// Preference
implementation "androidx.preference:preference-ktx:1.1.1"
// Lifecycle
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1"
// Bouncy Castle
implementation 'org.bouncycastle:bcpg-jdk15on:1.60'
// GSON
implementation 'com.google.code.gson:gson:2.8.6'
// EventBus
implementation 'org.greenrobot:eventbus:3.2.0'
// Volley
implementation "com.android.volley:volley:1.2.0"
// PhotoView
implementation "com.github.chrisbanes:PhotoView:2.3.0"
// RoundedImageView
implementation "com.makeramen:roundedimageview:2.3.0"
// RecyclerView
implementation 'androidx.recyclerview:recyclerview:1.2.0'
// WorkManager
implementation 'androidx.work:work-runtime:2.5.0'
implementation 'androidx.work:work-runtime-ktx:2.5.0'
// Android-Iconics
implementation 'com.mikepenz:iconics-core:3.1.0@aar'
implementation 'com.mikepenz:google-material-typeface:3.0.1.2.original@aar'
// Vectordrawable
def vector_version = "1.1.0"
implementation "androidx.vectordrawable:vectordrawable:$vector_version"
implementation "androidx.vectordrawable:vectordrawable-animated:$vector_version"
// Lifecycle
def lifecycle_version = "2.3.1"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
// Navigation component
def nav_version = "2.3.5"
......
......@@ -75,6 +75,13 @@
android:launchMode="singleInstance"
android:theme="@style/AppTheme1"
android:windowSoftInputMode="adjustResize" />
<receiver android:name=".updates.UpdatesManager">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
</application>
</manifest>
\ No newline at end of file
......@@ -52,7 +52,7 @@ import foundation.e.apps.updates.UpdatesManager
import foundation.e.apps.utils.Common
import foundation.e.apps.utils.Constants
import foundation.e.apps.utils.Constants.CURRENTLY_SELECTED_FRAGMENT_KEY
import kotlin.properties.Delegates
class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemSelectedListener,
ApplicationManagerServiceConnectionCallback {
......@@ -67,7 +67,7 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS
private val codeRequestPermissions = 9527
var doubleBackToExitPressedOnce = false;
private var isReceiverRegistered = false
var accentColorOS = 0
private var accentColorOS by Delegates.notNull<Int>()
init {
instance = this
......@@ -96,6 +96,9 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS
super.onCreate(savedInstanceState)
setContentView(binding.root)
accentColorOS = Common.getAccentColor(this)
mActivity = this
disableCategoryIfOpenSource()
......@@ -114,9 +117,6 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS
Common.updateMicroGStatus(this)
initialiseUpdatesWorker()
// Show the home fragment by default
currentFragmentId = if (savedInstanceState != null &&
savedInstanceState.containsKey(CURRENTLY_SELECTED_FRAGMENT_KEY)) {
......@@ -129,7 +129,6 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS
setupLangReceiver()
applicationManagerServiceConnection.bindService(this)
getAccentColor();
bottom_navigation_view_color()
openSearchFragment()
}
......@@ -168,12 +167,6 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS
}
private fun initialiseUpdatesWorker() {
UpdatesManager(applicationContext).startWorker()
}
override fun onServiceBind(applicationManager: ApplicationManager) {
initialiseFragments(applicationManager)
selectFragment(currentFragmentId, null)
......@@ -341,17 +334,4 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS
}
}, 2000)
}
/*
* get Accent color from OS
*
* */
private fun getAccentColor() {
accentColorOS = this.getColor(R.color.colorAccent);
}
}
......@@ -19,7 +19,7 @@ package foundation.e.apps.XAPK
import android.annotation.SuppressLint
import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
import kotlinx.parcelize.Parcelize
@SuppressLint("ParcelCreator")
@Parcelize
......
......@@ -17,7 +17,6 @@
package foundation.e.apps.XAPK
import android.os.Environment
import foundation.e.apps.BuildConfig
import foundation.e.apps.MainActivity
import java.io.File
......
......@@ -18,7 +18,6 @@
package foundation.e.apps.XAPK
import android.os.Environment
import android.text.TextUtils
import foundation.e.apps.MainActivity
import java.io.File
......@@ -37,7 +36,7 @@ object FsUtils {
}
fun exists(filePath: String?): Boolean {
return !TextUtils.isEmpty(filePath) && exists(File(filePath))
return if (!filePath.isNullOrEmpty()) exists(File(filePath)) else false
}
fun exists(file: File?): Boolean {
......
......@@ -26,7 +26,7 @@ import android.os.Build
import android.os.Handler
import android.os.Looper
import androidx.annotation.RequiresApi
import com.makeramen.roundedimageview.BuildConfig
import foundation.e.apps.BuildConfig
import java.io.File
import java.io.FileInputStream
import java.io.IOException
......
......@@ -19,7 +19,6 @@ package foundation.e.apps.XAPK
import android.content.Context
import android.content.Intent
import android.os.Build
import java.io.File
object IntentUtils {
......
......@@ -17,7 +17,6 @@
package foundation.e.apps.XAPK
import android.os.Build
import android.os.LocaleList
import android.text.TextUtils
import java.util.*
......
......@@ -19,7 +19,6 @@ package foundation.e.apps.XAPK
import android.content.Context
import android.net.Uri
import android.os.Build
import androidx.core.content.FileProvider
import foundation.e.apps.BuildConfig
import java.io.File
......
......@@ -17,7 +17,6 @@
package foundation.e.apps.XAPK
import android.os.Build
import android.os.Handler
import android.os.Looper
import androidx.annotation.MainThread
......
......@@ -19,7 +19,7 @@ package foundation.e.apps.api
import android.content.Context
import com.google.gson.Gson
import com.google.gson.JsonParser
import com.google.gson.JsonParser.parseReader
import foundation.e.apps.application.model.Application
import foundation.e.apps.application.model.data.BasicData
import foundation.e.apps.application.model.release.ReleaseData
......@@ -35,7 +35,7 @@ class GitlabDataRequest {
val url = Constants.RELEASE_API + Constants.MICROG_ID + Constants.RELEASE_ENDPOINT
val urlConnection = Common.createConnection(url, Constants.REQUEST_METHOD_GET)
val isr = InputStreamReader(urlConnection.inputStream)
val element = JsonParser().parse(isr)
val element = parseReader(isr)
val releaseList: List<ReleaseData> = Gson().fromJson(element.toString(),
Array<ReleaseData>::class.java).toList()
......
......@@ -21,31 +21,32 @@ import android.os.Bundle
import android.text.util.Linkify
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import foundation.e.apps.R
import foundation.e.apps.databinding.ActivityApplicationDescriptionBinding
import foundation.e.apps.utils.Constants.APPLICATION_DESCRIPTION_KEY
import kotlinx.android.synthetic.main.activity_application_description.*
class ApplicationDescriptionActivity : AppCompatActivity() {
private lateinit var binding: ActivityApplicationDescriptionBinding
override fun onCreate(savedInstanceState: Bundle?) {
binding = ActivityApplicationDescriptionBinding.inflate(layoutInflater)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_application_description)
setContentView(binding.root)
val toolbar = findViewById<Toolbar>(R.id.toolbar)
val toolbar = binding.toolbar
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setTitle(R.string.application_description_activity_title)
if (intent != null) {
app_description.text = intent.getStringExtra(APPLICATION_DESCRIPTION_KEY)
Linkify.addLinks(app_description, Linkify.ALL)
binding.appDescription.text = intent.getStringExtra(APPLICATION_DESCRIPTION_KEY)
Linkify.addLinks(binding.appDescription, Linkify.ALL)
}
}
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when {
item?.itemId == android.R.id.home -> {
item.itemId == android.R.id.home -> {
finish()
}
else -> {
......
......@@ -21,12 +21,14 @@ import android.annotation.SuppressLint
import android.app.Activity
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
import android.graphics.drawable.GradientDrawable
import android.view.Gravity
import android.view.View
import android.widget.Button
import android.widget.ImageView
import android.view.animation.AlphaAnimation
import android.view.animation.Animation
import android.widget.RatingBar
import android.widget.TextView
import androidx.appcompat.content.res.AppCompatResources
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.snackbar.Snackbar
......@@ -38,37 +40,36 @@ import foundation.e.apps.application.model.State
import foundation.e.apps.application.model.data.BasicData
import foundation.e.apps.application.model.data.PwasBasicData
import foundation.e.apps.application.viewmodel.ApplicationViewModel
import foundation.e.apps.databinding.ApplicationListItemBinding
import foundation.e.apps.utils.Common
import foundation.e.apps.utils.Common.toMiB
import foundation.e.apps.utils.Constants
import foundation.e.apps.utils.Error
import foundation.e.apps.utils.Execute
import kotlinx.android.synthetic.main.application_list_item.view.*
import kotlinx.android.synthetic.main.install_button_layout.view.*
class ApplicationViewHolder(private val activity: Activity, private val view: View, accentColorOS: Int) :
RecyclerView.ViewHolder(view),
class ApplicationViewHolder(private val activity: Activity, binding: ApplicationListItemBinding, private val accentColorOS: Int) :
RecyclerView.ViewHolder(binding.root),
ApplicationStateListener,
Downloader.DownloadProgressCallback,
BasicData.IconLoaderCallback,
PwasBasicData.IconLoaderCallback {
private val icon: ImageView = view.app_icon
private val title: TextView = view.app_title
private val pwa_icon: TextView = view.pwa_sympol
private val author: TextView = view.app_author
private val ratingBar: RatingBar = view.app_rating_bar
private val rating: TextView = view.app_rating
private val privacyScore: TextView = view.app_privacy_score
private var installButton: Button = view.app_install
private val view = binding.root
private val icon = binding.appIcon
private val title = binding.appTitle
private val pwaSympol = binding.pwaSympol
private val author = binding.appAuthor
private val ratingBar = binding.appRatingBar
private val rating = binding.appRating
private val privacyScore = binding.appPrivacyScore
private var installButton = binding.simpleInstallButtonLayout.appInstall
private var application: Application? = null
private val applicationViewModel = ApplicationViewModel()
private var downloader: Downloader? = null
var accentColorOS = accentColorOS;
init {
pwa_icon.visibility = View.GONE
pwaSympol.visibility = View.GONE
view.setOnClickListener {
if (application != null) {
if (application!!.packageName != Constants.MICROG_PACKAGE)
......@@ -76,11 +77,6 @@ class ApplicationViewHolder(private val activity: Activity, private val view: Vi
}
}
installButton.setTextColor(Color.parseColor("#ffffff"))
if (0 != this.accentColorOS) {
installButton.setBackgroundColor(this.accentColorOS)
}
installButton.setOnClickListener {
if (application?.fullData != null &&
application!!.fullData!!.getLastVersion() == null) {
......@@ -100,7 +96,7 @@ class ApplicationViewHolder(private val activity: Activity, private val view: Vi
fun createApplicationView(app: Application) {
pwa_icon.visibility = View.GONE
pwaSympol.visibility = View.GONE
this.application = app
if (app.basicData != null) {
......@@ -111,7 +107,11 @@ class ApplicationViewHolder(private val activity: Activity, private val view: Vi
application!!.addListener(this)
title.text = application!!.basicData!!.name
author.text = application!!.basicData!!.author
val drawable = ratingBar.progressDrawable
drawable.colorFilter = PorterDuffColorFilter(accentColorOS, PorterDuff.Mode.SRC_IN)
ratingBar.rating = application!!.basicData!!.ratings.rating!!
if (application!!.basicData!!.ratings.rating != -1f) {
rating.text = application!!.basicData!!.ratings.rating.toString()
} else {
......@@ -129,11 +129,26 @@ class ApplicationViewHolder(private val activity: Activity, private val view: Vi
application!!.addListener(this)
if (application!!.searchAppsBasicData != null) {
if (application!!.searchAppsBasicData!!.is_pwa) {
pwa_icon.visibility = View.VISIBLE
pwaSympol.visibility = View.VISIBLE
}
application!!.SearchAppsloadIcon(this)
title.text = application!!.searchAppsBasicData!!.name
author.text = application!!.searchAppsBasicData!!.author
val drawable = ratingBar.progressDrawable
drawable.colorFilter = PorterDuffColorFilter(accentColorOS, PorterDuff.Mode.SRC_IN)
ratingBar.rating = application!!.searchAppsBasicData!!.ratings.rating!!
if (application!!.searchAppsBasicData!!.ratings.rating != -1f) {
rating.text = application!!.searchAppsBasicData!!.ratings.rating.toString()
} else {
rating.text = activity.getString(R.string.not_available)
}
if (application!!.searchAppsBasicData!!.ratings.privacyRating != null && application!!.searchAppsBasicData!!.ratings.privacyRating != -1f) {
privacyScore.text = application!!.searchAppsBasicData!!.ratings.privacyRating.toString()
} else {
privacyScore.text = activity.getString(R.string.not_available)
}
} else {
application!!.PwaloadIcon(this)
title.text = application!!.pwabasicdata!!.name
......@@ -151,50 +166,37 @@ class ApplicationViewHolder(private val activity: Activity, private val view: Vi
override fun stateChanged(state: State) {
Execute({}, {
installButton.setTextColor(accentColorOS)
installButton.text = activity.getString(state.installButtonTextId)
installButton.setBackgroundResource(R.drawable.app_installing_border_simple)
val drawable = installButton.background as GradientDrawable
drawable.setStroke(2, accentColorOS)
installButton.text = activity.getString(state.installButtonTextId)
installButton.clearAnimation()
installButton.clearFocus()
when (state) {
State.NOT_DOWNLOADED -> {
if (0 != this.accentColorOS) {
installButton.setTextColor(this.accentColorOS)
} else {
installButton.setTextColor(Color.parseColor("#0088ED"))
installButton.isEnabled = true
}
installButton.setBackgroundResource(R.drawable.app_install_border_simple)
State.DOWNLOADING ->{
installButton.isEnabled = true
installButton.background.clearColorFilter()
}
State.INSTALLED -> {
installButton.isEnabled =
Common.appHasLaunchActivity(activity, application!!.packageName)
if (0 != this.accentColorOS) {
installButton.setBackgroundColor(this.accentColorOS)
} else {
installButton.setBackgroundResource(R.drawable.app_install_border)
}
installButton.setTextColor(Color.parseColor("#FAFAFA"))
installButton.background.colorFilter = PorterDuffColorFilter(accentColorOS, PorterDuff.Mode.SRC_IN)
}
State.INSTALLING -> {
installButton.isEnabled = false
installingAnimation()
}
State.NOT_UPDATED -> {
installButton.setTextColor(Color.parseColor("#FAFAFA"))
if (0 != this.accentColorOS) {
installButton.setBackgroundColor(this.accentColorOS)
} else {
installButton.setBackgroundResource(R.drawable.app_install_border)
}
installButton.isEnabled = true
}
else -> {
installButton.setTextColor(Color.parseColor("#0088ED"))
installButton.isEnabled = true
installButton.setTextColor(Color.parseColor("#FAFAFA"))
installButton.background.colorFilter = PorterDuffColorFilter(accentColorOS, PorterDuff.Mode.SRC_IN)
}
}
......@@ -208,12 +210,17 @@ class ApplicationViewHolder(private val activity: Activity, private val view: Vi
@SuppressLint("SetTextI18n")
override fun notifyDownloadProgress(count: Int, total: Int) {
installButton.setGravity(Gravity.CENTER)
installButton.text = ((toMiB(count) / toMiB(total)) * 100).toInt().toString() + "%"
installButton.setTextColor(Color.parseColor("#0088ED"))
installButton.setBackgroundResource(R.drawable.app_installing_border_simple)
}
private fun installingAnimation() {
val anim = AlphaAnimation(0.0f, 1.0f)
anim.duration = 200 //You can manage the blinking time with this parameter
anim.startOffset = 20
anim.repeatMode = Animation.REVERSE
anim.repeatCount = Animation.INFINITE
installButton.startAnimation(anim)
}
override fun anErrorHasOccurred(error: Error) {
Snackbar.make(activity.findViewById(R.id.container),
activity.getString(error.description),
......
......@@ -21,16 +21,17 @@ import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.viewpager.widget.ViewPager
import foundation.e.apps.R
import foundation.e.apps.application.model.Application
import foundation.e.apps.applicationmanager.ApplicationManager
import foundation.e.apps.applicationmanager.ApplicationManagerServiceConnection
import foundation.e.apps.applicationmanager.ApplicationManagerServiceConnectionCallback
import foundation.e.apps.databinding.ActivityScreenshotsBinding
import foundation.e.apps.utils.Constants
import foundation.e.apps.utils.Constants.SELECTED_APPLICATION_SCREENSHOT_KEY
import kotlinx.android.synthetic.main.activity_screenshots.*
class ScreenshotsActivity : AppCompatActivity(), ApplicationManagerServiceConnectionCallback {
private lateinit var binding: ActivityScreenshotsBinding
private val applicationManagerServiceConnection =
ApplicationManagerServiceConnection(this)
private lateinit var applicationPackageName: String
......@@ -40,8 +41,9 @@ class ScreenshotsActivity : AppCompatActivity(), ApplicationManagerServiceConnec
private val last_selected_screenshot_key = "last_selected_screenshot"
override fun onCreate(savedInstanceState: Bundle?) {
binding = ActivityScreenshotsBinding.inflate(layoutInflater)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_screenshots)
setContentView(binding.root)
if (savedInstanceState != null &&
savedInstanceState.containsKey(last_selected_screenshot_key)) {
......@@ -72,7 +74,7 @@ class ScreenshotsActivity : AppCompatActivity(), ApplicationManagerServiceConnec
val pwasBasicData =application.pwabasicdata
if(pwasBasicData!=null) {
screenshotsCarousel = screenshots_carousel
screenshotsCarousel = binding.screenshotsCarousel
screenshotsCarousel.visibility = View.GONE
pwasBasicData.loadImagesAsyncly {
......@@ -84,7 +86,7 @@ class ScreenshotsActivity : AppCompatActivity(), ApplicationManagerServiceConnec
}
}
else {
screenshotsCarousel = screenshots_carousel
screenshotsCarousel = binding.screenshotsCarousel
screenshotsCarousel.visibility = View.GONE
basicData!!.loadImagesAsyncly {
......
......@@ -24,12 +24,9 @@ import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.viewpager.widget.PagerAdapter
import foundation.e.apps.R
import kotlinx.android.synthetic.main.screenshots_carousel_item.view.*
import foundation.e.apps.databinding.ScreenshotsCarouselItemBinding
class ScreenshotsCarouselAdapter(context: Context, private val screenshots: List<Bitmap>) : PagerAdapter() {
private val layoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
class ScreenshotsCarouselAdapter