1
+ package awais.instagrabber.activities
2
+
3
+ import android.annotation.SuppressLint
4
+ import android.content.ActivityNotFoundException
5
+ import android.content.Intent
6
+ import android.net.Uri
7
+ import android.os.Build
8
+ import android.os.Bundle
9
+ import android.provider.DocumentsContract
10
+ import android.util.Log
11
+ import android.view.View
12
+ import androidx.activity.viewModels
13
+ import awais.instagrabber.R
14
+ import awais.instagrabber.databinding.ActivityDirectorySelectBinding
15
+ import awais.instagrabber.dialogs.ConfirmDialogFragment
16
+ import awais.instagrabber.utils.AppExecutors.mainThread
17
+ import awais.instagrabber.utils.Constants
18
+ import awais.instagrabber.utils.extensions.TAG
19
+ import awais.instagrabber.viewmodels.DirectorySelectActivityViewModel
20
+ import java.io.IOException
21
+ import java.io.PrintWriter
22
+ import java.io.StringWriter
23
+
24
+ class DirectorySelectActivity : BaseLanguageActivity () {
25
+ private var initialUri: Uri ? = null
26
+
27
+ private lateinit var binding: ActivityDirectorySelectBinding
28
+
29
+ private val viewModel: DirectorySelectActivityViewModel by viewModels()
30
+
31
+ override fun onCreate (savedInstanceState : Bundle ? ) {
32
+ super .onCreate(savedInstanceState)
33
+ binding = ActivityDirectorySelectBinding .inflate(layoutInflater)
34
+ setContentView(binding.root)
35
+ val intent = intent
36
+ viewModel.setInitialUri(intent)
37
+ setupObservers()
38
+ binding.selectDir.setOnClickListener { openDirectoryChooser() }
39
+ initialUri = intent.getParcelableExtra(Constants .EXTRA_INITIAL_URI )
40
+ }
41
+
42
+ private fun setupObservers () {
43
+ viewModel.message.observe(this , { message: String? -> binding.message.text = message })
44
+ viewModel.prevUri.observe(this , { prevUri: String? ->
45
+ if (prevUri == null ) {
46
+ binding.prevUri.visibility = View .GONE
47
+ binding.message2.visibility = View .GONE
48
+ return @observe
49
+ }
50
+ binding.prevUri.text = prevUri
51
+ binding.prevUri.visibility = View .VISIBLE
52
+ binding.message2.visibility = View .VISIBLE
53
+ })
54
+ viewModel.dirSuccess.observe(this , { success: Boolean -> binding.selectDir.visibility = if (success) View .GONE else View .VISIBLE })
55
+ viewModel.loading.observe(this , { loading: Boolean ->
56
+ binding.message.visibility = if (loading) View .GONE else View .VISIBLE
57
+ binding.loadingIndicator.visibility = if (loading) View .VISIBLE else View .GONE
58
+ })
59
+ }
60
+
61
+ private fun openDirectoryChooser () {
62
+ val intent = Intent (Intent .ACTION_OPEN_DOCUMENT_TREE )
63
+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .O && initialUri != null ) {
64
+ intent.putExtra(DocumentsContract .EXTRA_INITIAL_URI , initialUri)
65
+ }
66
+ try {
67
+ startActivityForResult(intent, SELECT_DIR_REQUEST_CODE )
68
+ } catch (e: ActivityNotFoundException ) {
69
+ Log .e(TAG , " openDirectoryChooser: " , e)
70
+ showErrorDialog(getString(R .string.no_directory_picker_activity))
71
+ } catch (e: Exception ) {
72
+ Log .e(TAG , " openDirectoryChooser: " , e)
73
+ }
74
+ }
75
+
76
+ @SuppressLint(" StringFormatInvalid" )
77
+ override fun onActivityResult (requestCode : Int , resultCode : Int , data : Intent ? ) {
78
+ super .onActivityResult(requestCode, resultCode, data)
79
+ if (requestCode != SELECT_DIR_REQUEST_CODE ) return
80
+ if (resultCode != RESULT_OK ) {
81
+ showErrorDialog(getString(R .string.select_a_folder))
82
+ return
83
+ }
84
+ if (data == null || data.data == null ) {
85
+ showErrorDialog(getString(R .string.select_a_folder))
86
+ return
87
+ }
88
+ val authority = data.data?.authority
89
+ if (" com.android.externalstorage.documents" != authority) {
90
+ showErrorDialog(getString(R .string.dir_select_no_download_folder, authority))
91
+ return
92
+ }
93
+ mainThread.execute({
94
+ try {
95
+ viewModel.setupSelectedDir(data)
96
+ val intent = Intent (this , MainActivity ::class .java)
97
+ startActivity(intent)
98
+ finish()
99
+ } catch (e: Exception ) {
100
+ // Should not come to this point.
101
+ // If it does, we have to show this error to the user so that they can report it.
102
+ try {
103
+ StringWriter ().use { sw ->
104
+ PrintWriter (sw).use { pw ->
105
+ e.printStackTrace(pw)
106
+ showErrorDialog(" Please report this error to the developers:\n\n $sw " )
107
+ }
108
+ }
109
+ } catch (ioException: IOException ) {
110
+ Log .e(TAG , " onActivityResult: " , ioException)
111
+ }
112
+ }
113
+ }, 500 )
114
+ }
115
+
116
+ private fun showErrorDialog (message : String ) {
117
+ val dialogFragment = ConfirmDialogFragment .newInstance(
118
+ ERROR_REQUEST_CODE ,
119
+ R .string.error,
120
+ message,
121
+ R .string.ok,
122
+ 0 ,
123
+ 0
124
+ )
125
+ dialogFragment.show(supportFragmentManager, ConfirmDialogFragment ::class .java.simpleName)
126
+ }
127
+
128
+ companion object {
129
+ const val SELECT_DIR_REQUEST_CODE = 0x01
130
+ private const val ERROR_REQUEST_CODE = 0x02
131
+ }
132
+ }
0 commit comments