Merge branch 'gradle-update' into 'master'
Update scrambler dependency and gradle See merge request pixeldroid/PixelDroid!523
This commit is contained in:
commit
233167d227
@ -1,4 +1,4 @@
|
||||
image: registry.gitlab.com/fdroid/ci-images-client
|
||||
image: registry.gitlab.com/fdroid/fdroidserver:buildserver-bullseye
|
||||
|
||||
variables:
|
||||
GIT_SUBMODULE_STRATEGY: recursive
|
||||
@ -6,16 +6,42 @@ variables:
|
||||
before_script:
|
||||
- export GRADLE_USER_HOME=`pwd`/.gradle
|
||||
|
||||
.base:
|
||||
before_script:
|
||||
- test -e /etc/apt/sources.list.d/bullseye-backports.list
|
||||
|| echo "deb http://deb.debian.org/debian bullseye-backports main" >> /etc/apt/sources.list
|
||||
- apt update
|
||||
- apt-get -qy install -t bullseye-backports --no-install-recommends git sdkmanager
|
||||
|
||||
- test -n "$ANDROID_HOME" || source /etc/profile.d/bsenv.sh
|
||||
|
||||
- export cmdline_tools_latest="$ANDROID_HOME/cmdline-tools/latest/bin"
|
||||
- test -e $cmdline_tools_latest && export PATH="$cmdline_tools_latest:$PATH"
|
||||
|
||||
- export GRADLE_USER_HOME=$PWD/.gradle
|
||||
- export ANDROID_COMPILE_SDK=`sed -n 's,.*compileSdkVersion\s*\([0-9][0-9]*\).*,\1,p' app/build.gradle`
|
||||
- echo y | sdkmanager "platforms;android-${ANDROID_COMPILE_SDK}" > /dev/null
|
||||
|
||||
- apt-get update || apt-get update
|
||||
- apt-get install -y openjdk-17-jdk-headless
|
||||
- update-java-alternatives -s java-1.17.0-openjdk-amd64
|
||||
after_script:
|
||||
# this file changes every time but should not be cached
|
||||
- rm -f $GRADLE_USER_HOME/caches/modules-2/modules-2.lock
|
||||
- rm -fr $GRADLE_USER_HOME/caches/*/plugin-resolution/
|
||||
cache:
|
||||
paths:
|
||||
- .gradle/wrapper
|
||||
- .gradle/caches
|
||||
|
||||
|
||||
# Basic android and gradle stuff
|
||||
# Check linting
|
||||
lintDebug:
|
||||
extends: .base
|
||||
interruptible: true
|
||||
stage: build
|
||||
script:
|
||||
- apt-get update || apt-get update
|
||||
- apt-get install -y openjdk-11-jdk-headless
|
||||
- update-alternatives --auto java
|
||||
- ./gradlew checkLicenses
|
||||
- ./gradlew -Pci --console=plain :app:lintDebug -PbuildDir=lint --write-verification-metadata sha256
|
||||
- git diff --quiet gradle/verification-metadata.xml || (echo 'Verification of dependencies failed!' && exit 1)
|
||||
artifacts:
|
||||
@ -26,14 +52,12 @@ lintDebug:
|
||||
|
||||
# Make Project
|
||||
assembleDebug:
|
||||
extends: .base
|
||||
interruptible: true
|
||||
stage: build
|
||||
tags:
|
||||
- server_artectrex
|
||||
script:
|
||||
- apt-get update || apt-get update
|
||||
- apt-get install -y openjdk-11-jdk-headless
|
||||
- update-alternatives --auto java
|
||||
- ./gradlew assembleDebug
|
||||
artifacts:
|
||||
paths:
|
||||
@ -41,27 +65,36 @@ assembleDebug:
|
||||
|
||||
# Run all tests, if any fails, interrupt the pipeline (fail it)
|
||||
debugTests:
|
||||
extends: .base
|
||||
interruptible: true
|
||||
stage: test
|
||||
script:
|
||||
- apt-get update || apt-get update
|
||||
- apt-get install -y openjdk-11-jdk-headless
|
||||
- update-alternatives --auto java
|
||||
- ./gradlew -Pci --console=plain :app:testDebug -x lint
|
||||
|
||||
.connected-template: &connected-template
|
||||
extends: .base
|
||||
allow_failure: true
|
||||
image: briar/ci-image-android-emulator:latest
|
||||
stage: test
|
||||
script:
|
||||
- start-emulator
|
||||
- wait-for-emulator
|
||||
- adb devices
|
||||
- adb shell input keyevent 82 &
|
||||
# Switch to right java version for building the app
|
||||
- apt-get update || apt-get update
|
||||
- apt-get install -y openjdk-11-jdk-headless
|
||||
- update-alternatives --auto java
|
||||
- ./gradlew connectedStagingAndroidTest --info || (adb -e logcat -d > logcat.txt; exit 1)
|
||||
- export JAVA_HOME="/usr/lib/jvm/java-17-openjdk-amd64"
|
||||
- ./gradlew assembleStaging
|
||||
- export AVD_SDK=`echo $CI_JOB_NAME | awk '{print $2}'`
|
||||
- export AVD_TAG=`echo $CI_JOB_NAME | awk '{print $3}'`
|
||||
- export AVD_ARCH=`echo $CI_JOB_NAME | awk '{print $4}'`
|
||||
- export AVD_PACKAGE="system-images;android-${AVD_SDK};${AVD_TAG};${AVD_ARCH}"
|
||||
- echo $AVD_PACKAGE
|
||||
- $ANDROID_HOME/cmdline-tools/latest/bin/avdmanager --verbose delete avd --name "$NAME_AVD"
|
||||
- export AVD="$AVD_PACKAGE"
|
||||
- echo y | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --install "$AVD"
|
||||
- echo no | $ANDROID_HOME/cmdline-tools/latest/bin/avdmanager --verbose create avd --name "$NAME_AVD" --package "$AVD" --device "pixel"
|
||||
- start-emulator.sh
|
||||
- ./gradlew installStaging
|
||||
- adb shell am start -n org.pixeldroid.app.debug/org.pixeldroid.app.MainActivity
|
||||
- if [ $AVD_SDK -lt 25 ] || ! emulator -accel-check; then
|
||||
export FLAG=-Pandroid.testInstrumentationRunnerArguments.notAnnotation=androidx.test.filters.LargeTest;
|
||||
fi
|
||||
- ./gradlew connectedStagingAndroidTest $FLAG --info || (adb -e logcat -d > logcat.txt; exit 1)
|
||||
artifacts:
|
||||
paths:
|
||||
- logcat.txt
|
||||
|
@ -1,16 +1,18 @@
|
||||
import com.android.build.api.dsl.ManagedVirtualDevice
|
||||
|
||||
plugins {
|
||||
id "com.cookpad.android.plugin.license-tools" version "1.2.8"
|
||||
id "com.mikepenz.aboutlibraries.plugin" version "10.5.2"
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'com.mikepenz.aboutlibraries.plugin'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
apply plugin: 'jacoco'
|
||||
apply plugin: "kotlin-parcelize"
|
||||
|
||||
|
||||
|
||||
// Force latest version of Jacoco, initially done to resolve https://github.com/jacoco/jacoco/issues/1155
|
||||
jacoco.toolVersion = "0.8.7"
|
||||
|
||||
@ -25,6 +27,7 @@ android {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_1_8
|
||||
freeCompilerArgs += ["-opt-in=kotlin.RequiresOptIn"]
|
||||
@ -32,7 +35,7 @@ android {
|
||||
defaultConfig {
|
||||
minSdkVersion 23
|
||||
targetSdkVersion 33
|
||||
versionCode 21
|
||||
versionCode 22
|
||||
versionName "1.0.beta" + versionCode
|
||||
|
||||
//TODO add resConfigs("en", "fr", "ja",...) ?
|
||||
@ -111,6 +114,7 @@ android {
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
dataBinding = true
|
||||
buildConfig = true
|
||||
}
|
||||
|
||||
apply plugin: 'kotlin-kapt'
|
||||
@ -153,14 +157,14 @@ dependencies {
|
||||
implementation "androidx.annotation:annotation:1.5.0"
|
||||
implementation 'androidx.gridlayout:gridlayout:1.0.0'
|
||||
implementation "androidx.activity:activity-ktx:1.6.1"
|
||||
implementation 'androidx.fragment:fragment-ktx:1.5.4'
|
||||
implementation 'androidx.fragment:fragment-ktx:1.5.5'
|
||||
implementation 'androidx.work:work-runtime-ktx:2.7.1'
|
||||
implementation 'androidx.media2:media2-widget:1.2.1'
|
||||
implementation 'androidx.media2:media2-player:1.2.1'
|
||||
|
||||
|
||||
// Use the most recent version of CameraX
|
||||
def cameraX_version = '1.1.0'
|
||||
def cameraX_version = '1.2.0'
|
||||
implementation "androidx.camera:camera-core:$cameraX_version"
|
||||
implementation "androidx.camera:camera-camera2:$cameraX_version"
|
||||
// CameraX Lifecycle library
|
||||
@ -200,7 +204,7 @@ dependencies {
|
||||
implementation 'com.github.connyduck:sparkbutton:4.1.0'
|
||||
|
||||
|
||||
implementation 'org.pixeldroid.pixeldroid:android-media-editor:1.2'
|
||||
implementation 'org.pixeldroid.pixeldroid:android-media-editor:1.4'
|
||||
implementation project(path: ':scrambler')
|
||||
|
||||
implementation('com.github.bumptech.glide:glide:4.14.2') {
|
||||
@ -235,6 +239,8 @@ dependencies {
|
||||
|
||||
implementation 'me.relex:circleindicator:2.1.6'
|
||||
|
||||
implementation "com.mikepenz:aboutlibraries-core:10.5.2"
|
||||
|
||||
/**
|
||||
* Not in release, so not mentioned in licenses list
|
||||
*/
|
||||
@ -253,13 +259,13 @@ dependencies {
|
||||
|
||||
|
||||
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
|
||||
androidTestImplementation 'androidx.test:runner:1.4.0'
|
||||
androidTestImplementation 'androidx.test:rules:1.4.0'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||
androidTestImplementation 'androidx.test:runner:1.4.0'
|
||||
androidTestImplementation 'androidx.test:rules:1.4.0'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.4.0'
|
||||
androidTestImplementation 'androidx.test:runner:1.5.1'
|
||||
androidTestImplementation 'androidx.test:rules:1.5.0'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.4'
|
||||
androidTestImplementation 'androidx.test:runner:1.5.1'
|
||||
androidTestImplementation 'androidx.test:rules:1.5.0'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.5.0'
|
||||
androidTestImplementation 'com.android.support.test.espresso:espresso-contrib:3.0.2'
|
||||
androidTestImplementation 'com.squareup.okhttp3:mockwebserver:4.9.2'
|
||||
|
||||
@ -274,8 +280,8 @@ tasks.withType(Test) {
|
||||
task jacocoTestReport(type: JacocoReport, dependsOn: ['connectedStagingAndroidTest', 'testStagingUnitTest', 'createStagingCoverageReport']) {
|
||||
|
||||
reports {
|
||||
xml.enabled = true
|
||||
html.enabled = true
|
||||
xml.required = true
|
||||
html.required = true
|
||||
}
|
||||
|
||||
def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*', 'android/**/*.*']
|
||||
|
File diff suppressed because one or more lines are too long
@ -1,314 +0,0 @@
|
||||
package org.pixeldroid.app.postCreation
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.text.Editable
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.exifinterface.media.ExifInterface
|
||||
import androidx.lifecycle.*
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.jarsilio.android.scrambler.exceptions.UnsupportedFileFormatException
|
||||
import com.jarsilio.android.scrambler.stripMetadata
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.disposables.Disposable
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import okhttp3.MultipartBody
|
||||
import org.pixeldroid.app.MainActivity
|
||||
import org.pixeldroid.app.R
|
||||
import org.pixeldroid.app.utils.PixelDroidApplication
|
||||
import org.pixeldroid.app.utils.api.objects.Attachment
|
||||
import org.pixeldroid.app.utils.db.entities.UserDatabaseEntity
|
||||
import org.pixeldroid.app.utils.di.PixelfedAPIHolder
|
||||
import org.pixeldroid.app.utils.fileExtension
|
||||
import org.pixeldroid.app.utils.getMimeType
|
||||
import retrofit2.HttpException
|
||||
import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
import java.net.URI
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
// Models the UI state for the PostCreationActivity
|
||||
data class PostSubmissionActivityUiState(
|
||||
val userMessage: String? = null,
|
||||
|
||||
val postCreationSendButtonEnabled: Boolean = true,
|
||||
|
||||
val newPostDescriptionText: String = "",
|
||||
val nsfw: Boolean = false,
|
||||
|
||||
val chosenAccount: UserDatabaseEntity? = null,
|
||||
|
||||
val uploadProgressBarVisible: Boolean = false,
|
||||
val uploadProgress: Int = 0,
|
||||
val uploadCompletedTextviewVisible: Boolean = false,
|
||||
val uploadErrorVisible: Boolean = false,
|
||||
val uploadErrorExplanationText: String = "",
|
||||
val uploadErrorExplanationVisible: Boolean = false,
|
||||
)
|
||||
|
||||
class PostSubmissionViewModel(application: Application, photodata: ArrayList<PhotoData>? = null, val existingDescription: String? = null) : AndroidViewModel(application) {
|
||||
private val photoData: MutableLiveData<MutableList<PhotoData>> by lazy {
|
||||
MutableLiveData<MutableList<PhotoData>>().also {
|
||||
if (photodata != null) {
|
||||
it.value = photodata.toMutableList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
lateinit var apiHolder: PixelfedAPIHolder
|
||||
|
||||
private val _uiState: MutableStateFlow<PostSubmissionActivityUiState>
|
||||
|
||||
init {
|
||||
(application as PixelDroidApplication).getAppComponent().inject(this)
|
||||
val sharedPreferences =
|
||||
PreferenceManager.getDefaultSharedPreferences(application)
|
||||
val initialDescription = sharedPreferences.getString("prefill_description", "") ?: ""
|
||||
|
||||
_uiState = MutableStateFlow(PostSubmissionActivityUiState(newPostDescriptionText = existingDescription ?: initialDescription))
|
||||
}
|
||||
|
||||
val uiState: StateFlow<PostSubmissionActivityUiState> = _uiState
|
||||
|
||||
// Map photoData indexes to FFmpeg Session IDs
|
||||
private val sessionMap: MutableMap<Uri, Long> = mutableMapOf()
|
||||
// Keep track of temporary files to delete them (avoids filling cache super fast with videos)
|
||||
private val tempFiles: java.util.ArrayList<File> = java.util.ArrayList()
|
||||
|
||||
fun userMessageShown() {
|
||||
_uiState.update { currentUiState ->
|
||||
currentUiState.copy(userMessage = null)
|
||||
}
|
||||
}
|
||||
|
||||
fun getPhotoData(): LiveData<MutableList<PhotoData>> = photoData
|
||||
|
||||
fun resetUploadStatus() {
|
||||
photoData.value = photoData.value?.map { it.copy(uploadId = null, progress = null) }?.toMutableList()
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploads the images that are in the [photoData] array.
|
||||
* Keeps track of them in the [PhotoData.progress] (for the upload progress), and the
|
||||
* [PhotoData.uploadId] (for the list of ids of the uploads).
|
||||
*/
|
||||
@OptIn(ExperimentalUnsignedTypes::class)
|
||||
fun upload() {
|
||||
_uiState.update { currentUiState ->
|
||||
currentUiState.copy(
|
||||
postCreationSendButtonEnabled = false,
|
||||
uploadCompletedTextviewVisible = false,
|
||||
uploadErrorVisible = false,
|
||||
uploadProgressBarVisible = true
|
||||
)
|
||||
}
|
||||
|
||||
for (data: PhotoData in getPhotoData().value ?: emptyList()) {
|
||||
val extension = data.imageUri.fileExtension(getApplication<PixelDroidApplication>().contentResolver)
|
||||
|
||||
val strippedImage = File.createTempFile("temp_img", ".$extension", getApplication<PixelDroidApplication>().cacheDir)
|
||||
|
||||
val imageUri = data.imageUri
|
||||
|
||||
val (strippedOrNot, size) = try {
|
||||
val orientation = ExifInterface(getApplication<PixelDroidApplication>().contentResolver.openInputStream(imageUri)!!).getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)
|
||||
|
||||
stripMetadata(imageUri, strippedImage, getApplication<PixelDroidApplication>().contentResolver)
|
||||
|
||||
// Restore EXIF orientation
|
||||
val exifInterface = ExifInterface(strippedImage)
|
||||
exifInterface.setAttribute(ExifInterface.TAG_ORIENTATION, orientation.toString())
|
||||
exifInterface.saveAttributes()
|
||||
|
||||
Pair(strippedImage.inputStream(), strippedImage.length())
|
||||
} catch (e: UnsupportedFileFormatException){
|
||||
strippedImage.delete()
|
||||
if(imageUri != data.imageUri) File(URI(imageUri.toString())).delete()
|
||||
val imageInputStream = try {
|
||||
getApplication<PixelDroidApplication>().contentResolver.openInputStream(imageUri)!!
|
||||
} catch (e: FileNotFoundException){
|
||||
_uiState.update { currentUiState ->
|
||||
currentUiState.copy(
|
||||
userMessage = getApplication<PixelDroidApplication>().getString(R.string.file_not_found,
|
||||
data.imageUri)
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
Pair(imageInputStream, data.size)
|
||||
} catch (e: IOException){
|
||||
strippedImage.delete()
|
||||
if(imageUri != data.imageUri) File(URI(imageUri.toString())).delete()
|
||||
_uiState.update { currentUiState ->
|
||||
currentUiState.copy(
|
||||
userMessage = getApplication<PixelDroidApplication>().getString(R.string.file_not_found,
|
||||
data.imageUri)
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val type = data.imageUri.getMimeType(getApplication<PixelDroidApplication>().contentResolver)
|
||||
val imagePart = ProgressRequestBody(strippedOrNot, size, type)
|
||||
val requestBody = MultipartBody.Builder()
|
||||
.setType(MultipartBody.FORM)
|
||||
.addFormDataPart("file", System.currentTimeMillis().toString(), imagePart)
|
||||
.build()
|
||||
|
||||
val sub = imagePart.progressSubject
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe { percentage ->
|
||||
data.progress = percentage.toInt()
|
||||
_uiState.update { currentUiState ->
|
||||
currentUiState.copy(
|
||||
uploadProgress = getPhotoData().value!!.sumOf { it.progress ?: 0 } / getPhotoData().value!!.size
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
var postSub: Disposable? = null
|
||||
|
||||
val description = data.imageDescription?.let { MultipartBody.Part.createFormData("description", it) }
|
||||
|
||||
//Ugly temporary account switching, but it works well enough for now
|
||||
val api = uiState.value.chosenAccount?.let {
|
||||
apiHolder.setToCurrentUser(it)
|
||||
} ?: apiHolder.api ?: apiHolder.setToCurrentUser()
|
||||
|
||||
val inter = api.mediaUpload(description, requestBody.parts[0])
|
||||
|
||||
apiHolder.api = null
|
||||
postSub = inter
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{ attachment: Attachment ->
|
||||
data.progress = 0
|
||||
data.uploadId = attachment.id!!
|
||||
},
|
||||
{ e: Throwable ->
|
||||
_uiState.update { currentUiState ->
|
||||
currentUiState.copy(
|
||||
uploadErrorVisible = true,
|
||||
uploadErrorExplanationText = if(e is HttpException){
|
||||
getApplication<PixelDroidApplication>().getString(R.string.upload_error, e.code())
|
||||
} else "",
|
||||
uploadErrorExplanationVisible = e is HttpException,
|
||||
)
|
||||
}
|
||||
strippedImage.delete()
|
||||
if(imageUri != data.imageUri) File(URI(imageUri.toString())).delete()
|
||||
e.printStackTrace()
|
||||
postSub?.dispose()
|
||||
sub.dispose()
|
||||
},
|
||||
{
|
||||
strippedImage.delete()
|
||||
if(imageUri != data.imageUri) File(URI(imageUri.toString())).delete()
|
||||
data.progress = 100
|
||||
if (getPhotoData().value!!.all { it.progress == 100 && it.uploadId != null }) {
|
||||
_uiState.update { currentUiState ->
|
||||
currentUiState.copy(
|
||||
uploadProgressBarVisible = false,
|
||||
uploadCompletedTextviewVisible = true
|
||||
)
|
||||
}
|
||||
post()
|
||||
}
|
||||
postSub?.dispose()
|
||||
sub.dispose()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun post() {
|
||||
val description = uiState.value.newPostDescriptionText
|
||||
|
||||
//TODO investigate why this works but booleans don't
|
||||
val nsfw = if (uiState.value.nsfw) 1 else 0
|
||||
|
||||
_uiState.update { currentUiState ->
|
||||
currentUiState.copy(
|
||||
postCreationSendButtonEnabled = false
|
||||
)
|
||||
}
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
//Ugly temporary account switching, but it works well enough for now
|
||||
val api = uiState.value.chosenAccount?.let {
|
||||
apiHolder.setToCurrentUser(it)
|
||||
} ?: apiHolder.api ?: apiHolder.setToCurrentUser()
|
||||
|
||||
api.postStatus(
|
||||
statusText = description,
|
||||
media_ids = getPhotoData().value!!.mapNotNull { it.uploadId }.toList(),
|
||||
sensitive = nsfw
|
||||
)
|
||||
Toast.makeText(getApplication(), getApplication<PixelDroidApplication>().getString(R.string.upload_post_success),
|
||||
Toast.LENGTH_SHORT).show()
|
||||
val intent = Intent(getApplication(), MainActivity::class.java)
|
||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||
//TODO make the activity launch this instead (and surrounding toasts too)
|
||||
getApplication<PixelDroidApplication>().startActivity(intent)
|
||||
} catch (exception: HttpException) {
|
||||
Toast.makeText(getApplication(), getApplication<PixelDroidApplication>().getString(R.string.upload_post_failed),
|
||||
Toast.LENGTH_SHORT).show()
|
||||
Log.e(TAG, exception.response().toString() + exception.message().toString())
|
||||
_uiState.update { currentUiState ->
|
||||
currentUiState.copy(
|
||||
postCreationSendButtonEnabled = true
|
||||
)
|
||||
}
|
||||
} catch (exception: Exception) {
|
||||
Toast.makeText(getApplication(), getApplication<PixelDroidApplication>().getString(R.string.upload_post_error),
|
||||
Toast.LENGTH_SHORT).show()
|
||||
Log.e(TAG, exception.toString())
|
||||
_uiState.update { currentUiState ->
|
||||
currentUiState.copy(
|
||||
postCreationSendButtonEnabled = true
|
||||
)
|
||||
}
|
||||
}finally {
|
||||
apiHolder.api = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun newPostDescriptionChanged(text: Editable?) {
|
||||
_uiState.update { it.copy(newPostDescriptionText = text.toString()) }
|
||||
}
|
||||
|
||||
fun trackTempFile(file: File) {
|
||||
tempFiles.add(file)
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
super.onCleared()
|
||||
tempFiles.forEach {
|
||||
it.delete()
|
||||
}
|
||||
}
|
||||
|
||||
fun updateNSFW(checked: Boolean) { _uiState.update { it.copy(nsfw = checked) } }
|
||||
|
||||
fun chooseAccount(which: UserDatabaseEntity) {
|
||||
_uiState.update { it.copy(chosenAccount = which) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PostSubmissionViewModelFactory(val application: Application, val photoData: ArrayList<PhotoData>, val existingDescription: String?) : ViewModelProvider.Factory {
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return modelClass.getConstructor(Application::class.java, ArrayList::class.java, String::class.java).newInstance(application, photoData, existingDescription)
|
||||
}
|
||||
}
|
@ -1,11 +1,9 @@
|
||||
package org.pixeldroid.app.settings
|
||||
|
||||
import android.os.Bundle
|
||||
import com.google.gson.Gson
|
||||
import com.mikepenz.aboutlibraries.Libs
|
||||
import org.pixeldroid.app.R
|
||||
import org.pixeldroid.app.databinding.OpenSourceLicenseBinding
|
||||
import org.pixeldroid.app.settings.licenseObjects.Libraries
|
||||
import org.pixeldroid.app.settings.licenseObjects.OpenSourceItem
|
||||
import org.pixeldroid.app.utils.BaseThemedWithBarActivity
|
||||
|
||||
/**
|
||||
@ -30,12 +28,14 @@ class LicenseActivity: BaseThemedWithBarActivity() {
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
val text: String = applicationContext.assets.open("licenses.json")
|
||||
val aboutLibsJson: String = applicationContext.resources.openRawResource(R.raw.aboutlibraries)
|
||||
.bufferedReader().use { it.readText() }
|
||||
|
||||
val listObj: List<OpenSourceItem> = Gson().fromJson(text, Libraries::class.java).libraries
|
||||
val libs = Libs.Builder()
|
||||
.withJson(aboutLibsJson)
|
||||
.build()
|
||||
|
||||
val adapter = OpenSourceLicenseAdapter(listObj)
|
||||
val adapter = OpenSourceLicenseAdapter(libs)
|
||||
binding.openSourceLicenseRecyclerView.adapter = adapter
|
||||
}
|
||||
}
|
@ -6,10 +6,11 @@ import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.mikepenz.aboutlibraries.Libs
|
||||
import com.mikepenz.aboutlibraries.entity.Library
|
||||
import org.pixeldroid.app.databinding.OpenSourceItemBinding
|
||||
import org.pixeldroid.app.settings.licenseObjects.OpenSourceItem
|
||||
|
||||
class OpenSourceLicenseAdapter(private val openSourceItems: List<OpenSourceItem>) :
|
||||
class OpenSourceLicenseAdapter(private val openSourceItems: Libs) :
|
||||
RecyclerView.Adapter<OpenSourceLicenseAdapter.OpenSourceLicenceViewHolder>() {
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OpenSourceLicenceViewHolder
|
||||
@ -19,43 +20,35 @@ class OpenSourceLicenseAdapter(private val openSourceItems: List<OpenSourceItem>
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: OpenSourceLicenceViewHolder, position: Int) {
|
||||
val item = openSourceItems[position]
|
||||
val item = openSourceItems.libraries[position]
|
||||
holder.bind(item)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = openSourceItems.size
|
||||
override fun getItemCount(): Int = openSourceItems.libraries.size
|
||||
|
||||
class OpenSourceLicenceViewHolder(val binding: OpenSourceItemBinding) :
|
||||
RecyclerView.ViewHolder(binding.root) {
|
||||
@SuppressLint("SetTextI18n")
|
||||
fun bind(item: OpenSourceItem) {
|
||||
fun bind(item: Library) {
|
||||
with(binding) {
|
||||
if (!item.libraryName.isNullOrEmpty()) {
|
||||
if (item.name.isNotEmpty()) {
|
||||
title.isVisible = true
|
||||
title.text = "${item.libraryName}"
|
||||
title.text = item.name
|
||||
} else {
|
||||
title.isVisible = false
|
||||
}
|
||||
val license = item.license
|
||||
if (license != null) {
|
||||
val licenseUrl = item.licenseUrl?.let { " (${it} )" } ?: ""
|
||||
copyright.isVisible = true
|
||||
copyright.apply {
|
||||
text = "$license$licenseUrl"
|
||||
movementMethod = LinkMovementMethod.getInstance()
|
||||
}
|
||||
} else {
|
||||
copyright.isVisible = false
|
||||
val license = item.licenses.firstOrNull()
|
||||
val licenseName = license?.name ?: ""
|
||||
val licenseUrl = license?.url?.let { " (${it} )" } ?: ""
|
||||
copyright.isVisible = true
|
||||
copyright.apply {
|
||||
text = "$licenseName$licenseUrl"
|
||||
movementMethod = LinkMovementMethod.getInstance()
|
||||
}
|
||||
if (item.url != null || item.copyrightHolder != null) {
|
||||
val licenseUrl = item.url?.let { " (${it} )" } ?: ""
|
||||
url.isVisible = true
|
||||
url.apply {
|
||||
text = "${item.copyrightHolder ?: ""}$licenseUrl"
|
||||
movementMethod = LinkMovementMethod.getInstance()
|
||||
}
|
||||
} else {
|
||||
url.isVisible = false
|
||||
url.isVisible = true
|
||||
url.apply {
|
||||
text = "${item.developers.firstOrNull()?.name ?: ""} ${item.website}"
|
||||
movementMethod = LinkMovementMethod.getInstance()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +0,0 @@
|
||||
package org.pixeldroid.app.settings.licenseObjects
|
||||
|
||||
data class Libraries(
|
||||
val libraries: List<OpenSourceItem>
|
||||
)
|
@ -1,10 +0,0 @@
|
||||
package org.pixeldroid.app.settings.licenseObjects
|
||||
|
||||
|
||||
data class OpenSourceItem(
|
||||
val libraryName: String?,
|
||||
val copyrightHolder: String?,
|
||||
val url: String?,
|
||||
val license: String?,
|
||||
val licenseUrl: String?,
|
||||
)
|
@ -9,7 +9,6 @@ import org.pixeldroid.app.utils.BaseFragment
|
||||
import dagger.Component
|
||||
import org.pixeldroid.app.postCreation.PostCreationViewModel
|
||||
import org.pixeldroid.app.profile.EditProfileViewModel
|
||||
import org.pixeldroid.app.postCreation.PostSubmissionViewModel
|
||||
import org.pixeldroid.app.utils.notificationsWorker.NotificationsWorker
|
||||
import javax.inject.Singleton
|
||||
|
||||
@ -23,7 +22,6 @@ interface ApplicationComponent {
|
||||
fun inject(notificationsWorker: NotificationsWorker)
|
||||
fun inject(postCreationViewModel: PostCreationViewModel)
|
||||
fun inject(editProfileViewModel: EditProfileViewModel)
|
||||
fun inject(postSubmissionViewModel: PostSubmissionViewModel)
|
||||
|
||||
val context: Context?
|
||||
val application: Application?
|
||||
|
@ -7,7 +7,7 @@ buildscript {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.0.0-alpha07'
|
||||
classpath 'com.android.tools.build:gradle:8.0.0-beta01'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
@ -25,3 +25,5 @@ org.gradle.parallel=true
|
||||
kapt.incremental.apt=true
|
||||
android.enableR8.fullMode=true
|
||||
android.nonTransitiveRClass=false
|
||||
android.defaults.buildfeatures.buildconfig=true
|
||||
android.nonFinalResIds=false
|
||||
|
File diff suppressed because it is too large
Load Diff
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,7 +1,7 @@
|
||||
#Fri Oct 14 13:37:44 GMT 2022
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionSha256Sum=cb87f222c5585bd46838ad4db78463a5c5f3d336e5e2b98dc7c0c586527351c2
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
|
||||
distributionSha256Sum=d5bb29e784426547e4f455fbc0e6512d7a6a67d7d890cf24d601309287128b79
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-rc-1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 6b5fbf81c5a52a97468d906c561887ab560422ff
|
||||
Subproject commit 5b7008b218399fa3ae2aec80ddab1a840241c3b2
|
Loading…
x
Reference in New Issue
Block a user