diff --git a/app/build.gradle b/app/build.gradle deleted file mode 100644 index 00c64ca..0000000 --- a/app/build.gradle +++ /dev/null @@ -1,77 +0,0 @@ -plugins { - id 'com.android.application' - id 'org.jetbrains.kotlin.android' - id 'androidx.navigation.safeargs.kotlin' - id 'kotlin-kapt' -} - -android { - compileSdk 33 - - defaultConfig { - applicationId "com.roozbehzarei.filester" - minSdk 21 - targetSdk 33 - versionCode 3 - versionName "2.0.1" - - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - } - - buildFeatures { - viewBinding true - } - - buildscript { - repositories { - google() - mavenCentral() - } - - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } - } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = '1.8' - } - } - namespace 'com.roozbehzarei.filester' -} - -dependencies { - implementation 'androidx.core:core-ktx:1.9.0' - implementation 'androidx.appcompat:appcompat:1.6.0' - implementation 'com.google.android.material:material:1.8.0' - implementation 'androidx.constraintlayout:constraintlayout:2.1.4' - // Fragments - implementation "androidx.fragment:fragment-ktx:$fragment_version" - // Navigation Component - implementation "androidx.navigation:navigation-fragment-ktx:$nav_version" - implementation "androidx.navigation:navigation-ui-ktx:$nav_version" - // ViewModel - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version" - implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version" - // Retrofit with Scalars Converter - implementation "com.squareup.retrofit2:converter-scalars:$retrofit_version" - // WorkManager - implementation "androidx.work:work-runtime-ktx:$work_version" - // Room - implementation "androidx.room:room-runtime:$room_version" - implementation "androidx.room:room-ktx:$room_version" - kapt "androidx.room:room-compiler:$room_version" - // CoordinatorLayout - implementation "androidx.coordinatorlayout:coordinatorlayout:1.2.0" - // Activity - implementation "androidx.activity:activity-ktx:$activity_version" - // SplashScreen - implementation 'androidx.core:core-splashscreen:1.0.0' - // Coordinatorlayout - implementation "androidx.coordinatorlayout:coordinatorlayout:1.2.0" -} \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts new file mode 100644 index 0000000..1945349 --- /dev/null +++ b/app/build.gradle.kts @@ -0,0 +1,88 @@ +plugins { + id("com.android.application") + id("org.jetbrains.kotlin.android") + id("androidx.navigation.safeargs.kotlin") + id("com.google.devtools.ksp") + id("com.google.gms.google-services") + id("com.google.firebase.crashlytics") + id("com.google.firebase.firebase-perf") +} + +android { + namespace = "com.roozbehzarei.filester" + compileSdk = 33 + + defaultConfig { + applicationId = "com.roozbehzarei.filester" + minSdk = 21 + targetSdk = 33 + versionCode = 4 + versionName = "2.1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + buildFeatures { + viewBinding = true + } + + buildTypes { + getByName("release") { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = "1.8" + } + androidResources { + generateLocaleConfig = true + } +} + +dependencies { + val navVersion = "2.5.3" + val activityVersion = "1.7.2" + val fragmentVersion = "1.6.1" + val lifecycleVersion = "2.6.1" + val retrofitVersion = "2.9.0" + val workVersion = "2.8.1" + val roomVersion = "2.5.2" + + implementation("androidx.core:core-ktx:1.10.1") + implementation("androidx.appcompat:appcompat:1.6.1") + implementation("com.google.android.material:material:1.9.0") + implementation("androidx.constraintlayout:constraintlayout:2.1.4") + // Fragment + implementation("androidx.fragment:fragment-ktx:$fragmentVersion") + // Navigation + implementation("androidx.navigation:navigation-fragment-ktx:$navVersion") + implementation("androidx.navigation:navigation-ui-ktx:$navVersion") + // ViewModel + implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleVersion") + implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion") + // Retrofit with Scalars Converter + implementation("com.squareup.retrofit2:converter-scalars:$retrofitVersion") + // WorkManager + implementation("androidx.work:work-runtime-ktx:$workVersion") + // Room + implementation("androidx.room:room-runtime:$roomVersion") + annotationProcessor("androidx.room:room-compiler:$roomVersion") + implementation("androidx.room:room-ktx:$roomVersion") + ksp("androidx.room:room-compiler:$roomVersion") + // Activity + implementation("androidx.activity:activity-ktx:$activityVersion") + // SplashScreen + implementation("androidx.core:core-splashscreen:1.0.1") + // Firebase + implementation(platform("com.google.firebase:firebase-bom:32.2.0")) + implementation("com.google.firebase:firebase-analytics-ktx") + implementation("com.google.firebase:firebase-crashlytics-ktx") + implementation("com.google.firebase:firebase-perf-ktx") +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 481bb43..ff59496 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -1,6 +1,6 @@ # Add project specific ProGuard rules here. # You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. +# proguardFiles setting in build.gradle.kts. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json index e24f270..1dee2e6 100644 --- a/app/release/output-metadata.json +++ b/app/release/output-metadata.json @@ -11,8 +11,8 @@ "type": "SINGLE", "filters": [], "attributes": [], - "versionCode": 3, - "versionName": "2.0.1", + "versionCode": 4, + "versionName": "2.1.0", "outputFile": "app-release.apk" } ], diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e27666e..966af37 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,9 +1,8 @@ + xmlns:tools="http://schemas.android.com/tools"> - + + + + + - + + \ No newline at end of file diff --git a/app/src/main/java/com/roozbehzarei/filester/NotificationUtils.kt b/app/src/main/java/com/roozbehzarei/filester/NotificationUtils.kt deleted file mode 100644 index 2119cd9..0000000 --- a/app/src/main/java/com/roozbehzarei/filester/NotificationUtils.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.roozbehzarei.filester - -import android.content.Context -import androidx.core.app.NotificationCompat -import androidx.core.app.NotificationManagerCompat - - -const val CHANNEL_ID = "FILESTER" - -fun showNotification( - context: Context, - notificationId: Int, - title: String, - description: String, - showProgress: Boolean -) { - val notification = NotificationCompat.Builder(context, CHANNEL_ID) - .setSmallIcon(R.drawable.ic_upload) - .setContentTitle(title) - .setContentText(description) - .setPriority(NotificationCompat.PRIORITY_DEFAULT) - .setAutoCancel(true) - if (showProgress) { - notification.setProgress(0, 0, true) - } - with(NotificationManagerCompat.from(context)) { - notify(notificationId, notification.build()) - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/roozbehzarei/filester/ui/AboutFragment.kt b/app/src/main/java/com/roozbehzarei/filester/ui/AboutFragment.kt index 8bb512d..39fb149 100644 --- a/app/src/main/java/com/roozbehzarei/filester/ui/AboutFragment.kt +++ b/app/src/main/java/com/roozbehzarei/filester/ui/AboutFragment.kt @@ -11,7 +11,7 @@ import com.roozbehzarei.filester.BuildConfig import com.roozbehzarei.filester.R import com.roozbehzarei.filester.databinding.FragmentAboutBinding -private const val GITHUB_URL = "https://github.com/roozbehzarei" +private const val GITHUB_URL = "https://roozbehzarei.me/project/filester/" private const val DONATE_URL = "https://www.buymeacoffee.com/roozbehzarei/" private const val TRANSFER_URL = "https://transfer.sh/" @@ -46,16 +46,6 @@ class AboutFragment : Fragment() { } } - override fun onResume() { - super.onResume() - requireActivity().actionBar?.setDisplayShowTitleEnabled(false) - } - - override fun onPause() { - super.onPause() - requireActivity().actionBar?.setDisplayShowTitleEnabled(true) - } - /** * Open the passed [url] in browser */ diff --git a/app/src/main/java/com/roozbehzarei/filester/ui/MainActivity.kt b/app/src/main/java/com/roozbehzarei/filester/ui/MainActivity.kt index 56bdc3c..237ed85 100644 --- a/app/src/main/java/com/roozbehzarei/filester/ui/MainActivity.kt +++ b/app/src/main/java/com/roozbehzarei/filester/ui/MainActivity.kt @@ -16,7 +16,6 @@ import androidx.navigation.NavController import androidx.navigation.fragment.NavHostFragment import androidx.navigation.ui.setupWithNavController import com.google.android.material.appbar.AppBarLayout -import com.roozbehzarei.filester.CHANNEL_ID import com.roozbehzarei.filester.R import com.roozbehzarei.filester.databinding.ActivityMainBinding @@ -54,8 +53,7 @@ class MainActivity : AppCompatActivity() { } // Change the color of the navigation bars - val windowInsetsController = - WindowCompat.getInsetsController(window, binding.root) + val windowInsetsController = WindowCompat.getInsetsController(window, binding.root) val currentNightMode = applicationContext.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK when (currentNightMode) { @@ -63,6 +61,7 @@ class MainActivity : AppCompatActivity() { windowInsetsController.isAppearanceLightNavigationBars = true windowInsetsController.isAppearanceLightStatusBars = true } + Configuration.UI_MODE_NIGHT_YES -> { windowInsetsController.isAppearanceLightNavigationBars = false windowInsetsController.isAppearanceLightStatusBars = false @@ -89,8 +88,10 @@ class MainActivity : AppCompatActivity() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val name = getString(R.string.channel_name) val descriptionText = getString(R.string.channel_description) - val importance = NotificationManager.IMPORTANCE_DEFAULT - val channel = NotificationChannel(CHANNEL_ID, name, importance).apply { + val importance = NotificationManager.IMPORTANCE_LOW + val channel = NotificationChannel( + getString(R.string.notification_channel_id), name, importance + ).apply { description = descriptionText } // Register the channel with the system diff --git a/app/src/main/java/com/roozbehzarei/filester/ui/MainFragment.kt b/app/src/main/java/com/roozbehzarei/filester/ui/MainFragment.kt index f333c48..4ba19a0 100644 --- a/app/src/main/java/com/roozbehzarei/filester/ui/MainFragment.kt +++ b/app/src/main/java/com/roozbehzarei/filester/ui/MainFragment.kt @@ -1,13 +1,23 @@ package com.roozbehzarei.filester.ui +import android.Manifest import android.content.ClipData import android.content.ClipboardManager import android.content.Context +import android.content.pm.PackageManager import android.net.Uri +import android.os.Build import android.os.Bundle -import android.view.* -import android.widget.Toast +import android.view.LayoutInflater +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import android.view.View +import android.view.ViewGroup +import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts +import androidx.annotation.RequiresApi +import androidx.core.content.ContextCompat import androidx.core.view.MenuHost import androidx.core.view.MenuProvider import androidx.documentfile.provider.DocumentFile @@ -32,6 +42,8 @@ class MainFragment : Fragment() { // Binding object instance with access to the views in the fragment_upload.xml layout private lateinit var binding: FragmentMainBinding + private lateinit var requestPermissionLauncher: ActivityResultLauncher + private val viewModel: FilesterViewModel by activityViewModels { FilesterViewModelFactory( (activity?.application as BaseApplication).database.fileDao(), @@ -47,10 +59,16 @@ class MainFragment : Fragment() { } } + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + requestPermissionLauncher = + registerForActivityResult(ActivityResultContracts.RequestPermission()) { _ -> + fileSelector.launch("*/*") + } + } + override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? + inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { // Inflate the layout XML file and return a binding object instance binding = FragmentMainBinding.inflate(inflater, container, false) @@ -74,10 +92,8 @@ class MainFragment : Fragment() { activity?.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager val clip: ClipData = ClipData.newPlainText("file url", file.fileUrl) clipboard.setPrimaryClip(clip) - Toast.makeText( - context, - getString(R.string.toast_clipboard), - Toast.LENGTH_SHORT + Snackbar.make( + binding.snackbarLayout, getString(R.string.snackbar_clipboard), Snackbar.LENGTH_SHORT ).show() } binding.fileListView.adapter = adapter @@ -100,7 +116,11 @@ class MainFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding.fab.setOnClickListener { - fileSelector.launch("*/*") + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + checkNotificationPermission() + } else { + fileSelector.launch("*/*") + } } viewModel.outputWorkInfo.observe(viewLifecycleOwner, workInfoObserver()) } @@ -108,7 +128,7 @@ class MainFragment : Fragment() { private fun workInfoObserver(): Observer> { return Observer { // If there are no matching work info, do nothing - if (it.isNullOrEmpty()) { + if (it.isEmpty()) { return@Observer } val workInfo = it[0] @@ -116,11 +136,10 @@ class MainFragment : Fragment() { if (!workInfo.state.isFinished) { isUploadInProgress(true) Snackbar.make( - binding.root, + binding.snackbarLayout, resources.getString(R.string.snackbar_uploading), Snackbar.LENGTH_LONG - ) - .show() + ).show() } else if (workInfo.state == WorkInfo.State.SUCCEEDED) { showDialog(true, fileUrl) viewModel.clearWorkQueue() @@ -145,10 +164,10 @@ class MainFragment : Fragment() { activity?.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager val clip: ClipData = ClipData.newPlainText("file url", fileUrl) clipboard.setPrimaryClip(clip) - Toast.makeText( - context, - getString(R.string.toast_clipboard), - Toast.LENGTH_SHORT + Snackbar.make( + binding.snackbarLayout, + getString(R.string.snackbar_clipboard), + Snackbar.LENGTH_SHORT ).show() } .setNegativeButton(resources.getString(R.string.dialog_button_close)) { dialog, _ -> @@ -160,9 +179,7 @@ class MainFragment : Fragment() { .setPositiveButton(resources.getString(R.string.dialog_button_close)) { dialog, _ -> dialog.dismiss() } - } - .setCancelable(false) - .show() + }.setCancelable(false).show() } private fun isUploadInProgress(state: Boolean) { @@ -175,4 +192,19 @@ class MainFragment : Fragment() { } } + @RequiresApi(Build.VERSION_CODES.TIRAMISU) + private fun checkNotificationPermission() { + when { + ContextCompat.checkSelfPermission( + requireContext(), Manifest.permission.POST_NOTIFICATIONS + ) != PackageManager.PERMISSION_GRANTED -> requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS) + + shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS) -> { + // Explain to the user why the app needs this permission + // To be implemented in future releases + } + + else -> fileSelector.launch("*/*") + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/roozbehzarei/filester/worker/UploadWorker.kt b/app/src/main/java/com/roozbehzarei/filester/worker/UploadWorker.kt index 27544bb..cb3c9c2 100644 --- a/app/src/main/java/com/roozbehzarei/filester/worker/UploadWorker.kt +++ b/app/src/main/java/com/roozbehzarei/filester/worker/UploadWorker.kt @@ -1,14 +1,23 @@ package com.roozbehzarei.filester.worker +import android.app.Notification +import android.app.NotificationManager +import android.app.PendingIntent import android.content.Context +import android.content.Intent +import android.content.pm.ServiceInfo import android.net.Uri +import android.os.Build +import androidx.core.app.NotificationCompat +import androidx.core.content.ContextCompat import androidx.work.CoroutineWorker +import androidx.work.ForegroundInfo import androidx.work.WorkerParameters import androidx.work.workDataOf import com.roozbehzarei.filester.BaseApplication import com.roozbehzarei.filester.R import com.roozbehzarei.filester.network.TransferApi -import com.roozbehzarei.filester.showNotification +import com.roozbehzarei.filester.ui.MainActivity import com.roozbehzarei.filester.viewmodel.KEY_FILE_NAME import com.roozbehzarei.filester.viewmodel.KEY_FILE_URI import okhttp3.MediaType @@ -19,23 +28,26 @@ import java.io.File class UploadWorker(private val context: Context, params: WorkerParameters) : CoroutineWorker(context, params) { + private val notificationManager = + context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager private val resolver = context.contentResolver private val fileDao = BaseApplication().database.fileDao() override suspend fun doWork(): Result { - return try { - showNotification( - context = applicationContext, - title = applicationContext.getString(R.string.notification_title_in_progress), - description = applicationContext.getString(R.string.notification_description_in_progress), - notificationId = 1, - showProgress = true + + setForeground( + createForegroundInfo( + context.getString(R.string.notification_title_start) ) - val resourceUri = Uri.parse(inputData.getString(KEY_FILE_URI)) - val fileName = inputData.getString(KEY_FILE_NAME) - val mediaType = MediaType.parse(resolver.getType(resourceUri)!!) - val inputStream = resolver.openInputStream(resourceUri) - val file = File(context.cacheDir, fileName!!) + ) + + val resourceUri = Uri.parse(inputData.getString(KEY_FILE_URI)) + val fileName = inputData.getString(KEY_FILE_NAME) + val mediaType = MediaType.parse(resolver.getType(resourceUri)!!) + val inputStream = resolver.openInputStream(resourceUri) + val file = File(context.cacheDir, fileName!!) + + return try { inputStream.use { input -> file.outputStream().use { output -> input?.copyTo(output) @@ -45,9 +57,12 @@ class UploadWorker(private val context: Context, params: WorkerParameters) : inputStream?.close() file.length() val filePart = MultipartBody.Part.createFormData( - "files", - file.name, - RequestBody.create(mediaType, file) + "files", file.name, RequestBody.create(mediaType, file) + ) + setForeground( + createForegroundInfo( + context.getString(R.string.notification_title_in_progress) + ) ) val apiResponse = TransferApi.retrofitService.sendFile(filePart) val responseBody = apiResponse.body() @@ -59,33 +74,48 @@ class UploadWorker(private val context: Context, params: WorkerParameters) : fileSize = file.length() / 1024 / 1024 ) fileDao.insert(newFileEntry) - showNotification( - context = applicationContext, - title = applicationContext.getString(R.string.title_upload_success), - description = applicationContext.getString(R.string.message_upload_success), - notificationId = 1, - showProgress = false + notificationManager.notify( + 1, createNotification(context.getString(R.string.title_upload_success)) ) Result.success(outputData) } else { - showNotification( - context = applicationContext, - title = applicationContext.getString(R.string.title_upload_error), - description = applicationContext.getString(R.string.message_upload_error), - notificationId = 1, - showProgress = false + notificationManager.notify( + 1, createNotification(context.getString(R.string.title_upload_error)) ) Result.failure() } } catch (e: Exception) { - showNotification( - context = applicationContext, - title = applicationContext.getString(R.string.title_upload_error), - description = applicationContext.getString(R.string.message_upload_error), - notificationId = 1, - showProgress = false + notificationManager.notify( + 1, createNotification(context.getString(R.string.title_upload_error)) ) Result.failure() } } + + private fun createForegroundInfo(progress: String): ForegroundInfo { + val notificationChannelId = context.getString(R.string.notification_channel_id) + val notification = + NotificationCompat.Builder(context, notificationChannelId).setContentTitle(progress) + .setSmallIcon(R.drawable.ic_notification) + .setColor(ContextCompat.getColor(applicationContext, R.color.seed)).setOngoing(true) + .setProgress(0, 0, true).build() + + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + ForegroundInfo(0, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC) + } else { + ForegroundInfo(0, notification) + } + } + + private fun createNotification(progress: String): Notification { + val notificationChannelId = context.getString(R.string.notification_channel_id) + val intent = Intent(applicationContext, MainActivity::class.java) + val pendingIntent = PendingIntent.getActivity( + applicationContext, 0, intent, PendingIntent.FLAG_IMMUTABLE + ) + return NotificationCompat.Builder(applicationContext, notificationChannelId) + .setContentTitle(progress).setSmallIcon(R.drawable.ic_notification) + .setColor(ContextCompat.getColor(applicationContext, R.color.seed)).setAutoCancel(true) + .setContentIntent(pendingIntent).build() + } } \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_notification.xml b/app/src/main/res/drawable/ic_notification.xml new file mode 100644 index 0000000..d8c9358 --- /dev/null +++ b/app/src/main/res/drawable/ic_notification.xml @@ -0,0 +1,14 @@ + + + + diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml index 79d981b..d798303 100644 --- a/app/src/main/res/layout/fragment_main.xml +++ b/app/src/main/res/layout/fragment_main.xml @@ -49,7 +49,7 @@ android:backgroundTint="@color/seed" android:contentDescription="@string/fab_label" android:src="@drawable/ic_upload" - app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintBottom_toTopOf="@id/snackbarLayout" app:layout_constraintEnd_toEndOf="parent" app:tint="@android:color/black" /> @@ -65,4 +65,10 @@ app:layout_constraintStart_toStartOf="parent" app:trackColor="@android:color/transparent" /> + + \ No newline at end of file diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml index 39c5854..c7f7bf1 100644 --- a/app/src/main/res/navigation/nav_graph.xml +++ b/app/src/main/res/navigation/nav_graph.xml @@ -6,7 +6,7 @@ + android:label="@string/empty" /> + + فایلستر + بارگذاری آسان فایل + نسخه: %1$s + کپی‌لفت © 2023 توسط روزبه زارعی + درباره + حمایت مالی + وبسایت + بارگذاری انجام شد + فایل آپلود شده برای 14 روز آینده در دسترس خواهد بود. + کپی نشانی + بستن + بارگذاری انجام نشد + خطایی رخ داده است. لطفا دوباره تلاش نمایید. + نشانی کپی شد + در حال بارگذاری فایل، لطفا صبر نمایید. + هنوز فایلی بارگذاری نکرده‌اید.\nابتدا فایلی را بارگذاری نمایید. + اطلاع رسانی درباره وضعیت بارگذاری + اطلاع رسانی درباره موفقیت آمیز بودن و یا با خطا مواجه شدن بارگذاری + بارگذاری فایل + تنظیمات + در حال آماده سازی بارگذاری… + در حال بارگذاری… + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5802a51..3820969 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2,25 +2,26 @@ Filester Simple File Uploader Version: %1$s - Copyleft © 2022 by Roozbeh Zarei + Copyleft © 2023 by Roozbeh Zarei About transfer.sh Donate - GitHub Repo + Website Upload successful - Your uploaded file will be available on the internet for the next 14 days. + Your uploaded file will be available for the next 14 days. Copy Link Close Upload failed Something went wrong. Please try again. - Link copied to clipboard + Link copied to clipboard Uploading file, please wait. - App info You haven\'t uploaded any files yet.\nTry uploading a file first. Upload progress status Notify when upload is in progress, successful or failed. - Upload in progress - Please wait Upload a file Settings + + filester_notification_id + Initializing upload… + Uploading… \ No newline at end of file diff --git a/build.gradle b/build.gradle deleted file mode 100644 index ab5dda5..0000000 --- a/build.gradle +++ /dev/null @@ -1,26 +0,0 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. -buildscript { - ext { - nav_version = "2.5.3" - fragment_version = "1.5.5" - lifecycle_version = "2.5.1" - retrofit_version = "2.9.0" - work_version = "2.7.1" - room_version = "2.5.0" - activity_version = "1.6.1" - } - dependencies { - classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version" - } -} - -plugins { - id 'com.android.application' version '7.4.0' apply false - id 'com.android.library' version '7.4.0' apply false - id 'org.jetbrains.kotlin.android' version '1.6.10' apply false -} - - -task clean(type: Delete) { - delete rootProject.buildDir -} \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..1c6a0c7 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,17 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +buildscript { + dependencies { + val navVersion = "2.6.0" + classpath("androidx.navigation:navigation-safe-args-gradle-plugin:$navVersion") + } +} + +plugins { + id("com.android.application") version "8.1.0" apply false + id("com.android.library") version "8.1.0" apply false + id("org.jetbrains.kotlin.android") version "1.9.0" apply false + id("com.google.devtools.ksp") version "1.9.0-1.0.12" apply false + id("com.google.gms.google-services") version "4.3.15" apply false + id("com.google.firebase.crashlytics") version "2.9.7" apply false + id("com.google.firebase.firebase-perf") version "1.4.2" apply false +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index cd0519b..022338b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,4 +20,6 @@ kotlin.code.style=official # Enables namespacing of each library's R class so that its R class includes only the # resources declared in the library itself and none from the library's dependencies, # thereby reducing the size of the R class for that library -android.nonTransitiveRClass=true \ No newline at end of file +android.nonTransitiveRClass=true +android.defaults.buildfeatures.buildconfig=true +android.nonFinalResIds=false \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 45011a2..3211692 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sat Jan 28 05:52:15 PST 2023 +#Thu Jul 27 08:14:26 IRST 2023 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip distributionPath=wrapper/dists -zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/settings.gradle b/settings.gradle.kts similarity index 95% rename from settings.gradle rename to settings.gradle.kts index 88abd25..5835d08 100644 --- a/settings.gradle +++ b/settings.gradle.kts @@ -13,4 +13,4 @@ dependencyResolutionManagement { } } rootProject.name = "Filester" -include ':app' +include(":app") \ No newline at end of file