Skip to content

Commit 15e0b3e

Browse files
authored
Updates (#64)
- Add Download to File List - Update Bottom Navigation - Update Widget Layout
1 parent 0d71c23 commit 15e0b3e

File tree

13 files changed

+220
-105
lines changed

13 files changed

+220
-105
lines changed

app/src/main/java/com/djangofiles/djangofiles/ui/files/FilesBottomSheet.kt

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package com.djangofiles.djangofiles.ui.files
22

3+
import android.app.DownloadManager
34
import android.content.Context
45
import android.content.res.ColorStateList
56
import android.os.Bundle
7+
import android.os.Environment
68
import android.util.Log
79
import android.view.LayoutInflater
810
import android.view.View
@@ -12,6 +14,7 @@ import android.widget.ImageView
1214
import android.widget.LinearLayout
1315
import android.widget.Toast
1416
import androidx.core.content.ContextCompat
17+
import androidx.core.net.toUri
1518
import androidx.fragment.app.activityViewModels
1619
import androidx.fragment.app.setFragmentResultListener
1720
import androidx.lifecycle.lifecycleScope
@@ -37,11 +40,13 @@ class FilesBottomSheet : BottomSheetDialogFragment() {
3740
private var _binding: FragmentFilesBottomBinding? = null
3841
private val binding get() = _binding!!
3942

43+
private val viewModel: FilesViewModel by activityViewModels()
44+
45+
private lateinit var downloadManager: DownloadManager
46+
4047
private lateinit var savedUrl: String
4148
private lateinit var filePassword: String
4249

43-
private val viewModel: FilesViewModel by activityViewModels()
44-
4550
companion object {
4651
fun newInstance(bundle: Bundle) = FilesBottomSheet().apply {
4752
arguments = bundle
@@ -157,9 +162,32 @@ class FilesBottomSheet : BottomSheetDialogFragment() {
157162
}
158163
requireContext().showExpireDialog(listOf(data.id), ::callback, data.expr)
159164
}
160-
// Open
161-
binding.openButton.setOnClickListener {
162-
requireContext().openUrl(data.url)
165+
//// Open
166+
//binding.openButton.setOnClickListener {
167+
// requireContext().openUrl(data.url)
168+
//}
169+
// Download
170+
downloadManager =
171+
requireContext().getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
172+
173+
binding.downloadButton.setOnClickListener {
174+
Log.d("downloadButton", "${data.name} - ${data.raw}")
175+
binding.downloadButton.isEnabled = false
176+
val request = DownloadManager.Request(data.raw.toUri()).apply {
177+
setTitle(data.name)
178+
setMimeType(data.mime)
179+
setDescription("Django Files")
180+
setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
181+
setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, data.name)
182+
setAllowedOverMetered(true)
183+
setAllowedOverRoaming(true)
184+
setRequiresCharging(false)
185+
}
186+
187+
val downloadId = downloadManager.enqueue(request)
188+
Log.d("downloadButton", "Download ID: $downloadId")
189+
Toast.makeText(requireContext(), "Download Started", Toast.LENGTH_SHORT).show()
190+
//dismiss()
163191
}
164192

165193
// Image

app/src/main/java/com/djangofiles/djangofiles/ui/files/FilesFragment.kt

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package com.djangofiles.djangofiles.ui.files
22

3+
import android.app.DownloadManager
34
import android.content.Context
45
import android.content.Intent
56
import android.net.ConnectivityManager
67
import android.os.Bundle
8+
import android.os.Environment
79
import android.os.Handler
810
import android.os.Looper
911
import android.util.Log
@@ -29,6 +31,7 @@ import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader
2931
import com.bumptech.glide.load.model.GlideUrl
3032
import com.djangofiles.djangofiles.R
3133
import com.djangofiles.djangofiles.ServerApi
34+
import com.djangofiles.djangofiles.ServerApi.FileResponse
3235
import com.djangofiles.djangofiles.ServerApi.FilesEditRequest
3336
import com.djangofiles.djangofiles.databinding.FragmentFilesBinding
3437
import com.djangofiles.djangofiles.db.AlbumDao
@@ -62,6 +65,7 @@ class FilesFragment : Fragment() {
6265

6366
private lateinit var api: ServerApi
6467
private lateinit var filesAdapter: FilesViewAdapter
68+
private lateinit var downloadManager: DownloadManager
6569

6670
private val viewModel: FilesViewModel by activityViewModels()
6771

@@ -411,6 +415,30 @@ class FilesFragment : Fragment() {
411415
}
412416
requireContext().deleteConfirmDialog(ids, selectedPositions, ::callback)
413417
}
418+
419+
downloadManager =
420+
requireContext().getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
421+
binding.downloadAllButton.setOnClickListener {
422+
if (viewModel.selected.value.isNullOrEmpty()) return@setOnClickListener
423+
val filesData = viewModel.filesData.value!!.toList()
424+
val positions: List<Int> = viewModel.selected.value!!.toList()
425+
Log.d("File[downloadAllButton]", "positions: $positions")
426+
fun callback() {
427+
//val fileUrls: List<String> = positions.map { index -> "${savedUrl}/raw/${data[index].name}" }
428+
//Log.d("File[callback]", "fileUrls: $fileUrls")
429+
lifecycleScope.launch {
430+
for (pos in positions) {
431+
val data = filesData[pos]
432+
Log.d("File[callback]", "data: $data")
433+
val request = getDownloadRequest(data)
434+
val downloadId = downloadManager.enqueue(request)
435+
Log.d("downloadButton", "Download ID: $downloadId")
436+
}
437+
}
438+
}
439+
requireContext().downloadConfirmDialog(positions, ::callback)
440+
}
441+
414442
binding.expireAllButton.setOnClickListener {
415443
Log.d("File[expireAllButton]", "viewModel.selected.value: ${viewModel.selected.value}")
416444
fun callback(newExpr: String) {
@@ -426,6 +454,7 @@ class FilesFragment : Fragment() {
426454
Log.d("File[expireAllButton]", "fileIds: $fileIds")
427455
requireContext().showExpireDialog(fileIds, ::callback)
428456
}
457+
429458
binding.albumAllButton.setOnClickListener {
430459
Log.d("File[albumAllButton]", "viewModel.selected.value: ${viewModel.selected.value}")
431460
setFragmentResultListener("albums_result") { _, bundle ->
@@ -604,6 +633,33 @@ class FilesFragment : Fragment() {
604633
}
605634
.show()
606635
}
636+
637+
private fun Context.downloadConfirmDialog(positions: List<Int>, callback: () -> Unit) {
638+
Log.d("downloadConfirmDialog", "positions: $positions")
639+
val count = positions.count()
640+
val s = if (count > 1) "s" else ""
641+
MaterialAlertDialogBuilder(this, R.style.AlertDialogTheme)
642+
.setTitle("Download $count File${s}")
643+
.setIcon(R.drawable.md_download_24px)
644+
.setMessage("Files are saved to the Downloads directory.")
645+
.setNegativeButton("Cancel", null)
646+
.setPositiveButton("Download $count File${s}") { _, _ -> callback() }
647+
.show()
648+
}
649+
650+
fun getDownloadRequest(data: FileResponse): DownloadManager.Request {
651+
Log.d("getDownloadRequest", "${data.name} - ${data.raw}")
652+
return DownloadManager.Request(data.raw.toUri()).apply {
653+
setTitle(data.name)
654+
setMimeType(data.mime)
655+
setDescription("Django Files")
656+
setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
657+
setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, data.name)
658+
setAllowedOverMetered(true)
659+
setAllowedOverRoaming(true)
660+
setRequiresCharging(false)
661+
}
662+
}
607663
}
608664

609665
fun Context.showExpireDialog(

app/src/main/java/com/djangofiles/djangofiles/widget/WidgetProvider.kt

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,12 @@ class WidgetProvider : AppWidgetProvider() {
112112
views.setTextColor(R.id.files_unit, selectedTextColor)
113113
views.setTextColor(R.id.update_time, selectedTextColor)
114114

115-
views.setInt(R.id.files_icon, "setColorFilter", selectedTextColor)
116-
views.setInt(R.id.size_icon, "setColorFilter", selectedTextColor)
115+
//views.setInt(R.id.files_icon, "setColorFilter", selectedTextColor)
116+
//views.setInt(R.id.size_icon, "setColorFilter", selectedTextColor)
117117

118118
views.setInt(R.id.widget_refresh_button, "setColorFilter", selectedTextColor)
119119
views.setInt(R.id.widget_upload_button, "setColorFilter", selectedTextColor)
120-
views.setInt(R.id.file_list_button, "setColorFilter", selectedTextColor)
120+
//views.setInt(R.id.file_list_button, "setColorFilter", selectedTextColor)
121121

122122
// Refresh
123123
val intent1 = Intent(context, WidgetProvider::class.java).apply {
@@ -145,17 +145,17 @@ class WidgetProvider : AppWidgetProvider() {
145145
)
146146
views.setOnClickPendingIntent(R.id.widget_upload_button, pendingIntent2)
147147

148-
// File List
149-
val intent3 = Intent(context, MainActivity::class.java).apply {
150-
action = "FILE_LIST"
151-
}
152-
val pendingIntent3 = PendingIntent.getActivity(
153-
context,
154-
0,
155-
intent3,
156-
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
157-
)
158-
views.setOnClickPendingIntent(R.id.file_list_button, pendingIntent3)
148+
//// File List
149+
//val intent3 = Intent(context, MainActivity::class.java).apply {
150+
// action = "FILE_LIST"
151+
//}
152+
//val pendingIntent3 = PendingIntent.getActivity(
153+
// context,
154+
// 0,
155+
// intent3,
156+
// PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
157+
//)
158+
//views.setOnClickPendingIntent(R.id.file_list_button, pendingIntent3)
159159

160160
// Room Data
161161
GlobalScope.launch(Dispatchers.IO) {
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="24dp"
3+
android:height="24dp"
4+
android:viewportWidth="960"
5+
android:viewportHeight="960"
6+
android:tint="?attr/colorControlNormal">
7+
<path
8+
android:fillColor="@android:color/white"
9+
android:pathData="M480,640L280,440L336,382L440,486L440,160L520,160L520,486L624,382L680,440L480,640ZM240,800Q207,800 183.5,776.5Q160,753 160,720L160,600L240,600L240,720Q240,720 240,720Q240,720 240,720L720,720Q720,720 720,720Q720,720 720,720L720,600L800,600L800,720Q800,753 776.5,776.5Q753,800 720,800L240,800Z"/>
10+
</vector>

app/src/main/res/layout/activity_main.xml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010

1111
<include
1212
android:id="@+id/app_bar_main"
13-
layout="@layout/app_bar_main"
1413
android:layout_width="match_parent"
15-
android:layout_height="match_parent" />
14+
android:layout_height="match_parent"
15+
layout="@layout/app_bar_main" />
1616

1717
<com.google.android.material.navigation.NavigationView
1818
android:id="@+id/nav_view"
@@ -22,4 +22,5 @@
2222
android:fitsSystemWindows="true"
2323
app:headerLayout="@layout/nav_header_main"
2424
app:menu="@menu/drawer_menu" />
25+
2526
</androidx.drawerlayout.widget.DrawerLayout>

app/src/main/res/layout/app_bar_main.xml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
<androidx.coordinatorlayout.widget.CoordinatorLayout
1+
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
22
android:id="@+id/app_bar_main_layout"
33
android:layout_width="match_parent"
44
android:layout_height="match_parent"
5-
android:fitsSystemWindows="true"
6-
xmlns:android="http://schemas.android.com/apk/res/android"
7-
xmlns:app="http://schemas.android.com/apk/res-auto">
5+
android:fitsSystemWindows="true">
86

97
<include
108
android:id="@+id/content_main"

app/src/main/res/layout/content_main.xml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
<androidx.constraintlayout.widget.ConstraintLayout
1+
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
2+
xmlns:app="http://schemas.android.com/apk/res-auto"
23
android:id="@+id/content_main_layout"
34
android:layout_width="match_parent"
45
android:layout_height="match_parent"
5-
android:fitsSystemWindows="true"
6-
xmlns:android="http://schemas.android.com/apk/res/android"
7-
xmlns:app="http://schemas.android.com/apk/res-auto">
6+
android:fitsSystemWindows="true">
87

98
<androidx.fragment.app.FragmentContainerView
109
android:id="@+id/nav_host_fragment_content_main"
@@ -20,7 +19,12 @@
2019
android:id="@+id/bottom_nav"
2120
android:layout_width="0dp"
2221
android:layout_height="wrap_content"
23-
android:background="?android:attr/windowBackground"
22+
android:minHeight="56dp"
23+
app:itemIconSize="20dp"
24+
app:itemPaddingTop="8dp"
25+
app:itemPaddingBottom="10dp"
26+
app:itemTextAppearanceActiveBoldEnabled="false"
27+
app:itemActiveIndicatorStyle="@style/BottomNavigation.Indicator"
2428
app:layout_constraintBottom_toBottomOf="parent"
2529
app:layout_constraintStart_toStartOf="parent"
2630
app:layout_constraintEnd_toEndOf="parent"

app/src/main/res/layout/file_item_files.xml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -111,30 +111,30 @@
111111
app:drawableEndCompat="@drawable/md_visibility_24"
112112
app:drawableTint="?attr/colorOnSecondary"
113113
tools:text="9999"
114-
tools:ignore="RtlCompat" />
114+
tools:ignore="RtlCompat,RtlSymmetry" />
115115

116116
<TextView
117-
android:id="@+id/file_private"
117+
android:id="@+id/file_expr"
118118
android:layout_width="wrap_content"
119119
android:layout_height="fill_parent"
120120
android:layout_weight="0"
121121
android:paddingHorizontal="4dp"
122122
android:gravity="center_vertical"
123-
app:drawableStartCompat="@drawable/md_lock_24"
124-
app:drawableTint="?attr/colorOnSecondary" />
123+
android:textAlignment="textEnd"
124+
app:drawableEndCompat="@drawable/md_timer_24"
125+
app:drawableTint="?attr/colorOnSecondary"
126+
tools:text=""
127+
tools:ignore="RtlCompat" />
125128

126129
<TextView
127-
android:id="@+id/file_expr"
130+
android:id="@+id/file_private"
128131
android:layout_width="wrap_content"
129132
android:layout_height="fill_parent"
130133
android:layout_weight="0"
131134
android:paddingHorizontal="4dp"
132135
android:gravity="center_vertical"
133-
android:textAlignment="textEnd"
134-
app:drawableEndCompat="@drawable/md_timer_24"
135-
app:drawableTint="?attr/colorOnSecondary"
136-
tools:text=""
137-
tools:ignore="RtlCompat" />
136+
app:drawableStartCompat="@drawable/md_lock_24"
137+
app:drawableTint="?attr/colorOnSecondary" />
138138

139139
<TextView
140140
android:id="@+id/file_password"

app/src/main/res/layout/fragment_files.xml

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,36 +66,44 @@
6666
tools:text="999 / 999 Files" />
6767

6868
<ImageView
69-
android:id="@+id/album_all_button"
69+
android:id="@+id/delete_all_button"
7070
android:layout_width="48dp"
7171
android:layout_height="match_parent"
7272
android:padding="6dp"
7373
android:gravity="center"
7474
android:background="?attr/selectableItemBackground"
7575
android:contentDescription="Delete All"
76-
android:src="@drawable/md_imagesmode_24" />
76+
android:src="@drawable/md_delete_24px"
77+
app:tint="@android:color/holo_red_dark" />
7778

7879
<ImageView
79-
android:id="@+id/expire_all_button"
80+
android:id="@+id/download_all_button"
81+
android:layout_width="48dp"
82+
android:layout_height="match_parent"
83+
android:padding="6dp"
84+
android:background="?attr/selectableItemBackground"
85+
android:contentDescription="Delete All"
86+
android:src="@drawable/md_download_24px" />
87+
88+
<ImageView
89+
android:id="@+id/album_all_button"
8090
android:layout_width="48dp"
8191
android:layout_height="match_parent"
8292
android:padding="6dp"
8393
android:gravity="center"
8494
android:background="?attr/selectableItemBackground"
8595
android:contentDescription="Delete All"
86-
android:src="@drawable/md_timer_24" />
96+
android:src="@drawable/md_imagesmode_24" />
8797

8898
<ImageView
89-
android:id="@+id/delete_all_button"
99+
android:id="@+id/expire_all_button"
90100
android:layout_width="48dp"
91101
android:layout_height="match_parent"
92-
android:layout_marginEnd="12dp"
93102
android:padding="6dp"
94103
android:gravity="center"
95104
android:background="?attr/selectableItemBackground"
96105
android:contentDescription="Delete All"
97-
android:src="@drawable/md_delete_24px"
98-
app:tint="@android:color/holo_red_dark" />
106+
android:src="@drawable/md_timer_24" />
99107

100108
</LinearLayout>
101109

0 commit comments

Comments
 (0)