Skip to content

Commit

Permalink
Merge branch 'master' into testrobo
Browse files Browse the repository at this point in the history
  • Loading branch information
Okuro3499 authored Aug 30, 2024
2 parents 9925c8a + 490005a commit 6c70f16
Show file tree
Hide file tree
Showing 162 changed files with 2,133 additions and 2,236 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/android-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -189,4 +189,4 @@ jobs:
sudo npm install -g @treehouses/cli
export discord_channel="${{ secrets.CHANNEL }}" #remote
echo "https://github.com/open-learning-exchange/myplanet/releases/tag/v${{ env.ANDROID_VERSION_NAME }}"
treehouses feedback "new myplanet app: https://github.com/open-learning-exchange/myplanet/releases/tag/v${{ env.ANDROID_VERSION_NAME }}"
treehouses feedback "new myplanet app: <https://github.com/open-learning-exchange/myplanet/releases/tag/v${{ env.ANDROID_VERSION_NAME }}>"
22 changes: 10 additions & 12 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ android {
applicationId "org.ole.planet.myplanet"
minSdkVersion 21
targetSdkVersion 34
versionCode 1771
versionName "0.17.71"
versionCode 1867
versionName "0.18.67"
ndkVersion '21.3.6528147'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
Expand Down Expand Up @@ -154,21 +154,18 @@ repositories {

dependencies {
testImplementation 'junit:junit:4.13.2'
implementation(project(':library')) {
exclude group: 'commons-logging', module: 'commons-logging'
}
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs')
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'androidx.recyclerview:recyclerview:1.3.2'
implementation 'androidx.annotation:annotation:1.8.1'
implementation 'androidx.annotation:annotation:1.8.2'
implementation 'androidx.exifinterface:exifinterface:1.3.7'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.cardview:cardview:1.0.0'
implementation "androidx.core:core-ktx:1.13.1"
implementation "androidx.work:work-runtime:2.9.0"
implementation "androidx.work:work-runtime:2.9.1"
implementation "androidx.slidingpanelayout:slidingpanelayout:1.2.0"
implementation 'androidx.preference:preference-ktx:1.2.1'

Expand All @@ -179,6 +176,7 @@ dependencies {
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
implementation 'com.github.jeancsanchez:jcplayer:2.7.2'
implementation 'com.github.clans:fab:1.6.4'
implementation 'com.github.barteksc:pdfium-android:1.9.0'
implementation 'com.applandeo:material-calendar-view:1.9.2'
implementation 'com.afollestad.material-dialogs:commons:0.9.6.0'
implementation 'com.borax12.materialdaterangepicker:library:2.0'
Expand All @@ -190,10 +188,10 @@ dependencies {

implementation 'de.hdodenhof:circleimageview:3.1.0'
implementation 'de.rtner:PBKDF2:1.1.4'
implementation 'org.osmdroid:osmdroid-android:6.1.18'
implementation 'org.osmdroid:osmdroid-android:6.1.20'
implementation 'org.jetbrains:annotations:24.1.0'
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.2"
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.29'

implementation 'com.mikepenz:google-material-typeface:3.0.1.1.original@aar'
Expand Down Expand Up @@ -222,7 +220,7 @@ dependencies {
implementation "com.github.bumptech.glide:glide:$glide_version"
kapt "com.github.bumptech.glide:compiler:$glide_version"

def media3_version = "1.4.0"
def media3_version = "1.4.1"
implementation "androidx.media3:media3-exoplayer:$media3_version"
implementation "androidx.media3:media3-ui:$media3_version"
implementation "androidx.media3:media3-common:$media3_version"
Expand All @@ -232,7 +230,7 @@ dependencies {
implementation "io.noties.markwon:image:$markwon_version"
implementation "io.noties.markwon:html:$markwon_version"
implementation "io.noties.markwon:ext-tables:$markwon_version"
implementation(platform("org.jetbrains.kotlin:kotlin-bom:2.0.10"))
implementation(platform("org.jetbrains.kotlin:kotlin-bom:2.0.20"))
}
realm {
syncEnabled = true
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
3 changes: 2 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
<service android:name=".datamanager.MyDownloadService" />
<service android:name=".datamanager.MyDownloadService"
android:exported="false" />
</application>
</manifest>
3 changes: 2 additions & 1 deletion app/src/main/AndroidManifest.xml.lite
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
<service android:name=".datamanager.MyDownloadService" />
<service android:name=".datamanager.MyDownloadService"
android:exported="false" />
</application>
</manifest>
118 changes: 90 additions & 28 deletions app/src/main/java/org/ole/planet/myplanet/MainApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,17 @@ import androidx.preference.PreferenceManager
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.PeriodicWorkRequest
import androidx.work.WorkManager
import io.realm.Realm
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.ole.planet.myplanet.base.BaseResourceFragment.Companion.backgroundDownload
import org.ole.planet.myplanet.base.BaseResourceFragment.Companion.getAllLibraryList
import org.ole.planet.myplanet.callback.TeamPageListener
import org.ole.planet.myplanet.datamanager.DatabaseService
import org.ole.planet.myplanet.model.RealmApkLog
Expand All @@ -26,12 +35,17 @@ import org.ole.planet.myplanet.service.StayOnlineWorker
import org.ole.planet.myplanet.service.TaskNotificationWorker
import org.ole.planet.myplanet.service.UserProfileDbHandler
import org.ole.planet.myplanet.utilities.Constants.PREFS_NAME
import org.ole.planet.myplanet.utilities.DownloadUtils.downloadAllFiles
import org.ole.planet.myplanet.utilities.LocaleHelper
import org.ole.planet.myplanet.utilities.NetworkUtils.initialize
import org.ole.planet.myplanet.utilities.NetworkUtils.isNetworkConnectedFlow
import org.ole.planet.myplanet.utilities.NetworkUtils.startListenNetworkState
import org.ole.planet.myplanet.utilities.NotificationUtil.cancelAll
import org.ole.planet.myplanet.utilities.ThemeMode
import org.ole.planet.myplanet.utilities.Utilities
import org.ole.planet.myplanet.utilities.VersionUtils.getVersionName
import java.net.HttpURLConnection
import java.net.URL
import java.util.Date
import java.util.UUID
import java.util.concurrent.TimeUnit
Expand All @@ -42,30 +56,27 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks {
private const val STAY_ONLINE_WORK_TAG = "stayOnlineWork"
private const val TASK_NOTIFICATION_WORK_TAG = "taskNotificationWork"
lateinit var context: Context
lateinit var mRealm: Realm
lateinit var service: DatabaseService
var preferences: SharedPreferences? = null
@JvmField
var syncFailedCount = 0
@JvmField
var isCollectionSwitchOn = false
@JvmField
var showDownload = false
@JvmField
var isSyncRunning = false
var showHealthDialog = true
@JvmField
var listener: TeamPageListener? = null
val androidId: String
get() {
try {
return Settings.Secure.getString(context.contentResolver, Settings.Secure.ANDROID_ID)
} catch (e: Exception) {
e.printStackTrace()
}
return "0"
val androidId: String get() {
try {
return Settings.Secure.getString(context.contentResolver, Settings.Secure.ANDROID_ID)
} catch (e: Exception) {
e.printStackTrace()
}
return "0"
}
val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
lateinit var defaultPref: SharedPreferences

fun createLog(type: String) {
val service = DatabaseService(context)
service = DatabaseService(context)
val mRealm = service.realmInstance
if (!mRealm.isInTransaction) {
mRealm.beginTransaction()
Expand All @@ -82,6 +93,44 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks {
log.type = type
mRealm.commitTransaction()
}

private fun applyThemeMode(themeMode: String?) {
when (themeMode) {
ThemeMode.LIGHT -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
ThemeMode.DARK -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
ThemeMode.FOLLOW_SYSTEM -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
}
}

fun setThemeMode(themeMode: String) {
val sharedPreferences = context.getSharedPreferences("app_preferences", Context.MODE_PRIVATE)
with(sharedPreferences.edit()) {
putString("theme_mode", themeMode)
apply()
}
applyThemeMode(themeMode)
}

suspend fun isServerReachable(urlString: String): Boolean {
return try {
val url = URL(urlString)
val connection = withContext(Dispatchers.IO) {
url.openConnection()
} as HttpURLConnection
connection.requestMethod = "GET"
connection.connectTimeout = 5000
connection.readTimeout = 5000
withContext(Dispatchers.IO) {
connection.connect()
}
val responseCode = connection.responseCode
connection.disconnect()
responseCode in 200..299

} catch (e: Exception) {
false
}
}
}

private var activityReferences = 0
Expand All @@ -95,9 +144,10 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks {

context = this
preferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE)
nightMode()
service = DatabaseService(context)
mRealm = service.realmInstance
defaultPref = PreferenceManager.getDefaultSharedPreferences(this)

AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
val builder = VmPolicy.Builder()
StrictMode.setVmPolicy(builder.build())
builder.detectFileUriExposure()
Expand All @@ -117,16 +167,29 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks {
registerActivityLifecycleCallbacks(this)
startListenNetworkState()
onAppStarted()
}

private fun nightMode() {
val preference = PreferenceManager.getDefaultSharedPreferences(this).getString("dark_mode", getString(R.string.dark_mode_follow_system))
val options = listOf(*resources.getStringArray(R.array.dark_mode_options))
when (options.indexOf(preference)) {
0 -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
1 -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
2 -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
}
val sharedPreferences = getSharedPreferences("app_preferences", Context.MODE_PRIVATE)
val themeMode = sharedPreferences.getString("theme_mode", ThemeMode.FOLLOW_SYSTEM)

applyThemeMode(themeMode)

isNetworkConnectedFlow.onEach { isConnected ->
if (isConnected) {
val serverUrl = preferences?.getString("serverURL", "")
if (!serverUrl.isNullOrEmpty()) {
applicationScope.launch {
val canReachServer = withContext(Dispatchers.IO) {
isServerReachable(serverUrl)
}
if (canReachServer) {
if (defaultPref.getBoolean("beta_auto_download", false)) {
backgroundDownload(downloadAllFiles(getAllLibraryList(mRealm)))
}
}
}
}
}
}.launchIn(applicationScope)
}

private fun scheduleAutoSyncWork(syncInterval: Int?) {
Expand Down Expand Up @@ -209,8 +272,6 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks {

private fun handleUncaughtException(e: Throwable) {
e.printStackTrace()
val service = DatabaseService(this)
val mRealm = service.realmInstance
if (!mRealm.isInTransaction) {
mRealm.beginTransaction()
}
Expand All @@ -235,5 +296,6 @@ class MainApplication : Application(), Application.ActivityLifecycleCallbacks {
override fun onTerminate() {
super.onTerminate()
onAppClosed()
applicationScope.cancel()
}
}
44 changes: 32 additions & 12 deletions app/src/main/java/org/ole/planet/myplanet/base/BaseNewsFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.res.Configuration
import android.database.Cursor
import android.net.Uri
import android.os.Build
import android.os.Bundle
Expand Down Expand Up @@ -36,6 +37,7 @@ import org.ole.planet.myplanet.utilities.FileUtils.getRealPathFromURI
import org.ole.planet.myplanet.utilities.FileUtils.openOleFolder
import org.ole.planet.myplanet.utilities.JsonUtils.getString
import java.io.File
import java.io.FileOutputStream

@RequiresApi(api = Build.VERSION_CODES.O)
abstract class BaseNewsFragment : BaseContainerFragment(), OnNewsItemClickListener {
Expand All @@ -58,7 +60,7 @@ abstract class BaseNewsFragment : BaseContainerFragment(), OnNewsItemClickListen
val url: Uri? = data?.data
path = getRealPathFromURI(requireActivity(), url)
if (TextUtils.isEmpty(path)) {
path = getImagePath(url)
path = getPathFromURI(url)
}
val `object` = JsonObject()
`object`.addProperty("imageUrl", path)
Expand Down Expand Up @@ -112,17 +114,35 @@ abstract class BaseNewsFragment : BaseContainerFragment(), OnNewsItemClickListen
count?.let { BaseRecyclerFragment.showNoData(v, it, source) }
}

private fun getImagePath(uri: Uri?): String? {
var cursor = uri?.let { requireContext().contentResolver.query(it, null, null, null, null) }
cursor?.moveToFirst()
var documentId = cursor?.getString(0)
documentId = documentId?.substring(documentId.lastIndexOf(":") + 1)
cursor?.close()
cursor = requireContext().contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, MediaStore.Images.Media._ID + " = ? ", arrayOf(documentId), null)
cursor?.moveToFirst()
val path = cursor?.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA))
cursor?.close()
return path
private fun getPathFromURI(uri: Uri?): String? {
var filePath: String? = null
if (uri != null) {
val scheme = uri.scheme
if (scheme == "content") {
val cursor: Cursor? = requireActivity().contentResolver.query(uri, null, null, null, null)
cursor?.use {
if (it.moveToFirst()) {
val columnIndex = it.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME)
val fileName = it.getString(columnIndex)
val cacheDir = requireActivity().cacheDir
val destinationFile = File(cacheDir, fileName)
copyFile(uri, destinationFile)
filePath = destinationFile.absolutePath
}
}
} else if (scheme == "file") {
filePath = uri.path
}
}
return filePath
}

private fun copyFile(sourceUri: Uri, destinationFile: File) {
requireActivity().contentResolver.openInputStream(sourceUri)?.use { inputStream ->
FileOutputStream(destinationFile).use { outputStream ->
inputStream.copyTo(outputStream)
}
}
}

fun changeLayoutManager(orientation: Int, recyclerView: RecyclerView) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import android.widget.TextView
import androidx.annotation.RequiresApi
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.common.reflect.TypeToken
import com.google.gson.Gson
import io.realm.Case
import io.realm.RealmList
import io.realm.RealmModel
Expand Down Expand Up @@ -66,11 +68,11 @@ abstract class BaseRecyclerFragment<LI> : BaseRecyclerParentFragment<Any?>(), On
arguments?.let {
isMyCourseLib = it.getBoolean("isMyCourseLib")
courseLib = it.getString("courseLib")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
resources = it.getSerializable("resources", ArrayList::class.java) as? List<RealmMyLibrary>
} else {
resources = it.getSerializable("resources") as? List<RealmMyLibrary>
}
val json = it.getString("resources")
resources = (json?.let {
val type = object : TypeToken<ArrayList<RealmMyLibrary>>() {}.type
Gson().fromJson<ArrayList<RealmMyLibrary>>(json, type)
} ?: arrayListOf())
}
}

Expand Down
Loading

0 comments on commit 6c70f16

Please sign in to comment.