@@ -3,20 +3,39 @@ package com.troplo.privateuploader
33import android.Manifest
44import android.content.Intent
55import android.content.pm.PackageManager
6+ import android.net.Uri
67import android.os.Build
78import android.os.Bundle
9+ import android.provider.OpenableColumns
810import android.util.Log
911import androidx.activity.ComponentActivity
1012import androidx.activity.compose.setContent
1113import androidx.activity.result.contract.ActivityResultContracts
1214import androidx.core.content.ContextCompat
15+ import androidx.startup.AppInitializer
1316import com.google.android.gms.common.GoogleApiAvailability
17+ import com.troplo.privateuploader.api.RequestBodyWithProgress
1418import com.troplo.privateuploader.api.SessionManager
1519import com.troplo.privateuploader.api.SocketHandler
1620import com.troplo.privateuploader.api.SocketHandlerService
1721import com.troplo.privateuploader.api.TpuApi
22+ import com.troplo.privateuploader.api.TpuFunctions
23+ import com.troplo.privateuploader.api.stores.CollectionStore
24+ import com.troplo.privateuploader.api.stores.UploadStore
1825import com.troplo.privateuploader.api.stores.UserStore
26+ import com.troplo.privateuploader.data.model.UploadTarget
1927import com.troplo.privateuploader.ui.theme.PrivateUploaderTheme
28+ import io.wax911.emojify.EmojiManager
29+ import io.wax911.emojify.initializer.EmojiInitializer
30+ import kotlinx.coroutines.CoroutineScope
31+ import kotlinx.coroutines.Dispatchers
32+ import kotlinx.coroutines.launch
33+ import kotlinx.coroutines.withContext
34+ import okhttp3.MediaType.Companion.toMediaType
35+ import okhttp3.MediaType.Companion.toMediaTypeOrNull
36+ import okhttp3.MultipartBody
37+ import okhttp3.RequestBody.Companion.asRequestBody
38+
2039
2140class MainActivity : ComponentActivity () {
2241 override fun onResume () {
@@ -129,5 +148,110 @@ class MainActivity : ComponentActivity() {
129148 }
130149 }
131150 }
151+
152+ fun upload (files : List <UploadTarget >) {
153+ UploadStore .uploads = files.toMutableList()
154+
155+ val filesBody = files.map { file ->
156+ TpuFunctions .uriToFile(file.uri, this , file.name)
157+ }
158+
159+ CoroutineScope (Dispatchers .IO ).launch {
160+ var totalSize = 0L
161+
162+ // Calculate total file size
163+ filesBody.forEach { file ->
164+ totalSize + = file.length()
165+ }
166+
167+ val parts = mutableListOf<MultipartBody .Part >()
168+
169+ val requestFile = RequestBodyWithProgress (
170+ filesBody,
171+ RequestBodyWithProgress .ContentType .ANY ,
172+ progressCallback = { progress ->
173+ Log .d(" TPU.Upload" , " Progress: $progress " )
174+ UploadStore .globalProgress.value = progress
175+ }
176+ )
177+
178+ filesBody.forEach { file ->
179+ val part = MultipartBody .Part .createFormData(
180+ " attachments" ,
181+ file.name,
182+ requestFile
183+ )
184+ parts.add(part)
185+ }
186+
187+ val response = TpuApi .retrofitService.uploadFiles(parts).execute()
188+ response.body()?.let {
189+ UploadStore .globalProgress.value = 0f
190+ UploadStore .uploads = mutableListOf ()
191+ }
192+ }
193+ }
194+
195+ @Deprecated(" Deprecated in Java" )
196+ override fun onActivityResult (requestCode : Int , resultCode : Int , data : Intent ? ) {
197+ super .onActivityResult(requestCode, resultCode, data)
198+ if (requestCode == UploadStore .intentCode && resultCode == RESULT_OK ) {
199+ if (data != null ) {
200+ if (data.clipData != null ) {
201+ // Multiple files were selected
202+ val clipData = data.clipData
203+ if (clipData != null ) {
204+ val files = mutableListOf<UploadTarget >()
205+ for (i in 0 until clipData.itemCount) {
206+ Log .d(" TPU.Upload" , " File: ${clipData.getItemAt(i).uri} " )
207+ val uri = clipData.getItemAt(i).uri
208+ files.add(UploadTarget (
209+ uri = uri,
210+ name = getFileName(uri) ? : " unknown.file"
211+ ))
212+ }
213+ upload(files)
214+ }
215+ } else if (data.data != null ) {
216+ val uri = data.data
217+ if (uri != null ) {
218+ upload(listOf (UploadTarget (
219+ uri = uri,
220+ name = getFileName(uri) ? : " unknown.file"
221+ )))
222+ }
223+ }
224+ }
225+ }
226+ }
227+
228+ private fun getFileName (uri : Uri ): String {
229+ var result: String? = null
230+ if (uri.scheme == " content" ) {
231+ val cursor = contentResolver.query(uri, null , null , null , null )
232+ cursor.use { c ->
233+ if (c != null && c.moveToFirst()) {
234+ val index = c.getColumnIndex(OpenableColumns .DISPLAY_NAME )
235+ result = c.getString(index)
236+ }
237+ }
238+ }
239+ if (result == null ) {
240+ result = uri.path
241+ val cut = result!! .lastIndexOf(' /' )
242+ if (cut != - 1 ) {
243+ result = result!! .substring(cut + 1 )
244+ }
245+ }
246+ return result as String
247+ }
248+
249+
250+ internal val emojiManager: EmojiManager by lazy {
251+ // should already be initialized if we haven't disabled initialization in manifest
252+ // see: https://developer.android.com/topic/libraries/app-startup#disable-individual
253+ AppInitializer .getInstance(this )
254+ .initializeComponent(EmojiInitializer ::class .java)
255+ }
132256}
133257
0 commit comments