Reformat code

pull/653/merge
Varun Patil 2023-08-21 12:38:55 -07:00
parent 3fb209a994
commit 4e89b101b2
11 changed files with 155 additions and 110 deletions

View File

@ -26,7 +26,8 @@ import androidx.media3.exoplayer.hls.HlsMediaSource
import androidx.media3.exoplayer.source.ProgressiveMediaSource
import gallery.memories.databinding.ActivityMainBinding
@UnstableApi class MainActivity : AppCompatActivity() {
@UnstableApi
class MainActivity : AppCompatActivity() {
companion object {
val TAG = MainActivity::class.java.simpleName
}
@ -124,7 +125,10 @@ import gallery.memories.databinding.ActivityMainBinding
private fun initializeWebView() {
// Intercept local APIs
binding.webview.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
override fun shouldOverrideUrlLoading(
view: WebView,
request: WebResourceRequest
): Boolean {
val pathMatches = request.url.path?.matches(memoriesRegex) == true
val hostMatches = request.url.host.equals(host)
if (pathMatches && hostMatches) {
@ -137,7 +141,10 @@ import gallery.memories.databinding.ActivityMainBinding
return true
}
override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse? {
override fun shouldInterceptRequest(
view: WebView,
request: WebResourceRequest
): WebResourceResponse? {
return if (request.url.host == "127.0.0.1") {
nativex.handleRequest(request)
} else null
@ -194,9 +201,11 @@ import gallery.memories.databinding.ActivityMainBinding
host = Uri.parse(memoriesUrl).host
// Set authorization header
binding.webview.loadUrl(memoriesUrl, mapOf(
"Authorization" to authHeader
))
binding.webview.loadUrl(
memoriesUrl, mapOf(
"Authorization" to authHeader
)
)
return true
}
@ -207,7 +216,8 @@ import gallery.memories.databinding.ActivityMainBinding
fun ensureStoragePermissions() {
val requestPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
ActivityResultContracts.RequestMultiplePermissions()
) { permissions ->
// we need all of these
val isGranted = permissions.all { it.value }
@ -236,10 +246,12 @@ import gallery.memories.databinding.ActivityMainBinding
// Request media read permission
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
requestPermissionLauncher.launch(arrayOf(
android.Manifest.permission.READ_MEDIA_IMAGES,
android.Manifest.permission.READ_MEDIA_VIDEO,
))
requestPermissionLauncher.launch(
arrayOf(
android.Manifest.permission.READ_MEDIA_IMAGES,
android.Manifest.permission.READ_MEDIA_VIDEO,
)
)
} else {
requestPermissionLauncher.launch(arrayOf(android.Manifest.permission.READ_EXTERNAL_STORAGE))
}
@ -278,7 +290,8 @@ import gallery.memories.databinding.ActivityMainBinding
DefaultHttpDataSource.Factory()
.setDefaultRequestProperties(mapOf("cookie" to cookies))
.setAllowCrossProtocolRedirects(true)
val dataSourceFactory = DefaultDataSource.Factory(this, httpDataSourceFactory)
val dataSourceFactory =
DefaultDataSource.Factory(this, httpDataSourceFactory)
// Check if HLS source from URI (contains .m3u8 anywhere)
exoPlayer.addMediaSource(
@ -355,10 +368,15 @@ import gallery.memories.databinding.ActivityMainBinding
// Set dark mode
setTheme(if (isDark) android.R.style.Theme_Black else android.R.style.Theme_Light)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val appearance = WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS or WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
window.insetsController?.setSystemBarsAppearance(if (isDark) 0 else appearance, appearance)
val appearance =
WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS or WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
window.insetsController?.setSystemBarsAppearance(
if (isDark) 0 else appearance,
appearance
)
} else {
window.decorView.systemUiVisibility = if (isDark) 0 else View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
window.decorView.systemUiVisibility =
if (isDark) 0 else View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
}
// Set colors
@ -390,8 +408,11 @@ import gallery.memories.databinding.ActivityMainBinding
// Schedule for resume if not active
if (lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED) || force) {
mNeedRefresh = false
binding.webview.evaluateJavascript("window._nc_event_bus?.emit('files:file:created')", null)
mNeedRefresh = false
binding.webview.evaluateJavascript(
"window._nc_event_bus?.emit('files:file:created')",
null
)
} else {
mNeedRefresh = true
}

View File

@ -15,7 +15,8 @@ abstract class AppDatabase : RoomDatabase() {
companion object {
private val DATABASE_NAME = "memories_room"
@Volatile private var INSTANCE: AppDatabase? = null
@Volatile
private var INSTANCE: AppDatabase? = null
fun get(context: Context): AppDatabase {
if (INSTANCE == null) {

View File

@ -2,7 +2,7 @@ package gallery.memories.mapper
import androidx.room.ColumnInfo
data class Bucket (
@ColumnInfo(name="bucket_id") val id: String,
@ColumnInfo(name="bucket_name") val name: String,
data class Bucket(
@ColumnInfo(name = "bucket_id") val id: String,
@ColumnInfo(name = "bucket_name") val name: String,
)

View File

@ -2,7 +2,7 @@ package gallery.memories.mapper
import androidx.room.ColumnInfo
data class Day (
@ColumnInfo(name="dayid") val dayId: Long,
@ColumnInfo(name="count") val count: Long
data class Day(
@ColumnInfo(name = "dayid") val dayId: Long,
@ColumnInfo(name = "count") val count: Long
)

View File

@ -4,8 +4,9 @@ import org.json.JSONObject
class Response {
companion object {
val OK get(): JSONObject {
return JSONObject().put("message", "ok")
}
val OK
get(): JSONObject {
return JSONObject().put("message", "ok")
}
}
}

View File

@ -28,9 +28,9 @@ class SystemImage {
var videoDuration = 0L
val uri: Uri
get() {
return ContentUris.withAppendedId(mCollection, fileId)
}
get() {
return ContentUris.withAppendedId(mCollection, fileId)
}
private var mCollection: Uri = IMAGE_URI
@ -137,72 +137,77 @@ class SystemImage {
}
}
val json get(): JSONObject {
val obj = JSONObject()
.put(Fields.Photo.FILEID, fileId)
.put(Fields.Photo.BASENAME, baseName)
.put(Fields.Photo.MIMETYPE, mimeType)
.put(Fields.Photo.HEIGHT, height)
.put(Fields.Photo.WIDTH, width)
.put(Fields.Photo.SIZE, size)
.put(Fields.Photo.ETAG, mtime.toString())
.put(Fields.Photo.EPOCH, epoch)
.put(Fields.Photo.AUID, auid)
val json
get(): JSONObject {
val obj = JSONObject()
.put(Fields.Photo.FILEID, fileId)
.put(Fields.Photo.BASENAME, baseName)
.put(Fields.Photo.MIMETYPE, mimeType)
.put(Fields.Photo.HEIGHT, height)
.put(Fields.Photo.WIDTH, width)
.put(Fields.Photo.SIZE, size)
.put(Fields.Photo.ETAG, mtime.toString())
.put(Fields.Photo.EPOCH, epoch)
.put(Fields.Photo.AUID, auid)
if (isVideo) {
obj.put(Fields.Photo.ISVIDEO, 1)
.put(Fields.Photo.VIDEO_DURATION, videoDuration / 1000)
}
return obj
}
val epoch get(): Long {
return dateTaken / 1000
}
val utcDate get(): Long {
// Get EXIF date using ExifInterface if image
if (!isVideo) {
try {
val exif = ExifInterface(dataPath)
val exifDate = exif.getAttribute(ExifInterface.TAG_DATETIME)
?: throw IOException()
val sdf = SimpleDateFormat("yyyy:MM:dd HH:mm:ss")
sdf.timeZone = TimeZone.GMT_ZONE
sdf.parse(exifDate).let {
return it.time / 1000
}
} catch (e: Exception) {
Log.e(TAG, "Failed to read EXIF data: " + e.message)
if (isVideo) {
obj.put(Fields.Photo.ISVIDEO, 1)
.put(Fields.Photo.VIDEO_DURATION, videoDuration / 1000)
}
return obj
}
// No way to get the actual local date, so just assume current timezone
return (dateTaken + TimeZone.getDefault().getOffset(dateTaken).toLong()) / 1000
}
val epoch
get(): Long {
return dateTaken / 1000
}
val auid get(): Long {
val crc = java.util.zip.CRC32()
val utcDate
get(): Long {
// Get EXIF date using ExifInterface if image
if (!isVideo) {
try {
val exif = ExifInterface(dataPath)
val exifDate = exif.getAttribute(ExifInterface.TAG_DATETIME)
?: throw IOException()
val sdf = SimpleDateFormat("yyyy:MM:dd HH:mm:ss")
sdf.timeZone = TimeZone.GMT_ZONE
sdf.parse(exifDate).let {
return it.time / 1000
}
} catch (e: Exception) {
Log.e(TAG, "Failed to read EXIF data: " + e.message)
}
}
// pass date taken + size as decimal string
crc.update((epoch.toString() + size.toString()).toByteArray())
// No way to get the actual local date, so just assume current timezone
return (dateTaken + TimeZone.getDefault().getOffset(dateTaken).toLong()) / 1000
}
return crc.value
}
val auid
get(): Long {
val crc = java.util.zip.CRC32()
val photo get(): Photo {
val dateCache = utcDate
return Photo(
localId = fileId,
auid = auid,
mtime = mtime,
dateTaken = dateCache,
dayId = dateCache / 86400,
baseName = baseName,
bucketId = bucketId,
bucketName = bucketName,
flag = 0,
)
}
// pass date taken + size as decimal string
crc.update((epoch.toString() + size.toString()).toByteArray())
return crc.value
}
val photo
get(): Photo {
val dateCache = utcDate
return Photo(
localId = fileId,
auid = auid,
mtime = mtime,
dateTaken = dateCache,
dayId = dateCache / 86400,
baseName = baseName,
bucketId = bucketId,
bucketName = bucketName,
flag = 0,
)
}
}

View File

@ -17,7 +17,8 @@ import okhttp3.Response
import org.json.JSONObject
import java.net.SocketTimeoutException
@UnstableApi class AccountService(private val mCtx: MainActivity) {
@UnstableApi
class AccountService(private val mCtx: MainActivity) {
companion object {
val TAG = AccountService::class.java.simpleName
}
@ -89,7 +90,8 @@ import java.net.SocketTimeoutException
}
val client = OkHttpClient()
val rbody = "token=$pollToken".toRequestBody("application/x-www-form-urlencoded".toMediaTypeOrNull())
val rbody =
"token=$pollToken".toRequestBody("application/x-www-form-urlencoded".toMediaTypeOrNull())
var pollCount = 0
while (true) {

View File

@ -12,14 +12,18 @@ class ConfigService(private val mCtx: Context) {
get() {
if (mEnabledBuckets != null) return mEnabledBuckets!!
mEnabledBuckets = mCtx.getSharedPreferences(mCtx.getString(R.string.preferences_key), 0)
.getStringSet(mCtx.getString(R.string.preferences_enabled_local_folders), null)?.toList()
?: listOf()
.getStringSet(mCtx.getString(R.string.preferences_enabled_local_folders), null)
?.toList()
?: listOf()
return mEnabledBuckets!!
}
set(value) {
mEnabledBuckets = value
mCtx.getSharedPreferences(mCtx.getString(R.string.preferences_key), 0).edit()
.putStringSet(mCtx.getString(R.string.preferences_enabled_local_folders), value.toSet())
.putStringSet(
mCtx.getString(R.string.preferences_enabled_local_folders),
value.toSet()
)
.apply()
}
}

View File

@ -44,7 +44,10 @@ class DownloadService(private val mActivity: AppCompatActivity) {
request.addRequestHeader("cookie", cookies)
if (filename != "") {
// Save the file to external storage
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "memories/$filename")
request.setDestinationInExternalPublicDir(
Environment.DIRECTORY_DOWNLOADS,
"memories/$filename"
)
}
// Start the download
@ -92,7 +95,8 @@ class DownloadService(private val mActivity: AppCompatActivity) {
}
private fun getDownloadedFileURI(downloadId: Long): String? {
val downloadManager = mActivity.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
val downloadManager =
mActivity.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
val query = DownloadManager.Query()
query.setFilterById(downloadId)
val cursor = downloadManager.query(query)

View File

@ -14,7 +14,10 @@ class ImageService(private val mCtx: Context) {
val bitmap =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
mCtx.contentResolver.loadThumbnail(
ContentUris.withAppendedId(MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL), id),
ContentUris.withAppendedId(
MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL),
id
),
android.util.Size(2048, 2048),
null
)
@ -22,10 +25,10 @@ class ImageService(private val mCtx: Context) {
MediaStore.Images.Thumbnails.getThumbnail(
mCtx.contentResolver, id, MediaStore.Images.Thumbnails.FULL_SCREEN_KIND, null
)
?: MediaStore.Video.Thumbnails.getThumbnail(
mCtx.contentResolver, id, MediaStore.Video.Thumbnails.FULL_SCREEN_KIND, null
)
?: throw Exception("Thumbnail not found")
?: MediaStore.Video.Thumbnails.getThumbnail(
mCtx.contentResolver, id, MediaStore.Video.Thumbnails.FULL_SCREEN_KIND, null
)
?: throw Exception("Thumbnail not found")
}
val stream = ByteArrayOutputStream()
@ -42,7 +45,7 @@ class ImageService(private val mCtx: Context) {
ImageDecoder.decodeBitmap(ImageDecoder.createSource(mCtx.contentResolver, uri))
} else {
MediaStore.Images.Media.getBitmap(mCtx.contentResolver, uri)
?: throw Exception("Image not found")
?: throw Exception("Image not found")
}
val stream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream)

View File

@ -26,7 +26,8 @@ import java.io.IOException
import java.time.Instant
import java.util.concurrent.CountDownLatch
@UnstableApi class TimelineQuery(private val mCtx: MainActivity) {
@UnstableApi
class TimelineQuery(private val mCtx: MainActivity) {
private val TAG = TimelineQuery::class.java.simpleName
private val mConfigService = ConfigService(mCtx)
@ -46,11 +47,12 @@ import java.util.concurrent.CountDownLatch
init {
// Register intent launcher for callback
deleteIntentLauncher = mCtx.registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result: ActivityResult? ->
synchronized(this) {
deleteCallback?.let { it(result) }
deleteIntentLauncher =
mCtx.registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result: ActivityResult? ->
synchronized(this) {
deleteCallback?.let { it(result) }
}
}
}
}
fun initialize() {
@ -192,7 +194,9 @@ import java.util.concurrent.CountDownLatch
// Delete file with media store
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val intent = MediaStore.createTrashRequest(mCtx.contentResolver, uris, true)
deleteIntentLauncher.launch(IntentSenderRequest.Builder(intent.intentSender).build())
deleteIntentLauncher.launch(
IntentSenderRequest.Builder(intent.intentSender).build()
)
// Wait for response
val latch = CountDownLatch(1)
@ -240,7 +244,7 @@ import java.util.concurrent.CountDownLatch
// Iterate all images and videos from system store
val files =
SystemImage.query(mCtx, SystemImage.IMAGE_URI, selection, selectionArgs, null) +
SystemImage.query(mCtx, SystemImage.VIDEO_URI, selection, selectionArgs, null)
SystemImage.query(mCtx, SystemImage.VIDEO_URI, selection, selectionArgs, null)
files.forEach { insertItemDb(it) }
// Store last sync time