Browse Source

AndroidX migration, update app from internet, announcements

keep-around/190a20189fc5801c6546f815a1c49b1ea4732578
Adler Neves 3 years ago
parent
commit
931918bd0c
  1. 24
      app/build.gradle
  2. 4
      app/src/androidTest/java/com/adlerosn/brasilfurfest/ExampleInstrumentedTest.kt
  3. 81
      app/src/main/AndroidManifest.xml
  4. BIN
      app/src/main/ic_launcher-web2.png
  5. 2
      app/src/main/java/com/adlerosn/brasilfurfest/AssetImageViewerActivity.kt
  6. 2
      app/src/main/java/com/adlerosn/brasilfurfest/CountdownActivity.kt
  7. 5
      app/src/main/java/com/adlerosn/brasilfurfest/MainActivity.kt
  8. 2
      app/src/main/java/com/adlerosn/brasilfurfest/SplashActivity.kt
  9. 2
      app/src/main/java/com/adlerosn/brasilfurfest/developer/DeveloperActivity.kt
  10. 4
      app/src/main/java/com/adlerosn/brasilfurfest/helper/ContextGetColorCompat.kt
  11. 2
      app/src/main/java/com/adlerosn/brasilfurfest/helper/ListDiffCallback.kt
  12. 4
      app/src/main/java/com/adlerosn/brasilfurfest/helper/NotificationBuilderCompat.kt
  13. 6
      app/src/main/java/com/adlerosn/brasilfurfest/helper/PeekAndPop.kt
  14. 2
      app/src/main/java/com/adlerosn/brasilfurfest/helper/bindPeekAndPop.kt
  15. 4
      app/src/main/java/com/adlerosn/brasilfurfest/helper/bindTabAndContainer.kt
  16. 4
      app/src/main/java/com/adlerosn/brasilfurfest/legal/SoftwareLicensesActivity.kt
  17. 2
      app/src/main/java/com/adlerosn/brasilfurfest/legal/SoftwareLicensesAdapter.kt
  18. 46
      app/src/main/java/com/adlerosn/brasilfurfest/notification/NotificationFirer.kt
  19. 13
      app/src/main/java/com/adlerosn/brasilfurfest/notification/ScheduleUpdaterJobService.kt
  20. 8
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/EventActivity.kt
  21. 4
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/FavoritesActivity.kt
  22. 2
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/QRCodeViewerActivity.kt
  23. 2
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/RoomPartyPreviewerActivity.kt
  24. 6
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/ScheduleActivity.kt
  25. 8
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/SearchFilterActivity.kt
  26. 14
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/abstractDataTypes/convention/Announcement.kt
  27. 3
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/abstractDataTypes/convention/ConventionSeries.kt
  28. 2
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/abstractDataTypes/convention/SocialMedia.kt
  29. 2
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/adapters/ConventionRulesAdapter.kt
  30. 2
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/adapters/ConventionSocialMediasAdapter.kt
  31. 4
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/adapters/DayHourEventsAdapter.kt
  32. 6
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/adapters/DaysPagerAdapter.kt
  33. 2
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/adapters/FavoritesAdapter.kt
  34. 2
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/adapters/FilterCriteriaRecyclerViewAdapter.kt
  35. 6
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/adapters/PeekableEventRecyclerViewAdapter.kt
  36. 2
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/adapters/RecyclerViewAdapter.kt
  37. 4
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/fragments/ConventionDayFragment.kt
  38. 4
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/fragments/ConventionRulesFragment.kt
  39. 4
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/fragments/ConventionSocialMediasFragment.kt
  40. 2
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/fragments/ConventionSummaryFragment.kt
  41. 7
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/managers/AbstractRemoteAssets.kt
  42. 5
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/managers/CacheManager.kt
  43. 34
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/managers/ConventionJsonReader.kt
  44. 55
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/managers/FullUpdateCheckerCancellable.kt
  45. 17
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/managers/OfflineCacheManager.kt
  46. 19
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/managers/OnlineCacheManager.kt
  47. 42
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/managers/OnlinePreloadedCacheManager.kt
  48. 11
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/managers/RemoteAssets.kt
  49. 3
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/managers/RemoteAssetsInterface.kt
  50. 81
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/managers/ScheduleManager.kt
  51. 10
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/managers/UpdateChecker.kt
  52. 2
      app/src/main/java/com/adlerosn/brasilfurfest/schedule/viewHolders/RecyclerViewHolder.kt
  53. 22
      app/src/main/java/com/adlerosn/brasilfurfest/updater/silent/UpdaterBackgroundService.kt
  54. 4
      app/src/main/java/com/adlerosn/brasilfurfest/updater/startup/UpdaterActivity.kt
  55. 4
      app/src/main/res/layout/activity_asset_image_viewer.xml
  56. 4
      app/src/main/res/layout/activity_countdown.xml
  57. 4
      app/src/main/res/layout/activity_developer.xml
  58. 20
      app/src/main/res/layout/activity_event.xml
  59. 4
      app/src/main/res/layout/activity_event_content.xml
  60. 4
      app/src/main/res/layout/activity_event_content_keypair.xml
  61. 4
      app/src/main/res/layout/activity_event_share.xml
  62. 16
      app/src/main/res/layout/activity_favorites.xml
  63. 4
      app/src/main/res/layout/activity_favorites_item.xml
  64. 4
      app/src/main/res/layout/activity_main.xml
  65. 4
      app/src/main/res/layout/activity_room_party_previewer.xml
  66. 26
      app/src/main/res/layout/activity_schedule.xml
  67. 10
      app/src/main/res/layout/activity_search_filter.xml
  68. 4
      app/src/main/res/layout/activity_search_filter_circle.xml
  69. 4
      app/src/main/res/layout/activity_search_filter_criteria_add.xml
  70. 4
      app/src/main/res/layout/activity_search_filter_criteria_item.xml
  71. 4
      app/src/main/res/layout/activity_search_filter_criteria_itemdialog.xml
  72. 4
      app/src/main/res/layout/activity_search_filter_item.xml
  73. 6
      app/src/main/res/layout/activity_software_licenses.xml
  74. 4
      app/src/main/res/layout/activity_software_licenses_item.xml
  75. 4
      app/src/main/res/layout/activity_splash.xml
  76. 10
      app/src/main/res/layout/activity_updater.xml
  77. 4
      app/src/main/res/layout/dialogview_schedule_registration_tier.xml
  78. 4
      app/src/main/res/layout/dialogview_schedule_registration_tiers.xml
  79. 4
      app/src/main/res/layout/fragment_rules_item.xml
  80. 6
      app/src/main/res/layout/fragment_rules_list.xml
  81. 6
      app/src/main/res/layout/fragment_schedule_day.xml
  82. 8
      app/src/main/res/layout/fragment_schedule_summary.xml
  83. 4
      app/src/main/res/layout/fragment_schedule_summary_countdown.xml
  84. 4
      app/src/main/res/layout/fragment_schedule_summary_eventitem.xml
  85. 4
      app/src/main/res/layout/fragment_schedule_summary_r621violation.xml
  86. 4
      app/src/main/res/layout/fragment_socialmedia_item.xml
  87. 6
      app/src/main/res/layout/fragment_socialmedia_list.xml
  88. 4
      app/src/main/res/layout/listitem_schedule_eventlist.xml
  89. 4
      app/src/main/res/layout/listitem_schedule_eventlist_subitem_header.xml
  90. 4
      app/src/main/res/layout/listitem_schedule_eventlist_subitem_item.xml
  91. 4
      app/src/main/res/layout/oldpart_schedule_day.xml
  92. 4
      app/src/main/res/layout/oldpart_schedule_edition.xml
  93. 4
      app/src/main/res/layout/oldpart_schedule_eventcard.xml
  94. 4
      app/src/main/res/layout/oldpart_schedule_eventlistitem.xml
  95. 6
      app/src/main/res/layout/oldpart_schedule_hour.xml
  96. 4
      app/src/main/res/layout/oldpart_schedule_hour_intention.xml
  97. 4
      app/src/main/res/layout/peek_event_item.xml
  98. 1
      app/src/main/res/values/strings.xml
  99. 2
      build.gradle
  100. 2
      gradle.properties
  101. Some files were not shown because too many files have changed in this diff Show More

24
app/build.gradle

@ -5,14 +5,14 @@ apply plugin: 'kotlin-android' @@ -5,14 +5,14 @@ apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 28
compileSdkVersion 29
defaultConfig {
applicationId "com.adlerosn.brasilfurfest"
minSdkVersion 21
targetSdkVersion 28
targetSdkVersion 29
versionCode 22
versionName "2019.6.4.1"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
@ -26,17 +26,17 @@ android { @@ -26,17 +26,17 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.31"
implementation "org.jetbrains.kotlin:kotlin-reflect:1.3.31"
implementation "com.android.support:animated-vector-drawable:28.0.0"
implementation "com.android.support:appcompat-v7:28.0.0"
implementation "com.android.support:design:28.0.0"
implementation "com.android.support:support-v4:28.0.0"
implementation "com.android.support:support-compat:28.0.0"
implementation "com.android.support:support-media-compat:28.0.0"
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'androidx.vectordrawable:vectordrawable-animated:1.0.0'
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.core:core:1.0.2'
implementation 'androidx.media:media:1.0.1'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'org.jetbrains.anko:anko-commons:0.10.5'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.brandongogetap:stickyheaders:0.5.1'

4
app/src/androidTest/java/com/adlerosn/brasilfurfest/ExampleInstrumentedTest.kt

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
package com.adlerosn.brasilfurfest
import android.support.test.InstrumentationRegistry
import android.support.test.runner.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith

81
app/src/main/AndroidManifest.xml

@ -34,21 +34,86 @@ @@ -34,21 +34,86 @@
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="http"
android:host="www.brasilfurfest.com.br"
android:pathPrefix="/app"
android:scheme="http" />
android:pathPrefix="/app" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="http"
android:host="www.brasilfurfest.com.br"
android:pathPrefix="/app"
android:scheme="https" />
android:pathPrefix="/app" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="http"
android:host="brasilfurfest.com.br"
android:pathPrefix="/app"
android:scheme="http" />
android:pathPrefix="/app" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="http"
android:host="brasilfurfest.com.br"
android:pathPrefix="/app" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="www.brasilfurfest.com.br"
android:pathPrefix="/app" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="www.brasilfurfest.com.br"
android:pathPrefix="/app" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="brasilfurfest.com.br"
android:pathPrefix="/app" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="brasilfurfest.com.br"
android:pathPrefix="/app"
android:scheme="https" />
android:pathPrefix="/app" />
</intent-filter>
</activity>
<activity

BIN
app/src/main/ic_launcher-web2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

2
app/src/main/java/com/adlerosn/brasilfurfest/AssetImageViewerActivity.kt

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
package com.adlerosn.brasilfurfest
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import androidx.appcompat.app.AppCompatActivity
import android.view.WindowManager
import com.adlerosn.brasilfurfest.helper.*
import com.adlerosn.brasilfurfest.schedule.managers.ScheduleManagerGetter

2
app/src/main/java/com/adlerosn/brasilfurfest/CountdownActivity.kt

@ -3,7 +3,7 @@ package com.adlerosn.brasilfurfest @@ -3,7 +3,7 @@ package com.adlerosn.brasilfurfest
import android.content.Context
import android.os.Bundle
import android.os.PowerManager
import android.support.v7.app.AppCompatActivity
import androidx.appcompat.app.AppCompatActivity
import android.view.View
import com.adlerosn.brasilfurfest.helper.getString
import com.adlerosn.brasilfurfest.helper.resourcesAliased

5
app/src/main/java/com/adlerosn/brasilfurfest/MainActivity.kt

@ -1,10 +1,12 @@ @@ -1,10 +1,12 @@
package com.adlerosn.brasilfurfest
import android.content.Intent
import android.support.v7.app.AppCompatActivity
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.adlerosn.brasilfurfest.helper.resourcesAliased
import com.adlerosn.brasilfurfest.notification.NotificationFirer
import com.adlerosn.brasilfurfest.schedule.RoomPartyPreviewerActivity
import com.adlerosn.brasilfurfest.schedule.managers.FullUpdateCheckerCancellable
import com.adlerosn.brasilfurfest.updater.startup.UpdaterActivity
//Entry point
@ -13,6 +15,7 @@ class MainActivity : AppCompatActivity() { @@ -13,6 +15,7 @@ class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
FullUpdateCheckerCancellable(baseContext).run { NotificationFirer().fire(baseContext) }
resourcesAliased = this.resources
when {
(this.intent != null) && (this.intent?.data?.path?.startsWith("/app/roomparty") ?: false) ->

2
app/src/main/java/com/adlerosn/brasilfurfest/SplashActivity.kt

@ -2,7 +2,7 @@ package com.adlerosn.brasilfurfest @@ -2,7 +2,7 @@ package com.adlerosn.brasilfurfest
import android.content.Intent
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import androidx.appcompat.app.AppCompatActivity
import android.view.View
import android.view.WindowManager
import com.adlerosn.brasilfurfest.helper.*

2
app/src/main/java/com/adlerosn/brasilfurfest/developer/DeveloperActivity.kt

@ -3,7 +3,7 @@ package com.adlerosn.brasilfurfest.developer @@ -3,7 +3,7 @@ package com.adlerosn.brasilfurfest.developer
import android.content.Intent
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import androidx.appcompat.app.AppCompatActivity
import com.adlerosn.brasilfurfest.R
import com.adlerosn.brasilfurfest.helper.KnownAssets
import com.adlerosn.brasilfurfest.legal.SoftwareLicensesActivity

4
app/src/main/java/com/adlerosn/brasilfurfest/helper/ContextGetColorCompat.kt

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
package com.adlerosn.brasilfurfest.helper
import android.content.Context
import android.support.annotation.ColorRes
import android.support.v4.content.ContextCompat
import androidx.annotation.ColorRes
import androidx.core.content.ContextCompat
fun Context.getColorCompat(@ColorRes colorId: Int) = ContextCompat.getColor(this, colorId)

2
app/src/main/java/com/adlerosn/brasilfurfest/helper/ListDiffCallback.kt

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
package com.adlerosn.brasilfurfest.helper
import android.support.v7.util.DiffUtil
import androidx.recyclerview.widget.DiffUtil
class ListDiffCallback(private val old: List<Any?>, private val new: List<Any?>) : DiffUtil.Callback() {
override fun getOldListSize(): Int = old.size

4
app/src/main/java/com/adlerosn/brasilfurfest/helper/NotificationBuilderCompat.kt

@ -4,8 +4,8 @@ import android.app.NotificationChannel @@ -4,8 +4,8 @@ import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.os.Build
import android.support.annotation.StringRes
import android.support.v4.app.NotificationCompat
import androidx.annotation.StringRes
import androidx.core.app.NotificationCompat
inline fun <reified KClass: Context> KClass.notificationBuilderCompat(@StringRes notificationChannelString: Int, important: Boolean): NotificationCompat.Builder =
getNotificationChannelBuilder(this, KClass::class.java.simpleName, notificationChannelString, important)

6
app/src/main/java/com/adlerosn/brasilfurfest/helper/PeekAndPop.kt

@ -3,9 +3,9 @@ package com.adlerosn.brasilfurfest.helper @@ -3,9 +3,9 @@ package com.adlerosn.brasilfurfest.helper
import android.app.Activity
import android.graphics.Point
import android.graphics.Rect
import android.support.annotation.IdRes
import android.support.annotation.LayoutRes
import android.support.v7.app.AlertDialog
import androidx.annotation.IdRes
import androidx.annotation.LayoutRes
import androidx.appcompat.app.AlertDialog
import android.util.DisplayMetrics
import android.util.Log
import android.view.GestureDetector

2
app/src/main/java/com/adlerosn/brasilfurfest/helper/bindPeekAndPop.kt

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
package com.adlerosn.brasilfurfest.helper
import android.app.Activity
import android.support.v4.content.ContextCompat
import androidx.core.content.ContextCompat
import android.view.Gravity
import android.view.View
import android.view.ViewGroup

4
app/src/main/java/com/adlerosn/brasilfurfest/helper/bindTabAndContainer.kt

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
package com.adlerosn.brasilfurfest.helper
import android.support.design.widget.TabLayout
import android.support.v4.view.ViewPager
import com.google.android.material.tabs.TabLayout
import androidx.viewpager.widget.ViewPager
fun TabLayout.fullSetup(viewPager: ViewPager){
this.setupWithViewPager(viewPager)

4
app/src/main/java/com/adlerosn/brasilfurfest/legal/SoftwareLicensesActivity.kt

@ -1,8 +1,8 @@ @@ -1,8 +1,8 @@
package com.adlerosn.brasilfurfest.legal
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.LinearLayoutManager
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import com.adlerosn.brasilfurfest.R
import kotlinx.android.synthetic.main.activity_software_licenses.*

2
app/src/main/java/com/adlerosn/brasilfurfest/legal/SoftwareLicensesAdapter.kt

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
package com.adlerosn.brasilfurfest.legal
import android.support.v7.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView
import android.view.ViewGroup
import com.adlerosn.brasilfurfest.R
import com.adlerosn.brasilfurfest.helper.inflate

46
app/src/main/java/com/adlerosn/brasilfurfest/notification/NotificationFirer.kt

@ -4,11 +4,13 @@ import android.app.Notification @@ -4,11 +4,13 @@ import android.app.Notification
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.support.v4.app.NotificationCompat
import android.support.v4.app.NotificationManagerCompat
import android.net.Uri
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import android.util.Log
import com.adlerosn.brasilfurfest.R
import com.adlerosn.brasilfurfest.helper.notificationBuilderCompat
import com.adlerosn.brasilfurfest.helper.runtimeLanguage
import com.adlerosn.brasilfurfest.schedule.EventActivity
import com.adlerosn.brasilfurfest.schedule.managers.ScheduleManagerGetter
import java.io.PrintWriter
@ -68,6 +70,46 @@ class NotificationFirer { @@ -68,6 +70,46 @@ class NotificationFirer {
val s = writer.toString()
Log.e(NotificationFirer::class.java.simpleName, s)
}
///////////////////////
try {
val notificationManager = NotificationManagerCompat.from(context)
val scheduleManager = ScheduleManagerGetter[context]
val announcements = scheduleManager.unreadAnnouncements
scheduleManager.setAnnouncementsRead()
announcements.forEach { announcement ->
val title = announcement.title[context.runtimeLanguage]
val body = announcement.body[context.runtimeLanguage]
val link = announcement.link?.get(context.runtimeLanguage)
val nt = context.notificationBuilderCompat(R.string.announcementsNotificationChannel, true)
.setDefaults(Notification.DEFAULT_ALL)
.setSmallIcon(R.drawable.ic_notificacao)
.setContentTitle(title)
.setContentText(body)
.let { builder ->
if(link==null)
builder
else
builder.setContentIntent(
PendingIntent.getActivity(
context,
announcement.uuid.hashCode(),
Intent(Intent.ACTION_VIEW, Uri.parse(link)),
0
)
)
}
.setPriority(NotificationCompat.PRIORITY_HIGH)
notificationManager.notify(
1, nt.build()
)
}
} catch (e: Throwable) {
val writer = StringWriter()
e.printStackTrace(PrintWriter(writer))
val s = writer.toString()
Log.e(NotificationFirer::class.java.simpleName, s)
}
}
// fun firePing(context: Context){

13
app/src/main/java/com/adlerosn/brasilfurfest/notification/ScheduleUpdaterJobService.kt

@ -2,14 +2,23 @@ package com.adlerosn.brasilfurfest.notification @@ -2,14 +2,23 @@ package com.adlerosn.brasilfurfest.notification
import android.app.job.JobParameters
import android.app.job.JobService
import com.adlerosn.brasilfurfest.schedule.managers.FullUpdateCheckerCancellable
class ScheduleUpdaterJobService: JobService() {
private lateinit var fucc: FullUpdateCheckerCancellable
override fun onStartJob(jobParameters: JobParameters): Boolean {
jobFinished(jobParameters, true)
return false
fucc = FullUpdateCheckerCancellable(baseContext)
fucc.run {
NotificationFirer().fire(baseContext)
jobFinished(jobParameters, true)
}
return true
}
override fun onStopJob(jobParameters: JobParameters): Boolean {
fucc.stop()
jobFinished(jobParameters, true)
return true
}

8
app/src/main/java/com/adlerosn/brasilfurfest/schedule/EventActivity.kt

@ -10,9 +10,9 @@ import android.graphics.Color @@ -10,9 +10,9 @@ import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.provider.CalendarContract
import android.support.design.widget.Snackbar
import android.support.v7.app.AlertDialog
import android.support.v7.app.AppCompatActivity
import com.google.android.material.snackbar.Snackbar
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import android.text.Spannable
import android.text.SpannableStringBuilder
import android.view.View
@ -219,7 +219,7 @@ class EventActivity : AppCompatActivity() { @@ -219,7 +219,7 @@ class EventActivity : AppCompatActivity() {
view.btnLink.setOnClickListener {
val clipboardManager = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clipData = ClipData.newPlainText("Room party link", link)
clipboardManager.primaryClip = clipData
clipboardManager.setPrimaryClip(clipData)
startActivity(Intent.createChooser(Intent(Intent.ACTION_SEND).apply { type="text/plain"; putExtra(Intent.EXTRA_TEXT, link) }, null))
dialog.dismiss()
}

4
app/src/main/java/com/adlerosn/brasilfurfest/schedule/FavoritesActivity.kt

@ -1,9 +1,9 @@ @@ -1,9 +1,9 @@
package com.adlerosn.brasilfurfest.schedule
import android.graphics.Color
import android.support.v7.app.AppCompatActivity
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import android.view.WindowManager
import com.adlerosn.brasilfurfest.R
import com.adlerosn.brasilfurfest.helper.*

2
app/src/main/java/com/adlerosn/brasilfurfest/schedule/QRCodeViewerActivity.kt

@ -2,7 +2,7 @@ package com.adlerosn.brasilfurfest.schedule @@ -2,7 +2,7 @@ package com.adlerosn.brasilfurfest.schedule
import android.graphics.Point
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import androidx.appcompat.app.AppCompatActivity
import android.view.WindowManager
import androidmads.library.qrgenearator.QRGContents
import androidmads.library.qrgenearator.QRGEncoder

2
app/src/main/java/com/adlerosn/brasilfurfest/schedule/RoomPartyPreviewerActivity.kt

@ -3,7 +3,7 @@ package com.adlerosn.brasilfurfest.schedule @@ -3,7 +3,7 @@ package com.adlerosn.brasilfurfest.schedule
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import androidx.appcompat.app.AppCompatActivity
import com.adlerosn.brasilfurfest.MainActivity
import com.adlerosn.brasilfurfest.R
import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.managed.AttendeeConFavorite

6
app/src/main/java/com/adlerosn/brasilfurfest/schedule/ScheduleActivity.kt

@ -5,9 +5,9 @@ import android.content.DialogInterface @@ -5,9 +5,9 @@ import android.content.DialogInterface
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.support.design.widget.Snackbar
import android.support.v4.app.FragmentPagerAdapter
import android.support.v7.app.AppCompatActivity
import com.google.android.material.snackbar.Snackbar
import androidx.fragment.app.FragmentPagerAdapter
import androidx.appcompat.app.AppCompatActivity
import android.view.Menu
import android.view.MenuItem
import com.adlerosn.brasilfurfest.R

8
app/src/main/java/com/adlerosn/brasilfurfest/schedule/SearchFilterActivity.kt

@ -1,10 +1,10 @@ @@ -1,10 +1,10 @@
package com.adlerosn.brasilfurfest.schedule
import android.os.Bundle
import android.support.annotation.StringRes
import android.support.v7.app.AlertDialog
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.LinearLayoutManager
import androidx.annotation.StringRes
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import android.text.Editable
import android.text.TextWatcher
import com.adlerosn.brasilfurfest.R

14
app/src/main/java/com/adlerosn/brasilfurfest/schedule/abstractDataTypes/convention/Announcement.kt

@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
package com.adlerosn.brasilfurfest.schedule.abstractDataTypes.convention
import com.adlerosn.brasilfurfest.helper.Language
import java.io.Serializable
import java.util.*
class Announcement(
val uuid: String,
val title: Map<Language, String>,
val body: Map<Language, String>,
val link: Map<Language, String>?,
val created: GregorianCalendar,
val modified: GregorianCalendar
) : Serializable

3
app/src/main/java/com/adlerosn/brasilfurfest/schedule/abstractDataTypes/convention/ConventionSeries.kt

@ -14,7 +14,8 @@ class ConventionSeries( @@ -14,7 +14,8 @@ class ConventionSeries(
val statute: Map<Language, String>,
val defaultBanner: Map<Language, String>,
val banners: List<Banner>,
val updateFrequency: Double
val updateFrequency: Double,
val announcements: List<Announcement>
) : Serializable {
val allImages get() =
editions.flatMap { it.allImages } + banners.map { it.banner } + listOf(defaultBanner)

2
app/src/main/java/com/adlerosn/brasilfurfest/schedule/abstractDataTypes/convention/SocialMedia.kt

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
package com.adlerosn.brasilfurfest.schedule.abstractDataTypes.convention
import android.support.annotation.DrawableRes
import androidx.annotation.DrawableRes
import com.adlerosn.brasilfurfest.helper.Language
import java.io.Serializable

2
app/src/main/java/com/adlerosn/brasilfurfest/schedule/adapters/ConventionRulesAdapter.kt

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
package com.adlerosn.brasilfurfest.schedule.adapters
import android.content.Context
import android.support.v4.content.ContextCompat
import androidx.core.content.ContextCompat
import android.view.View
import android.view.ViewGroup
import com.adlerosn.brasilfurfest.R

2
app/src/main/java/com/adlerosn/brasilfurfest/schedule/adapters/ConventionSocialMediasAdapter.kt

@ -3,7 +3,7 @@ package com.adlerosn.brasilfurfest.schedule.adapters @@ -3,7 +3,7 @@ package com.adlerosn.brasilfurfest.schedule.adapters
import android.content.Intent
import android.content.res.ColorStateList
import android.net.Uri
import android.support.v7.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView
import android.view.ViewGroup
import com.adlerosn.brasilfurfest.R
import com.adlerosn.brasilfurfest.helper.layoutInflater

4
app/src/main/java/com/adlerosn/brasilfurfest/schedule/adapters/DayHourEventsAdapter.kt

@ -2,8 +2,8 @@ package com.adlerosn.brasilfurfest.schedule.adapters @@ -2,8 +2,8 @@ package com.adlerosn.brasilfurfest.schedule.adapters
import android.app.Activity
import android.content.Intent
import android.support.v7.app.AlertDialog
import android.support.v7.util.DiffUtil
import androidx.appcompat.app.AlertDialog
import androidx.recyclerview.widget.DiffUtil
import android.view.View
import android.view.ViewGroup
import com.adlerosn.brasilfurfest.R

6
app/src/main/java/com/adlerosn/brasilfurfest/schedule/adapters/DaysPagerAdapter.kt

@ -1,8 +1,8 @@ @@ -1,8 +1,8 @@
package com.adlerosn.brasilfurfest.schedule.adapters
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentManager
import android.support.v4.app.FragmentPagerAdapter
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
import com.adlerosn.brasilfurfest.R
import com.adlerosn.brasilfurfest.helper.*
import com.adlerosn.brasilfurfest.schedule.managers.ScheduleManager

2
app/src/main/java/com/adlerosn/brasilfurfest/schedule/adapters/FavoritesAdapter.kt

@ -2,7 +2,7 @@ package com.adlerosn.brasilfurfest.schedule.adapters @@ -2,7 +2,7 @@ package com.adlerosn.brasilfurfest.schedule.adapters
import android.app.Activity
import android.content.Intent
import android.support.v7.util.DiffUtil
import androidx.recyclerview.widget.DiffUtil
import android.view.View
import android.view.ViewGroup
import com.adlerosn.brasilfurfest.R

2
app/src/main/java/com/adlerosn/brasilfurfest/schedule/adapters/FilterCriteriaRecyclerViewAdapter.kt

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
package com.adlerosn.brasilfurfest.schedule.adapters
import android.content.res.ColorStateList
import android.support.v7.util.DiffUtil
import androidx.recyclerview.widget.DiffUtil
import android.view.ViewGroup
import com.adlerosn.brasilfurfest.R
import com.adlerosn.brasilfurfest.helper.*

6
app/src/main/java/com/adlerosn/brasilfurfest/schedule/adapters/PeekableEventRecyclerViewAdapter.kt

@ -4,9 +4,9 @@ import android.app.Activity @@ -4,9 +4,9 @@ import android.app.Activity
import android.content.Intent
import android.content.res.ColorStateList
import android.graphics.Paint
import android.support.design.widget.Snackbar
import android.support.v4.content.ContextCompat
import android.support.v7.util.DiffUtil
import com.google.android.material.snackbar.Snackbar
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.DiffUtil
import android.view.View
import android.view.ViewGroup
import com.adlerosn.brasilfurfest.R

2
app/src/main/java/com/adlerosn/brasilfurfest/schedule/adapters/RecyclerViewAdapter.kt

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
package com.adlerosn.brasilfurfest.schedule.adapters
import android.support.v7.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView
import com.adlerosn.brasilfurfest.schedule.viewHolders.RecyclerViewHolder
abstract class RecyclerViewAdapter: RecyclerView.Adapter<RecyclerViewHolder>()

4
app/src/main/java/com/adlerosn/brasilfurfest/schedule/fragments/ConventionDayFragment.kt

@ -1,8 +1,8 @@ @@ -1,8 +1,8 @@
package com.adlerosn.brasilfurfest.schedule.fragments
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v7.widget.LinearLayoutManager
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

4
app/src/main/java/com/adlerosn/brasilfurfest/schedule/fragments/ConventionRulesFragment.kt

@ -1,8 +1,8 @@ @@ -1,8 +1,8 @@
package com.adlerosn.brasilfurfest.schedule.fragments
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v7.widget.LinearLayoutManager
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

4
app/src/main/java/com/adlerosn/brasilfurfest/schedule/fragments/ConventionSocialMediasFragment.kt

@ -1,8 +1,8 @@ @@ -1,8 +1,8 @@
package com.adlerosn.brasilfurfest.schedule.fragments
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v7.widget.LinearLayoutManager
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

2
app/src/main/java/com/adlerosn/brasilfurfest/schedule/fragments/ConventionSummaryFragment.kt

@ -6,7 +6,7 @@ import android.content.DialogInterface @@ -6,7 +6,7 @@ import android.content.DialogInterface
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.support.v4.app.Fragment
import androidx.fragment.app.Fragment
import android.util.Log
import android.view.LayoutInflater
import android.view.View

7
app/src/main/java/com/adlerosn/brasilfurfest/schedule/managers/AbstractRemoteAssets.kt

@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
package com.adlerosn.brasilfurfest.schedule.managers
abstract class AbstractRemoteAssets(server: String, project: String) : RemoteAssetsInterface {
override val json = "$server/api/conventions/$project/minified.json"
override val media = "$server/"
override val attending = "$server/api/conventions/$project/choices"
}

5
app/src/main/java/com/adlerosn/brasilfurfest/schedule/managers/CacheManager.kt

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
package com.adlerosn.brasilfurfest.schedule.managers
import android.content.Context
import java.io.File
import java.io.InputStream
import java.io.Serializable
@ -15,12 +16,12 @@ abstract class CacheManager : Serializable { @@ -15,12 +16,12 @@ abstract class CacheManager : Serializable {
abstract val files: Set<String>
abstract fun startMonitoringNeededFiles()
abstract fun removeNotNeededFiles(): Int
abstract fun setupScheduleManagerUpdater(sm: ScheduleManager)
abstract fun getFileFor(asset: String): File
companion object {
operator fun invoke(context: Context) =
if(RemoteAssets.onlineApp) {
if (RemoteAssets.selfUpdate)
if (RemoteAssets.preloaded)
OnlinePreloadedCacheManager(context)
else
OnlineCacheManager(context)

34
app/src/main/java/com/adlerosn/brasilfurfest/schedule/managers/ConventionJsonReader.kt

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
package com.adlerosn.brasilfurfest.schedule.managers
import android.support.annotation.DrawableRes
import androidx.annotation.DrawableRes
import com.adlerosn.brasilfurfest.R
import com.adlerosn.brasilfurfest.helper.*
import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.GregorianCalendarRange
@ -34,6 +34,7 @@ object ConventionJsonReader { @@ -34,6 +34,7 @@ object ConventionJsonReader {
val banners = mutableMapOf<String, Banner>()
val maps = mutableMapOf<String, MapImage>()
val registrationLinks = mutableMapOf<String, RegistrationLink>()
val announcements = mutableMapOf<String, Announcement>()
}
fun readFromFile(file: String) =
@ -45,6 +46,9 @@ object ConventionJsonReader { @@ -45,6 +46,9 @@ object ConventionJsonReader {
fun readFromInputStream(inputStream: InputStream): ConventionSeries =
readFromJson(inputStream.bufferedReader(Charsets.UTF_8).readText())
fun readFromByteArray(byteArray: ByteArray): ConventionSeries =
readFromInputStream(byteArray.inputStream())
fun readFromJson(json: String) =
readFromJson(JSONObject(json))
@ -64,6 +68,7 @@ object ConventionJsonReader { @@ -64,6 +68,7 @@ object ConventionJsonReader {
val featured = uuidHashResolver.conventions[jsonObject.getString("featured")] ?: uuidHashResolver.conventions.values.first()
val defaultBanner = parseLanguageImage(jsonObject.getJSONObject("default_banner"), uuidHashResolver)!!
val banners = parseBanners(jsonObject.getJSONArray("banners"), uuidHashResolver)
val announcements = parseAnnouncements(jsonObject.getJSONArray("announcements"), uuidHashResolver)
return ConventionSeries(
name,
featured,
@ -74,12 +79,37 @@ object ConventionJsonReader { @@ -74,12 +79,37 @@ object ConventionJsonReader {
statute,
defaultBanner,
banners,
1.0/6
1.0/6,
announcements
).apply {
uuidHashResolver.conventionSeries[uuid] = this
}
}
private fun parseAnnouncements(jsonArray: JSONArray, uuidHashResolver: ConventionJsonReader.UuidHashResolver): List<Announcement> =
jsonArray.asSequence<JSONObject>().map { parseAnnouncement(it, uuidHashResolver) }.toList()
private fun parseAnnouncement(jsonObject: JSONObject, uuidHashResolver: UuidHashResolver): Announcement {
val uuid = jsonObject.getString("uuid")
val previouslyKnown = uuidHashResolver.announcements[uuid]
if (previouslyKnown != null) return previouslyKnown
val title = parseLanguageString(jsonObject.getJSONObject("title"), uuidHashResolver)
val body = parseLanguageString(jsonObject.getJSONObject("body"), uuidHashResolver)
val link = parseLanguageString(jsonObject.getJSONObject("link"), uuidHashResolver)
val created = parseGregCal(jsonObject.getJSONObject("created"))
val modified = parseGregCal(jsonObject.getJSONObject("modified"))
return Announcement(
uuid,
title,
body,
link,
created,
modified
).apply {
uuidHashResolver.announcements[uuid] = this
}
}
private fun parseBanners(jsonArray: JSONArray, uuidHashResolver: UuidHashResolver) =
jsonArray.asSequence<JSONObject>().map { parseBanner(it, uuidHashResolver) }.toList()

55
app/src/main/java/com/adlerosn/brasilfurfest/schedule/managers/FullUpdateCheckerCancellable.kt

@ -0,0 +1,55 @@ @@ -0,0 +1,55 @@
package com.adlerosn.brasilfurfest.schedule.managers
import android.content.Context
import com.adlerosn.brasilfurfest.helper.lastPathPart
import java.util.concurrent.Future
class FullUpdateCheckerCancellable(context: Context) {
private val uc = UpdateChecker(context)
private val promises: MutableList<Future<Unit>> = mutableListOf()
private val processedImages: MutableList<String> = mutableListOf()
fun run(onCompletedCallback: (Boolean)->Any? = {}){
promises.add(uc.downloadBaseJsonWithWatcher { downloadState: UpdateChecker.DownloadState, bytes: ByteArray?, _: Throwable? ->
when(downloadState){
UpdateChecker.DownloadState.ERROR -> {
onCompletedCallback(false)
}
UpdateChecker.DownloadState.SUCCESS -> {
val conventionSeries = ConventionJsonReader.readFromByteArray(bytes!!)
val allImages = conventionSeries.allImages.flatMap { it.values }.distinct()
allImages.forEach { image: String ->
if(uc.cacheManager[image.lastPathPart()] != null){
synchronized(::processedImages){
processedImages.add(image)
if(processedImages.size >= allImages.size)
onCompletedCallback(true)
}
} else {
val url = RemoteAssets.media+image
promises.add(uc.downloadWithWatcher(url) { ds: UpdateChecker.DownloadState, _: ByteArray?, _: Throwable? ->
when(ds){
UpdateChecker.DownloadState.SUCCESS, UpdateChecker.DownloadState.ERROR -> {
synchronized(::processedImages){
processedImages.add(image)
if(processedImages.size >= allImages.size)
onCompletedCallback(true)
}
}
else -> {}
}
})
}
}
}
else -> null
}
})
}
fun stop(){
promises.forEach { it.cancel(true) }
promises.clear()
processedImages.clear()
}
}

17
app/src/main/java/com/adlerosn/brasilfurfest/schedule/managers/OfflineCacheManager.kt

@ -1,12 +1,17 @@ @@ -1,12 +1,17 @@
package com.adlerosn.brasilfurfest.schedule.managers
import android.content.Context
import android.content.res.Resources
import com.adlerosn.brasilfurfest.helper.joinFile
import com.adlerosn.brasilfurfest.helper.lastPathPart
import com.adlerosn.brasilfurfest.helper.nullFun
import java.io.File
import java.io.InputStream
import java.lang.Exception
class OfflineCacheManager(context: Context): CacheManager() {
private val assets = context.assets
private val cacheDir = context.cacheDir
override val goesOnline = false
override val preloaded = false
override fun getStamp(file: String): String? = get(file)?.second
@ -19,5 +24,15 @@ class OfflineCacheManager(context: Context): CacheManager() { @@ -19,5 +24,15 @@ class OfflineCacheManager(context: Context): CacheManager() {
override fun startMonitoringNeededFiles() = nullFun()
override fun removeNotNeededFiles() = 0
override val files get() = (assets.list("out") ?: arrayOf()).toSet()
override fun setupScheduleManagerUpdater(sm: ScheduleManager) = nullFun()
override fun getFileFor(asset: String): File {
val cachedFile = cacheDir.joinFile(asset.lastPathPart())
if(!cachedFile.exists()){
val assetDescriptor = get(asset.lastPathPart())
if (assetDescriptor == null)
throw Resources.NotFoundException("Unavailable asset: $asset")
else
cachedFile.writeBytes(assetDescriptor.first.readBytes())
}
return cachedFile
}
}

19
app/src/main/java/com/adlerosn/brasilfurfest/schedule/managers/OnlineCacheManager.kt

@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
package com.adlerosn.brasilfurfest.schedule.managers
import android.content.Context
import android.content.res.Resources
import com.adlerosn.brasilfurfest.helper.joinFile
import com.adlerosn.brasilfurfest.helper.lastPathPart
import com.adlerosn.brasilfurfest.helper.nullFun
import java.io.File
import java.io.InputStream
class OnlineCacheManager(context: Context): CacheManager() {
private val cacheLocation = File(context.filesDir, "cache_data")
internal val cacheLocation = File(context.filesDir, "cache_data")
.also {
if (!it.isDirectory) {
it.mkdirs()
@ -64,16 +64,16 @@ class OnlineCacheManager(context: Context): CacheManager() { @@ -64,16 +64,16 @@ class OnlineCacheManager(context: Context): CacheManager() {
}
override fun sanitize(): Int{
val datas = cacheLocation.listFiles().toList().map { it.absolutePath.lastPathPart() }
val stmps = cacheStamps.listFiles().toList().map { it.absolutePath.lastPathPart() }
val datas = (cacheLocation.listFiles() ?: arrayOf()).toList().map { it.absolutePath.lastPathPart() }
val stmps = (cacheStamps.listFiles() ?: arrayOf()).toList().map { it.absolutePath.lastPathPart() }
val unreliableEntries = (datas-stmps) + (stmps-datas)
return unreliableEntries.map { delete(it) }.size
}
override val files: Set<String>
get() {
val datas = cacheLocation.listFiles().toList().map { it.absolutePath.lastPathPart() }
val stmps = cacheStamps.listFiles().toList().map { it.absolutePath.lastPathPart() }
val datas = (cacheLocation.listFiles() ?: arrayOf()).toList().map { it.absolutePath.lastPathPart() }
val stmps = (cacheStamps.listFiles() ?: arrayOf()).toList().map { it.absolutePath.lastPathPart() }
return datas.intersect(stmps)
}
@ -87,5 +87,10 @@ class OnlineCacheManager(context: Context): CacheManager() { @@ -87,5 +87,10 @@ class OnlineCacheManager(context: Context): CacheManager() {
return notNeeded.map { delete(it) }.size
}
override fun setupScheduleManagerUpdater(sm: ScheduleManager) = nullFun()
override fun getFileFor(asset: String): File {
val retFile = cacheLocation.joinFile(asset.lastPathPart())
if(!retFile.exists())
throw Resources.NotFoundException("Unavailable asset: $asset")
return retFile
}
}

42
app/src/main/java/com/adlerosn/brasilfurfest/schedule/managers/OnlinePreloadedCacheManager.kt

@ -1,10 +1,11 @@ @@ -1,10 +1,11 @@
package com.adlerosn.brasilfurfest.schedule.managers
import android.app.AlarmManager
import android.content.Context
import android.support.v4.app.AlarmManagerCompat
import android.content.res.Resources
import com.adlerosn.brasilfurfest.helper.joinFile
import com.adlerosn.brasilfurfest.helper.lastPathPart
import com.adlerosn.brasilfurfest.helper.nullFun
import java.io.File
class OnlinePreloadedCacheManager(context: Context): CacheManager() {
private val offCacheMan = OfflineCacheManager(context)
@ -12,7 +13,7 @@ class OnlinePreloadedCacheManager(context: Context): CacheManager() { @@ -12,7 +13,7 @@ class OnlinePreloadedCacheManager(context: Context): CacheManager() {
override val goesOnline = true
override val preloaded = true
private var updateScheduleManagerNow: ()->Any? = nullFun
private var updateScheduleManagerNow: () -> Any? = nullFun
override fun getStamp(file: String) = onCacheMan.getStamp(file) ?: offCacheMan.getStamp(file)
override fun get(file: String) = onCacheMan[file] ?: offCacheMan[file]
@ -20,31 +21,26 @@ class OnlinePreloadedCacheManager(context: Context): CacheManager() { @@ -20,31 +21,26 @@ class OnlinePreloadedCacheManager(context: Context): CacheManager() {
val prevHash = get(file)?.second
val currHash = requestResult.second
onCacheMan[file] = requestResult
if (file.lastPathPart() == RemoteAssets.json.lastPathPart() && currHash!=prevHash)
if (file.lastPathPart() == RemoteAssets.json.lastPathPart() && currHash != prevHash)
updateScheduleManagerNow()
}
override fun delete(file: String) = listOf(onCacheMan.delete(file), offCacheMan.delete(file)).any { it }
override fun sanitize() = onCacheMan.sanitize()+offCacheMan.sanitize()
override val files get() = onCacheMan.files+offCacheMan.files
override fun sanitize() = onCacheMan.sanitize() + offCacheMan.sanitize()
override val files get() = onCacheMan.files + offCacheMan.files
override fun startMonitoringNeededFiles() = onCacheMan.startMonitoringNeededFiles()
override fun removeNotNeededFiles() = onCacheMan.removeNotNeededFiles()
override fun setupScheduleManagerUpdater(sm: ScheduleManager) {
// AlarmManagerCompat.setExactAndAllowWhileIdle(
// sm.alarmManager,
// AlarmManager.RTC_WAKEUP,
// System.currentTimeMillis()+500L,
// pendingIntent
// )
// sm.conventionSeriesUpdateHandler.removeCallbacksAndMessages(null)
// (object : Runnable { override fun run() {
// updateScheduleManagerNow = { sm.updateConventionSeries() }
// sm.conventionSeriesUpdateHandler.postAtTime(this, System.currentTimeMillis()+500L)
// sm.conventionSeriesUpdateHandler.postDelayed(this, 500L) //(max(sm.conventionSeries.updateFrequency, .5)*60*1000).roundToLong()
// println("asjdbaoebfsabefasjebgolsbrgoisbeogibsoeigboiwsbgoibewsogb")
// println("asjdbaoebfsabefasjebgolsbrgoisbeogibsoeigboiwsbgoibassogb")
// println("asjdbaoebfsabefasjebgolsbrgoisbeogibsoeigboiwsbgodsbwsogb")
// println("asjdbaoebfsabefasjebgolsbrgoisbeogibsoeigboiwsbgdfaedfegb")
// } }).apply { run() }
override fun getFileFor(asset: String): File {
val retFile = onCacheMan.cacheLocation.joinFile(asset.lastPathPart())
if (!retFile.exists()) {
val assetDescriptor = get(asset.lastPathPart())
if (assetDescriptor == null)
throw Resources.NotFoundException("Unavailable asset: $asset")
else
set(asset.lastPathPart(), Pair(assetDescriptor.first.readBytes(), UNIX_TIMESTAMP_START))
}
println(retFile)
return retFile
}
}

11
app/src/main/java/com/adlerosn/brasilfurfest/schedule/managers/RemoteAssets.kt

@ -1,8 +1,9 @@ @@ -1,8 +1,9 @@
package com.adlerosn.brasilfurfest.schedule.managers
object RemoteAssets: RemoteAssetsInterface {
override val json = "https://bff-ws.adlerneves.com/api/conventions/bff/minified.json"
override val media = "https://bff-ws.adlerneves.com/"
override val onlineApp = false
override val selfUpdate = false
object RemoteAssets: AbstractRemoteAssets(
"https://events.furmeet.app",
"bff"
) {
override val onlineApp = true
override val preloaded = true
}

3
app/src/main/java/com/adlerosn/brasilfurfest/schedule/managers/RemoteAssetsInterface.kt

@ -3,6 +3,7 @@ package com.adlerosn.brasilfurfest.schedule.managers @@ -3,6 +3,7 @@ package com.adlerosn.brasilfurfest.schedule.managers
interface RemoteAssetsInterface {
val json: String
val media: String
val attending: String
val onlineApp: Boolean
val selfUpdate: Boolean
val preloaded: Boolean
}

81
app/src/main/java/com/adlerosn/brasilfurfest/schedule/managers/ScheduleManager.kt

@ -1,14 +1,13 @@ @@ -1,14 +1,13 @@
package com.adlerosn.brasilfurfest.schedule.managers
import android.app.AlarmManager
import android.content.Context
import android.os.FileObserver
import android.os.Handler
import android.os.Looper
import android.util.Log
import com.adlerosn.brasilfurfest.helper.*
import com.adlerosn.brasilfurfest.helper.observables.Observable
import com.adlerosn.brasilfurfest.helper.observables.Observer
import com.adlerosn.brasilfurfest.notification.NotificationFirer
import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.convention.Announcement
import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.convention.Convention
import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.convention.ConventionSeries
import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.convention.Event
@ -16,7 +15,6 @@ import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.managed.AttendeeCon @@ -16,7 +15,6 @@ import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.managed.AttendeeCon
import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.managed.AttendeeConsFavorites
import com.google.gson.GsonBuilder
import org.jetbrains.anko.doAsync
import org.jetbrains.anko.uiThread
import java.io.File
import java.io.Serializable
import java.util.*
@ -24,15 +22,20 @@ import java.util.* @@ -24,15 +22,20 @@ import java.util.*
class ScheduleManager(context: Context) : UncomplicatedObservable<Any?>(), Observer<Observable<Any?>, Any?>, Serializable {
override fun update(observable: Observable<Any?>, args: Any?) = onAttendeeIntentionsChanged()
val cacheManager = CacheManager(context).also { it.setupScheduleManagerUpdater(this) }
private val uniqueIdentifierFile = File(context.filesDir, "rduid.txt")
val uniqueIdentifier: String
val cacheManager = CacheManager(context)
private val cachedChoices = File(context.filesDir, "schedule_choices.json")
private val cachedChoicesCanonicalPath = cachedChoices.canonicalPath
private inner class InnerFileObserver(path: String, private val scheduleManager: ScheduleManager) : FixedFileObserver(path){
private val fireNotificationsClosure = { NotificationFirer().fire(context) }
private inner class InnerFileObserver(path: String, private val closure: ()->Any?) : FixedFileObserver(path){
override fun onEvent(event: Int, path: String) {
val mask = FileObserver.CLOSE_WRITE
if ((event and mask) != 0) {
scheduleManager.notifyDiskChanges()
closure()
}
}
}
@ -54,7 +57,8 @@ class ScheduleManager(context: Context) : UncomplicatedObservable<Any?>(), Obser @@ -54,7 +57,8 @@ class ScheduleManager(context: Context) : UncomplicatedObservable<Any?>(), Obser
notifyObservers()
}
private var fileObserver: InnerFileObserver
private val fileObserver: InnerFileObserver
private val scheduleObserver: InnerFileObserver
fun updateConventionSeries() =
cacheManager[RemoteAssets.json.lastPathPart()]!!.first
@ -77,33 +81,62 @@ class ScheduleManager(context: Context) : UncomplicatedObservable<Any?>(), Obser @@ -77,33 +81,62 @@ class ScheduleManager(context: Context) : UncomplicatedObservable<Any?>(), Obser
//.setExclusionStrategies(ObservableFieldsExclusionStrategy())
.registerTypeAdapter(Convention::class.java, ConventionInstanceCreator(convention))
.create()
val nextNotificationTime: Long get(){
val early: Long = convention.notificationFireMinutesBefore*60*1000.toLong()
val now = conventionTime
val thisRange = now.dayRange.split(convention.splitDayIn).first { conventionTime in it }
val diff = thisRange.finish.timeInMillis - thisRange.start.timeInMillis
val nextEnd = thisRange.start.timeInMillis+(1*diff)
val nextNextEnd = thisRange.start.timeInMillis+(2*diff)
val earlyNextEnd = nextEnd-early
val earlyNextNextEnd = nextNextEnd-early
return if(now.timeInMillis < earlyNextEnd) earlyNextEnd else earlyNextNextEnd
}
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
fun onConventionSeriesHasPendingUpdates(){ doAsync { uiThread { updateConventionSeries() } } }
// val nextNotificationTime: Long get(){
// val early: Long = convention.notificationFireMinutesBefore*60*1000.toLong()
// val now = conventionTime
// val thisRange = now.dayRange.split(convention.splitDayIn).first { conventionTime in it }
// val diff = thisRange.finish.timeInMillis - thisRange.start.timeInMillis
// val nextEnd = thisRange.start.timeInMillis+(1*diff)
// val nextNextEnd = thisRange.start.timeInMillis+(2*diff)
// val earlyNextEnd = nextEnd-early
// val earlyNextNextEnd = nextNextEnd-early
// return if(now.timeInMillis < earlyNextEnd) earlyNextEnd else earlyNextNextEnd
// }
init {
loadFromDisk()
if(!cachedChoices.exists())
saveToDisk(false)
fileObserver = InnerFileObserver(cachedChoicesCanonicalPath, this)
fileObserver.startWatching()
uniqueIdentifier = initUniqueIdentifierFile()
fileObserver = (InnerFileObserver(cachedChoicesCanonicalPath) {notifyDiskChanges()}).apply { startWatching() }
scheduleObserver = (InnerFileObserver(cacheManager.getFileFor(RemoteAssets.json).absolutePath) {notifyScheduleChanged()}).apply { startWatching() }
}
private fun notifyScheduleChanged() {
conventionSeries = updateConventionSeries()
setChanged()
notifyObservers()
fireNotificationsClosure()
}
private val readAnnouncementsFile = File(context.filesDir, "announcements_read.txt")
val unreadAnnouncements: List<Announcement> get() {
if(!readAnnouncementsFile.exists())
return listOf()
val readAnnouncementUUIDs = readAnnouncementsFile.readLines()
return conventionSeries.announcements.filter { it.uuid !in readAnnouncementUUIDs }
}
fun setAnnouncementsRead() {
readAnnouncementsFile.writeText(
conventionSeries.announcements.map {
it.uuid
}.joinToString(separator = "\n")
)
}
private fun initUniqueIdentifierFile(): String{
if(!uniqueIdentifierFile.exists())
uniqueIdentifierFile.writeText(UUID.randomUUID().toString())
return uniqueIdentifierFile.readText()
}
private fun readObject(ois: java.io.ObjectInputStream){
ois.defaultReadObject()
fileObserver.stopWatching()
fileObserver.startWatching()
scheduleObserver.stopWatching()
scheduleObserver.startWatching()
loadFromDisk()
}

10
app/src/main/java/com/adlerosn/brasilfurfest/schedule/managers/UpdateChecker.kt

@ -13,7 +13,7 @@ import java.net.URL @@ -13,7 +13,7 @@ import java.net.URL
class UpdateChecker(context: Context): Serializable {
val cacheManager = CacheManager(context).also { it.startMonitoringNeededFiles() }
private val baseJsonFileName = RemoteAssets.json.split('/').last()
private val baseJsonFileName = RemoteAssets.json.lastPathPart()
val hasBaseJsonCached get() = baseJsonFileName.let {
cacheManager.getStamp(it) != null
}
@ -21,8 +21,8 @@ class UpdateChecker(context: Context): Serializable { @@ -21,8 +21,8 @@ class UpdateChecker(context: Context): Serializable {
fun downloadBaseJsonWithWatcher(watcher: (DownloadState, ByteArray?, Throwable?)->Any?) =
downloadWithWatcher(RemoteAssets.json, watcher)
fun downloadWithWatcher(httpThingToFetch: String, watcher: (DownloadState, ByteArray?, Throwable?)->Any?){
if(cacheManager.goesOnline) {
fun downloadWithWatcher(httpThingToFetch: String, watcher: (DownloadState, ByteArray?, Throwable?)->Any?) =
if(cacheManager.goesOnline)
doAsync {
try {
val url = URL(httpThingToFetch)
@ -67,14 +67,12 @@ class UpdateChecker(context: Context): Serializable { @@ -67,14 +67,12 @@ class UpdateChecker(context: Context): Serializable {
uiThread { watcher(DownloadState.ERROR, null, t) }
}
}
} else {
else
doAsync { uiThread {
watcher(DownloadState.CONNECTING, null, null)
watcher(DownloadState.CACHE_HIT, null, null)
watcher(DownloadState.SUCCESS, cacheManager[httpThingToFetch.lastPathPart()]!!.first.readBytes(), null)
} }
}
}
enum class DownloadState{
CONNECTING,