From 88b40736874a876576e1dc6c49c299fdfeb600bb Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Sun, 23 Dec 2018 20:04:08 -0500 Subject: Migrate to androidx (#1257) * Initial migration * Update gradle wrapper * Update iconics and revert progressanimator api * Clean up imports * Update dependencies and address some lint issues * Update constants * Remove extra import --- app/build.gradle | 13 ++++++------- app/src/main/AndroidManifest.xml | 2 +- .../com/pitchedapps/frost/activities/AboutActivity.kt | 14 +++++++------- .../com/pitchedapps/frost/activities/BaseMainActivity.kt | 16 ++++++++-------- .../com/pitchedapps/frost/activities/DebugActivity.kt | 6 +++--- .../com/pitchedapps/frost/activities/ImageActivity.kt | 2 +- .../com/pitchedapps/frost/activities/IntroActivity.kt | 8 ++++---- .../com/pitchedapps/frost/activities/LoginActivity.kt | 6 +++--- .../com/pitchedapps/frost/activities/MainActivity.kt | 4 ++-- .../com/pitchedapps/frost/activities/SelectorActivity.kt | 8 ++++---- .../com/pitchedapps/frost/activities/SettingsActivity.kt | 2 +- .../frost/activities/TabCustomizerActivity.kt | 10 +++++----- .../pitchedapps/frost/activities/WebOverlayActivity.kt | 10 +++++----- .../main/kotlin/com/pitchedapps/frost/enums/FeedSort.kt | 2 +- .../main/kotlin/com/pitchedapps/frost/enums/Support.kt | 2 +- app/src/main/kotlin/com/pitchedapps/frost/enums/Theme.kt | 2 +- .../main/kotlin/com/pitchedapps/frost/facebook/FbItem.kt | 6 +++--- .../com/pitchedapps/frost/fragments/FragmentBase.kt | 4 ++-- .../com/pitchedapps/frost/intro/IntroMainFragments.kt | 4 ++-- .../com/pitchedapps/frost/services/FrostNotifications.kt | 6 +++--- .../pitchedapps/frost/services/NotificationService.kt | 2 +- .../com/pitchedapps/frost/services/NotificationUtils.kt | 8 ++++---- .../pitchedapps/frost/utils/AnimatedVectorDelegate.kt | 2 +- app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt | 10 +++++----- .../kotlin/com/pitchedapps/frost/views/AccountItem.kt | 4 ++-- .../kotlin/com/pitchedapps/frost/views/BadgedIcon.kt | 2 +- .../com/pitchedapps/frost/views/FrostContentView.kt | 2 +- .../com/pitchedapps/frost/views/FrostRecyclerView.kt | 4 ++-- .../kotlin/com/pitchedapps/frost/views/FrostVideoView.kt | 6 +++--- .../com/pitchedapps/frost/views/FrostVideoViewer.kt | 2 +- .../kotlin/com/pitchedapps/frost/views/FrostViewPager.kt | 2 +- .../main/kotlin/com/pitchedapps/frost/views/Keywords.kt | 10 +++++----- .../kotlin/com/pitchedapps/frost/web/DebugWebView.kt | 2 +- .../kotlin/com/pitchedapps/frost/web/NestedWebView.kt | 6 +++--- app/src/main/res/drawable/frost_f_200.xml | 14 ++++++++++++++ app/src/main/res/drawable/frost_f_256.xml | 14 -------------- app/src/main/res/layout/activity_debug.xml | 10 +++++----- app/src/main/res/layout/activity_image.xml | 6 +++--- app/src/main/res/layout/activity_image_textless.xml | 6 +++--- app/src/main/res/layout/activity_intro.xml | 8 ++++---- app/src/main/res/layout/activity_invalid.xml | 4 ++-- app/src/main/res/layout/activity_login.xml | 6 +++--- app/src/main/res/layout/activity_main.xml | 8 ++++---- app/src/main/res/layout/activity_main_bottom_tabs.xml | 8 ++++---- app/src/main/res/layout/activity_selector.xml | 8 ++++---- app/src/main/res/layout/activity_tab_customizer.xml | 6 +++--- app/src/main/res/layout/activity_web_overlay.xml | 6 +++--- app/src/main/res/layout/iitem_menu.xml | 4 ++-- app/src/main/res/layout/iitem_notification.xml | 4 ++-- app/src/main/res/layout/intro_end.xml | 6 +++--- app/src/main/res/layout/intro_image.xml | 4 ++-- app/src/main/res/layout/intro_theme.xml | 4 ++-- app/src/main/res/layout/intro_welcome.xml | 6 +++--- app/src/main/res/layout/item_about_links.xml | 2 +- app/src/main/res/layout/item_keyword.xml | 2 +- app/src/main/res/layout/login_webview.xml | 6 +++--- app/src/main/res/layout/material_drawer_header.xml | 4 ++-- app/src/main/res/layout/view_account.xml | 4 ++-- app/src/main/res/layout/view_badged_icon.xml | 8 ++++---- app/src/main/res/layout/view_content_base_recycler.xml | 4 ++-- app/src/main/res/layout/view_content_base_web.xml | 4 ++-- app/src/main/res/layout/view_keywords.xml | 8 ++++---- app/src/main/res/layout/view_main_fab.xml | 2 +- app/src/main/res/layout/view_main_tab_layout.xml | 2 +- app/src/main/res/layout/view_main_toolbar.xml | 2 +- app/src/main/res/layout/view_video.xml | 2 +- 66 files changed, 185 insertions(+), 186 deletions(-) create mode 100644 app/src/main/res/drawable/frost_f_200.xml delete mode 100644 app/src/main/res/drawable/frost_f_256.xml (limited to 'app') diff --git a/app/build.gradle b/app/build.gradle index 34e57f84..2c7c5bcc 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -23,7 +23,7 @@ android { versionCode androidGitVersion.code() versionName androidGitVersion.name() multiDexEnabled true - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } applicationVariants.all { variant -> @@ -148,14 +148,13 @@ repositories { } dependencies { - androidTestImplementation("com.android.support.test:runner:${kau.testRunner}") { - exclude group: 'com.android.support', module: 'support-annotations' - } - - implementation "com.android.support:exifinterface:${kau.supportLibs}" + implementation 'androidx.exifinterface:exifinterface:1.0.0' androidTestImplementation kauDependency.kotlinTest - androidTestImplementation "com.android.support.test:rules:${TEST_RULE}" + androidTestImplementation kauDependency.espresso + androidTestImplementation kauDependency.testRules + androidTestImplementation kauDependency.testRunner + testImplementation kauDependency.kotlinTest testImplementation "org.jetbrains.kotlin:kotlin-reflect:${KOTLIN}" testImplementation kauDependency.junit diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index bdfb5688..ed197510 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -156,7 +156,7 @@ diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/AboutActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/AboutActivity.kt index 2261328d..4d333099 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/AboutActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/AboutActivity.kt @@ -1,8 +1,8 @@ package com.pitchedapps.frost.activities -import android.support.constraint.ConstraintLayout -import android.support.constraint.ConstraintSet -import android.support.v7.widget.RecyclerView +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.constraintlayout.widget.ConstraintSet +import androidx.recyclerview.widget.RecyclerView import android.view.View import android.view.ViewGroup import android.widget.ImageView @@ -34,7 +34,7 @@ class AboutActivity : AboutActivityBase(null, { accentColor = Prefs.accentColor backgroundColor = Prefs.bgColor.withMinAlpha(200) cutoutForeground = Prefs.accentColor - cutoutDrawableRes = R.drawable.frost_f_256 + cutoutDrawableRes = R.drawable.frost_f_200 faqPageTitleRes = R.string.faq_title faqXmlRes = R.xml.frost_faq faqParseNewLine = false @@ -137,10 +137,10 @@ class AboutActivity : AboutActivityBase(null, { val size = c.dimenPixelSize(R.dimen.kau_avatar_bounds) images = arrayOf Unit>>( GoogleMaterial.Icon.gmd_arrow_downward to { c.startLink(R.string.github_downloads_url) }, - CommunityMaterial.Icon.cmd_reddit to { c.startLink(R.string.reddit_url) }, + CommunityMaterial.Icon2.cmd_reddit to { c.startLink(R.string.reddit_url) }, CommunityMaterial.Icon.cmd_github_circle to { c.startLink(R.string.github_url) }, - CommunityMaterial.Icon.cmd_slack to { c.startLink(R.string.slack_url) }, - CommunityMaterial.Icon.cmd_xda to { c.startLink(R.string.xda_url) } + CommunityMaterial.Icon2.cmd_slack to { c.startLink(R.string.slack_url) }, + CommunityMaterial.Icon2.cmd_xda to { c.startLink(R.string.xda_url) } ).mapIndexed { i, (icon, onClick) -> ImageView(c).apply { layoutParams = ViewGroup.LayoutParams(size, size) diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt index 2fce69a8..52f61bea 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt @@ -8,14 +8,14 @@ import android.graphics.PointF import android.graphics.drawable.ColorDrawable import android.net.Uri import android.os.Bundle -import android.support.annotation.StringRes -import android.support.design.widget.AppBarLayout -import android.support.design.widget.CoordinatorLayout -import android.support.design.widget.FloatingActionButton -import android.support.design.widget.TabLayout -import android.support.v4.app.Fragment -import android.support.v4.app.FragmentPagerAdapter -import android.support.v7.widget.Toolbar +import androidx.annotation.StringRes +import com.google.android.material.appbar.AppBarLayout +import androidx.coordinatorlayout.widget.CoordinatorLayout +import com.google.android.material.floatingactionbutton.FloatingActionButton +import com.google.android.material.tabs.TabLayout +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentPagerAdapter +import androidx.appcompat.widget.Toolbar import android.view.Menu import android.view.MenuItem import android.webkit.ValueCallback diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/DebugActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/DebugActivity.kt index 9b1d8e79..9a90f090 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/DebugActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/DebugActivity.kt @@ -5,9 +5,9 @@ import android.content.Context import android.content.Intent import android.content.res.ColorStateList import android.os.Bundle -import android.support.design.widget.FloatingActionButton -import android.support.v4.widget.SwipeRefreshLayout -import android.support.v7.widget.Toolbar +import com.google.android.material.floatingactionbutton.FloatingActionButton +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout +import androidx.appcompat.widget.Toolbar import ca.allanwang.kau.internal.KauBaseActivity import ca.allanwang.kau.utils.bindView import ca.allanwang.kau.utils.setIcon diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/ImageActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/ImageActivity.kt index 30a77107..348b36b9 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/ImageActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/ImageActivity.kt @@ -5,7 +5,7 @@ import android.content.res.ColorStateList import android.graphics.Color import android.os.Bundle import android.os.Environment -import android.support.design.widget.FloatingActionButton +import com.google.android.material.floatingactionbutton.FloatingActionButton import android.view.View import ca.allanwang.kau.internal.KauBaseActivity import ca.allanwang.kau.logging.KauLoggerExtension diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/IntroActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/IntroActivity.kt index 4b00c242..c41229da 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/IntroActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/IntroActivity.kt @@ -4,10 +4,10 @@ import android.animation.ValueAnimator import android.content.res.ColorStateList import android.graphics.Color import android.os.Bundle -import android.support.v4.app.Fragment -import android.support.v4.app.FragmentManager -import android.support.v4.app.FragmentPagerAdapter -import android.support.v4.view.ViewPager +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentManager +import androidx.fragment.app.FragmentPagerAdapter +import androidx.viewpager.widget.ViewPager import android.view.View import android.view.WindowManager import android.widget.Button diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt index b5e2119f..9c8a60aa 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt @@ -3,9 +3,9 @@ package com.pitchedapps.frost.activities import android.graphics.drawable.Drawable import android.os.Bundle import android.os.Handler -import android.support.v4.widget.SwipeRefreshLayout -import android.support.v7.widget.AppCompatTextView -import android.support.v7.widget.Toolbar +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout +import androidx.appcompat.widget.AppCompatTextView +import androidx.appcompat.widget.Toolbar import android.widget.ImageView import ca.allanwang.kau.utils.bindView import ca.allanwang.kau.utils.fadeIn diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt index bf8120de..2555fe5b 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt @@ -1,8 +1,8 @@ package com.pitchedapps.frost.activities import android.os.Bundle -import android.support.design.widget.TabLayout -import android.support.v4.view.ViewPager +import com.google.android.material.tabs.TabLayout +import androidx.viewpager.widget.ViewPager import com.pitchedapps.frost.facebook.FbItem import com.pitchedapps.frost.views.BadgedIcon import io.reactivex.android.schedulers.AndroidSchedulers diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/SelectorActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/SelectorActivity.kt index 58ab3dac..514af197 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/SelectorActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/SelectorActivity.kt @@ -1,10 +1,10 @@ package com.pitchedapps.frost.activities import android.os.Bundle -import android.support.constraint.ConstraintLayout -import android.support.v7.widget.AppCompatTextView -import android.support.v7.widget.GridLayoutManager -import android.support.v7.widget.RecyclerView +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.appcompat.widget.AppCompatTextView +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.RecyclerView import android.view.View import ca.allanwang.kau.utils.bindView import com.mikepenz.fastadapter.FastAdapter diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt index 7561dc88..7663b70f 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt @@ -100,7 +100,7 @@ class SettingsActivity : KPrefActivity() { subItems(R.string.newsfeed, getFeedPrefs()) { descRes = R.string.newsfeed_desc - iicon = CommunityMaterial.Icon.cmd_newspaper + iicon = CommunityMaterial.Icon2.cmd_newspaper } subItems(R.string.notifications, getNotificationPrefs()) { diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/TabCustomizerActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/TabCustomizerActivity.kt index 7b2cfbf2..1938add0 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/TabCustomizerActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/TabCustomizerActivity.kt @@ -3,10 +3,10 @@ package com.pitchedapps.frost.activities import android.app.Activity import android.content.res.ColorStateList import android.os.Bundle -import android.support.design.widget.FloatingActionButton -import android.support.v7.widget.GridLayoutManager -import android.support.v7.widget.RecyclerView -import android.support.v7.widget.helper.ItemTouchHelper +import com.google.android.material.floatingactionbutton.FloatingActionButton +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.RecyclerView +import androidx.recyclerview.widget.ItemTouchHelper import android.view.View import android.view.animation.AnimationUtils import android.widget.TextView @@ -50,7 +50,7 @@ class TabCustomizerActivity : BaseActivity() { toolbar.setBackgroundColor(Prefs.headerColor) - recycler.layoutManager = GridLayoutManager(this, TAB_COUNT, GridLayoutManager.VERTICAL, false) + recycler.layoutManager = GridLayoutManager(this, TAB_COUNT, RecyclerView.VERTICAL, false) recycler.adapter = adapter recycler.setHasFixedSize(true) diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt index 323a2eb5..6d930fff 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt @@ -5,9 +5,8 @@ import android.content.Intent import android.graphics.PointF import android.net.Uri import android.os.Bundle -import android.support.design.widget.CoordinatorLayout -import android.support.design.widget.Snackbar -import android.support.v7.widget.Toolbar +import androidx.coordinatorlayout.widget.CoordinatorLayout +import androidx.appcompat.widget.Toolbar import android.view.Menu import android.view.MenuItem import android.webkit.ValueCallback @@ -16,6 +15,7 @@ import android.widget.FrameLayout import ca.allanwang.kau.swipe.kauSwipeOnCreate import ca.allanwang.kau.swipe.kauSwipeOnDestroy import ca.allanwang.kau.utils.* +import com.google.android.material.snackbar.BaseTransientBottomBar import com.mikepenz.community_material_typeface_library.CommunityMaterial import com.mikepenz.google_material_typeface_library.GoogleMaterial import com.pitchedapps.frost.R @@ -168,7 +168,7 @@ open class WebOverlayActivityBase(private val forceBasicAgent: Boolean) : BaseAc else reloadBase(true) if (Showcase.firstWebOverlay) { coordinator.frostSnackbar(R.string.web_overlay_swipe_hint) { - duration = Snackbar.LENGTH_INDEFINITE + duration = BaseTransientBottomBar.LENGTH_INDEFINITE setAction(R.string.kau_got_it) { _ -> this.dismiss() } } } @@ -248,7 +248,7 @@ open class WebOverlayActivityBase(private val forceBasicAgent: Boolean) : BaseAc overlayContext?.onMenuCreate(this, menu) toolbar.tint(Prefs.iconColor) setMenuIcons(menu, Prefs.iconColor, - R.id.action_share to CommunityMaterial.Icon.cmd_share, + R.id.action_share to CommunityMaterial.Icon2.cmd_share, R.id.action_copy_link to GoogleMaterial.Icon.gmd_content_copy) return true } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/enums/FeedSort.kt b/app/src/main/kotlin/com/pitchedapps/frost/enums/FeedSort.kt index d2de9988..d8a0f349 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/enums/FeedSort.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/enums/FeedSort.kt @@ -1,6 +1,6 @@ package com.pitchedapps.frost.enums -import android.support.annotation.StringRes +import androidx.annotation.StringRes import com.pitchedapps.frost.R import com.pitchedapps.frost.facebook.FbItem diff --git a/app/src/main/kotlin/com/pitchedapps/frost/enums/Support.kt b/app/src/main/kotlin/com/pitchedapps/frost/enums/Support.kt index ef3c88b6..34fa4b5f 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/enums/Support.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/enums/Support.kt @@ -1,7 +1,7 @@ package com.pitchedapps.frost.enums import android.content.Context -import android.support.annotation.StringRes +import androidx.annotation.StringRes import ca.allanwang.kau.utils.string import com.pitchedapps.frost.R import com.pitchedapps.frost.utils.sendFrostEmail diff --git a/app/src/main/kotlin/com/pitchedapps/frost/enums/Theme.kt b/app/src/main/kotlin/com/pitchedapps/frost/enums/Theme.kt index ada0b456..934dda07 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/enums/Theme.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/enums/Theme.kt @@ -1,7 +1,7 @@ package com.pitchedapps.frost.enums import android.graphics.Color -import android.support.annotation.StringRes +import androidx.annotation.StringRes import com.pitchedapps.frost.R import com.pitchedapps.frost.injectors.CssAssets import com.pitchedapps.frost.injectors.InjectorContract diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbItem.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbItem.kt index d6915f75..2f0e4e22 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbItem.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbItem.kt @@ -1,6 +1,6 @@ package com.pitchedapps.frost.facebook -import android.support.annotation.StringRes +import androidx.annotation.StringRes import com.mikepenz.community_material_typeface_library.CommunityMaterial import com.mikepenz.google_material_typeface_library.GoogleMaterial import com.mikepenz.iconics.typeface.IIcon @@ -25,14 +25,14 @@ enum class FbItem( BIRTHDAYS(R.string.birthdays, GoogleMaterial.Icon.gmd_cake, "events/birthdays"), CHAT(R.string.chat, GoogleMaterial.Icon.gmd_chat, "buddylist"), EVENTS(R.string.events, GoogleMaterial.Icon.gmd_event_note, "events/upcoming"), - FEED(R.string.feed, CommunityMaterial.Icon.cmd_newspaper, ""), + FEED(R.string.feed, CommunityMaterial.Icon2.cmd_newspaper, ""), FEED_MOST_RECENT(R.string.most_recent, GoogleMaterial.Icon.gmd_history, "home.php?sk=h_chr"), FEED_TOP_STORIES(R.string.top_stories, GoogleMaterial.Icon.gmd_star, "home.php?sk=h_nor"), FRIENDS(R.string.friends, GoogleMaterial.Icon.gmd_person_add, "friends/center/requests"), GROUPS(R.string.groups, GoogleMaterial.Icon.gmd_group, "groups"), MENU(R.string.menu, GoogleMaterial.Icon.gmd_menu, "settings", ::MenuFragment), MESSAGES(R.string.messages, MaterialDesignIconic.Icon.gmi_comments, "messages"), - NOTES(R.string.notes, CommunityMaterial.Icon.cmd_note, "notes"), + NOTES(R.string.notes, CommunityMaterial.Icon2.cmd_note, "notes"), NOTIFICATIONS(R.string.notifications, MaterialDesignIconic.Icon.gmi_globe, "notifications", ::NotificationFragment), ON_THIS_DAY(R.string.on_this_day, GoogleMaterial.Icon.gmd_today, "onthisday"), PAGES(R.string.pages, GoogleMaterial.Icon.gmd_flag, "pages"), diff --git a/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt b/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt index cf48893c..34e28c2e 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt @@ -2,8 +2,8 @@ package com.pitchedapps.frost.fragments import android.content.Context import android.os.Bundle -import android.support.design.widget.FloatingActionButton -import android.support.v4.app.Fragment +import com.google.android.material.floatingactionbutton.FloatingActionButton +import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup diff --git a/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroMainFragments.kt b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroMainFragments.kt index 39a39232..6e953777 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroMainFragments.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroMainFragments.kt @@ -3,8 +3,8 @@ package com.pitchedapps.frost.intro import android.annotation.SuppressLint import android.content.res.ColorStateList import android.os.Bundle -import android.support.constraint.ConstraintLayout -import android.support.v4.app.Fragment +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup diff --git a/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt b/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt index 295dbe0c..ededaad4 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt @@ -8,8 +8,8 @@ import android.net.Uri import android.os.BaseBundle import android.os.Build import android.os.Bundle -import android.support.v4.app.NotificationCompat -import android.support.v4.app.NotificationManagerCompat +import androidx.core.app.NotificationCompat +import androidx.core.app.NotificationManagerCompat import ca.allanwang.kau.utils.dpToPx import ca.allanwang.kau.utils.string import com.pitchedapps.frost.BuildConfig @@ -206,7 +206,7 @@ enum class NotificationType( .setCategory(Notification.CATEGORY_SOCIAL) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - notifBuilder.setGroupAlertBehavior(Notification.GROUP_ALERT_CHILDREN) + notifBuilder.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_CHILDREN) } return FrostNotification(group, 1, notifBuilder) diff --git a/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt b/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt index 56ff4db7..f15df482 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt @@ -2,7 +2,7 @@ package com.pitchedapps.frost.services import android.app.job.JobParameters import android.app.job.JobService -import android.support.v4.app.NotificationManagerCompat +import androidx.core.app.NotificationManagerCompat import ca.allanwang.kau.utils.string import com.pitchedapps.frost.BuildConfig import com.pitchedapps.frost.R diff --git a/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationUtils.kt b/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationUtils.kt index 59352f8e..707220f6 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationUtils.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationUtils.kt @@ -11,8 +11,8 @@ import android.content.Context import android.net.Uri import android.os.Build import android.os.PersistableBundle -import android.support.annotation.RequiresApi -import android.support.v4.app.NotificationCompat +import androidx.annotation.RequiresApi +import androidx.core.app.NotificationCompat import ca.allanwang.kau.utils.color import ca.allanwang.kau.utils.string import com.pitchedapps.frost.R @@ -70,8 +70,8 @@ fun Context.frostNotification(id: String) = fun NotificationCompat.Builder.setFrostAlert(enable: Boolean, ringtone: String): NotificationCompat.Builder { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { setGroupAlertBehavior( - if (enable) Notification.GROUP_ALERT_CHILDREN - else Notification.GROUP_ALERT_SUMMARY) + if (enable) NotificationCompat.GROUP_ALERT_CHILDREN + else NotificationCompat.GROUP_ALERT_SUMMARY) } else if (!enable) { setDefaults(0) } else { diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/AnimatedVectorDelegate.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/AnimatedVectorDelegate.kt index 8d800e9b..223eed3f 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/AnimatedVectorDelegate.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/AnimatedVectorDelegate.kt @@ -1,7 +1,7 @@ package com.pitchedapps.frost.utils import android.graphics.drawable.AnimatedVectorDrawable -import android.support.annotation.DrawableRes +import androidx.annotation.DrawableRes import android.widget.ImageView import ca.allanwang.kau.utils.drawable diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt index 6c78d922..650f277b 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt @@ -8,11 +8,10 @@ import android.content.Intent import android.graphics.Color import android.graphics.drawable.ColorDrawable import android.net.Uri -import android.support.annotation.StringRes -import android.support.design.widget.Snackbar -import android.support.design.widget.SnackbarContentLayout -import android.support.v4.content.FileProvider -import android.support.v7.widget.Toolbar +import androidx.annotation.StringRes +import com.google.android.material.snackbar.Snackbar +import androidx.core.content.FileProvider +import androidx.appcompat.widget.Toolbar import android.view.View import android.widget.FrameLayout import android.widget.TextView @@ -23,6 +22,7 @@ import ca.allanwang.kau.mediapicker.createPrivateMediaFile import ca.allanwang.kau.utils.* import ca.allanwang.kau.xml.showChangelog import com.afollestad.materialdialogs.MaterialDialog +import com.google.android.material.snackbar.SnackbarContentLayout import com.pitchedapps.frost.BuildConfig import com.pitchedapps.frost.R import com.pitchedapps.frost.activities.* diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/AccountItem.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/AccountItem.kt index 7262fa17..9f6d0c06 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/AccountItem.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/AccountItem.kt @@ -1,8 +1,8 @@ package com.pitchedapps.frost.views import android.graphics.drawable.Drawable -import android.support.v7.widget.AppCompatTextView -import android.support.v7.widget.RecyclerView +import androidx.appcompat.widget.AppCompatTextView +import androidx.recyclerview.widget.RecyclerView import android.view.View import android.widget.ImageView import ca.allanwang.kau.iitems.KauIItem diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/BadgedIcon.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/BadgedIcon.kt index 60713034..92620567 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/BadgedIcon.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/BadgedIcon.kt @@ -2,7 +2,7 @@ package com.pitchedapps.frost.views import android.content.Context import android.graphics.drawable.GradientDrawable -import android.support.constraint.ConstraintLayout +import androidx.constraintlayout.widget.ConstraintLayout import android.util.AttributeSet import android.widget.ImageView import android.widget.TextView diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt index 19b1176e..c44a8188 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt @@ -2,7 +2,7 @@ package com.pitchedapps.frost.views import android.content.Context import android.os.Build -import android.support.v4.widget.SwipeRefreshLayout +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import android.util.AttributeSet import android.view.View import android.widget.FrameLayout diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostRecyclerView.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostRecyclerView.kt index 38b09657..19869426 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostRecyclerView.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostRecyclerView.kt @@ -1,8 +1,8 @@ package com.pitchedapps.frost.views import android.content.Context -import android.support.v7.widget.LinearLayoutManager -import android.support.v7.widget.RecyclerView +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import android.util.AttributeSet import android.view.View import ca.allanwang.kau.utils.circularReveal diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoView.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoView.kt index d7f44420..85dc7e18 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoView.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoView.kt @@ -79,7 +79,7 @@ class FrostVideoView @JvmOverloads constructor( if (!isPlaying) showControls() else viewerContract.onControlsHidden() } - }.start() + } } else { hideControls() val (scale, tX, tY) = mapBounds() @@ -90,7 +90,7 @@ class FrostVideoView @JvmOverloads constructor( withAnimator(origScale, scale) { scaleXY = it } withAnimator(origX, tX) { translationX = it } withAnimator(origY, tY) { translationY = it } - }.start() + } } } @@ -210,7 +210,7 @@ class FrostVideoView @JvmOverloads constructor( duration = FAST_ANIMATION_DURATION withAnimator(alpha, 0f) { alpha = it } withEndAction { onFinishedListener() } - }.start() + } else onFinishedListener() } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoViewer.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoViewer.kt index 2d5e376d..5afb3a21 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoViewer.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoViewer.kt @@ -4,7 +4,7 @@ import android.content.Context import android.graphics.Color import android.graphics.PointF import android.net.Uri -import android.support.v7.widget.Toolbar +import androidx.appcompat.widget.Toolbar import android.util.AttributeSet import android.view.MotionEvent import android.view.View diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostViewPager.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostViewPager.kt index 8122d362..18b7ae49 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostViewPager.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostViewPager.kt @@ -2,7 +2,7 @@ package com.pitchedapps.frost.views import android.annotation.SuppressLint import android.content.Context -import android.support.v4.view.ViewPager +import androidx.viewpager.widget.ViewPager import android.util.AttributeSet import android.view.MotionEvent import com.pitchedapps.frost.utils.Prefs diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/Keywords.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/Keywords.kt index 8092133b..c171ce77 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/Keywords.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/Keywords.kt @@ -2,11 +2,11 @@ package com.pitchedapps.frost.views import android.content.Context import android.graphics.drawable.Drawable -import android.support.constraint.ConstraintLayout -import android.support.v7.widget.AppCompatEditText -import android.support.v7.widget.AppCompatTextView -import android.support.v7.widget.LinearLayoutManager -import android.support.v7.widget.RecyclerView +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.appcompat.widget.AppCompatEditText +import androidx.appcompat.widget.AppCompatTextView +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import android.util.AttributeSet import android.view.View import android.widget.ImageView diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/DebugWebView.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/DebugWebView.kt index ac62f142..4ce6f005 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/web/DebugWebView.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/web/DebugWebView.kt @@ -4,7 +4,7 @@ import android.annotation.SuppressLint import android.content.Context import android.graphics.Bitmap import android.graphics.Color -import android.support.annotation.WorkerThread +import androidx.annotation.WorkerThread import android.util.AttributeSet import android.view.View import android.webkit.WebView diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/NestedWebView.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/NestedWebView.kt index 297c4158..760d81fc 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/web/NestedWebView.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/web/NestedWebView.kt @@ -2,9 +2,9 @@ package com.pitchedapps.frost.web import android.annotation.SuppressLint import android.content.Context -import android.support.v4.view.NestedScrollingChild -import android.support.v4.view.NestedScrollingChildHelper -import android.support.v4.view.ViewCompat +import androidx.core.view.NestedScrollingChild +import androidx.core.view.NestedScrollingChildHelper +import androidx.core.view.ViewCompat import android.util.AttributeSet import android.view.MotionEvent import android.webkit.WebView diff --git a/app/src/main/res/drawable/frost_f_200.xml b/app/src/main/res/drawable/frost_f_200.xml new file mode 100644 index 00000000..3f07c641 --- /dev/null +++ b/app/src/main/res/drawable/frost_f_200.xml @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/frost_f_256.xml b/app/src/main/res/drawable/frost_f_256.xml deleted file mode 100644 index 220dee69..00000000 --- a/app/src/main/res/drawable/frost_f_256.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_debug.xml b/app/src/main/res/layout/activity_debug.xml index 42428e49..55553f42 100644 --- a/app/src/main/res/layout/activity_debug.xml +++ b/app/src/main/res/layout/activity_debug.xml @@ -1,5 +1,5 @@ - - - - + - + diff --git a/app/src/main/res/layout/activity_image.xml b/app/src/main/res/layout/activity_image.xml index a2264b25..4e6d4ce1 100644 --- a/app/src/main/res/layout/activity_image.xml +++ b/app/src/main/res/layout/activity_image.xml @@ -1,5 +1,5 @@ - - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_image_textless.xml b/app/src/main/res/layout/activity_image_textless.xml index c5da87e6..e047b23d 100644 --- a/app/src/main/res/layout/activity_image_textless.xml +++ b/app/src/main/res/layout/activity_image_textless.xml @@ -1,5 +1,5 @@ - @@ -19,7 +19,7 @@ android:scaleX="0.9" android:scaleY="0.9" /> - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_intro.xml b/app/src/main/res/layout/activity_intro.xml index 839e33a9..e61a618d 100644 --- a/app/src/main/res/layout/activity_intro.xml +++ b/app/src/main/res/layout/activity_intro.xml @@ -1,5 +1,5 @@ - - - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_invalid.xml b/app/src/main/res/layout/activity_invalid.xml index dba1375b..42c16b38 100644 --- a/app/src/main/res/layout/activity_invalid.xml +++ b/app/src/main/res/layout/activity_invalid.xml @@ -1,5 +1,5 @@ - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index 8b3ca157..653656a6 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -1,5 +1,5 @@ - - - + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 883221d9..8fa9283f 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,5 +1,5 @@ - - - + - + diff --git a/app/src/main/res/layout/activity_main_bottom_tabs.xml b/app/src/main/res/layout/activity_main_bottom_tabs.xml index 783aa455..2c2527cd 100644 --- a/app/src/main/res/layout/activity_main_bottom_tabs.xml +++ b/app/src/main/res/layout/activity_main_bottom_tabs.xml @@ -5,7 +5,7 @@ android:layout_height="match_parent" android:orientation="vertical"> - - - + - + diff --git a/app/src/main/res/layout/activity_selector.xml b/app/src/main/res/layout/activity_selector.xml index d9625731..4bbbd866 100644 --- a/app/src/main/res/layout/activity_selector.xml +++ b/app/src/main/res/layout/activity_selector.xml @@ -1,5 +1,5 @@ - - - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_tab_customizer.xml b/app/src/main/res/layout/activity_tab_customizer.xml index 8e540f11..8cf9d903 100644 --- a/app/src/main/res/layout/activity_tab_customizer.xml +++ b/app/src/main/res/layout/activity_tab_customizer.xml @@ -16,7 +16,7 @@ android:layout_height="match_parent" android:orientation="vertical"> - @@ -36,14 +36,14 @@ - - - - - + diff --git a/app/src/main/res/layout/iitem_menu.xml b/app/src/main/res/layout/iitem_menu.xml index 3dbc7ea1..eb849cca 100644 --- a/app/src/main/res/layout/iitem_menu.xml +++ b/app/src/main/res/layout/iitem_menu.xml @@ -1,5 +1,5 @@ - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/iitem_notification.xml b/app/src/main/res/layout/iitem_notification.xml index 266b9dc4..e7cdab73 100644 --- a/app/src/main/res/layout/iitem_notification.xml +++ b/app/src/main/res/layout/iitem_notification.xml @@ -1,5 +1,5 @@ - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/intro_end.xml b/app/src/main/res/layout/intro_end.xml index 67931e43..501cf1a9 100644 --- a/app/src/main/res/layout/intro_end.xml +++ b/app/src/main/res/layout/intro_end.xml @@ -1,5 +1,5 @@ - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/intro_image.xml b/app/src/main/res/layout/intro_image.xml index 8bdf4c90..97a5bcae 100644 --- a/app/src/main/res/layout/intro_image.xml +++ b/app/src/main/res/layout/intro_image.xml @@ -1,5 +1,5 @@ - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/intro_theme.xml b/app/src/main/res/layout/intro_theme.xml index 2a8cead3..cd0538dd 100644 --- a/app/src/main/res/layout/intro_theme.xml +++ b/app/src/main/res/layout/intro_theme.xml @@ -1,5 +1,5 @@ - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/intro_welcome.xml b/app/src/main/res/layout/intro_welcome.xml index b53af755..a73657ce 100644 --- a/app/src/main/res/layout/intro_welcome.xml +++ b/app/src/main/res/layout/intro_welcome.xml @@ -1,5 +1,5 @@ - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/item_about_links.xml b/app/src/main/res/layout/item_about_links.xml index 09c79f37..2417c321 100644 --- a/app/src/main/res/layout/item_about_links.xml +++ b/app/src/main/res/layout/item_about_links.xml @@ -1,7 +1,7 @@ - - - @@ -18,7 +18,7 @@ android:scaleType="centerInside" android:visibility="invisible" /> - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/material_drawer_header.xml b/app/src/main/res/layout/material_drawer_header.xml index 21cd20a1..085a1870 100644 --- a/app/src/main/res/layout/material_drawer_header.xml +++ b/app/src/main/res/layout/material_drawer_header.xml @@ -92,7 +92,7 @@ android:fontFamily="sans-serif-medium" android:lines="1" android:maxLines="1" - android:textSize="@dimen/material_drawer_account_header_text" /> + android:textSize="@dimen/material_drawer_account_header_title" /> + android:textSize="@dimen/material_drawer_account_header_subtext" /> diff --git a/app/src/main/res/layout/view_account.xml b/app/src/main/res/layout/view_account.xml index 63d3e9cd..de8ee0a2 100644 --- a/app/src/main/res/layout/view_account.xml +++ b/app/src/main/res/layout/view_account.xml @@ -10,11 +10,11 @@ android:layout_width="@dimen/account_image_size" android:layout_height="@dimen/account_image_size" /> - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/view_content_base_recycler.xml b/app/src/main/res/layout/view_content_base_recycler.xml index e1591efe..05b14215 100644 --- a/app/src/main/res/layout/view_content_base_recycler.xml +++ b/app/src/main/res/layout/view_content_base_recycler.xml @@ -6,7 +6,7 @@ android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> - @@ -19,7 +19,7 @@ android:focusableInTouchMode="true" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> - + - @@ -19,7 +19,7 @@ android:focusableInTouchMode="true" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> - + - - - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/view_main_fab.xml b/app/src/main/res/layout/view_main_fab.xml index 7e3ec2aa..e9fe9981 100644 --- a/app/src/main/res/layout/view_main_fab.xml +++ b/app/src/main/res/layout/view_main_fab.xml @@ -1,5 +1,5 @@ - - - - Date: Sun, 23 Dec 2018 20:05:18 -0500 Subject: Update play listings (#1250) * Update play listing * Update default language * Delete fastlane --- app/src/main/play/defaultLanguage | 2 +- app/src/main/play/en-CA/listing/fulldescription | 38 ---------- app/src/main/play/en-CA/listing/shortdescription | 1 - app/src/main/play/en-CA/listing/title | 1 - app/src/main/play/en-CA/whatsnew | 1 - app/src/main/play/en-US/listing/fulldescription | 38 ++++++++++ .../play/en-US/listing/images/featureGraphic.png | Bin 0 -> 8596 bytes .../images/phoneScreenshots/frost_1_themes.png | Bin 0 -> 41141 bytes .../images/phoneScreenshots/frost_2_glass.png | Bin 0 -> 128325 bytes .../phoneScreenshots/frost_3_multi_accounts.png | Bin 0 -> 30160 bytes .../images/phoneScreenshots/frost_4_pip.png | Bin 0 -> 63637 bytes .../images/phoneScreenshots/frost_5_swipe.png | Bin 0 -> 41821 bytes .../phoneScreenshots/frost_6_quick_links.png | Bin 0 -> 25264 bytes app/src/main/play/en-US/listing/shortdescription | 1 + app/src/main/play/en-US/listing/title | 1 + app/src/main/play/en-US/whatsnew | 1 + .../play/es-ES/listing/images/featureGraphic.png | Bin 0 -> 8596 bytes .../images/phoneScreenshots/frost_1_themes.png | Bin 0 -> 41141 bytes .../images/phoneScreenshots/frost_2_glass.png | Bin 0 -> 128325 bytes .../phoneScreenshots/frost_3_multi_accounts.png | Bin 0 -> 30160 bytes .../images/phoneScreenshots/frost_4_pip.png | Bin 0 -> 63637 bytes .../images/phoneScreenshots/frost_5_swipe.png | Bin 0 -> 41821 bytes .../phoneScreenshots/frost_6_quick_links.png | Bin 0 -> 25264 bytes .../metadata/android/en-CA/full_description.txt | 80 --------------------- .../android/en-CA/images/featureGraphic.png | Bin 8596 -> 0 bytes .../images/phoneScreenshots/frost_1_themes.png | Bin 41141 -> 0 bytes .../images/phoneScreenshots/frost_2_glass.png | Bin 128325 -> 0 bytes .../phoneScreenshots/frost_3_multi_accounts.png | Bin 30160 -> 0 bytes .../en-CA/images/phoneScreenshots/frost_4_pip.png | Bin 63637 -> 0 bytes .../images/phoneScreenshots/frost_5_swipe.png | Bin 41821 -> 0 bytes .../phoneScreenshots/frost_6_quick_links.png | Bin 25264 -> 0 bytes .../metadata/android/en-CA/short_description.txt | 1 - fastlane/metadata/android/en-CA/title.txt | 1 - 33 files changed, 42 insertions(+), 124 deletions(-) delete mode 100644 app/src/main/play/en-CA/listing/fulldescription delete mode 100644 app/src/main/play/en-CA/listing/shortdescription delete mode 100644 app/src/main/play/en-CA/listing/title delete mode 100644 app/src/main/play/en-CA/whatsnew create mode 100644 app/src/main/play/en-US/listing/fulldescription create mode 100644 app/src/main/play/en-US/listing/images/featureGraphic.png create mode 100644 app/src/main/play/en-US/listing/images/phoneScreenshots/frost_1_themes.png create mode 100644 app/src/main/play/en-US/listing/images/phoneScreenshots/frost_2_glass.png create mode 100644 app/src/main/play/en-US/listing/images/phoneScreenshots/frost_3_multi_accounts.png create mode 100644 app/src/main/play/en-US/listing/images/phoneScreenshots/frost_4_pip.png create mode 100644 app/src/main/play/en-US/listing/images/phoneScreenshots/frost_5_swipe.png create mode 100644 app/src/main/play/en-US/listing/images/phoneScreenshots/frost_6_quick_links.png create mode 100644 app/src/main/play/en-US/listing/shortdescription create mode 100644 app/src/main/play/en-US/listing/title create mode 100644 app/src/main/play/en-US/whatsnew create mode 100644 app/src/main/play/es-ES/listing/images/featureGraphic.png create mode 100644 app/src/main/play/es-ES/listing/images/phoneScreenshots/frost_1_themes.png create mode 100644 app/src/main/play/es-ES/listing/images/phoneScreenshots/frost_2_glass.png create mode 100644 app/src/main/play/es-ES/listing/images/phoneScreenshots/frost_3_multi_accounts.png create mode 100644 app/src/main/play/es-ES/listing/images/phoneScreenshots/frost_4_pip.png create mode 100644 app/src/main/play/es-ES/listing/images/phoneScreenshots/frost_5_swipe.png create mode 100644 app/src/main/play/es-ES/listing/images/phoneScreenshots/frost_6_quick_links.png delete mode 100644 fastlane/metadata/android/en-CA/full_description.txt delete mode 100644 fastlane/metadata/android/en-CA/images/featureGraphic.png delete mode 100644 fastlane/metadata/android/en-CA/images/phoneScreenshots/frost_1_themes.png delete mode 100644 fastlane/metadata/android/en-CA/images/phoneScreenshots/frost_2_glass.png delete mode 100644 fastlane/metadata/android/en-CA/images/phoneScreenshots/frost_3_multi_accounts.png delete mode 100644 fastlane/metadata/android/en-CA/images/phoneScreenshots/frost_4_pip.png delete mode 100644 fastlane/metadata/android/en-CA/images/phoneScreenshots/frost_5_swipe.png delete mode 100644 fastlane/metadata/android/en-CA/images/phoneScreenshots/frost_6_quick_links.png delete mode 100644 fastlane/metadata/android/en-CA/short_description.txt delete mode 100644 fastlane/metadata/android/en-CA/title.txt (limited to 'app') diff --git a/app/src/main/play/defaultLanguage b/app/src/main/play/defaultLanguage index ffdd217e..f2b0341f 100644 --- a/app/src/main/play/defaultLanguage +++ b/app/src/main/play/defaultLanguage @@ -1 +1 @@ -en-CA \ No newline at end of file +en-US \ No newline at end of file diff --git a/app/src/main/play/en-CA/listing/fulldescription b/app/src/main/play/en-CA/listing/fulldescription deleted file mode 100644 index 8e917db2..00000000 --- a/app/src/main/play/en-CA/listing/fulldescription +++ /dev/null @@ -1,38 +0,0 @@ -Welcome to Frost for Facebook! - -Frost is a fully functional web wrapper, with many unique and native features such as: - -• True multi user interactions - More than just an option in a settings menu, Frost's account switcher is right in the drawer. You are one tap away from switching accounts, and everything refreshes on the switch so that you can view other accounts instantaneously. Furthermore, the notification service will fetch notifications from all accounts, and will let you know which account has the new notification. -• Better multitasking - Frost contains an overlaying web browser that can be drawn on top of your foreground task. Open links and notifications with a full screen view, then swipe away to get back to your previous task. -• Contextual awareness - Frost integrates additional features via long presses. Need to copy a block of text or share a link? Long press the text. Need to zoom into an image or download it? Long press the image! -• Material Design - Built for lollipop and up, Frost focuses strongly on a beautiful and functional UI, and embraces material transitions and dimensions. -• Complete theme engine - Frost contains very comprehensive themes that customize all components of the app. Frost is also the only app to support transparent themes. -• Fully opened - Nothing speaks for privacy more than being open sourced. Frost is proud to be one of those apps, and can be found on github (Link in the app's about section) -• Fixes the little things - Frost is community driven, and many tweaks are added to address minor inconveniences and give a full native experience, despite being a web app. To list a few: -   • Focusing on a text input will prevent refreshing, so you don't accidentally swipe and lose your progress. -   • Horizontal swipe can be enabled along side the viewpager swipe with a simple long press -   • Automatic bug reports are sent when a crash is detected, so even if you don't contact the devs, you are helping contribute by using the app. - -Mandatory permissions used and why: - -• Internet, Network State, Wifi State - Frost fetches the pages from Facebook's mobile website. It also needs the network state so as to limit internet usage when you are on a metered network. -• Receive Boot Completed - Frost notifications persist on reboot, and need this permission to be added each time. -• Vibrate - Needed to vibrate phone for notifications; this can be toggled in the settings -• Billing - For purchasing pro and unlocking all of Frost's features - -Optional permissions used and why: -(these are only requested when they have to be, and are disabled until then) - -• Read/write external storage - Needed to upload photos in a new status and save photos when prompted -• Fine/coarse location - Needed for the check in option if users wish to search for their location - -• That's it! No privacy intrusion and no extra demands. - -Permissions NOT used and why: - -• Wakelock - Frost takes advantage of Android's Job Scheduler, and lets the framework decide when to run background services. Frost therefore doesn't need to constantly run in the background, nor does it force your phone to stay awake. -• Retrieve running apps - Frost has no need to access external apps or see what else is running -• Identity - Frost manages its accounts internally and uses it solely to give you access to your account. We don't depend on other personal information and we don't even save your email. -• Camera - While the camera permission can be added to allow you to directly take photos and upload them, we've decided that it would be best to allow you to do so externally and then share the photo with Frost - -* Frost is a third party app and is in no way affiliated with Facebook Inc.* \ No newline at end of file diff --git a/app/src/main/play/en-CA/listing/shortdescription b/app/src/main/play/en-CA/listing/shortdescription deleted file mode 100644 index b1ac9928..00000000 --- a/app/src/main/play/en-CA/listing/shortdescription +++ /dev/null @@ -1 +0,0 @@ -A fast and extensive third party wrapper for Facebook. \ No newline at end of file diff --git a/app/src/main/play/en-CA/listing/title b/app/src/main/play/en-CA/listing/title deleted file mode 100644 index a933d845..00000000 --- a/app/src/main/play/en-CA/listing/title +++ /dev/null @@ -1 +0,0 @@ -Frost for Facebook \ No newline at end of file diff --git a/app/src/main/play/en-CA/whatsnew b/app/src/main/play/en-CA/whatsnew deleted file mode 100644 index 1d15ce22..00000000 --- a/app/src/main/play/en-CA/whatsnew +++ /dev/null @@ -1 +0,0 @@ -A full changelog is available in the app \ No newline at end of file diff --git a/app/src/main/play/en-US/listing/fulldescription b/app/src/main/play/en-US/listing/fulldescription new file mode 100644 index 00000000..8e917db2 --- /dev/null +++ b/app/src/main/play/en-US/listing/fulldescription @@ -0,0 +1,38 @@ +Welcome to Frost for Facebook! + +Frost is a fully functional web wrapper, with many unique and native features such as: + +• True multi user interactions - More than just an option in a settings menu, Frost's account switcher is right in the drawer. You are one tap away from switching accounts, and everything refreshes on the switch so that you can view other accounts instantaneously. Furthermore, the notification service will fetch notifications from all accounts, and will let you know which account has the new notification. +• Better multitasking - Frost contains an overlaying web browser that can be drawn on top of your foreground task. Open links and notifications with a full screen view, then swipe away to get back to your previous task. +• Contextual awareness - Frost integrates additional features via long presses. Need to copy a block of text or share a link? Long press the text. Need to zoom into an image or download it? Long press the image! +• Material Design - Built for lollipop and up, Frost focuses strongly on a beautiful and functional UI, and embraces material transitions and dimensions. +• Complete theme engine - Frost contains very comprehensive themes that customize all components of the app. Frost is also the only app to support transparent themes. +• Fully opened - Nothing speaks for privacy more than being open sourced. Frost is proud to be one of those apps, and can be found on github (Link in the app's about section) +• Fixes the little things - Frost is community driven, and many tweaks are added to address minor inconveniences and give a full native experience, despite being a web app. To list a few: +   • Focusing on a text input will prevent refreshing, so you don't accidentally swipe and lose your progress. +   • Horizontal swipe can be enabled along side the viewpager swipe with a simple long press +   • Automatic bug reports are sent when a crash is detected, so even if you don't contact the devs, you are helping contribute by using the app. + +Mandatory permissions used and why: + +• Internet, Network State, Wifi State - Frost fetches the pages from Facebook's mobile website. It also needs the network state so as to limit internet usage when you are on a metered network. +• Receive Boot Completed - Frost notifications persist on reboot, and need this permission to be added each time. +• Vibrate - Needed to vibrate phone for notifications; this can be toggled in the settings +• Billing - For purchasing pro and unlocking all of Frost's features + +Optional permissions used and why: +(these are only requested when they have to be, and are disabled until then) + +• Read/write external storage - Needed to upload photos in a new status and save photos when prompted +• Fine/coarse location - Needed for the check in option if users wish to search for their location + +• That's it! No privacy intrusion and no extra demands. + +Permissions NOT used and why: + +• Wakelock - Frost takes advantage of Android's Job Scheduler, and lets the framework decide when to run background services. Frost therefore doesn't need to constantly run in the background, nor does it force your phone to stay awake. +• Retrieve running apps - Frost has no need to access external apps or see what else is running +• Identity - Frost manages its accounts internally and uses it solely to give you access to your account. We don't depend on other personal information and we don't even save your email. +• Camera - While the camera permission can be added to allow you to directly take photos and upload them, we've decided that it would be best to allow you to do so externally and then share the photo with Frost + +* Frost is a third party app and is in no way affiliated with Facebook Inc.* \ No newline at end of file diff --git a/app/src/main/play/en-US/listing/images/featureGraphic.png b/app/src/main/play/en-US/listing/images/featureGraphic.png new file mode 100644 index 00000000..c47aa1d9 Binary files /dev/null and b/app/src/main/play/en-US/listing/images/featureGraphic.png differ diff --git a/app/src/main/play/en-US/listing/images/phoneScreenshots/frost_1_themes.png b/app/src/main/play/en-US/listing/images/phoneScreenshots/frost_1_themes.png new file mode 100644 index 00000000..6d579adf Binary files /dev/null and b/app/src/main/play/en-US/listing/images/phoneScreenshots/frost_1_themes.png differ diff --git a/app/src/main/play/en-US/listing/images/phoneScreenshots/frost_2_glass.png b/app/src/main/play/en-US/listing/images/phoneScreenshots/frost_2_glass.png new file mode 100644 index 00000000..4ee98308 Binary files /dev/null and b/app/src/main/play/en-US/listing/images/phoneScreenshots/frost_2_glass.png differ diff --git a/app/src/main/play/en-US/listing/images/phoneScreenshots/frost_3_multi_accounts.png b/app/src/main/play/en-US/listing/images/phoneScreenshots/frost_3_multi_accounts.png new file mode 100644 index 00000000..11536dfe Binary files /dev/null and b/app/src/main/play/en-US/listing/images/phoneScreenshots/frost_3_multi_accounts.png differ diff --git a/app/src/main/play/en-US/listing/images/phoneScreenshots/frost_4_pip.png b/app/src/main/play/en-US/listing/images/phoneScreenshots/frost_4_pip.png new file mode 100644 index 00000000..e2b5910b Binary files /dev/null and b/app/src/main/play/en-US/listing/images/phoneScreenshots/frost_4_pip.png differ diff --git a/app/src/main/play/en-US/listing/images/phoneScreenshots/frost_5_swipe.png b/app/src/main/play/en-US/listing/images/phoneScreenshots/frost_5_swipe.png new file mode 100644 index 00000000..f5a7fb82 Binary files /dev/null and b/app/src/main/play/en-US/listing/images/phoneScreenshots/frost_5_swipe.png differ diff --git a/app/src/main/play/en-US/listing/images/phoneScreenshots/frost_6_quick_links.png b/app/src/main/play/en-US/listing/images/phoneScreenshots/frost_6_quick_links.png new file mode 100644 index 00000000..bd42e92b Binary files /dev/null and b/app/src/main/play/en-US/listing/images/phoneScreenshots/frost_6_quick_links.png differ diff --git a/app/src/main/play/en-US/listing/shortdescription b/app/src/main/play/en-US/listing/shortdescription new file mode 100644 index 00000000..b1ac9928 --- /dev/null +++ b/app/src/main/play/en-US/listing/shortdescription @@ -0,0 +1 @@ +A fast and extensive third party wrapper for Facebook. \ No newline at end of file diff --git a/app/src/main/play/en-US/listing/title b/app/src/main/play/en-US/listing/title new file mode 100644 index 00000000..a933d845 --- /dev/null +++ b/app/src/main/play/en-US/listing/title @@ -0,0 +1 @@ +Frost for Facebook \ No newline at end of file diff --git a/app/src/main/play/en-US/whatsnew b/app/src/main/play/en-US/whatsnew new file mode 100644 index 00000000..1d15ce22 --- /dev/null +++ b/app/src/main/play/en-US/whatsnew @@ -0,0 +1 @@ +A full changelog is available in the app \ No newline at end of file diff --git a/app/src/main/play/es-ES/listing/images/featureGraphic.png b/app/src/main/play/es-ES/listing/images/featureGraphic.png new file mode 100644 index 00000000..c47aa1d9 Binary files /dev/null and b/app/src/main/play/es-ES/listing/images/featureGraphic.png differ diff --git a/app/src/main/play/es-ES/listing/images/phoneScreenshots/frost_1_themes.png b/app/src/main/play/es-ES/listing/images/phoneScreenshots/frost_1_themes.png new file mode 100644 index 00000000..6d579adf Binary files /dev/null and b/app/src/main/play/es-ES/listing/images/phoneScreenshots/frost_1_themes.png differ diff --git a/app/src/main/play/es-ES/listing/images/phoneScreenshots/frost_2_glass.png b/app/src/main/play/es-ES/listing/images/phoneScreenshots/frost_2_glass.png new file mode 100644 index 00000000..4ee98308 Binary files /dev/null and b/app/src/main/play/es-ES/listing/images/phoneScreenshots/frost_2_glass.png differ diff --git a/app/src/main/play/es-ES/listing/images/phoneScreenshots/frost_3_multi_accounts.png b/app/src/main/play/es-ES/listing/images/phoneScreenshots/frost_3_multi_accounts.png new file mode 100644 index 00000000..11536dfe Binary files /dev/null and b/app/src/main/play/es-ES/listing/images/phoneScreenshots/frost_3_multi_accounts.png differ diff --git a/app/src/main/play/es-ES/listing/images/phoneScreenshots/frost_4_pip.png b/app/src/main/play/es-ES/listing/images/phoneScreenshots/frost_4_pip.png new file mode 100644 index 00000000..e2b5910b Binary files /dev/null and b/app/src/main/play/es-ES/listing/images/phoneScreenshots/frost_4_pip.png differ diff --git a/app/src/main/play/es-ES/listing/images/phoneScreenshots/frost_5_swipe.png b/app/src/main/play/es-ES/listing/images/phoneScreenshots/frost_5_swipe.png new file mode 100644 index 00000000..f5a7fb82 Binary files /dev/null and b/app/src/main/play/es-ES/listing/images/phoneScreenshots/frost_5_swipe.png differ diff --git a/app/src/main/play/es-ES/listing/images/phoneScreenshots/frost_6_quick_links.png b/app/src/main/play/es-ES/listing/images/phoneScreenshots/frost_6_quick_links.png new file mode 100644 index 00000000..bd42e92b Binary files /dev/null and b/app/src/main/play/es-ES/listing/images/phoneScreenshots/frost_6_quick_links.png differ diff --git a/fastlane/metadata/android/en-CA/full_description.txt b/fastlane/metadata/android/en-CA/full_description.txt deleted file mode 100644 index d0c3f6dc..00000000 --- a/fastlane/metadata/android/en-CA/full_description.txt +++ /dev/null @@ -1,80 +0,0 @@ -'''Welcome to Frost for Facebook!''' - -[https://allanwang.github.io/Frost-for-Facebook/ Webpage] - -Frost is a fully functional web wrapper, with many unique and native features -such as: - -* '''True multi user interactions''' - More than just an option in a settings -menu, Frost's account switcher is right in the drawer. You are one tap away from -switching accounts, and everything refreshes on the switch so that you can view -other accounts instantaneously. Furthermore, the notification service will fetch -notifications from all accounts, and will let you know which account has the new -notification. - -* '''Better multitasking''' - Frost contains an overlaying web browser that can -be drawn on top of your foreground task. Open links and notifications with a -full screen view, then swipe away to get back to your previous task. - -* '''Contextual awareness''' - Frost integrates additional features via long -presses. Need to copy a block of text or share a link? Long press the text. Need -to zoom into an image or download it? Long press the image! - -* '''Material Design''' - Built for lollipop and up, Frost focuses strongly on -a beautiful and functional UI, and embraces material transitions and dimensions. - -* '''Complete theme engine''' - Frost contains very comprehensive themes that -customize all components of the app. Frost is also the only app to support -transparent themes. - -* '''Fully opened''' - Nothing speaks for privacy more than being open sourced. -Frost is proud to be one of those apps, and can be found on github (Link in the -app's about section) - -* '''Fixes the little things''' - Frost is community driven, and many tweaks -are added to address minor inconveniences and give a full native experience, -despite being a web app. - -Mandatory permissions used and why: - -* Internet, Network State, Wifi State - Frost fetches the pages from Facebook's -mobile website. It also needs the network state so as to limit internet usage -when you are on a metered network. - -* Receive Boot Completed - Frost notifications persist on reboot, and need this -permission to be added each time. - -* Vibrate - Needed to vibrate phone for notifications; this can be toggled in -the settings - -* Billing - For purchasing pro and unlocking all of Frost's features - -Optional permissions used and why: ''(these are only requested when they have -to be, and are disabled until then)'' - -* Read/write external storage - Needed to upload photos in a new status and save -photos when prompted - -* Fine/coarse location - Needed for the check in option if users wish to search -for their location - -* That's it! No privacy intrusion and no extra demands. - -Permissions ''NOT'' used and why: - -* Wakelock - Frost takes advantage of Android's Job Scheduler, and lets the -framework decide when to run background services. Frost therefore doesn't need -to constantly run in the background, nor does it force your phone to stay awake. - -* Retrieve running apps - Frost has no need to access external apps or see what -else is running - -* Identity - Frost manages its accounts internally and uses it solely to give -you access to your account. We don't depend on other personal information and we -don't even save your email. - -* Camera - While the camera permission can be added to allow you to directly -take photos and upload them, we've decided that it would be best to allow you to -do so externally and then share the photo with Frost - -''Frost is a third party app and is in no way affiliated with Facebook Inc.'' \ No newline at end of file diff --git a/fastlane/metadata/android/en-CA/images/featureGraphic.png b/fastlane/metadata/android/en-CA/images/featureGraphic.png deleted file mode 100644 index c47aa1d9..00000000 Binary files a/fastlane/metadata/android/en-CA/images/featureGraphic.png and /dev/null differ diff --git a/fastlane/metadata/android/en-CA/images/phoneScreenshots/frost_1_themes.png b/fastlane/metadata/android/en-CA/images/phoneScreenshots/frost_1_themes.png deleted file mode 100644 index 6d579adf..00000000 Binary files a/fastlane/metadata/android/en-CA/images/phoneScreenshots/frost_1_themes.png and /dev/null differ diff --git a/fastlane/metadata/android/en-CA/images/phoneScreenshots/frost_2_glass.png b/fastlane/metadata/android/en-CA/images/phoneScreenshots/frost_2_glass.png deleted file mode 100644 index 4ee98308..00000000 Binary files a/fastlane/metadata/android/en-CA/images/phoneScreenshots/frost_2_glass.png and /dev/null differ diff --git a/fastlane/metadata/android/en-CA/images/phoneScreenshots/frost_3_multi_accounts.png b/fastlane/metadata/android/en-CA/images/phoneScreenshots/frost_3_multi_accounts.png deleted file mode 100644 index 11536dfe..00000000 Binary files a/fastlane/metadata/android/en-CA/images/phoneScreenshots/frost_3_multi_accounts.png and /dev/null differ diff --git a/fastlane/metadata/android/en-CA/images/phoneScreenshots/frost_4_pip.png b/fastlane/metadata/android/en-CA/images/phoneScreenshots/frost_4_pip.png deleted file mode 100644 index e2b5910b..00000000 Binary files a/fastlane/metadata/android/en-CA/images/phoneScreenshots/frost_4_pip.png and /dev/null differ diff --git a/fastlane/metadata/android/en-CA/images/phoneScreenshots/frost_5_swipe.png b/fastlane/metadata/android/en-CA/images/phoneScreenshots/frost_5_swipe.png deleted file mode 100644 index f5a7fb82..00000000 Binary files a/fastlane/metadata/android/en-CA/images/phoneScreenshots/frost_5_swipe.png and /dev/null differ diff --git a/fastlane/metadata/android/en-CA/images/phoneScreenshots/frost_6_quick_links.png b/fastlane/metadata/android/en-CA/images/phoneScreenshots/frost_6_quick_links.png deleted file mode 100644 index bd42e92b..00000000 Binary files a/fastlane/metadata/android/en-CA/images/phoneScreenshots/frost_6_quick_links.png and /dev/null differ diff --git a/fastlane/metadata/android/en-CA/short_description.txt b/fastlane/metadata/android/en-CA/short_description.txt deleted file mode 100644 index 5fd6d401..00000000 --- a/fastlane/metadata/android/en-CA/short_description.txt +++ /dev/null @@ -1 +0,0 @@ -Facebook Web Wrapper \ No newline at end of file diff --git a/fastlane/metadata/android/en-CA/title.txt b/fastlane/metadata/android/en-CA/title.txt deleted file mode 100644 index a933d845..00000000 --- a/fastlane/metadata/android/en-CA/title.txt +++ /dev/null @@ -1 +0,0 @@ -Frost for Facebook \ No newline at end of file -- cgit v1.2.3 From 9a40780c3baffcef381e4575f7c28b4b5fb4a56b Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Sun, 23 Dec 2018 20:16:20 -0500 Subject: Add composer to css --- app/src/main/assets/css/core/_core_bg.scss | 2 +- app/src/main/assets/css/themes/custom.css | 2 +- app/src/main/assets/css/themes/material_amoled.css | 2 +- app/src/main/assets/css/themes/material_dark.css | 2 +- app/src/main/assets/css/themes/material_glass.css | 2 +- app/src/main/assets/css/themes/material_light.css | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) (limited to 'app') diff --git a/app/src/main/assets/css/core/_core_bg.scss b/app/src/main/assets/css/core/_core_bg.scss index 75e0b521..eba4cd10 100644 --- a/app/src/main/assets/css/core/_core_bg.scss +++ b/app/src/main/assets/css/core/_core_bg.scss @@ -2,7 +2,7 @@ background: $background !important; } -body, :root, #root, #header, [style*="background-color"], ._1upc, input, ._2f9r, ._59e9, ._5pz4, ._5lp4, +body, :root, #root, #header, #MComposer, [style*="background-color"], ._1upc, input, ._2f9r, ._59e9, ._5pz4, ._5lp4, ._5lp5, .container, .subpage, ._5n_f, #static_templates, ._22_8, ._1t4h, ._uoq, ._3qdh, ._8ca, ._3h8i, ._6-l ._2us7, ._6-l ._6-p, ._333v, div.sharerSelector, ._529j, ._305j, ._1pph, ._3t_l, ._4pvz, ._1g05, .acy, ._51-g, ._533c, ._ib-, .sharerAttachmentEmpty, .sharerBottomWrapper, ._24e1, ._-j7, diff --git a/app/src/main/assets/css/themes/custom.css b/app/src/main/assets/css/themes/custom.css index df1a3908..a64e964f 100644 --- a/app/src/main/assets/css/themes/custom.css +++ b/app/src/main/assets/css/themes/custom.css @@ -40,7 +40,7 @@ a, background: $B$ !important; } -body, :root, #root, #header, [style*=background-color], ._1upc, input, ._2f9r, ._59e9, ._5pz4, ._5lp4, +body, :root, #root, #header, #MComposer, [style*=background-color], ._1upc, input, ._2f9r, ._59e9, ._5pz4, ._5lp4, ._5lp5, .container, .subpage, ._5n_f, #static_templates, ._22_8, ._1t4h, ._uoq, ._3qdh, ._8ca, ._3h8i, ._6-l ._2us7, ._6-l ._6-p, ._333v, div.sharerSelector, ._529j, ._305j, ._1pph, ._3t_l, ._4pvz, ._1g05, .acy, ._51-g, ._533c, ._ib-, .sharerAttachmentEmpty, .sharerBottomWrapper, ._24e1, ._-j7, diff --git a/app/src/main/assets/css/themes/material_amoled.css b/app/src/main/assets/css/themes/material_amoled.css index 78bd119b..d4cf8233 100644 --- a/app/src/main/assets/css/themes/material_amoled.css +++ b/app/src/main/assets/css/themes/material_amoled.css @@ -40,7 +40,7 @@ a, background: #000 !important; } -body, :root, #root, #header, [style*=background-color], ._1upc, input, ._2f9r, ._59e9, ._5pz4, ._5lp4, +body, :root, #root, #header, #MComposer, [style*=background-color], ._1upc, input, ._2f9r, ._59e9, ._5pz4, ._5lp4, ._5lp5, .container, .subpage, ._5n_f, #static_templates, ._22_8, ._1t4h, ._uoq, ._3qdh, ._8ca, ._3h8i, ._6-l ._2us7, ._6-l ._6-p, ._333v, div.sharerSelector, ._529j, ._305j, ._1pph, ._3t_l, ._4pvz, ._1g05, .acy, ._51-g, ._533c, ._ib-, .sharerAttachmentEmpty, .sharerBottomWrapper, ._24e1, ._-j7, diff --git a/app/src/main/assets/css/themes/material_dark.css b/app/src/main/assets/css/themes/material_dark.css index 179bec1a..e13f5600 100644 --- a/app/src/main/assets/css/themes/material_dark.css +++ b/app/src/main/assets/css/themes/material_dark.css @@ -40,7 +40,7 @@ a, background: #303030 !important; } -body, :root, #root, #header, [style*=background-color], ._1upc, input, ._2f9r, ._59e9, ._5pz4, ._5lp4, +body, :root, #root, #header, #MComposer, [style*=background-color], ._1upc, input, ._2f9r, ._59e9, ._5pz4, ._5lp4, ._5lp5, .container, .subpage, ._5n_f, #static_templates, ._22_8, ._1t4h, ._uoq, ._3qdh, ._8ca, ._3h8i, ._6-l ._2us7, ._6-l ._6-p, ._333v, div.sharerSelector, ._529j, ._305j, ._1pph, ._3t_l, ._4pvz, ._1g05, .acy, ._51-g, ._533c, ._ib-, .sharerAttachmentEmpty, .sharerBottomWrapper, ._24e1, ._-j7, diff --git a/app/src/main/assets/css/themes/material_glass.css b/app/src/main/assets/css/themes/material_glass.css index ad50e494..0d4cb726 100644 --- a/app/src/main/assets/css/themes/material_glass.css +++ b/app/src/main/assets/css/themes/material_glass.css @@ -40,7 +40,7 @@ a, background: rgba(0, 0, 0, 0.1) !important; } -body, :root, #root, #header, [style*=background-color], ._1upc, input, ._2f9r, ._59e9, ._5pz4, ._5lp4, +body, :root, #root, #header, #MComposer, [style*=background-color], ._1upc, input, ._2f9r, ._59e9, ._5pz4, ._5lp4, ._5lp5, .container, .subpage, ._5n_f, #static_templates, ._22_8, ._1t4h, ._uoq, ._3qdh, ._8ca, ._3h8i, ._6-l ._2us7, ._6-l ._6-p, ._333v, div.sharerSelector, ._529j, ._305j, ._1pph, ._3t_l, ._4pvz, ._1g05, .acy, ._51-g, ._533c, ._ib-, .sharerAttachmentEmpty, .sharerBottomWrapper, ._24e1, ._-j7, diff --git a/app/src/main/assets/css/themes/material_light.css b/app/src/main/assets/css/themes/material_light.css index cbc3002c..f3c6cc92 100644 --- a/app/src/main/assets/css/themes/material_light.css +++ b/app/src/main/assets/css/themes/material_light.css @@ -40,7 +40,7 @@ a, background: #fafafa !important; } -body, :root, #root, #header, [style*=background-color], ._1upc, input, ._2f9r, ._59e9, ._5pz4, ._5lp4, +body, :root, #root, #header, #MComposer, [style*=background-color], ._1upc, input, ._2f9r, ._59e9, ._5pz4, ._5lp4, ._5lp5, .container, .subpage, ._5n_f, #static_templates, ._22_8, ._1t4h, ._uoq, ._3qdh, ._8ca, ._3h8i, ._6-l ._2us7, ._6-l ._6-p, ._333v, div.sharerSelector, ._529j, ._305j, ._1pph, ._3t_l, ._4pvz, ._1g05, .acy, ._51-g, ._533c, ._ib-, .sharerAttachmentEmpty, .sharerBottomWrapper, ._24e1, ._-j7, -- cgit v1.2.3 From c45b30e28f451699f3be828a1201260ed27e321e Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Mon, 24 Dec 2018 00:21:21 -0500 Subject: Update/bindview (#1258) * Update bindview for FrostVideoViewer * Remove more bindview usages * Fix compilation problems * Remove custom drawer header --- .../frost/activities/BaseMainActivity.kt | 1 - .../pitchedapps/frost/activities/DebugActivity.kt | 34 +++--- .../frost/activities/TabCustomizerActivity.kt | 41 ++++--- .../pitchedapps/frost/intro/IntroFragmentTheme.kt | 19 ++-- .../com/pitchedapps/frost/views/BadgedIcon.kt | 24 ++--- .../pitchedapps/frost/views/FrostVideoViewer.kt | 43 +++----- app/src/main/res/layout/material_drawer_header.xml | 119 --------------------- app/src/main/res/layout/view_account.xml | 2 +- build.gradle | 1 + gradle.properties | 4 +- 10 files changed, 69 insertions(+), 219 deletions(-) delete mode 100644 app/src/main/res/layout/material_drawer_header.xml (limited to 'app') diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt index 52f61bea..8f6bbacb 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt @@ -185,7 +185,6 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract, translucentStatusBar = false sliderBackgroundColor = navBg drawerHeader = accountHeader { - customViewRes = R.layout.material_drawer_header textColor = Prefs.iconColor.toLong() backgroundDrawable = ColorDrawable(navHeader) selectionSecondLineShown = false diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/DebugActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/DebugActivity.kt index 9a90f090..3acbf7b3 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/DebugActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/DebugActivity.kt @@ -5,25 +5,22 @@ import android.content.Context import android.content.Intent import android.content.res.ColorStateList import android.os.Bundle -import com.google.android.material.floatingactionbutton.FloatingActionButton -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout -import androidx.appcompat.widget.Toolbar import ca.allanwang.kau.internal.KauBaseActivity -import ca.allanwang.kau.utils.bindView import ca.allanwang.kau.utils.setIcon import ca.allanwang.kau.utils.visible import com.mikepenz.google_material_typeface_library.GoogleMaterial -import com.pitchedapps.frost.R import com.pitchedapps.frost.facebook.FbItem import com.pitchedapps.frost.injectors.JsActions +import com.pitchedapps.frost.R import com.pitchedapps.frost.utils.L import com.pitchedapps.frost.utils.Prefs import com.pitchedapps.frost.utils.createFreshDir import com.pitchedapps.frost.utils.setFrostColors -import com.pitchedapps.frost.web.DebugWebView import io.reactivex.Single import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.schedulers.Schedulers +import kotlinx.android.synthetic.main.activity_debug.* +import kotlinx.android.synthetic.main.view_main_fab.* import java.io.File /** @@ -31,11 +28,6 @@ import java.io.File */ class DebugActivity : KauBaseActivity() { - private val toolbar: Toolbar by bindView(R.id.toolbar) - private val web: DebugWebView by bindView(R.id.debug_webview) - private val swipeRefresh: SwipeRefreshLayout by bindView(R.id.swipe_refresh) - private val fab: FloatingActionButton by bindView(R.id.fab) - companion object { const val RESULT_URL = "extra_result_url" const val RESULT_SCREENSHOT = "extra_result_screenshot" @@ -56,10 +48,10 @@ class DebugActivity : KauBaseActivity() { setFrostColors { toolbar(toolbar) } - web.loadUrl(FbItem.FEED.url) - web.onPageFinished = { swipeRefresh.isRefreshing = false } + debug_webview.loadUrl(FbItem.FEED.url) + debug_webview.onPageFinished = { swipe_refresh.isRefreshing = false } - swipeRefresh.setOnRefreshListener(web::reload) + swipe_refresh.setOnRefreshListener(debug_webview::reload) fab.visible().setIcon(GoogleMaterial.Icon.gmd_bug_report, Prefs.iconColor) fab.backgroundTintList = ColorStateList.valueOf(Prefs.accentColor) @@ -69,10 +61,10 @@ class DebugActivity : KauBaseActivity() { val parent = baseDir(this) parent.createFreshDir() val rxScreenshot = Single.fromCallable { - web.getScreenshot(File(parent, "screenshot.png")) + debug_webview.getScreenshot(File(parent, "screenshot.png")) }.subscribeOn(Schedulers.io()) val rxBody = Single.create { emitter -> - web.evaluateJavascript(JsActions.RETURN_BODY.function) { + debug_webview.evaluateJavascript(JsActions.RETURN_BODY.function) { emitter.onSuccess(it) } }.subscribeOn(AndroidSchedulers.mainThread()) @@ -89,7 +81,7 @@ class DebugActivity : KauBaseActivity() { return@subscribe } val intent = Intent() - intent.putExtra(RESULT_URL, web.url) + intent.putExtra(RESULT_URL, debug_webview.url) intent.putExtra(RESULT_SCREENSHOT, screenshot) if (body != null) intent.putExtra(RESULT_BODY, body) @@ -107,17 +99,17 @@ class DebugActivity : KauBaseActivity() { override fun onResume() { super.onResume() - web.resumeTimers() + debug_webview.resumeTimers() } override fun onPause() { - web.pauseTimers() + debug_webview.pauseTimers() super.onPause() } override fun onBackPressed() { - if (web.canGoBack()) - web.goBack() + if (debug_webview.canGoBack()) + debug_webview.goBack() else super.onBackPressed() } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/TabCustomizerActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/TabCustomizerActivity.kt index 1938add0..6222d98f 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/TabCustomizerActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/TabCustomizerActivity.kt @@ -3,23 +3,23 @@ package com.pitchedapps.frost.activities import android.app.Activity import android.content.res.ColorStateList import android.os.Bundle -import com.google.android.material.floatingactionbutton.FloatingActionButton -import androidx.recyclerview.widget.GridLayoutManager -import androidx.recyclerview.widget.RecyclerView -import androidx.recyclerview.widget.ItemTouchHelper import android.view.View import android.view.animation.AnimationUtils import android.widget.TextView +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.ItemTouchHelper +import androidx.recyclerview.widget.RecyclerView import ca.allanwang.kau.kotlin.lazyContext import ca.allanwang.kau.utils.bindView import ca.allanwang.kau.utils.scaleXY import ca.allanwang.kau.utils.setIcon +import com.pitchedapps.frost.R import ca.allanwang.kau.utils.withAlpha +import com.google.android.material.floatingactionbutton.FloatingActionButton import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter import com.mikepenz.fastadapter_extensions.drag.ItemTouchCallback import com.mikepenz.fastadapter_extensions.drag.SimpleDragCallback import com.mikepenz.google_material_typeface_library.GoogleMaterial -import com.pitchedapps.frost.R import com.pitchedapps.frost.dbflow.TAB_COUNT import com.pitchedapps.frost.dbflow.loadFbTabs import com.pitchedapps.frost.dbflow.save @@ -27,6 +27,7 @@ import com.pitchedapps.frost.facebook.FbItem import com.pitchedapps.frost.iitems.TabIItem import com.pitchedapps.frost.utils.Prefs import com.pitchedapps.frost.utils.setFrostColors +import kotlinx.android.synthetic.main.activity_tab_customizer.* import java.util.* /** @@ -34,13 +35,7 @@ import java.util.* */ class TabCustomizerActivity : BaseActivity() { - val toolbar: View by bindView(R.id.pseudo_toolbar) - val recycler: RecyclerView by bindView(R.id.tab_recycler) - val instructions: TextView by bindView(R.id.instructions) - val divider: View by bindView(R.id.divider) - val adapter = FastItemAdapter() - val fabCancel: FloatingActionButton by bindView(R.id.fab_cancel) - val fabSave: FloatingActionButton by bindView(R.id.fab_save) + private val adapter = FastItemAdapter() private val wobble = lazyContext { AnimationUtils.loadAnimation(it, R.anim.rotate_delta) } @@ -48,11 +43,11 @@ class TabCustomizerActivity : BaseActivity() { super.onCreate(savedInstanceState) setContentView(R.layout.activity_tab_customizer) - toolbar.setBackgroundColor(Prefs.headerColor) + pseudo_toolbar.setBackgroundColor(Prefs.headerColor) - recycler.layoutManager = GridLayoutManager(this, TAB_COUNT, RecyclerView.VERTICAL, false) - recycler.adapter = adapter - recycler.setHasFixedSize(true) + tab_recycler.layoutManager = GridLayoutManager(this, TAB_COUNT, RecyclerView.VERTICAL, false) + tab_recycler.adapter = adapter + tab_recycler.setHasFixedSize(true) divider.setBackgroundColor(Prefs.textColor.withAlpha(30)) instructions.setTextColor(Prefs.textColor) @@ -63,22 +58,22 @@ class TabCustomizerActivity : BaseActivity() { tabs.addAll(remaining) adapter.add(tabs.map(::TabIItem)) - bindSwapper(adapter, recycler) + bindSwapper(adapter, tab_recycler) adapter.withOnClickListener { view, _, _, _ -> view!!.wobble(); true } setResult(Activity.RESULT_CANCELED) - fabSave.setIcon(GoogleMaterial.Icon.gmd_check, Prefs.iconColor) - fabSave.backgroundTintList = ColorStateList.valueOf(Prefs.accentColor) - fabSave.setOnClickListener { + fab_save.setIcon(GoogleMaterial.Icon.gmd_check, Prefs.iconColor) + fab_save.backgroundTintList = ColorStateList.valueOf(Prefs.accentColor) + fab_save.setOnClickListener { adapter.adapterItems.subList(0, TAB_COUNT).map(TabIItem::item).save() setResult(Activity.RESULT_OK) finish() } - fabCancel.setIcon(GoogleMaterial.Icon.gmd_close, Prefs.iconColor) - fabCancel.backgroundTintList = ColorStateList.valueOf(Prefs.accentColor) - fabCancel.setOnClickListener { finish() } + fab_cancel.setIcon(GoogleMaterial.Icon.gmd_close, Prefs.iconColor) + fab_cancel.backgroundTintList = ColorStateList.valueOf(Prefs.accentColor) + fab_cancel.setOnClickListener { finish() } setFrostColors { themeWindow = true } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroFragmentTheme.kt b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroFragmentTheme.kt index 42630d79..3e40b6ba 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroFragmentTheme.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroFragmentTheme.kt @@ -2,34 +2,29 @@ package com.pitchedapps.frost.intro import android.os.Bundle import android.view.View -import ca.allanwang.kau.utils.bindViewResettable import ca.allanwang.kau.utils.scaleXY import com.pitchedapps.frost.R import com.pitchedapps.frost.activities.IntroActivity import com.pitchedapps.frost.enums.Theme import com.pitchedapps.frost.utils.Prefs +import kotlinx.android.synthetic.main.intro_theme.* /** * Created by Allan Wang on 2017-07-28. */ class IntroFragmentTheme : BaseIntroFragment(R.layout.intro_theme) { - val light: View by bindViewResettable(R.id.intro_theme_light) - val dark: View by bindViewResettable(R.id.intro_theme_dark) - val amoled: View by bindViewResettable(R.id.intro_theme_amoled) - val glass: View by bindViewResettable(R.id.intro_theme_glass) - val themeList - get() = listOf(light, dark, amoled, glass) + get() = listOf(intro_theme_light, intro_theme_dark, intro_theme_amoled, intro_theme_glass) - override fun viewArray(): Array> = arrayOf(arrayOf(title), arrayOf(light, dark), arrayOf(amoled, glass)) + override fun viewArray(): Array> = arrayOf(arrayOf(title), arrayOf(intro_theme_light, intro_theme_dark), arrayOf(intro_theme_amoled, intro_theme_glass)) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - light.setThemeClick(Theme.LIGHT) - dark.setThemeClick(Theme.DARK) - amoled.setThemeClick(Theme.AMOLED) - glass.setThemeClick(Theme.GLASS) + intro_theme_light.setThemeClick(Theme.LIGHT) + intro_theme_dark.setThemeClick(Theme.DARK) + intro_theme_amoled.setThemeClick(Theme.AMOLED) + intro_theme_glass.setThemeClick(Theme.GLASS) val currentTheme = Prefs.theme - 1 if (currentTheme in 0..3) themeList.forEachIndexed { index, v -> v.scaleXY = if (index == currentTheme) 1.6f else 0.8f } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/BadgedIcon.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/BadgedIcon.kt index 92620567..8093c852 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/BadgedIcon.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/BadgedIcon.kt @@ -4,12 +4,11 @@ import android.content.Context import android.graphics.drawable.GradientDrawable import androidx.constraintlayout.widget.ConstraintLayout import android.util.AttributeSet -import android.widget.ImageView -import android.widget.TextView import ca.allanwang.kau.utils.* import com.mikepenz.iconics.typeface.IIcon import com.pitchedapps.frost.R import com.pitchedapps.frost.utils.Prefs +import kotlinx.android.synthetic.main.view_badged_icon.view.* /** @@ -19,36 +18,33 @@ class BadgedIcon @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : ConstraintLayout(context, attrs, defStyleAttr) { - val badgeTextView: TextView by bindView(R.id.badge_text) - val badgeImage: ImageView by bindView(R.id.badge_image) - init { inflate(context, R.layout.view_badged_icon, this) val badgeColor = Prefs.mainActivityLayout.backgroundColor().withAlpha(255).colorToForeground(0.2f) val badgeBackground = GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP, intArrayOf(badgeColor, badgeColor)) badgeBackground.cornerRadius = 13.dpToPx.toFloat() - badgeTextView.background = badgeBackground - badgeTextView.setTextColor(Prefs.mainActivityLayout.iconColor()) + badge_text.background = badgeBackground + badge_text.setTextColor(Prefs.mainActivityLayout.iconColor()) } var iicon: IIcon? = null set(value) { field = value - badgeImage.setImageDrawable(value?.toDrawable(context, sizeDp = 20, color = Prefs.mainActivityLayout.iconColor())) + badge_image.setImageDrawable(value?.toDrawable(context, sizeDp = 20, color = Prefs.mainActivityLayout.iconColor())) } fun setAllAlpha(alpha: Float) { //badgeTextView.setTextColor(Prefs.textColor.withAlpha(alpha.toInt())) - badgeImage.drawable.alpha = alpha.toInt() + badge_image.drawable.alpha = alpha.toInt() } var badgeText: String? - get() = badgeTextView.text.toString() + get() = badge_text.text.toString() set(value) { - if (badgeTextView.text == value) return - badgeTextView.text = value - if (value != null && value != "0") badgeTextView.visible() - else badgeTextView.gone() + if (badge_text.text == value) return + badge_text.text = value + if (value != null && value != "0") badge_text.visible() + else badge_text.gone() } } \ No newline at end of file diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoViewer.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoViewer.kt index 5afb3a21..b2796999 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoViewer.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoViewer.kt @@ -4,21 +4,18 @@ import android.content.Context import android.graphics.Color import android.graphics.PointF import android.net.Uri -import androidx.appcompat.widget.Toolbar import android.util.AttributeSet import android.view.MotionEvent -import android.view.View -import android.view.ViewGroup import android.view.ViewTreeObserver import android.widget.FrameLayout -import android.widget.ImageView import ca.allanwang.kau.utils.* import com.devbrackets.android.exomedia.listener.VideoControlsVisibilityListener import com.mikepenz.google_material_typeface_library.GoogleMaterial -import com.pitchedapps.frost.R import com.pitchedapps.frost.utils.L +import com.pitchedapps.frost.R import com.pitchedapps.frost.utils.Prefs import com.pitchedapps.frost.utils.frostDownload +import kotlinx.android.synthetic.main.view_video.view.* /** * Created by Allan Wang on 2017-10-13. @@ -27,12 +24,6 @@ class FrostVideoViewer @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : FrameLayout(context, attrs, defStyleAttr), FrostVideoViewerContract { - val container: ViewGroup by bindView(R.id.video_container) - val toolbar: Toolbar by bindView(R.id.video_toolbar) - val background: View by bindView(R.id.video_background) - val video: FrostVideoView by bindView(R.id.video) - val restarter: ImageView by bindView(R.id.video_restart) - companion object { /** * Matches VideoControls.CONTROL_VISIBILITY_ANIMATION_LENGTH @@ -59,29 +50,29 @@ class FrostVideoViewer @JvmOverloads constructor( init { inflate(R.layout.view_video, true) alpha = 0f - background.setBackgroundColor( + video_background.setBackgroundColor( if (!Prefs.blackMediaBg && Prefs.bgColor.isColorDark) Prefs.bgColor.withMinAlpha(200) else Color.BLACK) video.setViewerContract(this) video.pause() - toolbar.inflateMenu(R.menu.menu_video) - context.setMenuIcons(toolbar.menu, Prefs.iconColor, + video_toolbar.inflateMenu(R.menu.menu_video) + context.setMenuIcons(video_toolbar.menu, Prefs.iconColor, R.id.action_pip to GoogleMaterial.Icon.gmd_picture_in_picture_alt, R.id.action_download to GoogleMaterial.Icon.gmd_file_download ) - toolbar.setOnMenuItemClickListener { + video_toolbar.setOnMenuItemClickListener { when (it.itemId) { R.id.action_pip -> video.isExpanded = false R.id.action_download -> context.frostDownload(video.videoUri) } true } - restarter.gone().setIcon(GoogleMaterial.Icon.gmd_replay, 64) - restarter.setOnClickListener { + video_restart.gone().setIcon(GoogleMaterial.Icon.gmd_replay, 64) + video_restart.setOnClickListener { video.restart() - restarter.fadeOut { restarter.gone() } + video_restart.fadeOut { video_restart.gone() } } } @@ -115,13 +106,13 @@ class FrostVideoViewer @JvmOverloads constructor( */ override fun onExpand(progress: Float) { - toolbar.goneIf(progress == 0f).alpha = progress - background.alpha = progress + video_toolbar.goneIf(progress == 0f).alpha = progress + video_background.alpha = progress } override fun onSingleTapConfirmed(event: MotionEvent): Boolean { - if (restarter.isVisible) { - restarter.performClick() + if (video_restart.isVisible) { + video_restart.performClick() return true } return false @@ -129,7 +120,7 @@ class FrostVideoViewer @JvmOverloads constructor( override fun onVideoComplete() { video.jumpToStart() - restarter.fadeIn() + video_restart.fadeIn() } fun updateLocation() { @@ -143,12 +134,12 @@ class FrostVideoViewer @JvmOverloads constructor( override fun onControlsShown() { if (video.isExpanded) - toolbar.fadeIn(duration = CONTROL_ANIMATION_DURATION, onStart = { toolbar.visible() }) + video_toolbar.fadeIn(duration = CONTROL_ANIMATION_DURATION, onStart = { video_toolbar.visible() }) } override fun onControlsHidden() { - if (!toolbar.isGone) - toolbar.fadeOut(duration = CONTROL_ANIMATION_DURATION) { toolbar.gone() } + if (!video_toolbar.isGone) + video_toolbar.fadeOut(duration = CONTROL_ANIMATION_DURATION) { video_toolbar.gone() } } } diff --git a/app/src/main/res/layout/material_drawer_header.xml b/app/src/main/res/layout/material_drawer_header.xml deleted file mode 100644 index 085a1870..00000000 --- a/app/src/main/res/layout/material_drawer_header.xml +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/view_account.xml b/app/src/main/res/layout/view_account.xml index de8ee0a2..1c7eea66 100644 --- a/app/src/main/res/layout/view_account.xml +++ b/app/src/main/res/layout/view_account.xml @@ -10,7 +10,7 @@ android:layout_width="@dimen/account_image_size" android:layout_height="@dimen/account_image_size" /> - diff --git a/build.gradle b/build.gradle index a163b512..ef1dc448 100644 --- a/build.gradle +++ b/build.gradle @@ -8,6 +8,7 @@ buildscript { dependencies { classpath "ca.allanwang:kau:${KAU}" + classpath 'com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta02' classpath "com.android.tools.build:gradle:${ANDROID_GRADLE}" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${KOTLIN}" classpath "com.bugsnag:bugsnag-android-gradle-plugin:${BUGSNAG_PLUGIN}" diff --git a/gradle.properties b/gradle.properties index 6728eb08..f708598c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,11 +14,11 @@ org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryErro APP_ID=Frost APP_GROUP=com.pitchedapps -KAU=0d24880 +KAU=b4a2ded KOTLIN=1.3.11 # https://mvnrepository.com/artifact/com.android.tools.build/gradle?repo=google -ANDROID_GRADLE=3.3.0-rc02 +ANDROID_GRADLE=3.2.1 # https://github.com/bugsnag/bugsnag-android/releases BUGSNAG=4.9.3 -- cgit v1.2.3 From 697d01882ba8b1dbb85484ba3bf6e810e32448fc Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Mon, 24 Dec 2018 01:47:03 -0500 Subject: Enhancement/ktlint (#1259) * Add spotless * Reformat code * Apply license header * Add remaining license headers --- app/build.gradle | 2 + .../main/kotlin/com/pitchedapps/frost/FrostApp.kt | 53 ++++-- .../kotlin/com/pitchedapps/frost/StartActivity.kt | 31 +++- .../pitchedapps/frost/activities/AboutActivity.kt | 84 ++++++--- .../pitchedapps/frost/activities/BaseActivity.kt | 19 +- .../frost/activities/BaseMainActivity.kt | 148 +++++++++++----- .../pitchedapps/frost/activities/DebugActivity.kt | 47 +++-- .../pitchedapps/frost/activities/ImageActivity.kt | 84 +++++++-- .../pitchedapps/frost/activities/IntroActivity.kt | 76 +++++--- .../pitchedapps/frost/activities/LoginActivity.kt | 120 ++++++++----- .../pitchedapps/frost/activities/MainActivity.kt | 76 ++++---- .../frost/activities/SelectorActivity.kt | 22 ++- .../frost/activities/SettingsActivity.kt | 54 +++++- .../frost/activities/TabCustomizerActivity.kt | 29 ++- .../frost/activities/WebOverlayActivity.kt | 82 +++++++-- .../frost/contracts/ActivityContract.kt | 18 +- .../frost/contracts/DynamicUiContract.kt | 20 ++- .../com/pitchedapps/frost/contracts/FileChooser.kt | 35 +++- .../frost/contracts/FrostContentContract.kt | 21 ++- .../frost/contracts/FrostObservables.kt | 19 +- .../pitchedapps/frost/contracts/FrostThemable.kt | 25 ++- .../pitchedapps/frost/contracts/VideoViewHolder.kt | 17 +- .../com/pitchedapps/frost/dbflow/CookiesDb.kt | 79 ++++++--- .../kotlin/com/pitchedapps/frost/dbflow/DbUtils.kt | 19 +- .../com/pitchedapps/frost/dbflow/FbTabsDb.kt | 18 +- .../com/pitchedapps/frost/dbflow/NotificationDb.kt | 45 ++++- .../pitchedapps/frost/debugger/OfflineWebsite.kt | 65 ++++--- .../kotlin/com/pitchedapps/frost/enums/FeedSort.kt | 18 +- .../pitchedapps/frost/enums/MainActivityLayout.kt | 39 ++-- .../com/pitchedapps/frost/enums/OverlayContext.kt | 25 ++- .../kotlin/com/pitchedapps/frost/enums/Support.kt | 18 +- .../kotlin/com/pitchedapps/frost/enums/Theme.kt | 106 ++++++----- .../com/pitchedapps/frost/facebook/FbConst.kt | 27 ++- .../com/pitchedapps/frost/facebook/FbCookie.kt | 32 +++- .../com/pitchedapps/frost/facebook/FbItem.kt | 24 ++- .../com/pitchedapps/frost/facebook/FbRegex.kt | 17 +- .../pitchedapps/frost/facebook/FbUrlFormatter.kt | 46 +++-- .../frost/facebook/parsers/FrostParser.kt | 29 ++- .../frost/facebook/parsers/MessageParser.kt | 98 +++++++---- .../frost/facebook/parsers/NotifParser.kt | 94 ++++++---- .../frost/facebook/parsers/SearchParser.kt | 37 ++-- .../frost/facebook/requests/FbRequest.kt | 61 +++++-- .../pitchedapps/frost/facebook/requests/Images.kt | 49 ++++-- .../pitchedapps/frost/facebook/requests/Menu.kt | 137 ++++++++------ .../frost/facebook/requests/Messages.kt | 26 ++- .../frost/facebook/requests/Notifications.kt | 32 +++- .../pitchedapps/frost/fragments/FragmentBase.kt | 93 ++++++---- .../frost/fragments/FragmentContract.kt | 27 ++- .../frost/fragments/RecyclerFragmentBase.kt | 17 +- .../frost/fragments/RecyclerFragments.kt | 34 +++- .../pitchedapps/frost/fragments/WebFragments.kt | 18 +- .../com/pitchedapps/frost/glide/GlideUtils.kt | 30 +++- .../frost/glide/RoundCornerTransformation.kt | 36 +++- .../com/pitchedapps/frost/iitems/GenericIItems.kt | 53 ++++-- .../com/pitchedapps/frost/iitems/MenuIItem.kt | 41 +++-- .../pitchedapps/frost/iitems/NotificationIItem.kt | 62 +++++-- .../com/pitchedapps/frost/iitems/TabIItem.kt | 29 ++- .../com/pitchedapps/frost/injectors/CssAssets.kt | 48 +++-- .../com/pitchedapps/frost/injectors/CssHider.kt | 33 +++- .../com/pitchedapps/frost/injectors/JsActions.kt | 21 ++- .../com/pitchedapps/frost/injectors/JsAssets.kt | 19 +- .../com/pitchedapps/frost/injectors/JsInjector.kt | 34 +++- .../pitchedapps/frost/intro/IntroFragmentTheme.kt | 25 ++- .../pitchedapps/frost/intro/IntroImageFragments.kt | 52 ++++-- .../pitchedapps/frost/intro/IntroMainFragments.kt | 23 ++- .../kotlin/com/pitchedapps/frost/rx/RxFlyweight.kt | 25 ++- .../frost/services/FrostNotifications.kt | 196 ++++++++++++--------- .../frost/services/FrostRequestService.kt | 50 ++++-- .../frost/services/NotificationService.kt | 55 ++++-- .../frost/services/NotificationUtils.kt | 69 +++++--- .../pitchedapps/frost/services/UpdateReceiver.kt | 19 +- .../com/pitchedapps/frost/settings/Appearance.kt | 41 ++++- .../com/pitchedapps/frost/settings/Behaviour.kt | 22 ++- .../kotlin/com/pitchedapps/frost/settings/Debug.kt | 40 +++-- .../com/pitchedapps/frost/settings/Experimental.kt | 19 +- .../kotlin/com/pitchedapps/frost/settings/Feed.kt | 18 +- .../com/pitchedapps/frost/settings/Network.kt | 24 ++- .../pitchedapps/frost/settings/Notifications.kt | 72 +++++--- .../com/pitchedapps/frost/utils/AdBlocker.kt | 18 +- .../frost/utils/AnimatedVectorDelegate.kt | 62 ++++--- .../com/pitchedapps/frost/utils/BuildUtils.kt | 21 ++- .../kotlin/com/pitchedapps/frost/utils/Const.kt | 18 +- .../com/pitchedapps/frost/utils/Downloader.kt | 43 +++-- .../com/pitchedapps/frost/utils/EnumUtils.kt | 25 ++- .../com/pitchedapps/frost/utils/JsoupCleaner.kt | 22 ++- .../main/kotlin/com/pitchedapps/frost/utils/L.kt | 20 ++- .../kotlin/com/pitchedapps/frost/utils/Prefs.kt | 20 ++- .../kotlin/com/pitchedapps/frost/utils/Showcase.kt | 17 +- .../kotlin/com/pitchedapps/frost/utils/Utils.kt | 143 ++++++++++----- .../com/pitchedapps/frost/utils/WebContextMenu.kt | 22 ++- .../com/pitchedapps/frost/views/AccountItem.kt | 69 ++++++-- .../com/pitchedapps/frost/views/BadgedIcon.kt | 44 ++++- .../pitchedapps/frost/views/FrostContentView.kt | 91 ++++++---- .../pitchedapps/frost/views/FrostRecyclerView.kt | 29 ++- .../com/pitchedapps/frost/views/FrostVideoView.kt | 37 +++- .../pitchedapps/frost/views/FrostVideoViewer.kt | 54 ++++-- .../com/pitchedapps/frost/views/FrostViewPager.kt | 43 +++-- .../com/pitchedapps/frost/views/FrostWebView.kt | 31 +++- .../pitchedapps/frost/views/KPrefTextSeekbar.kt | 18 +- .../kotlin/com/pitchedapps/frost/views/Keywords.kt | 35 +++- .../com/pitchedapps/frost/web/DebugWebView.kt | 48 +++-- .../pitchedapps/frost/web/FrostChromeClients.kt | 35 +++- .../kotlin/com/pitchedapps/frost/web/FrostJSI.kt | 44 +++-- .../frost/web/FrostRequestInterceptor.kt | 34 +++- .../frost/web/FrostUrlOverlayValidator.kt | 38 +++- .../pitchedapps/frost/web/FrostWebViewClients.kt | 84 ++++++--- .../com/pitchedapps/frost/web/LoginWebView.kt | 36 +++- .../com/pitchedapps/frost/web/NestedWebView.kt | 46 +++-- .../test/kotlin/com/pitchedapps/frost/MiscTest.kt | 32 +++- .../frost/debugger/OfflineWebsiteTest.kt | 27 ++- .../com/pitchedapps/frost/facebook/FbDomTest.kt | 19 +- .../com/pitchedapps/frost/facebook/FbRegexTest.kt | 22 ++- .../com/pitchedapps/frost/facebook/FbUrlTest.kt | 38 ++-- .../frost/facebook/parsers/FbParseTest.kt | 22 ++- .../frost/facebook/requests/FbFullImageTest.kt | 18 +- .../frost/facebook/requests/FbRequestTest.kt | 22 ++- .../pitchedapps/frost/injectors/InjectorTest.kt | 16 ++ .../com/pitchedapps/frost/internal/Internal.kt | 20 ++- .../frost/rx/ResettableFlyweightTest.kt | 20 ++- .../com/pitchedapps/frost/utils/BuildUtilsTest.kt | 18 +- .../pitchedapps/frost/utils/JsoupCleanerTest.kt | 24 ++- .../com/pitchedapps/frost/utils/PrefsTest.kt | 18 +- .../frost/utils/StringEscapeUtilsTest.kt | 18 +- .../kotlin/com/pitchedapps/frost/utils/UrlTests.kt | 44 +++-- build.gradle | 1 + gradle.properties | 3 + spotless.gradle | 11 ++ spotless.license.kt | 16 ++ 128 files changed, 3870 insertions(+), 1354 deletions(-) create mode 100644 spotless.gradle create mode 100644 spotless.license.kt (limited to 'app') diff --git a/app/build.gradle b/app/build.gradle index 2c7c5bcc..1b8feda7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,6 +6,8 @@ apply plugin: 'kotlin-kapt' apply plugin: 'com.getkeepsafe.dexcount' apply plugin: 'com.gladed.androidgitversion' +apply from: '../spotless.gradle' + android { compileSdkVersion kau.targetSdk buildToolsVersion kau.buildTools diff --git a/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt b/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt index c566aa05..7f3d6b62 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost import android.app.Activity @@ -21,7 +37,11 @@ import com.pitchedapps.frost.facebook.FbCookie import com.pitchedapps.frost.glide.GlideApp import com.pitchedapps.frost.services.scheduleNotifications import com.pitchedapps.frost.services.setupNotificationChannels -import com.pitchedapps.frost.utils.* +import com.pitchedapps.frost.utils.BuildUtils +import com.pitchedapps.frost.utils.FrostPglAdBlock +import com.pitchedapps.frost.utils.L +import com.pitchedapps.frost.utils.Prefs +import com.pitchedapps.frost.utils.Showcase import com.raizlabs.android.dbflow.config.DatabaseConfig import com.raizlabs.android.dbflow.config.FlowConfig import com.raizlabs.android.dbflow.config.FlowManager @@ -30,10 +50,9 @@ import io.reactivex.exceptions.UndeliverableException import io.reactivex.plugins.RxJavaPlugins import java.net.SocketTimeoutException import java.net.UnknownHostException -import java.util.* +import java.util.Random import kotlin.reflect.KClass - /** * Created by Allan Wang on 2017-05-28. */ @@ -46,10 +65,12 @@ class FrostApp : Application() { // lateinit var refWatcher: RefWatcher private fun FlowConfig.Builder.withDatabase(name: String, klass: KClass<*>) = - addDatabaseConfig(DatabaseConfig.builder(klass.java) - .databaseName(name) - .modelNotifier(ContentResolverNotifier("${BuildConfig.APPLICATION_ID}.dbflow.provider")) - .build()) + addDatabaseConfig( + DatabaseConfig.builder(klass.java) + .databaseName(name) + .modelNotifier(ContentResolverNotifier("${BuildConfig.APPLICATION_ID}.dbflow.provider")) + .build() + ) override fun onCreate() { if (!buildIsLollipopAndUp) { // not supported @@ -57,11 +78,13 @@ class FrostApp : Application() { return } - FlowManager.init(FlowConfig.Builder(this) + FlowManager.init( + FlowConfig.Builder(this) .withDatabase(CookiesDb.NAME, CookiesDb::class) .withDatabase(FbTabsDb.NAME, FbTabsDb::class) .withDatabase(NotificationDb.NAME, NotificationDb::class) - .build()) + .build() + ) Showcase.initialize(this, "${BuildConfig.APPLICATION_ID}.showcase") Prefs.initialize(this, "${BuildConfig.APPLICATION_ID}.prefs") // if (LeakCanary.isInAnalyzerProcess(this)) return @@ -95,9 +118,11 @@ class FrostApp : Application() { val c = imageView.context val request = GlideApp.with(c) val old = request.load(uri).apply(RequestOptions().placeholder(placeholder)) - request.load(uri).apply(RequestOptions() - .signature(ApplicationVersionSignature.obtain(c))) - .thumbnail(old).into(imageView) + request.load(uri).apply( + RequestOptions() + .signature(ApplicationVersionSignature.obtain(c)) + ) + .thumbnail(old).into(imageView) } }) if (BuildConfig.DEBUG) @@ -127,7 +152,6 @@ class FrostApp : Application() { L.e(it) { "RxJava error" } } } - } private fun initBugsnag() { @@ -136,7 +160,7 @@ class FrostApp : Application() { Bugsnag.disableExceptionHandler() if (!BuildConfig.APPLICATION_ID.startsWith("com.pitchedapps.frost")) return val version = BuildUtils.match(BuildConfig.VERSION_NAME) - ?: return L.d { "Bugsnag disabled for ${BuildConfig.VERSION_NAME}" } + ?: return L.d { "Bugsnag disabled for ${BuildConfig.VERSION_NAME}" } Bugsnag.enableExceptionHandler() Bugsnag.setNotifyReleaseStages(*BuildUtils.getAllStages()) Bugsnag.setAppVersion(version.versionName) @@ -157,5 +181,4 @@ class FrostApp : Application() { } } } - } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt index 034dabe2..14cc579f 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/StartActivity.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost import android.content.Intent @@ -21,7 +37,8 @@ import com.pitchedapps.frost.utils.EXTRA_COOKIES import com.pitchedapps.frost.utils.L import com.pitchedapps.frost.utils.Prefs import com.pitchedapps.frost.utils.launchNewTask -import java.util.* +import java.util.ArrayList +import java.util.IllegalFormatException /** * Created by Allan Wang on 2017-05-28. @@ -46,7 +63,8 @@ class StartActivity : KauBaseActivity() { if (Prefs.userId != -1L) startActivity(intentBuilder = { putParcelableArrayListExtra(EXTRA_COOKIES, cookies) - flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP + flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP or + Intent.FLAG_ACTIVITY_SINGLE_TOP }) else launchNewTask(cookies) @@ -57,11 +75,10 @@ class StartActivity : KauBaseActivity() { } catch (e: Exception) { showInvalidWebView() } - } private fun showInvalidWebView() = - showInvalidView(R.string.error_webview) + showInvalidView(R.string.error_webview) private fun showInvalidSdkView() { val text = try { @@ -73,12 +90,12 @@ class StartActivity : KauBaseActivity() { } private fun showInvalidView(textRes: Int) = - showInvalidView(string(textRes)) + showInvalidView(string(textRes)) private fun showInvalidView(text: String) { setContentView(R.layout.activity_invalid) findViewById(R.id.invalid_icon) - .setIcon(GoogleMaterial.Icon.gmd_adb, -1, Color.WHITE) + .setIcon(GoogleMaterial.Icon.gmd_adb, -1, Color.WHITE) findViewById(R.id.invalid_text).text = text } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/AboutActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/AboutActivity.kt index 4d333099..a110071c 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/AboutActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/AboutActivity.kt @@ -1,17 +1,40 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.activities -import androidx.constraintlayout.widget.ConstraintLayout -import androidx.constraintlayout.widget.ConstraintSet -import androidx.recyclerview.widget.RecyclerView import android.view.View import android.view.ViewGroup import android.widget.ImageView +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.constraintlayout.widget.ConstraintSet +import androidx.recyclerview.widget.RecyclerView import ca.allanwang.kau.about.AboutActivityBase import ca.allanwang.kau.about.LibraryIItem import ca.allanwang.kau.adapters.FastItemThemedAdapter import ca.allanwang.kau.adapters.ThemableIItem import ca.allanwang.kau.adapters.ThemableIItemDelegate -import ca.allanwang.kau.utils.* +import ca.allanwang.kau.utils.bindView +import ca.allanwang.kau.utils.dimenPixelSize +import ca.allanwang.kau.utils.resolveDrawable +import ca.allanwang.kau.utils.startLink +import ca.allanwang.kau.utils.string +import ca.allanwang.kau.utils.toDrawable +import ca.allanwang.kau.utils.toast +import ca.allanwang.kau.utils.withMinAlpha import com.mikepenz.aboutlibraries.Libs import com.mikepenz.aboutlibraries.entity.Library import com.mikepenz.aboutlibraries.entity.License @@ -25,7 +48,6 @@ import com.pitchedapps.frost.R import com.pitchedapps.frost.utils.L import com.pitchedapps.frost.utils.Prefs - /** * Created by Allan Wang on 2017-06-26. */ @@ -42,21 +64,21 @@ class AboutActivity : AboutActivityBase(null, { override fun getLibraries(libs: Libs): List { val include = arrayOf( - "AboutLibraries", - "AndroidIconics", - "androidin_appbillingv3", - "androidslidinguppanel", - "Crashlytics", - "dbflow", - "fastadapter", - "glide", - "Jsoup", - "kau", - "kotterknife", - "materialdialogs", - "materialdrawer", - "rxjava", - "subsamplingscaleimageview" + "AboutLibraries", + "AndroidIconics", + "androidin_appbillingv3", + "androidslidinguppanel", + "Crashlytics", + "dbflow", + "fastadapter", + "glide", + "Jsoup", + "kau", + "kotterknife", + "materialdialogs", + "materialdrawer", + "rxjava", + "subsamplingscaleimageview" ) val l = libs.prepareLibraries(this, include, null, false, true, true) @@ -136,11 +158,11 @@ class AboutActivity : AboutActivityBase(null, { val c = itemView.context val size = c.dimenPixelSize(R.dimen.kau_avatar_bounds) images = arrayOf Unit>>( - GoogleMaterial.Icon.gmd_arrow_downward to { c.startLink(R.string.github_downloads_url) }, - CommunityMaterial.Icon2.cmd_reddit to { c.startLink(R.string.reddit_url) }, - CommunityMaterial.Icon.cmd_github_circle to { c.startLink(R.string.github_url) }, - CommunityMaterial.Icon2.cmd_slack to { c.startLink(R.string.slack_url) }, - CommunityMaterial.Icon2.cmd_xda to { c.startLink(R.string.xda_url) } + GoogleMaterial.Icon.gmd_arrow_downward to { c.startLink(R.string.github_downloads_url) }, + CommunityMaterial.Icon2.cmd_reddit to { c.startLink(R.string.reddit_url) }, + CommunityMaterial.Icon.cmd_github_circle to { c.startLink(R.string.github_url) }, + CommunityMaterial.Icon2.cmd_slack to { c.startLink(R.string.slack_url) }, + CommunityMaterial.Icon2.cmd_xda to { c.startLink(R.string.xda_url) } ).mapIndexed { i, (icon, onClick) -> ImageView(c).apply { layoutParams = ViewGroup.LayoutParams(size, size) @@ -154,10 +176,16 @@ class AboutActivity : AboutActivityBase(null, { } val set = ConstraintSet() set.clone(container) - set.createHorizontalChain(ConstraintSet.PARENT_ID, ConstraintSet.LEFT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT, - images.map { it.id }.toIntArray(), null, ConstraintSet.CHAIN_SPREAD_INSIDE) + set.createHorizontalChain(ConstraintSet.PARENT_ID, + ConstraintSet.LEFT, + ConstraintSet.PARENT_ID, + ConstraintSet.RIGHT, + images.map { it.id }.toIntArray(), + null, + ConstraintSet.CHAIN_SPREAD_INSIDE + ) set.applyTo(container) } } } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseActivity.kt index 3ac8c6ce..08b5ab0c 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseActivity.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.activities import android.content.res.Configuration @@ -80,7 +96,6 @@ abstract class BaseActivity : KauBaseActivity() { //// disposeNetworkConnectivity() // } - override fun onStop() { if (this is VideoViewHolder) videoOnStop() super.onStop() @@ -90,4 +105,4 @@ abstract class BaseActivity : KauBaseActivity() { super.onConfigurationChanged(newConfig) if (this is VideoViewHolder) videoViewer?.updateLocation() } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt index 8f6bbacb..20b5727f 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.activities import android.annotation.SuppressLint @@ -8,25 +24,31 @@ import android.graphics.PointF import android.graphics.drawable.ColorDrawable import android.net.Uri import android.os.Bundle -import androidx.annotation.StringRes -import com.google.android.material.appbar.AppBarLayout -import androidx.coordinatorlayout.widget.CoordinatorLayout -import com.google.android.material.floatingactionbutton.FloatingActionButton -import com.google.android.material.tabs.TabLayout -import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentPagerAdapter -import androidx.appcompat.widget.Toolbar import android.view.Menu import android.view.MenuItem import android.webkit.ValueCallback import android.webkit.WebChromeClient import android.webkit.WebView import android.widget.FrameLayout +import androidx.annotation.StringRes +import androidx.appcompat.widget.Toolbar +import androidx.coordinatorlayout.widget.CoordinatorLayout +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentPagerAdapter import ca.allanwang.kau.searchview.SearchItem import ca.allanwang.kau.searchview.SearchView import ca.allanwang.kau.searchview.SearchViewHolder import ca.allanwang.kau.searchview.bindSearchView -import ca.allanwang.kau.utils.* +import ca.allanwang.kau.utils.bindView +import ca.allanwang.kau.utils.fadeScaleTransition +import ca.allanwang.kau.utils.restart +import ca.allanwang.kau.utils.setIcon +import ca.allanwang.kau.utils.setMenuIcons +import ca.allanwang.kau.utils.showIf +import ca.allanwang.kau.utils.string +import ca.allanwang.kau.utils.tint +import ca.allanwang.kau.utils.toast +import ca.allanwang.kau.utils.withMinAlpha import co.zsmb.materialdrawerkt.builders.Builder import co.zsmb.materialdrawerkt.builders.accountHeader import co.zsmb.materialdrawerkt.builders.drawer @@ -35,6 +57,9 @@ import co.zsmb.materialdrawerkt.draweritems.badgeable.secondaryItem import co.zsmb.materialdrawerkt.draweritems.divider import co.zsmb.materialdrawerkt.draweritems.profile.profile import co.zsmb.materialdrawerkt.draweritems.profile.profileSetting +import com.google.android.material.appbar.AppBarLayout +import com.google.android.material.floatingactionbutton.FloatingActionButton +import com.google.android.material.tabs.TabLayout import com.mikepenz.google_material_typeface_library.GoogleMaterial import com.mikepenz.iconics.IconicsDrawable import com.mikepenz.iconics.typeface.IIcon @@ -57,7 +82,26 @@ import com.pitchedapps.frost.facebook.parsers.SearchParser import com.pitchedapps.frost.facebook.profilePictureUrl import com.pitchedapps.frost.fragments.BaseFragment import com.pitchedapps.frost.fragments.WebFragment -import com.pitchedapps.frost.utils.* +import com.pitchedapps.frost.utils.ACTIVITY_SETTINGS +import com.pitchedapps.frost.utils.EXTRA_COOKIES +import com.pitchedapps.frost.utils.L +import com.pitchedapps.frost.utils.MAIN_TIMEOUT_DURATION +import com.pitchedapps.frost.utils.Prefs +import com.pitchedapps.frost.utils.REQUEST_NAV +import com.pitchedapps.frost.utils.REQUEST_REFRESH +import com.pitchedapps.frost.utils.REQUEST_RESTART +import com.pitchedapps.frost.utils.REQUEST_RESTART_APPLICATION +import com.pitchedapps.frost.utils.REQUEST_SEARCH +import com.pitchedapps.frost.utils.REQUEST_TEXT_ZOOM +import com.pitchedapps.frost.utils.cookies +import com.pitchedapps.frost.utils.frostChangelog +import com.pitchedapps.frost.utils.frostEvent +import com.pitchedapps.frost.utils.frostNavigationBar +import com.pitchedapps.frost.utils.launchLogin +import com.pitchedapps.frost.utils.launchNewTask +import com.pitchedapps.frost.utils.launchWebOverlay +import com.pitchedapps.frost.utils.materialDialogThemed +import com.pitchedapps.frost.utils.setFrostColors import com.pitchedapps.frost.views.BadgedIcon import com.pitchedapps.frost.views.FrostVideoViewer import com.pitchedapps.frost.views.FrostViewPager @@ -68,8 +112,8 @@ import com.pitchedapps.frost.views.FrostViewPager * Most of the logic that is unrelated to handling fragments */ abstract class BaseMainActivity : BaseActivity(), MainActivityContract, - FileChooserContract by FileChooserDelegate(), - VideoViewHolder, SearchViewHolder { + FileChooserContract by FileChooserDelegate(), + VideoViewHolder, SearchViewHolder { protected lateinit var adapter: SectionsPagerAdapter override val frameWrapper: FrameLayout by bindView(R.id.frame_wrapper) @@ -111,12 +155,14 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract, Prefs.versionCode = BuildConfig.VERSION_CODE if (!BuildConfig.DEBUG) { frostChangelog() - frostEvent("Version", - "Version code" to BuildConfig.VERSION_CODE, - "Prev version code" to Prefs.prevVersionCode, - "Version name" to BuildConfig.VERSION_NAME, - "Build type" to BuildConfig.BUILD_TYPE, - "Frost id" to Prefs.frostId) + frostEvent( + "Version", + "Version code" to BuildConfig.VERSION_CODE, + "Prev version code" to Prefs.prevVersionCode, + "Version name" to BuildConfig.VERSION_NAME, + "Build type" to BuildConfig.BUILD_TYPE, + "Frost id" to Prefs.frostId + ) } } setupDrawer(savedInstanceState) @@ -204,7 +250,9 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract, identifier = -2L } profileSetting(nameRes = R.string.kau_add_account) { - iconDrawable = IconicsDrawable(this@BaseMainActivity, GoogleMaterial.Icon.gmd_add).actionBar().paddingDp(5).color(Prefs.textColor) + iconDrawable = + IconicsDrawable(this@BaseMainActivity, GoogleMaterial.Icon.gmd_add).actionBar().paddingDp(5) + .color(Prefs.textColor) textColor = Prefs.textColor.toLong() identifier = -3L } @@ -225,8 +273,12 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract, } else { materialDialogThemed { title(R.string.kau_logout) - content(String.format(string(R.string.kau_logout_confirm_as_x), currentCookie.name - ?: Prefs.userId.toString())) + content( + String.format( + string(R.string.kau_logout_confirm_as_x), currentCookie.name + ?: Prefs.userId.toString() + ) + ) positiveText(R.string.kau_yes) negativeText(R.string.kau_no) onPositive { _, _ -> FbCookie.logout(this@BaseMainActivity) } @@ -295,9 +347,11 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract, override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.menu_main, menu) toolbar.tint(Prefs.iconColor) - setMenuIcons(menu, Prefs.iconColor, - R.id.action_settings to GoogleMaterial.Icon.gmd_settings, - R.id.action_search to GoogleMaterial.Icon.gmd_search) + setMenuIcons( + menu, Prefs.iconColor, + R.id.action_settings to GoogleMaterial.Icon.gmd_settings, + R.id.action_search to GoogleMaterial.Icon.gmd_search + ) searchViewBindIfNull { bindSearchView(menu, R.id.action_search, Prefs.iconColor) { textCallback = { query, searchView -> @@ -309,7 +363,13 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract, if (data != null) { val items = data.mapTo(mutableListOf(), FrostSearch::toSearchItem) if (items.isNotEmpty()) - items.add(SearchItem("${FbItem._SEARCH.url}?q=$query", string(R.string.show_all_results), iicon = null)) + items.add( + SearchItem( + "${FbItem._SEARCH.url}?q=$query", + string(R.string.show_all_results), + iicon = null + ) + ) searchViewCache[query] = items searchView.results = items } @@ -332,7 +392,8 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract, R.id.action_settings -> { val intent = Intent(this, SettingsActivity::class.java) intent.putParcelableArrayListExtra(EXTRA_COOKIES, cookies()) - val bundle = ActivityOptions.makeCustomAnimation(this, R.anim.kau_slide_in_right, R.anim.kau_fade_out).toBundle() + val bundle = + ActivityOptions.makeCustomAnimation(this, R.anim.kau_slide_in_right, R.anim.kau_fade_out).toBundle() startActivityForResult(intent, ACTIVITY_SETTINGS, bundle) } else -> return super.onOptionsItemSelected(item) @@ -340,7 +401,10 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract, return true } - override fun openFileChooser(filePathCallback: ValueCallback?>, fileChooserParams: WebChromeClient.FileChooserParams) { + override fun openFileChooser( + filePathCallback: ValueCallback?>, + fileChooserParams: WebChromeClient.FileChooserParams + ) { openMediaPicker(filePathCallback, fileChooserParams) } @@ -377,8 +441,10 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract, override fun onRestoreInstanceState(savedInstanceState: Bundle) { super.onRestoreInstanceState(savedInstanceState) adapter.forcedFallbacks.clear() - adapter.forcedFallbacks.addAll(savedInstanceState.getStringArrayList(STATE_FORCE_FALLBACK) - ?: emptyList()) + adapter.forcedFallbacks.addAll( + savedInstanceState.getStringArrayList(STATE_FORCE_FALLBACK) + ?: emptyList() + ) } override fun onResume() { @@ -444,10 +510,12 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract, override fun getItem(position: Int): Fragment { val item = pages[position] - return BaseFragment(item.fragmentCreator, - forcedFallbacks.contains(item.name), - item, - position) + return BaseFragment( + item.fragmentCreator, + forcedFallbacks.contains(item.name), + item, + position + ) } override fun getCount() = pages.size @@ -455,12 +523,12 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract, override fun getPageTitle(position: Int): CharSequence = getString(pages[position].titleId) override fun getItemPosition(fragment: Any) = - if (fragment !is BaseFragment) - POSITION_UNCHANGED - else if (fragment is WebFragment || fragment.valid) - POSITION_UNCHANGED - else - POSITION_NONE + if (fragment !is BaseFragment) + POSITION_UNCHANGED + else if (fragment is WebFragment || fragment.valid) + POSITION_UNCHANGED + else + POSITION_NONE } override val lowerVideoPadding: PointF @@ -469,4 +537,4 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract, PointF(0f, toolbar.height.toFloat()) else PointF(0f, 0f) -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/DebugActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/DebugActivity.kt index 3acbf7b3..6257e6f1 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/DebugActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/DebugActivity.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.activities import android.app.Activity @@ -9,9 +25,9 @@ import ca.allanwang.kau.internal.KauBaseActivity import ca.allanwang.kau.utils.setIcon import ca.allanwang.kau.utils.visible import com.mikepenz.google_material_typeface_library.GoogleMaterial +import com.pitchedapps.frost.R import com.pitchedapps.frost.facebook.FbItem import com.pitchedapps.frost.injectors.JsActions -import com.pitchedapps.frost.R import com.pitchedapps.frost.utils.L import com.pitchedapps.frost.utils.Prefs import com.pitchedapps.frost.utils.createFreshDir @@ -73,23 +89,22 @@ class DebugActivity : KauBaseActivity() { val body = it[1] as? String screenshot to body }.observeOn(AndroidSchedulers.mainThread()) - .subscribe { (screenshot, body), err -> - if (err != null) { - L.e { "DebugActivity error ${err.message}" } - setResult(Activity.RESULT_CANCELED) - finish() - return@subscribe - } - val intent = Intent() - intent.putExtra(RESULT_URL, debug_webview.url) - intent.putExtra(RESULT_SCREENSHOT, screenshot) - if (body != null) - intent.putExtra(RESULT_BODY, body) - setResult(Activity.RESULT_OK, intent) + .subscribe { (screenshot, body), err -> + if (err != null) { + L.e { "DebugActivity error ${err.message}" } + setResult(Activity.RESULT_CANCELED) finish() + return@subscribe } + val intent = Intent() + intent.putExtra(RESULT_URL, debug_webview.url) + intent.putExtra(RESULT_SCREENSHOT, screenshot) + if (body != null) + intent.putExtra(RESULT_BODY, body) + setResult(Activity.RESULT_OK, intent) + finish() + } } - } override fun onSupportNavigateUp(): Boolean { @@ -113,4 +128,4 @@ class DebugActivity : KauBaseActivity() { else super.onBackPressed() } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/ImageActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/ImageActivity.kt index 348b36b9..83f617ba 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/ImageActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/ImageActivity.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.activities import android.content.Intent @@ -5,16 +21,25 @@ import android.content.res.ColorStateList import android.graphics.Color import android.os.Bundle import android.os.Environment -import com.google.android.material.floatingactionbutton.FloatingActionButton import android.view.View import ca.allanwang.kau.internal.KauBaseActivity import ca.allanwang.kau.logging.KauLoggerExtension import ca.allanwang.kau.mediapicker.scanMedia import ca.allanwang.kau.permissions.PERMISSION_WRITE_EXTERNAL_STORAGE import ca.allanwang.kau.permissions.kauRequestPermissions -import ca.allanwang.kau.utils.* +import ca.allanwang.kau.utils.colorToForeground +import ca.allanwang.kau.utils.fadeOut +import ca.allanwang.kau.utils.fadeScaleTransition +import ca.allanwang.kau.utils.isHidden +import ca.allanwang.kau.utils.scaleXY +import ca.allanwang.kau.utils.setIcon +import ca.allanwang.kau.utils.tint +import ca.allanwang.kau.utils.use +import ca.allanwang.kau.utils.withAlpha +import ca.allanwang.kau.utils.withMinAlpha import com.davemorrissey.labs.subscaleview.ImageSource import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView +import com.google.android.material.floatingactionbutton.FloatingActionButton import com.mikepenz.google_material_typeface_library.GoogleMaterial import com.mikepenz.iconics.typeface.IIcon import com.pitchedapps.frost.R @@ -23,7 +48,19 @@ import com.pitchedapps.frost.facebook.get import com.pitchedapps.frost.facebook.requests.call import com.pitchedapps.frost.facebook.requests.getFullSizedImageUrl import com.pitchedapps.frost.facebook.requests.requestBuilder -import com.pitchedapps.frost.utils.* +import com.pitchedapps.frost.utils.ARG_COOKIE +import com.pitchedapps.frost.utils.ARG_IMAGE_URL +import com.pitchedapps.frost.utils.ARG_TEXT +import com.pitchedapps.frost.utils.L +import com.pitchedapps.frost.utils.Prefs +import com.pitchedapps.frost.utils.createFreshFile +import com.pitchedapps.frost.utils.frostSnackbar +import com.pitchedapps.frost.utils.frostUriFromFile +import com.pitchedapps.frost.utils.isIndirectImageUrl +import com.pitchedapps.frost.utils.logFrostEvent +import com.pitchedapps.frost.utils.materialDialogThemed +import com.pitchedapps.frost.utils.sendFrostEmail +import com.pitchedapps.frost.utils.setFrostColors import com.sothree.slidinguppanel.SlidingUpPanelLayout import kotlinx.android.synthetic.main.activity_image.* import okhttp3.Response @@ -34,7 +71,8 @@ import java.io.File import java.io.FileFilter import java.io.IOException import java.text.SimpleDateFormat -import java.util.* +import java.util.Date +import java.util.Locale /** * Created by Allan Wang on 2017-07-15. @@ -94,8 +132,10 @@ class ImageActivity : KauBaseActivity() { // a unique image identifier based on the id (if it exists), and its hash private val imageHash: String by lazy { - "${Math.abs(FB_IMAGE_ID_MATCHER.find(imageUrl)[1]?.hashCode() - ?: 0)}_${Math.abs(imageUrl.hashCode())}" + "${Math.abs( + FB_IMAGE_ID_MATCHER.find(imageUrl)[1]?.hashCode() + ?: 0 + )}_${Math.abs(imageUrl.hashCode())}" } override fun onCreate(savedInstanceState: Bundle?) { @@ -105,11 +145,15 @@ class ImageActivity : KauBaseActivity() { L.v { "Displaying image $imageUrl" } val layout = if (!imageText.isNullOrBlank()) R.layout.activity_image else R.layout.activity_image_textless setContentView(layout) - image_container.setBackgroundColor(if (Prefs.blackMediaBg) Color.BLACK - else Prefs.bgColor.withMinAlpha(222)) + image_container.setBackgroundColor( + if (Prefs.blackMediaBg) Color.BLACK + else Prefs.bgColor.withMinAlpha(222) + ) image_text?.setTextColor(if (Prefs.blackMediaBg) Color.WHITE else Prefs.textColor) - image_text?.setBackgroundColor((if (Prefs.blackMediaBg) Color.BLACK else Prefs.bgColor) - .colorToForeground(0.2f).withAlpha(255)) + image_text?.setBackgroundColor( + (if (Prefs.blackMediaBg) Color.BLACK else Prefs.bgColor) + .colorToForeground(0.2f).withAlpha(255) + ) image_text?.text = imageText image_progress.tint(if (Prefs.blackMediaBg) Color.WHITE else Prefs.accentColor) image_panel?.addPanelSlideListener(object : SlidingUpPanelLayout.SimplePanelSlideListener() { @@ -208,16 +252,15 @@ class ImageActivity : KauBaseActivity() { } private fun getImageResponse(): Response = cookie.requestBuilder() - .url(trueImageUrl) - .get() - .call() - .execute() - + .url(trueImageUrl) + .get() + .call() + .execute() @Throws(IOException::class) private fun downloadImageTo(file: File) { val body = getImageResponse().body() - ?: throw IOException("Failed to retrieve image body") + ?: throw IOException("Failed to retrieve image body") body.byteStream().use { input -> file.outputStream().use { output -> input.copyTo(output) @@ -272,7 +315,11 @@ class ImageActivity : KauBaseActivity() { } } -internal enum class FabStates(val iicon: IIcon, val iconColor: Int = Prefs.iconColor, val backgroundTint: Int = Int.MAX_VALUE) { +internal enum class FabStates( + val iicon: IIcon, + val iconColor: Int = Prefs.iconColor, + val backgroundTint: Int = Int.MAX_VALUE +) { ERROR(GoogleMaterial.Icon.gmd_error, Color.WHITE, Color.RED) { override fun onClick(activity: ImageActivity) { activity.materialDialogThemed { @@ -334,5 +381,4 @@ internal enum class FabStates(val iicon: IIcon, val iconColor: Int = Prefs.iconC } abstract fun onClick(activity: ImageActivity) - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/IntroActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/IntroActivity.kt index c41229da..a3ab6172 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/IntroActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/IntroActivity.kt @@ -1,31 +1,60 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.activities import android.animation.ValueAnimator import android.content.res.ColorStateList import android.graphics.Color import android.os.Bundle -import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentManager -import androidx.fragment.app.FragmentPagerAdapter -import androidx.viewpager.widget.ViewPager import android.view.View import android.view.WindowManager import android.widget.Button import android.widget.ImageButton import android.widget.ImageView +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentManager +import androidx.fragment.app.FragmentPagerAdapter +import androidx.viewpager.widget.ViewPager import ca.allanwang.kau.internal.KauBaseActivity import ca.allanwang.kau.ui.views.RippleCanvas import ca.allanwang.kau.ui.widgets.InkPageIndicator -import ca.allanwang.kau.utils.* +import ca.allanwang.kau.utils.bindView +import ca.allanwang.kau.utils.blendWith +import ca.allanwang.kau.utils.color +import ca.allanwang.kau.utils.fadeScaleTransition +import ca.allanwang.kau.utils.navigationBarColor +import ca.allanwang.kau.utils.postDelayed +import ca.allanwang.kau.utils.scaleXY +import ca.allanwang.kau.utils.setIcon +import ca.allanwang.kau.utils.statusBarColor import com.mikepenz.google_material_typeface_library.GoogleMaterial import com.pitchedapps.frost.R -import com.pitchedapps.frost.intro.* +import com.pitchedapps.frost.intro.BaseIntroFragment +import com.pitchedapps.frost.intro.IntroAccountFragment +import com.pitchedapps.frost.intro.IntroFragmentEnd +import com.pitchedapps.frost.intro.IntroFragmentTheme +import com.pitchedapps.frost.intro.IntroFragmentWelcome +import com.pitchedapps.frost.intro.IntroTabContextFragment +import com.pitchedapps.frost.intro.IntroTabTouchFragment import com.pitchedapps.frost.utils.Prefs import com.pitchedapps.frost.utils.cookies import com.pitchedapps.frost.utils.launchNewTask import org.jetbrains.anko.find - /** * Created by Allan Wang on 2017-07-25. * @@ -43,12 +72,12 @@ class IntroActivity : KauBaseActivity(), ViewPager.PageTransformer, ViewPager.On private var barHasNext = true val fragments = listOf( - IntroFragmentWelcome(), - IntroFragmentTheme(), - IntroAccountFragment(), - IntroTabTouchFragment(), - IntroTabContextFragment(), - IntroFragmentEnd() + IntroFragmentWelcome(), + IntroFragmentTheme(), + IntroAccountFragment(), + IntroTabTouchFragment(), + IntroTabContextFragment(), + IntroFragmentEnd() ) override fun onCreate(savedInstanceState: Bundle?) { @@ -97,7 +126,6 @@ class IntroActivity : KauBaseActivity(), ViewPager.PageTransformer, ViewPager.On page.alpha = 1f page.translationX = 0f } - } fun finish(x: Float, y: Float) { @@ -107,9 +135,11 @@ class IntroActivity : KauBaseActivity(), ViewPager.PageTransformer, ViewPager.On postDelayed(1000) { finish() } } val lastView: View? = fragments.last().view - arrayOf(skip, indicator, next, - lastView?.find(R.id.intro_title), - lastView?.find(R.id.intro_desc)).forEach { + arrayOf( + skip, indicator, next, + lastView?.find(R.id.intro_title), + lastView?.find(R.id.intro_desc) + ).forEach { it?.animate()?.alpha(0f)?.setDuration(600)?.start() } if (Prefs.textColor != Color.WHITE) { @@ -147,7 +177,6 @@ class IntroActivity : KauBaseActivity(), ViewPager.PageTransformer, ViewPager.On } override fun onPageScrollStateChanged(state: Int) { - } override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) { @@ -162,16 +191,19 @@ class IntroActivity : KauBaseActivity(), ViewPager.PageTransformer, ViewPager.On if (barHasNext == hasNext) return barHasNext = hasNext next.fadeScaleTransition { - setIcon(if (barHasNext) GoogleMaterial.Icon.gmd_navigate_next else GoogleMaterial.Icon.gmd_done, color = Prefs.textColor) + setIcon( + if (barHasNext) GoogleMaterial.Icon.gmd_navigate_next else GoogleMaterial.Icon.gmd_done, + color = Prefs.textColor + ) } skip.animate().scaleXY(if (barHasNext) 1f else 0f) } - class IntroPageAdapter(fm: FragmentManager, private val fragments: List) : FragmentPagerAdapter(fm) { + class IntroPageAdapter(fm: FragmentManager, private val fragments: List) : + FragmentPagerAdapter(fm) { override fun getItem(position: Int): Fragment = fragments[position] override fun getCount(): Int = fragments.size } - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt index 9c8a60aa..8b5fe38d 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt @@ -1,12 +1,28 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.activities import android.graphics.drawable.Drawable import android.os.Bundle import android.os.Handler -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout +import android.widget.ImageView import androidx.appcompat.widget.AppCompatTextView import androidx.appcompat.widget.Toolbar -import android.widget.ImageView +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import ca.allanwang.kau.utils.bindView import ca.allanwang.kau.utils.fadeIn import ca.allanwang.kau.utils.fadeOut @@ -24,14 +40,18 @@ import com.pitchedapps.frost.facebook.profilePictureUrl import com.pitchedapps.frost.glide.FrostGlide import com.pitchedapps.frost.glide.GlideApp import com.pitchedapps.frost.glide.transform -import com.pitchedapps.frost.utils.* +import com.pitchedapps.frost.utils.L +import com.pitchedapps.frost.utils.Showcase +import com.pitchedapps.frost.utils.frostEvent +import com.pitchedapps.frost.utils.launchNewTask +import com.pitchedapps.frost.utils.logFrostEvent +import com.pitchedapps.frost.utils.setFrostColors import com.pitchedapps.frost.web.LoginWebView import io.reactivex.Single import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.functions.BiFunction import io.reactivex.subjects.SingleSubject - /** * Created by Allan Wang on 2017-06-01. */ @@ -78,51 +98,62 @@ class LoginActivity : BaseActivity() { private fun loadInfo(cookie: CookieModel) { refresh = true Single.zip>( - profileSubject, - usernameSubject, - BiFunction(::Pair)) - .observeOn(AndroidSchedulers.mainThread()).subscribe { (foundImage, name) -> - refresh = false - if (!foundImage) { - L.e { "Could not get profile photo; Invalid userId?" } - L._i { cookie } - } - textview.text = String.format(getString(R.string.welcome), name) - textview.fadeIn() - frostEvent("Login", "success" to true) - /* - * The user may have logged into an account that is already in the database - * We will let the db handle duplicates and load it now after the new account has been saved - */ - loadFbCookiesAsync { - val cookies = ArrayList(it) - Handler().postDelayed({ - if (Showcase.intro) - launchNewTask(cookies, true) - else - launchNewTask(cookies, true) - }, 1000) - } - }.disposeOnDestroy() + profileSubject, + usernameSubject, + BiFunction(::Pair) + ) + .observeOn(AndroidSchedulers.mainThread()).subscribe { (foundImage, name) -> + refresh = false + if (!foundImage) { + L.e { "Could not get profile photo; Invalid userId?" } + L._i { cookie } + } + textview.text = String.format(getString(R.string.welcome), name) + textview.fadeIn() + frostEvent("Login", "success" to true) + /* + * The user may have logged into an account that is already in the database + * We will let the db handle duplicates and load it now after the new account has been saved + */ + loadFbCookiesAsync { + val cookies = ArrayList(it) + Handler().postDelayed({ + if (Showcase.intro) + launchNewTask(cookies, true) + else + launchNewTask(cookies, true) + }, 1000) + } + }.disposeOnDestroy() loadProfile(cookie.id) loadUsername(cookie) } - private fun loadProfile(id: Long) { profileLoader.load(profilePictureUrl(id)) - .transform(FrostGlide.roundCorner).listener(object : RequestListener { - override fun onResourceReady(resource: Drawable?, model: Any?, target: Target?, dataSource: DataSource?, isFirstResource: Boolean): Boolean { - profileSubject.onSuccess(true) - return false - } - - override fun onLoadFailed(e: GlideException?, model: Any?, target: Target?, isFirstResource: Boolean): Boolean { - e.logFrostEvent("Profile loading exception") - profileSubject.onSuccess(false) - return false - } - }).into(profile) + .transform(FrostGlide.roundCorner).listener(object : RequestListener { + override fun onResourceReady( + resource: Drawable?, + model: Any?, + target: Target?, + dataSource: DataSource?, + isFirstResource: Boolean + ): Boolean { + profileSubject.onSuccess(true) + return false + } + + override fun onLoadFailed( + e: GlideException?, + model: Any?, + target: Target?, + isFirstResource: Boolean + ): Boolean { + e.logFrostEvent("Profile loading exception") + profileSubject.onSuccess(false) + return false + } + }).into(profile) } private fun loadUsername(cookie: CookieModel) { @@ -146,5 +177,4 @@ class LoginActivity : BaseActivity() { web.pauseTimers() super.onPause() } - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt index 2555fe5b..d03c6496 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt @@ -1,8 +1,24 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.activities import android.os.Bundle -import com.google.android.material.tabs.TabLayout import androidx.viewpager.widget.ViewPager +import com.google.android.material.tabs.TabLayout import com.pitchedapps.frost.facebook.FbItem import com.pitchedapps.frost.views.BadgedIcon import io.reactivex.android.schedulers.AndroidSchedulers @@ -36,19 +52,19 @@ class MainActivity : BaseMainActivity() { super.onPageScrolled(position, positionOffset, positionOffsetPixels) val delta = positionOffset * (255 - 128).toFloat() tabsForEachView { tabPosition, view -> - view.setAllAlpha(when (tabPosition) { - position -> 255.0f - delta - position + 1 -> 128.0f + delta - else -> 128f - }) + view.setAllAlpha( + when (tabPosition) { + position -> 255.0f - delta + position + 1 -> 128.0f + delta + else -> 128f + } + ) } } }) viewPager.post { fragmentSubject.onNext(0); lastPosition = 0 } //trigger hook so title is set - } - private fun setupTabs() { viewPager.addOnPageChangeListener(TabLayout.TabLayoutOnPageChangeListener(tabs)) tabs.addOnTabSelectedListener(object : TabLayout.ViewPagerOnTabSelectedListener(viewPager) { @@ -63,31 +79,31 @@ class MainActivity : BaseMainActivity() { } }) headerBadgeObservable.throttleFirst(15, TimeUnit.SECONDS) - .subscribeOn(Schedulers.newThread()) - .map { Jsoup.parse(it) } - .filter { it.select("[data-sigil=count]").size >= 0 } //ensure headers exist - .map { - val feed = it.select("[data-sigil*=feed] [data-sigil=count]") - val requests = it.select("[data-sigil*=requests] [data-sigil=count]") - val messages = it.select("[data-sigil*=messages] [data-sigil=count]") - val notifications = it.select("[data-sigil*=notifications] [data-sigil=count]") - return@map arrayOf(feed, requests, messages, notifications).map { e -> e?.getOrNull(0)?.ownText() } - } - .observeOn(AndroidSchedulers.mainThread()) - .subscribe { (feed, requests, messages, notifications) -> - tabsForEachView { _, view -> - when (view.iicon) { - FbItem.FEED.icon -> view.badgeText = feed - FbItem.FRIENDS.icon -> view.badgeText = requests - FbItem.MESSAGES.icon -> view.badgeText = messages - FbItem.NOTIFICATIONS.icon -> view.badgeText = notifications - } + .subscribeOn(Schedulers.newThread()) + .map { Jsoup.parse(it) } + .filter { it.select("[data-sigil=count]").size >= 0 } //ensure headers exist + .map { + val feed = it.select("[data-sigil*=feed] [data-sigil=count]") + val requests = it.select("[data-sigil*=requests] [data-sigil=count]") + val messages = it.select("[data-sigil*=messages] [data-sigil=count]") + val notifications = it.select("[data-sigil*=notifications] [data-sigil=count]") + return@map arrayOf(feed, requests, messages, notifications).map { e -> e?.getOrNull(0)?.ownText() } + } + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { (feed, requests, messages, notifications) -> + tabsForEachView { _, view -> + when (view.iicon) { + FbItem.FEED.icon -> view.badgeText = feed + FbItem.FRIENDS.icon -> view.badgeText = requests + FbItem.MESSAGES.icon -> view.badgeText = messages + FbItem.NOTIFICATIONS.icon -> view.badgeText = notifications } - }.disposeOnDestroy() + } + }.disposeOnDestroy() adapter.pages.forEach { tabs.addTab(tabs.newTab() - .setCustomView(BadgedIcon(this).apply { iicon = it.icon })) + .setCustomView(BadgedIcon(this).apply { iicon = it.icon }) + ) } } - } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/SelectorActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/SelectorActivity.kt index 514af197..2907bac6 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/SelectorActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/SelectorActivity.kt @@ -1,11 +1,27 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.activities import android.os.Bundle -import androidx.constraintlayout.widget.ConstraintLayout +import android.view.View import androidx.appcompat.widget.AppCompatTextView +import androidx.constraintlayout.widget.ConstraintLayout import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView -import android.view.View import ca.allanwang.kau.utils.bindView import com.mikepenz.fastadapter.FastAdapter import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter @@ -47,4 +63,4 @@ class SelectorActivity : BaseActivity() { background(container) } } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt index 7663b70f..37047448 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.activities import android.annotation.SuppressLint @@ -12,14 +28,33 @@ import ca.allanwang.kau.kpref.activity.CoreAttributeContract import ca.allanwang.kau.kpref.activity.KPrefActivity import ca.allanwang.kau.kpref.activity.KPrefAdapterBuilder import ca.allanwang.kau.ui.views.RippleCanvas -import ca.allanwang.kau.utils.* +import ca.allanwang.kau.utils.finishSlideOut +import ca.allanwang.kau.utils.setMenuIcons +import ca.allanwang.kau.utils.startActivityForResult +import ca.allanwang.kau.utils.startLink +import ca.allanwang.kau.utils.string +import ca.allanwang.kau.utils.tint +import ca.allanwang.kau.utils.withSceneTransitionAnimation import com.mikepenz.community_material_typeface_library.CommunityMaterial import com.mikepenz.google_material_typeface_library.GoogleMaterial import com.pitchedapps.frost.R import com.pitchedapps.frost.enums.Support -import com.pitchedapps.frost.settings.* -import com.pitchedapps.frost.utils.* - +import com.pitchedapps.frost.settings.getAppearancePrefs +import com.pitchedapps.frost.settings.getBehaviourPrefs +import com.pitchedapps.frost.settings.getDebugPrefs +import com.pitchedapps.frost.settings.getExperimentalPrefs +import com.pitchedapps.frost.settings.getFeedPrefs +import com.pitchedapps.frost.settings.getNotificationPrefs +import com.pitchedapps.frost.settings.sendDebug +import com.pitchedapps.frost.utils.L +import com.pitchedapps.frost.utils.Prefs +import com.pitchedapps.frost.utils.REQUEST_RESTART +import com.pitchedapps.frost.utils.cookies +import com.pitchedapps.frost.utils.frostChangelog +import com.pitchedapps.frost.utils.frostNavigationBar +import com.pitchedapps.frost.utils.launchNewTask +import com.pitchedapps.frost.utils.materialDialogThemed +import com.pitchedapps.frost.utils.setFrostTheme /** * Created by Allan Wang on 2017-06-06. @@ -146,7 +181,6 @@ class SettingsActivity : KPrefActivity() { iicon = CommunityMaterial.Icon.cmd_android_debug_bridge visible = { Prefs.debugSettings } } - } fun shouldRestartMain() { @@ -179,9 +213,11 @@ class SettingsActivity : KPrefActivity() { override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.menu_settings, menu) toolbar.tint(Prefs.iconColor) - setMenuIcons(menu, Prefs.iconColor, - R.id.action_email to GoogleMaterial.Icon.gmd_email, - R.id.action_changelog to GoogleMaterial.Icon.gmd_info) + setMenuIcons( + menu, Prefs.iconColor, + R.id.action_email to GoogleMaterial.Icon.gmd_email, + R.id.action_changelog to GoogleMaterial.Icon.gmd_info + ) return true } @@ -201,4 +237,4 @@ class SettingsActivity : KPrefActivity() { fun setFrostResult(flag: Int) { resultFlag = resultFlag or flag } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/TabCustomizerActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/TabCustomizerActivity.kt index 6222d98f..7f632940 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/TabCustomizerActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/TabCustomizerActivity.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.activities import android.app.Activity @@ -5,21 +21,18 @@ import android.content.res.ColorStateList import android.os.Bundle import android.view.View import android.view.animation.AnimationUtils -import android.widget.TextView import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView import ca.allanwang.kau.kotlin.lazyContext -import ca.allanwang.kau.utils.bindView import ca.allanwang.kau.utils.scaleXY import ca.allanwang.kau.utils.setIcon -import com.pitchedapps.frost.R import ca.allanwang.kau.utils.withAlpha -import com.google.android.material.floatingactionbutton.FloatingActionButton import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter import com.mikepenz.fastadapter_extensions.drag.ItemTouchCallback import com.mikepenz.fastadapter_extensions.drag.SimpleDragCallback import com.mikepenz.google_material_typeface_library.GoogleMaterial +import com.pitchedapps.frost.R import com.pitchedapps.frost.dbflow.TAB_COUNT import com.pitchedapps.frost.dbflow.loadFbTabs import com.pitchedapps.frost.dbflow.save @@ -28,7 +41,7 @@ import com.pitchedapps.frost.iitems.TabIItem import com.pitchedapps.frost.utils.Prefs import com.pitchedapps.frost.utils.setFrostColors import kotlinx.android.synthetic.main.activity_tab_customizer.* -import java.util.* +import java.util.Collections /** * Created by Allan Wang on 26/11/17. @@ -96,9 +109,9 @@ class TabCustomizerActivity : BaseActivity() { override fun itemTouchDropped(oldPosition: Int, newPosition: Int) = Unit } - private class TabDragCallback( - directions: Int, itemTouchCallback: ItemTouchCallback + directions: Int, + itemTouchCallback: ItemTouchCallback ) : SimpleDragCallback(directions, itemTouchCallback) { private var draggingView: TabIItem.ViewHolder? = null @@ -122,7 +135,5 @@ class TabCustomizerActivity : BaseActivity() { } } } - } - } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt index 6d930fff..b706d467 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.activities import android.annotation.SuppressLint @@ -5,25 +21,52 @@ import android.content.Intent import android.graphics.PointF import android.net.Uri import android.os.Bundle -import androidx.coordinatorlayout.widget.CoordinatorLayout -import androidx.appcompat.widget.Toolbar import android.view.Menu import android.view.MenuItem import android.webkit.ValueCallback import android.webkit.WebChromeClient import android.widget.FrameLayout +import androidx.appcompat.widget.Toolbar +import androidx.coordinatorlayout.widget.CoordinatorLayout import ca.allanwang.kau.swipe.kauSwipeOnCreate import ca.allanwang.kau.swipe.kauSwipeOnDestroy -import ca.allanwang.kau.utils.* +import ca.allanwang.kau.utils.bindView +import ca.allanwang.kau.utils.copyToClipboard +import ca.allanwang.kau.utils.darken +import ca.allanwang.kau.utils.dpToPx +import ca.allanwang.kau.utils.finishSlideOut +import ca.allanwang.kau.utils.navigationBarColor +import ca.allanwang.kau.utils.setMenuIcons +import ca.allanwang.kau.utils.shareText +import ca.allanwang.kau.utils.statusBarColor +import ca.allanwang.kau.utils.tint +import ca.allanwang.kau.utils.toDrawable +import ca.allanwang.kau.utils.toast +import ca.allanwang.kau.utils.withAlpha import com.google.android.material.snackbar.BaseTransientBottomBar import com.mikepenz.community_material_typeface_library.CommunityMaterial import com.mikepenz.google_material_typeface_library.GoogleMaterial import com.pitchedapps.frost.R -import com.pitchedapps.frost.contracts.* +import com.pitchedapps.frost.contracts.ActivityContract +import com.pitchedapps.frost.contracts.FileChooserContract +import com.pitchedapps.frost.contracts.FileChooserDelegate +import com.pitchedapps.frost.contracts.FrostContentContainer +import com.pitchedapps.frost.contracts.VideoViewHolder import com.pitchedapps.frost.enums.OverlayContext -import com.pitchedapps.frost.facebook.* +import com.pitchedapps.frost.facebook.FB_URL_BASE +import com.pitchedapps.frost.facebook.FbCookie +import com.pitchedapps.frost.facebook.FbItem +import com.pitchedapps.frost.facebook.USER_AGENT_BASIC +import com.pitchedapps.frost.facebook.formattedFbUrl import com.pitchedapps.frost.services.FrostRunnable -import com.pitchedapps.frost.utils.* +import com.pitchedapps.frost.utils.ARG_URL +import com.pitchedapps.frost.utils.ARG_USER_ID +import com.pitchedapps.frost.utils.L +import com.pitchedapps.frost.utils.Prefs +import com.pitchedapps.frost.utils.Showcase +import com.pitchedapps.frost.utils.frostSnackbar +import com.pitchedapps.frost.utils.materialDialogThemed +import com.pitchedapps.frost.utils.setFrostColors import com.pitchedapps.frost.views.FrostContentWeb import com.pitchedapps.frost.views.FrostVideoViewer import com.pitchedapps.frost.views.FrostWebView @@ -31,7 +74,6 @@ import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.Disposable import okhttp3.HttpUrl - /** * Created by Allan Wang on 2017-06-01. * @@ -103,8 +145,8 @@ class WebOverlayActivity : WebOverlayActivityBase(false) @SuppressLint("Registered") open class WebOverlayActivityBase(private val forceBasicAgent: Boolean) : BaseActivity(), - ActivityContract, FrostContentContainer, - VideoViewHolder, FileChooserContract by FileChooserDelegate() { + ActivityContract, FrostContentContainer, + VideoViewHolder, FileChooserContract by FileChooserDelegate() { override val frameWrapper: FrameLayout by bindView(R.id.frame_wrapper) val toolbar: Toolbar by bindView(R.id.overlay_toolbar) @@ -156,9 +198,9 @@ open class WebOverlayActivityBase(private val forceBasicAgent: Boolean) : BaseAc content.bind(this) content.titleObservable - .observeOn(AndroidSchedulers.mainThread()) - .subscribe { toolbar.title = it } - .disposeOnDestroy() + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { toolbar.title = it } + .disposeOnDestroy() with(web) { if (forceBasicAgent) //todo check; the webview already adds it dynamically @@ -235,7 +277,10 @@ open class WebOverlayActivityBase(private val forceBasicAgent: Boolean) : BaseAc kauSwipeOnDestroy() } - override fun openFileChooser(filePathCallback: ValueCallback?>, fileChooserParams: WebChromeClient.FileChooserParams) { + override fun openFileChooser( + filePathCallback: ValueCallback?>, + fileChooserParams: WebChromeClient.FileChooserParams + ) { openMediaPicker(filePathCallback, fileChooserParams) } @@ -247,9 +292,11 @@ open class WebOverlayActivityBase(private val forceBasicAgent: Boolean) : BaseAc menuInflater.inflate(R.menu.menu_web, menu) overlayContext?.onMenuCreate(this, menu) toolbar.tint(Prefs.iconColor) - setMenuIcons(menu, Prefs.iconColor, - R.id.action_share to CommunityMaterial.Icon2.cmd_share, - R.id.action_copy_link to GoogleMaterial.Icon.gmd_content_copy) + setMenuIcons( + menu, Prefs.iconColor, + R.id.action_share to CommunityMaterial.Icon2.cmd_share, + R.id.action_copy_link to GoogleMaterial.Icon.gmd_content_copy + ) return true } @@ -270,5 +317,4 @@ open class WebOverlayActivityBase(private val forceBasicAgent: Boolean) : BaseAc */ override var videoViewer: FrostVideoViewer? = null override val lowerVideoPadding: PointF = PointF(0f, 0f) - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt b/app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt index 1182e609..2ce83871 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.contracts import com.mikepenz.iconics.typeface.IIcon @@ -25,4 +41,4 @@ interface MainActivityContract : ActivityContract, MainFabContract { interface MainFabContract { fun showFab(iicon: IIcon, clickEvent: () -> Unit) fun hideFab() -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/contracts/DynamicUiContract.kt b/app/src/main/kotlin/com/pitchedapps/frost/contracts/DynamicUiContract.kt index 303c64b3..736ef72d 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/contracts/DynamicUiContract.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/DynamicUiContract.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.contracts /** @@ -21,10 +37,8 @@ interface DynamicUiContract { */ fun reloadTextSize() - /** * Change text size without propagation */ fun reloadTextSizeSelf() - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FileChooser.kt b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FileChooser.kt index 15165456..73d5c56d 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FileChooser.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FileChooser.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.contracts import android.app.Activity @@ -17,12 +33,19 @@ import com.pitchedapps.frost.utils.L const val MEDIA_CHOOSER_RESULT = 67 interface FileChooserActivityContract { - fun openFileChooser(filePathCallback: ValueCallback?>, fileChooserParams: WebChromeClient.FileChooserParams) + fun openFileChooser( + filePathCallback: ValueCallback?>, + fileChooserParams: WebChromeClient.FileChooserParams + ) } interface FileChooserContract { var filePathCallback: ValueCallback?>? - fun Activity.openMediaPicker(filePathCallback: ValueCallback?>, fileChooserParams: WebChromeClient.FileChooserParams) + fun Activity.openMediaPicker( + filePathCallback: ValueCallback?>, + fileChooserParams: WebChromeClient.FileChooserParams + ) + fun Activity.onActivityResultWeb(requestCode: Int, resultCode: Int, intent: Intent?): Boolean } @@ -30,7 +53,10 @@ class FileChooserDelegate : FileChooserContract { override var filePathCallback: ValueCallback?>? = null - override fun Activity.openMediaPicker(filePathCallback: ValueCallback?>, fileChooserParams: WebChromeClient.FileChooserParams) { + override fun Activity.openMediaPicker( + filePathCallback: ValueCallback?>, + fileChooserParams: WebChromeClient.FileChooserParams + ) { kauRequestPermissions(PERMISSION_WRITE_EXTERNAL_STORAGE) { granted, _ -> if (!granted) { filePathCallback.onReceiveValue(null) @@ -52,5 +78,4 @@ class FileChooserDelegate : FileChooserContract { filePathCallback = null return true } - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt index 613295e6..50c2fe77 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostContentContract.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.contracts import android.view.View @@ -23,7 +39,6 @@ interface FrostContentContainer { * Update toolbar title */ fun setTitle(title: String) - } /** @@ -84,7 +99,6 @@ interface FrostContentParent : DynamicUiContract { * For those cases, we will return false to stop it */ fun registerTransition(urlChanged: Boolean, animate: Boolean): Boolean - } /** @@ -147,5 +161,4 @@ interface FrostContentCore : DynamicUiContract { * Signal destruction to release some content manually */ fun destroy() - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostObservables.kt b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostObservables.kt index 882b67a0..b3b93b66 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostObservables.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostObservables.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.contracts import io.reactivex.subjects.BehaviorSubject @@ -27,5 +43,4 @@ interface FrostObservables { other.progressObservable = progressObservable other.titleObservable = titleObservable } - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostThemable.kt b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostThemable.kt index 3322f62e..93d827a6 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostThemable.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FrostThemable.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.contracts import android.view.View @@ -18,12 +34,11 @@ interface FrostThemable { fun reloadTheme() fun setTextColors(color: Int, vararg textViews: TextView?) = - themeViews(color, *textViews) { setTextColor(it) } + themeViews(color, *textViews) { setTextColor(it) } fun setBackgrounds(color: Int, vararg views: View?) = - themeViews(color, *views) { setBackgroundColor(it) } + themeViews(color, *views) { setBackgroundColor(it) } fun themeViews(color: Int, vararg views: T?, action: T.(Int) -> Unit) = - views.filterNotNull().forEach { it.action(color) } - -} \ No newline at end of file + views.filterNotNull().forEach { it.action(color) } +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/contracts/VideoViewHolder.kt b/app/src/main/kotlin/com/pitchedapps/frost/contracts/VideoViewHolder.kt index 13b6a7aa..e749b0d3 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/contracts/VideoViewHolder.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/VideoViewHolder.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.contracts import android.app.Activity @@ -49,5 +65,4 @@ interface FrameWrapper { setContentView(R.layout.activity_frame_wrapper) frameWrapper.inflate(layoutRes, true) } - } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt index 1fe65d5a..db3bf973 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.dbflow import android.os.Parcel @@ -11,7 +27,13 @@ import com.raizlabs.android.dbflow.annotation.ConflictAction import com.raizlabs.android.dbflow.annotation.Database import com.raizlabs.android.dbflow.annotation.PrimaryKey import com.raizlabs.android.dbflow.annotation.Table -import com.raizlabs.android.dbflow.kotlinextensions.* +import com.raizlabs.android.dbflow.kotlinextensions.async +import com.raizlabs.android.dbflow.kotlinextensions.delete +import com.raizlabs.android.dbflow.kotlinextensions.eq +import com.raizlabs.android.dbflow.kotlinextensions.from +import com.raizlabs.android.dbflow.kotlinextensions.save +import com.raizlabs.android.dbflow.kotlinextensions.select +import com.raizlabs.android.dbflow.kotlinextensions.where import com.raizlabs.android.dbflow.structure.BaseModel import io.reactivex.disposables.Disposable import io.reactivex.schedulers.Schedulers @@ -30,7 +52,8 @@ object CookiesDb { @PaperParcel @Table(database = CookiesDb::class, allFields = true, primaryKeyConflict = ConflictAction.REPLACE) -data class CookieModel(@PrimaryKey var id: Long = -1L, var name: String? = null, var cookie: String? = null) : BaseModel(), Parcelable { +data class CookieModel(@PrimaryKey var id: Long = -1L, var name: String? = null, var cookie: String? = null) : + BaseModel(), Parcelable { companion object { @JvmField val CREATOR = PaperParcelCookieModel.CREATOR @@ -40,18 +63,22 @@ data class CookieModel(@PrimaryKey var id: Long = -1L, var name: String? = null, override fun writeToParcel(dest: Parcel, flags: Int) = PaperParcelCookieModel.writeToParcel(this, dest, flags) } -fun loadFbCookie(id: Long): CookieModel? = (select from CookieModel::class where (CookieModel_Table.id eq id)).querySingle() -fun loadFbCookie(name: String): CookieModel? = (select from CookieModel::class where (CookieModel_Table.name eq name)).querySingle() +fun loadFbCookie(id: Long): CookieModel? = + (select from CookieModel::class where (CookieModel_Table.id eq id)).querySingle() + +fun loadFbCookie(name: String): CookieModel? = + (select from CookieModel::class where (CookieModel_Table.name eq name)).querySingle() /** * Loads cookies sorted by name */ fun loadFbCookiesAsync(callback: (cookies: List) -> Unit) { - (select from CookieModel::class).orderBy(CookieModel_Table.name, true).async().queryListResultCallback { _, tResult -> callback(tResult) }.execute() + (select from CookieModel::class).orderBy(CookieModel_Table.name, true).async() + .queryListResultCallback { _, tResult -> callback(tResult) }.execute() } -fun loadFbCookiesSync(): List = (select from CookieModel::class).orderBy(CookieModel_Table.name, true).queryList() - +fun loadFbCookiesSync(): List = + (select from CookieModel::class).orderBy(CookieModel_Table.name, true).queryList() inline fun saveFbCookie(cookie: CookieModel, crossinline callback: (() -> Unit) = {}) { cookie.async save { @@ -69,24 +96,24 @@ fun removeCookie(id: Long) { } inline fun CookieModel.fetchUsername(crossinline callback: (String) -> Unit): Disposable = - ReactiveNetwork.checkInternetConnectivity().subscribeOn(Schedulers.io()).subscribe { yes, _ -> - if (!yes) return@subscribe callback("") - var result = "" - try { - result = frostJsoup(cookie, FbItem.PROFILE.url).title() - L.d { "Fetch username found" } - } catch (e: Exception) { - if (e !is UnknownHostException) - e.logFrostEvent("Fetch username failed") - } finally { - if (result.isBlank() && (name?.isNotBlank() == true)) { - callback(name!!) - return@subscribe - } - if (name != result) { - name = result - saveFbCookie(this@fetchUsername) - } - callback(result) + ReactiveNetwork.checkInternetConnectivity().subscribeOn(Schedulers.io()).subscribe { yes, _ -> + if (!yes) return@subscribe callback("") + var result = "" + try { + result = frostJsoup(cookie, FbItem.PROFILE.url).title() + L.d { "Fetch username found" } + } catch (e: Exception) { + if (e !is UnknownHostException) + e.logFrostEvent("Fetch username failed") + } finally { + if (result.isBlank() && (name?.isNotBlank() == true)) { + callback(name!!) + return@subscribe } + if (name != result) { + name = result + saveFbCookie(this@fetchUsername) + } + callback(result) } + } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/DbUtils.kt b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/DbUtils.kt index e4aef2a9..740fef62 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/DbUtils.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/DbUtils.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.dbflow import android.content.Context @@ -14,11 +30,10 @@ object DbUtils { fun db(name: String) = FlowManager.getDatabase(name) fun dbName(name: String) = "$name.db" fun deleteDatabase(c: Context, name: String) = c.deleteDatabase(dbName(name)) - } inline fun List.replace(dbName: String) { L.d { "Replacing $dbName.db" } DbUtils.db(dbName).reset() FastStoreModelTransaction.saveBuilder(FlowManager.getModelAdapter(T::class.java)).addAll(this).build() -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/FbTabsDb.kt b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/FbTabsDb.kt index 827881e3..9d330169 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/FbTabsDb.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/FbTabsDb.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.dbflow import com.pitchedapps.frost.facebook.FbItem @@ -39,4 +55,4 @@ fun loadFbTabs(): List { fun List.save() { database().beginTransactionAsync(mapIndexed(::FbTabModel).fastSave().build()).execute() -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/NotificationDb.kt b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/NotificationDb.kt index b61fc218..a054d95e 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/NotificationDb.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/NotificationDb.kt @@ -1,8 +1,33 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.dbflow import com.pitchedapps.frost.utils.L -import com.raizlabs.android.dbflow.annotation.* -import com.raizlabs.android.dbflow.kotlinextensions.* +import com.raizlabs.android.dbflow.annotation.ConflictAction +import com.raizlabs.android.dbflow.annotation.Database +import com.raizlabs.android.dbflow.annotation.Migration +import com.raizlabs.android.dbflow.annotation.PrimaryKey +import com.raizlabs.android.dbflow.annotation.Table +import com.raizlabs.android.dbflow.kotlinextensions.async +import com.raizlabs.android.dbflow.kotlinextensions.eq +import com.raizlabs.android.dbflow.kotlinextensions.from +import com.raizlabs.android.dbflow.kotlinextensions.save +import com.raizlabs.android.dbflow.kotlinextensions.select +import com.raizlabs.android.dbflow.kotlinextensions.where import com.raizlabs.android.dbflow.sql.SQLiteType import com.raizlabs.android.dbflow.sql.migration.AlterTableMigration import com.raizlabs.android.dbflow.structure.BaseModel @@ -18,7 +43,8 @@ object NotificationDb { } @Migration(version = 2, database = NotificationDb::class) -class NotificationMigration2(modelClass: Class) : AlterTableMigration(modelClass) { +class NotificationMigration2(modelClass: Class) : + AlterTableMigration(modelClass) { override fun onPreMigrate() { super.onPreMigrate() addColumn(SQLiteType.INTEGER, "epochIm") @@ -27,11 +53,14 @@ class NotificationMigration2(modelClass: Class) : AlterTableM } @Table(database = NotificationDb::class, allFields = true, primaryKeyConflict = ConflictAction.REPLACE) -data class NotificationModel(@PrimaryKey var id: Long = -1L, - var epoch: Long = -1L, - var epochIm: Long = -1L) : BaseModel() +data class NotificationModel( + @PrimaryKey var id: Long = -1L, + var epoch: Long = -1L, + var epochIm: Long = -1L +) : BaseModel() -fun lastNotificationTime(id: Long): NotificationModel = (select from NotificationModel::class where (NotificationModel_Table.id eq id)).querySingle() +fun lastNotificationTime(id: Long): NotificationModel = + (select from NotificationModel::class where (NotificationModel_Table.id eq id)).querySingle() ?: NotificationModel(id = id) fun saveNotificationTime(notificationModel: NotificationModel, callback: (() -> Unit)? = null) { @@ -40,4 +69,4 @@ fun saveNotificationTime(notificationModel: NotificationModel, callback: (() -> L._d { notificationModel } callback?.invoke() } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/debugger/OfflineWebsite.kt b/app/src/main/kotlin/com/pitchedapps/frost/debugger/OfflineWebsite.kt index 6298f1f9..f5009cc5 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/debugger/OfflineWebsite.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/debugger/OfflineWebsite.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.debugger import ca.allanwang.kau.logging.KauLoggerExtension @@ -32,21 +48,23 @@ import java.util.zip.ZipOutputStream * * Inspired by Save for Offline */ -class OfflineWebsite(private val url: String, - private val cookie: String = "", - baseUrl: String? = null, - private val html: String? = null, - /** - * Directory that holds all the files - */ - val baseDir: File, - private val userAgent: String = USER_AGENT_BASIC) { +class OfflineWebsite( + private val url: String, + private val cookie: String = "", + baseUrl: String? = null, + private val html: String? = null, + /** + * Directory that holds all the files + */ + val baseDir: File, + private val userAgent: String = USER_AGENT_BASIC +) { /** * Supplied url without the queries */ private val baseUrl = (baseUrl ?: url.substringBefore("?") - .substringBefore(".com")).trim('/') + .substringBefore(".com")).trim('/') private val mainFile = File(baseDir, "index.html") private val assetDir = File(baseDir, "assets") @@ -67,11 +85,11 @@ class OfflineWebsite(private val url: String, private val cssQueue = mutableSetOf() private fun request(url: String) = Request.Builder() - .header("Cookie", cookie) - .header("User-Agent", userAgent) - .url(url) - .get() - .call() + .header("Cookie", cookie) + .header("User-Agent", userAgent) + .url(url) + .get() + .call() private val compositeDisposable = CompositeDisposable() @@ -94,7 +112,6 @@ class OfflineWebsite(private val url: String, return callback(false) } - if (!assetDir.createFreshDir()) { L.e { "Could not create ${assetDir.absolutePath}" } return callback(false) @@ -245,8 +262,10 @@ class OfflineWebsite(private val url: String, } }) - private inline fun String.downloadUrl(fallback: () -> T, - action: (file: File, body: ResponseBody) -> T): T { + private inline fun String.downloadUrl( + fallback: () -> T, + action: (file: File, body: ResponseBody) -> T + ): T { val file = File(assetDir, fileName()) if (!file.createNewFile()) { @@ -289,11 +308,10 @@ class OfflineWebsite(private val url: String, if (mapped != null) return mapped val candidate = substringBefore("?").trim('/') - .substringAfterLast("/").shorten() + .substringAfterLast("/").shorten() val index = atomicInt.getAndIncrement() - var newUrl = "a${index}_$candidate" /** @@ -308,10 +326,10 @@ class OfflineWebsite(private val url: String, } private fun String.shorten() = - if (length <= 10) this else substring(length - 10) + if (length <= 10) this else substring(length - 10) private fun Set.clean(): List = - filter(String::isNotBlank).filter { it.startsWith("http") } + filter(String::isNotBlank).filter { it.startsWith("http") } private fun reset() { cancelled = false @@ -326,5 +344,4 @@ class OfflineWebsite(private val url: String, compositeDisposable.dispose() L.v { "Request cancelled" } } - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/enums/FeedSort.kt b/app/src/main/kotlin/com/pitchedapps/frost/enums/FeedSort.kt index d8a0f349..7312399e 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/enums/FeedSort.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/enums/FeedSort.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.enums import androidx.annotation.StringRes @@ -16,4 +32,4 @@ enum class FeedSort(@StringRes val textRes: Int, val item: FbItem) { val values = values() //save one instance operator fun invoke(index: Int) = values[index] } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/enums/MainActivityLayout.kt b/app/src/main/kotlin/com/pitchedapps/frost/enums/MainActivityLayout.kt index 79b11752..2d51b032 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/enums/MainActivityLayout.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/enums/MainActivityLayout.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.enums import com.pitchedapps.frost.R @@ -7,23 +23,24 @@ import com.pitchedapps.frost.utils.Prefs * Created by Allan Wang on 2017-08-19. */ enum class MainActivityLayout( - val titleRes: Int, - val layoutRes: Int, - val backgroundColor: () -> Int, - val iconColor: () -> Int) { + val titleRes: Int, + val layoutRes: Int, + val backgroundColor: () -> Int, + val iconColor: () -> Int +) { TOP_BAR(R.string.top_bar, - R.layout.activity_main, - { Prefs.headerColor }, - { Prefs.iconColor }), + R.layout.activity_main, + { Prefs.headerColor }, + { Prefs.iconColor }), BOTTOM_BAR(R.string.bottom_bar, - R.layout.activity_main_bottom_tabs, - { Prefs.bgColor }, - { Prefs.textColor }); + R.layout.activity_main_bottom_tabs, + { Prefs.bgColor }, + { Prefs.textColor }); companion object { val values = values() //save one instance operator fun invoke(index: Int) = values[index] } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/enums/OverlayContext.kt b/app/src/main/kotlin/com/pitchedapps/frost/enums/OverlayContext.kt index f93a2229..d529db12 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/enums/OverlayContext.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/enums/OverlayContext.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.enums import android.content.Context @@ -52,12 +68,13 @@ enum class OverlayContext(private val menuItem: FrostMenuItem?) : EnumBundle. + */ package com.pitchedapps.frost.enums import android.content.Context @@ -21,4 +37,4 @@ enum class Support(@StringRes val title: Int) { } } } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/enums/Theme.kt b/app/src/main/kotlin/com/pitchedapps/frost/enums/Theme.kt index 934dda07..345aa88e 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/enums/Theme.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/enums/Theme.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.enums import android.graphics.Color @@ -14,61 +30,63 @@ import com.pitchedapps.frost.utils.Prefs const val FACEBOOK_BLUE = 0xff3b5998.toInt() const val BLUE_LIGHT = 0xff5d86dd.toInt() -enum class Theme(@StringRes val textRes: Int, - val injector: InjectorContract, - private val textColorGetter: () -> Int, - private val accentColorGetter: () -> Int, - private val backgroundColorGetter: () -> Int, - private val headerColorGetter: () -> Int, - private val iconColorGetter: () -> Int) { +enum class Theme( + @StringRes val textRes: Int, + val injector: InjectorContract, + private val textColorGetter: () -> Int, + private val accentColorGetter: () -> Int, + private val backgroundColorGetter: () -> Int, + private val headerColorGetter: () -> Int, + private val iconColorGetter: () -> Int +) { DEFAULT(R.string.kau_default, - JsActions.EMPTY, - { 0xde000000.toInt() }, - { FACEBOOK_BLUE }, - { 0xfffafafa.toInt() }, - { FACEBOOK_BLUE }, - { Color.WHITE }), + JsActions.EMPTY, + { 0xde000000.toInt() }, + { FACEBOOK_BLUE }, + { 0xfffafafa.toInt() }, + { FACEBOOK_BLUE }, + { Color.WHITE }), LIGHT(R.string.kau_light, - CssAssets.MATERIAL_LIGHT, - { 0xde000000.toInt() }, - { FACEBOOK_BLUE }, - { 0xfffafafa.toInt() }, - { FACEBOOK_BLUE }, - { Color.WHITE }), + CssAssets.MATERIAL_LIGHT, + { 0xde000000.toInt() }, + { FACEBOOK_BLUE }, + { 0xfffafafa.toInt() }, + { FACEBOOK_BLUE }, + { Color.WHITE }), DARK(R.string.kau_dark, - CssAssets.MATERIAL_DARK, - { Color.WHITE }, - { BLUE_LIGHT }, - { 0xff303030.toInt() }, - { 0xff2e4b86.toInt() }, - { Color.WHITE }), + CssAssets.MATERIAL_DARK, + { Color.WHITE }, + { BLUE_LIGHT }, + { 0xff303030.toInt() }, + { 0xff2e4b86.toInt() }, + { Color.WHITE }), AMOLED(R.string.kau_amoled, - CssAssets.MATERIAL_AMOLED, - { Color.WHITE }, - { BLUE_LIGHT }, - { Color.BLACK }, - { Color.BLACK }, - { Color.WHITE }), + CssAssets.MATERIAL_AMOLED, + { Color.WHITE }, + { BLUE_LIGHT }, + { Color.BLACK }, + { Color.BLACK }, + { Color.WHITE }), GLASS(R.string.kau_glass, - CssAssets.MATERIAL_GLASS, - { Color.WHITE }, - { BLUE_LIGHT }, - { 0x80000000.toInt() }, - { 0xb3000000.toInt() }, - { Color.WHITE }), + CssAssets.MATERIAL_GLASS, + { Color.WHITE }, + { BLUE_LIGHT }, + { 0x80000000.toInt() }, + { 0xb3000000.toInt() }, + { Color.WHITE }), CUSTOM(R.string.kau_custom, - CssAssets.CUSTOM, - { Prefs.customTextColor }, - { Prefs.customAccentColor }, - { Prefs.customBackgroundColor }, - { Prefs.customHeaderColor }, - { Prefs.customIconColor }); + CssAssets.CUSTOM, + { Prefs.customTextColor }, + { Prefs.customAccentColor }, + { Prefs.customBackgroundColor }, + { Prefs.customHeaderColor }, + { Prefs.customIconColor }); val textColor: Int get() = textColorGetter() @@ -89,4 +107,4 @@ enum class Theme(@StringRes val textRes: Int, val values = values() //save one instance operator fun invoke(index: Int) = values[index] } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbConst.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbConst.kt index 2b881d1c..b6207a7b 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbConst.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbConst.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.facebook /** @@ -12,9 +28,12 @@ fun profilePictureUrl(id: Long) = "https://graph.facebook.com/$id/picture?type=l const val FB_LOGIN_URL = "${FB_URL_BASE}login" const val FB_HOME_URL = "${FB_URL_BASE}home.php" -const val USER_AGENT_FULL = "Mozilla/5.0 (Linux; Android 4.4.2; en-us; SAMSUNG SM-G900T Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/1.6 Chrome/28.0.1500.94 Mobile Safari/537.36" -const val USER_AGENT_BASIC_OLD = "Mozilla/5.0 (Linux; Android 6.0) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.1.0.4633 Mobile Safari/537.10+" -const val USER_AGENT_MESSENGER = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36" +const val USER_AGENT_FULL = + "Mozilla/5.0 (Linux; Android 4.4.2; en-us; SAMSUNG SM-G900T Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/1.6 Chrome/28.0.1500.94 Mobile Safari/537.36" +const val USER_AGENT_BASIC_OLD = + "Mozilla/5.0 (Linux; Android 6.0) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.1.0.4633 Mobile Safari/537.10+" +const val USER_AGENT_MESSENGER = + "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36" const val USER_AGENT_BASIC = USER_AGENT_MESSENGER /** @@ -27,4 +46,4 @@ const val WEB_LOAD_DELAY = 50L * Note that transitions are also called from onFinish, so this value * will never make a load slower than it is */ -const val WEB_COMMIT_LOAD_DELAY = 200L \ No newline at end of file +const val WEB_COMMIT_LOAD_DELAY = 200L diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbCookie.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbCookie.kt index ab7e165a..c6583712 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbCookie.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbCookie.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.facebook import android.app.Activity @@ -38,13 +54,13 @@ object FbCookie { val cookies = cookie.split(";").map { Pair(it, SingleSubject.create()) } cookies.forEach { (cookie, callback) -> setCookie(FB_URL_BASE, cookie) { callback.onSuccess(it) } } Observable.zip(cookies.map { (_, callback) -> callback.toObservable() }) {} - .observeOn(AndroidSchedulers.mainThread()) - .subscribe { - callback?.invoke() - L.d { "Cookies set" } - L._d { cookie } - flush() - } + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { + callback?.invoke() + L.d { "Cookies set" } + L._d { cookie } + flush() + } } } } @@ -132,4 +148,4 @@ object FbCookie { } } else callback() } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbItem.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbItem.kt index 2f0e4e22..723ed450 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbItem.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbItem.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.facebook import androidx.annotation.StringRes @@ -15,10 +31,10 @@ import com.pitchedapps.frost.utils.EnumBundleCompanion import com.pitchedapps.frost.utils.EnumCompanion enum class FbItem( - @StringRes val titleId: Int, - val icon: IIcon, - relativeUrl: String, - val fragmentCreator: () -> BaseFragment = ::WebFragment + @StringRes val titleId: Int, + val icon: IIcon, + relativeUrl: String, + val fragmentCreator: () -> BaseFragment = ::WebFragment ) : EnumBundle { ACTIVITY_LOG(R.string.activity_log, GoogleMaterial.Icon.gmd_list, "me/allactivity"), diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbRegex.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbRegex.kt index 9b29d009..2c987a48 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbRegex.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbRegex.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.facebook /** @@ -29,4 +45,3 @@ val FB_IMAGE_ID_MATCHER: Regex = Regex("fbcdn.*?/[0-9]+_([0-9]+)_") val FB_REDIRECT_URL_MATCHER: Regex = Regex("url=(.*?fbcdn.*?)\"") operator fun MatchResult?.get(groupIndex: Int) = this?.groupValues?.get(groupIndex) - diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbUrlFormatter.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbUrlFormatter.kt index 62675df6..2c171762 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbUrlFormatter.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbUrlFormatter.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.facebook import com.pitchedapps.frost.utils.L @@ -91,13 +107,13 @@ class FbUrlFormatter(url: String) { * That shouldn't break anything */ val discardable = arrayOf( - "http://lm.facebook.com/l.php?u=", - "https://lm.facebook.com/l.php?u=", - "http://m.facebook.com/l.php?u=", - "https://m.facebook.com/l.php?u=", - "http://touch.facebook.com/l.php?u=", - "https://touch.facebook.com/l.php?u=", - VIDEO_REDIRECT + "http://lm.facebook.com/l.php?u=", + "https://lm.facebook.com/l.php?u=", + "http://m.facebook.com/l.php?u=", + "https://m.facebook.com/l.php?u=", + "http://touch.facebook.com/l.php?u=", + "https://touch.facebook.com/l.php?u=", + VIDEO_REDIRECT ) /** @@ -108,13 +124,13 @@ class FbUrlFormatter(url: String) { val discardableQueries = arrayOf("ref", "refid", "SharedWith") val converter = listOf( - "\\3C " to "%3C", "\\3E " to "%3E", "\\23 " to "%23", "\\25 " to "%25", - "\\7B " to "%7B", "\\7D " to "%7D", "\\7C " to "%7C", "\\5C " to "%5C", - "\\5E " to "%5E", "\\7E " to "%7E", "\\5B " to "%5B", "\\5D " to "%5D", - "\\60 " to "%60", "\\3B " to "%3B", "\\2F " to "%2F", "\\3F " to "%3F", - "\\3A " to "%3A", "\\40 " to "%40", "\\3D " to "%3D", "\\26 " to "%26", - "\\24 " to "%24", "\\2B " to "%2B", "\\22 " to "%22", "\\2C " to "%2C", - "\\20 " to "%20" + "\\3C " to "%3C", "\\3E " to "%3E", "\\23 " to "%23", "\\25 " to "%25", + "\\7B " to "%7B", "\\7D " to "%7D", "\\7C " to "%7C", "\\5C " to "%5C", + "\\5E " to "%5E", "\\7E " to "%7E", "\\5B " to "%5B", "\\5D " to "%5D", + "\\60 " to "%60", "\\3B " to "%3B", "\\2F " to "%2F", "\\3F " to "%3F", + "\\3A " to "%3A", "\\40 " to "%40", "\\3D " to "%3D", "\\26 " to "%26", + "\\24 " to "%24", "\\2B " to "%2B", "\\22 " to "%22", "\\2C " to "%2C", + "\\20 " to "%20" ) } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/FrostParser.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/FrostParser.kt index 3d5c5bce..5709bb9f 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/FrostParser.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/FrostParser.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.facebook.parsers import com.pitchedapps.frost.dbflow.CookieModel @@ -54,7 +70,6 @@ interface FrostParser { * Call parsing with given data */ fun parseFromData(cookie: String?, text: String): ParseResponse? - } const val FALLBACK_TIME_MOD = 1000000 @@ -92,7 +107,7 @@ internal abstract class FrostParserBase(private val redirectToText: } final override fun parseFromUrl(cookie: String?, url: String): ParseResponse? = - parse(cookie, frostJsoup(cookie, url)) + parse(cookie, frostJsoup(cookie, url)) override fun parse(cookie: String?, document: Document): ParseResponse? { cookie ?: return null @@ -109,17 +124,17 @@ internal abstract class FrostParserBase(private val redirectToText: * Returns the formatted url, or an empty string if nothing was found */ protected fun Element.getInnerImgStyle(): String? = - select("i.img[style*=url]").getStyleUrl() + select("i.img[style*=url]").getStyleUrl() protected fun Elements.getStyleUrl(): String? = - FB_CSS_URL_MATCHER.find(attr("style"))[1]?.formattedFbUrl + FB_CSS_URL_MATCHER.find(attr("style"))[1]?.formattedFbUrl protected open fun textToDoc(text: String): Document? = - if (!redirectToText) Jsoup.parse(text) - else throw RuntimeException("${this::class.java.simpleName} requires text redirect but did not implement textToDoc") + if (!redirectToText) Jsoup.parse(text) + else throw RuntimeException("${this::class.java.simpleName} requires text redirect but did not implement textToDoc") protected fun parseLink(element: Element?): FrostLink? { val a = element?.getElementsByTag("a")?.first() ?: return null return FrostLink(a.text(), a.attr("href")) } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/MessageParser.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/MessageParser.kt index 27b731bc..f05c42e9 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/MessageParser.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/MessageParser.kt @@ -1,7 +1,27 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.facebook.parsers import com.pitchedapps.frost.dbflow.CookieModel -import com.pitchedapps.frost.facebook.* +import com.pitchedapps.frost.facebook.FB_EPOCH_MATCHER +import com.pitchedapps.frost.facebook.FB_MESSAGE_NOTIF_ID_MATCHER +import com.pitchedapps.frost.facebook.FbItem +import com.pitchedapps.frost.facebook.formattedFbUrl +import com.pitchedapps.frost.facebook.get import com.pitchedapps.frost.services.NotificationContent import com.pitchedapps.frost.utils.L import org.apache.commons.text.StringEscapeUtils @@ -19,12 +39,12 @@ import org.jsoup.nodes.Element object MessageParser : FrostParser by MessageParserImpl() { fun queryUser(cookie: String?, name: String) = parseFromUrl(cookie, "${FbItem.MESSAGES.url}/?q=$name") - } -data class FrostMessages(val threads: List, - val seeMore: FrostLink?, - val extraLinks: List +data class FrostMessages( + val threads: List, + val seeMore: FrostLink?, + val extraLinks: List ) : ParseNotification { override fun toString() = StringBuilder().apply { append("FrostMessages {\n") @@ -35,19 +55,19 @@ data class FrostMessages(val threads: List, }.toString() override fun getUnreadNotifications(data: CookieModel) = - threads.asSequence().filter(FrostThread::unread).map { - with(it) { - NotificationContent( - data = data, - id = id, - href = url, - title = title, - text = content ?: "", - timestamp = time, - profileUrl = img - ) - } - }.toList() + threads.asSequence().filter(FrostThread::unread).map { + with(it) { + NotificationContent( + data = data, + id = id, + href = url, + title = title, + text = content ?: "", + timestamp = time, + profileUrl = img + ) + } + }.toList() } /** @@ -58,14 +78,16 @@ data class FrostMessages(val threads: List, * [unread] true if image is unread, false otherwise * [content] optional string for thread */ -data class FrostThread(val id: Long, - val img: String?, - val title: String, - val time: Long, - val url: String, - val unread: Boolean, - val content: String?, - val contentImgUrl: String?) +data class FrostThread( + val id: Long, + val img: String?, + val title: String, + val time: Long, + val url: String, + val unread: Boolean, + val content: String?, + val contentImgUrl: String? +) private class MessageParserImpl : FrostParserBase(true) { @@ -92,11 +114,12 @@ private class MessageParserImpl : FrostParserBase(true) { override fun parseImpl(doc: Document): FrostMessages? { val threadList = doc.getElementById("threadlist_rows") ?: return null - val threads: List = threadList.getElementsByAttributeValueMatching("id", ".*${FB_MESSAGE_NOTIF_ID_MATCHER.pattern}.*") + val threads: List = + threadList.getElementsByAttributeValueMatching("id", ".*${FB_MESSAGE_NOTIF_ID_MATCHER.pattern}.*") .mapNotNull(this::parseMessage) val seeMore = parseLink(doc.getElementById("see_older_threads")) val extraLinks = threadList.nextElementSibling().select("a") - .mapNotNull(this::parseLink) + .mapNotNull(this::parseLink) return FrostMessages(threads, seeMore, extraLinks) } @@ -106,21 +129,20 @@ private class MessageParserImpl : FrostParserBase(true) { val epoch = FB_EPOCH_MATCHER.find(abbr.attr("data-store"))[1]?.toLongOrNull() ?: -1L //fetch id val id = FB_MESSAGE_NOTIF_ID_MATCHER.find(element.id())[1]?.toLongOrNull() - ?: System.currentTimeMillis() % FALLBACK_TIME_MOD + ?: System.currentTimeMillis() % FALLBACK_TIME_MOD val snippet = element.select("span.snippet").firstOrNull() val content = snippet?.text()?.trim() val contentImg = snippet?.select("i[style*=url]")?.getStyleUrl() val img = element.getInnerImgStyle() return FrostThread( - id = id, - img = img, - title = a.text(), - time = epoch, - url = a.attr("href").formattedFbUrl, - unread = !element.hasClass("acw"), - content = content, - contentImgUrl = contentImg + id = id, + img = img, + title = a.text(), + time = epoch, + url = a.attr("href").formattedFbUrl, + unread = !element.hasClass("acw"), + content = content, + contentImgUrl = contentImg ) } - } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/NotifParser.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/NotifParser.kt index 8aa8e706..b8aa899b 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/NotifParser.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/NotifParser.kt @@ -1,7 +1,27 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.facebook.parsers import com.pitchedapps.frost.dbflow.CookieModel -import com.pitchedapps.frost.facebook.* +import com.pitchedapps.frost.facebook.FB_EPOCH_MATCHER +import com.pitchedapps.frost.facebook.FB_NOTIF_ID_MATCHER +import com.pitchedapps.frost.facebook.FbItem +import com.pitchedapps.frost.facebook.formattedFbUrl +import com.pitchedapps.frost.facebook.get import com.pitchedapps.frost.services.NotificationContent import org.jsoup.nodes.Document import org.jsoup.nodes.Element @@ -13,8 +33,8 @@ import org.jsoup.nodes.Element object NotifParser : FrostParser by NotifParserImpl() data class FrostNotifs( - val notifs: List, - val seeMore: FrostLink? + val notifs: List, + val seeMore: FrostLink? ) : ParseNotification { override fun toString() = StringBuilder().apply { append("FrostNotifs {\n") @@ -24,19 +44,19 @@ data class FrostNotifs( }.toString() override fun getUnreadNotifications(data: CookieModel) = - notifs.asSequence().filter(FrostNotif::unread).map { - with(it) { - NotificationContent( - data = data, - id = id, - href = url, - title = null, - text = content, - timestamp = time, - profileUrl = img - ) - } - }.toList() + notifs.asSequence().filter(FrostNotif::unread).map { + with(it) { + NotificationContent( + data = data, + id = id, + href = url, + title = null, + text = content, + timestamp = time, + profileUrl = img + ) + } + }.toList() } /** @@ -49,14 +69,16 @@ data class FrostNotifs( * [timeString] text version of time from Facebook * [thumbnailUrl] optional thumbnail url if existent */ -data class FrostNotif(val id: Long, - val img: String?, - val time: Long, - val url: String, - val unread: Boolean, - val content: String, - val timeString: String, - val thumbnailUrl: String?) +data class FrostNotif( + val id: Long, + val img: String?, + val time: Long, + val url: String, + val unread: Boolean, + val content: String, + val timeString: String, + val thumbnailUrl: String? +) private class NotifParserImpl : FrostParserBase(false) { @@ -67,8 +89,8 @@ private class NotifParserImpl : FrostParserBase(false) { override fun parseImpl(doc: Document): FrostNotifs? { val notificationList = doc.getElementById("notifications_list") ?: return null val notifications = notificationList - .getElementsByAttributeValueMatching("id", ".*${FB_NOTIF_ID_MATCHER.pattern}.*") - .mapNotNull(this::parseNotif) + .getElementsByAttributeValueMatching("id", ".*${FB_NOTIF_ID_MATCHER.pattern}.*") + .mapNotNull(this::parseNotif) val seeMore = parseLink(doc.getElementsByAttributeValue("href", "/notifications.php?more").first()) return FrostNotifs(notifications, seeMore) } @@ -79,22 +101,20 @@ private class NotifParserImpl : FrostParserBase(false) { val epoch = FB_EPOCH_MATCHER.find(abbr.attr("data-store"))[1]?.toLongOrNull() ?: -1L //fetch id val id = FB_NOTIF_ID_MATCHER.find(element.id())[1]?.toLongOrNull() - ?: System.currentTimeMillis() % FALLBACK_TIME_MOD + ?: System.currentTimeMillis() % FALLBACK_TIME_MOD val img = element.getInnerImgStyle() val timeString = abbr.text() val content = a.text().replace("\u00a0", " ").removeSuffix(timeString).trim() //remove   val thumbnail = element.selectFirst("img.thumbnail")?.attr("src") return FrostNotif( - id = id, - img = img, - time = epoch, - url = a.attr("href").formattedFbUrl, - unread = !element.hasClass("acw"), - content = content, - timeString = timeString, - thumbnailUrl = if (thumbnail?.isNotEmpty() == true) thumbnail else null + id = id, + img = img, + time = epoch, + url = a.attr("href").formattedFbUrl, + unread = !element.hasClass("acw"), + content = content, + timeString = timeString, + thumbnailUrl = if (thumbnail?.isNotEmpty() == true) thumbnail else null ) } - - } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/SearchParser.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/SearchParser.kt index d3367514..7869d881 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/SearchParser.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/SearchParser.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.facebook.parsers import ca.allanwang.kau.searchview.SearchItem @@ -46,9 +62,9 @@ data class FrostSearch(val href: String, val title: String, val description: Str companion object { fun create(href: String, title: String, description: String?) = FrostSearch( - with(href.indexOf("?")) { if (this == -1) href else href.substring(0, this) }, - title.format(), - description?.format() + with(href.indexOf("?")) { if (this == -1) href else href.substring(0, this) }, + title.format(), + description?.format() ) } } @@ -61,17 +77,18 @@ private class SearchParserImpl : FrostParserBase(false) { override fun parseImpl(doc: Document): FrostSearches? { val container: Element = doc.getElementById("BrowseResultsContainer") - ?: doc.getElementById("root") - ?: return null + ?: doc.getElementById("root") + ?: return null /** * * Removed [data-store*=result_id] */ return FrostSearches(container.select("a.touchable[href]").filter(Element::hasText).map { - FrostSearch.create(it.attr("href").formattedFbUrl, - it.select("._uoi").first()?.text() ?: "", - it.select("._1tcc").first()?.text()) + FrostSearch.create( + it.attr("href").formattedFbUrl, + it.select("._uoi").first()?.text() ?: "", + it.select("._1tcc").first()?.text() + ) }.filter { it.title.isNotBlank() }) } - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/FbRequest.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/FbRequest.kt index 500c4102..584107cc 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/FbRequest.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/FbRequest.kt @@ -1,7 +1,29 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.facebook.requests import com.pitchedapps.frost.BuildConfig -import com.pitchedapps.frost.facebook.* +import com.pitchedapps.frost.facebook.FB_DTSG_MATCHER +import com.pitchedapps.frost.facebook.FB_JSON_URL_MATCHER +import com.pitchedapps.frost.facebook.FB_REV_MATCHER +import com.pitchedapps.frost.facebook.FB_URL_BASE +import com.pitchedapps.frost.facebook.FB_USER_MATCHER +import com.pitchedapps.frost.facebook.USER_AGENT_BASIC +import com.pitchedapps.frost.facebook.get import com.pitchedapps.frost.rx.RxFlyweight import com.pitchedapps.frost.utils.L import io.reactivex.Single @@ -21,10 +43,9 @@ private class RxAuth : RxFlyweight() { override fun call(input: String) = input.getAuth() override fun validate(input: String, cond: Long) = - System.currentTimeMillis() - cond < 3600000 // valid for an hour + System.currentTimeMillis() - cond < 3600000 // valid for an hour override fun cache(input: String) = System.currentTimeMillis() - } private val auth = RxAuth() @@ -48,10 +69,12 @@ fun String?.fbRequest(fail: () -> Unit = {}, action: RequestAuth.() -> Unit) { /** * Underlying container for all fb requests */ -data class RequestAuth(val userId: Long = -1, - val cookie: String = "", - val fb_dtsg: String = "", - val rev: String = "") { +data class RequestAuth( + val userId: Long = -1, + val cookie: String = "", + val fb_dtsg: String = "", + val rev: String = "" +) { val isComplete get() = userId > 0 && cookie.isNotEmpty() && fb_dtsg.isNotEmpty() && rev.isNotEmpty() } @@ -64,8 +87,8 @@ class FrostRequest(val call: Call, private val invoke: (Call) -> T } internal inline fun RequestAuth.frostRequest( - noinline invoke: (Call) -> T, - builder: Request.Builder.() -> Request.Builder // to ensure we don't do anything extra at the end + noinline invoke: (Call) -> T, + builder: Request.Builder.() -> Request.Builder // to ensure we don't do anything extra at the end ): FrostRequest { val request = cookie.requestBuilder() request.builder() @@ -75,8 +98,10 @@ internal inline fun RequestAuth.frostRequest( val httpClient: OkHttpClient by lazy { val builder = OkHttpClient.Builder() if (BuildConfig.DEBUG) - builder.addInterceptor(HttpLoggingInterceptor() - .setLevel(HttpLoggingInterceptor.Level.BASIC)) + builder.addInterceptor( + HttpLoggingInterceptor() + .setLevel(HttpLoggingInterceptor.Level.BASIC) + ) builder.build() } @@ -97,7 +122,7 @@ internal fun List>.withEmptyData(vararg key: String): List lines.forEach { val text = StringEscapeUtils.unescapeEcmaScript(it) @@ -135,8 +160,10 @@ fun String.getAuth(): RequestAuth { return auth } -inline fun Array.zip(crossinline mapper: (List) -> O, - crossinline caller: (T) -> R): Single { +inline fun Array.zip( + crossinline mapper: (List) -> O, + crossinline caller: (T) -> R +): Single { if (isEmpty()) return Single.just(mapper(emptyList())) val singles = map { Single.fromCallable { caller(it) }.subscribeOn(Schedulers.io()) } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Images.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Images.kt index 8eeef08d..e0ccea81 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Images.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Images.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.facebook.requests import com.bumptech.glide.Priority @@ -11,7 +27,11 @@ import com.bumptech.glide.load.model.MultiModelLoaderFactory import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.target.Target import com.bumptech.glide.signature.ObjectKey -import com.pitchedapps.frost.facebook.* +import com.pitchedapps.frost.facebook.FB_IMAGE_ID_MATCHER +import com.pitchedapps.frost.facebook.FB_REDIRECT_URL_MATCHER +import com.pitchedapps.frost.facebook.FB_URL_BASE +import com.pitchedapps.frost.facebook.formattedFbUrl +import com.pitchedapps.frost.facebook.get import io.reactivex.Maybe import okhttp3.Call import okhttp3.Request @@ -33,9 +53,9 @@ val test: () -> InputStream? = { null } */ fun String.getFullSizedImageUrl(url: String): Maybe = Maybe.fromCallable { val redirect = requestBuilder().url(url).get().call() - .execute().body()?.string() ?: return@fromCallable null + .execute().body()?.string() ?: return@fromCallable null return@fromCallable FB_REDIRECT_URL_MATCHER.find(redirect)[1]?.formattedFbUrl - ?: return@fromCallable null + ?: return@fromCallable null }.onErrorComplete() /** @@ -51,7 +71,6 @@ data class HdImageMaybe(val url: String, val cookie: String) { val isValid: Boolean by lazy { id != -1L && cookie.isNotBlank() } - } /* @@ -69,18 +88,20 @@ class HdImageLoadingFactory : ModelLoaderFactory { } fun RequestBuilder.loadWithPotentialHd(model: HdImageMaybe) = - thumbnail(clone().load(model.url)) - .load(model) - .apply(RequestOptions().override(Target.SIZE_ORIGINAL)) + thumbnail(clone().load(model.url)) + .load(model) + .apply(RequestOptions().override(Target.SIZE_ORIGINAL)) class HdImageLoading : ModelLoader { - override fun buildLoadData(model: HdImageMaybe, - width: Int, - height: Int, - options: Options): ModelLoader.LoadData? = - if (!model.isValid) null - else ModelLoader.LoadData(ObjectKey(model), HdImageFetcher(model)) + override fun buildLoadData( + model: HdImageMaybe, + width: Int, + height: Int, + options: Options + ): ModelLoader.LoadData? = + if (!model.isValid) null + else ModelLoader.LoadData(ObjectKey(model), HdImageFetcher(model)) override fun handles(model: HdImageMaybe) = model.isValid } @@ -105,7 +126,7 @@ class HdImageFetcher(private val model: HdImageMaybe) : DataFetcher model.cookie.fbRequest(fail = { callback.fail("Invalid auth") }) { if (cancelled) return@fbRequest callback.fail("Cancelled") val url = getFullSizedImage(model.id).invoke() - ?: return@fbRequest callback.fail("Null url") + ?: return@fbRequest callback.fail("Null url") if (cancelled) return@fbRequest callback.fail("Cancelled") if (!url.contains("png") && !url.contains("jpg")) return@fbRequest callback.fail("Invalid format") urlCall = Request.Builder().url(url).get().call() diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Menu.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Menu.kt index e83e4e43..dcb0ce10 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Menu.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Menu.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.facebook.requests import com.fasterxml.jackson.annotation.JsonCreator @@ -19,28 +35,27 @@ import java.io.IOException fun RequestAuth.getMenuData(): FrostRequest { val body = listOf( - "fb_dtsg" to fb_dtsg, - "__user" to userId + "fb_dtsg" to fb_dtsg, + "__user" to userId ).withEmptyData("m_sess", "__dyn", "__req", "__ajax__") return frostRequest(::parseMenu) { url("${FB_URL_BASE}bookmarks/flyout/body/?id=u_0_2") post(body.toForm()) } - } fun parseMenu(call: Call): MenuData? { val fullString = call.execute().body()?.string() ?: return null var jsonString = fullString.substringAfter("bookmarkGroups", "") - .substringAfter("[", "") + .substringAfter("[", "") if (jsonString.isBlank()) return null jsonString = "{ \"data\" : [${StringEscapeUtils.unescapeEcmaScript(jsonString)}" val mapper = ObjectMapper() - .disable(MapperFeature.AUTO_DETECT_SETTERS) + .disable(MapperFeature.AUTO_DETECT_SETTERS) return try { val data = mapper.readValue(jsonString, MenuData::class.java) @@ -48,11 +63,14 @@ fun parseMenu(call: Call): MenuData? { // parse footer content val footer = fullString.substringAfter("footerMarkup", "") - .substringAfter("{", "") - .substringBefore("}", "") - - val doc = Jsoup.parseBodyFragment(StringEscapeUtils.unescapeEcmaScript( - StringEscapeUtils.unescapeEcmaScript(footer))) + .substringAfter("{", "") + .substringBefore("}", "") + + val doc = Jsoup.parseBodyFragment( + StringEscapeUtils.unescapeEcmaScript( + StringEscapeUtils.unescapeEcmaScript(footer) + ) + ) val footerData = mutableListOf() val footerSmallData = mutableListOf() @@ -76,11 +94,14 @@ fun parseMenu(call: Call): MenuData? { } @JsonIgnoreProperties(ignoreUnknown = true) -data class MenuData(val data: List = emptyList(), - val footer: MenuFooter = MenuFooter()) { - - @JsonCreator constructor( - @JsonProperty("data") data: List? +data class MenuData( + val data: List = emptyList(), + val footer: MenuFooter = MenuFooter() +) { + + @JsonCreator + constructor( + @JsonProperty("data") data: List? ) : this(data ?: emptyList(), MenuFooter()) fun flatMapValid(): List { @@ -95,7 +116,6 @@ data class MenuData(val data: List = emptyList(), return items } - } interface MenuItemData { @@ -103,17 +123,20 @@ interface MenuItemData { } @JsonIgnoreProperties(ignoreUnknown = true) -data class MenuHeader(val id: String? = null, - val header: String? = null, - val visible: List = emptyList(), - val all: List = emptyList()) : MenuItemData { - - @JsonCreator constructor( - @JsonProperty("id") id: String?, - @JsonProperty("header") header: String?, - @JsonProperty("visible") visible: List?, - @JsonProperty("all") all: List?, - @JsonProperty("fake") fake: Boolean? +data class MenuHeader( + val id: String? = null, + val header: String? = null, + val visible: List = emptyList(), + val all: List = emptyList() +) : MenuItemData { + + @JsonCreator + constructor( + @JsonProperty("id") id: String?, + @JsonProperty("header") header: String?, + @JsonProperty("visible") visible: List?, + @JsonProperty("all") all: List?, + @JsonProperty("fake") fake: Boolean? ) : this(id, header, visible ?: emptyList(), all ?: emptyList()) override val isValid: Boolean @@ -121,41 +144,49 @@ data class MenuHeader(val id: String? = null, } @JsonIgnoreProperties(ignoreUnknown = true) -data class MenuItem(val id: String? = null, - val name: String? = null, - val pic: String? = null, - val url: String? = null, - val badge: String? = null, - val countDetails: String? = null) : MenuItemData { - - @JsonCreator constructor( - @JsonProperty("id") id: String?, - @JsonProperty("name") name: String?, - @JsonProperty("pic") pic: String?, - @JsonProperty("url") url: String?, - @JsonProperty("count") badge: String?, - @JsonProperty("count_details") countDetails: String?, - @JsonProperty("fake") fake: Boolean? - ) : this(id, name, pic?.formattedFbUrl, - url?.formattedFbUrl, - if (badge == "0") null else badge, - countDetails) +data class MenuItem( + val id: String? = null, + val name: String? = null, + val pic: String? = null, + val url: String? = null, + val badge: String? = null, + val countDetails: String? = null +) : MenuItemData { + + @JsonCreator + constructor( + @JsonProperty("id") id: String?, + @JsonProperty("name") name: String?, + @JsonProperty("pic") pic: String?, + @JsonProperty("url") url: String?, + @JsonProperty("count") badge: String?, + @JsonProperty("count_details") countDetails: String?, + @JsonProperty("fake") fake: Boolean? + ) : this( + id, name, pic?.formattedFbUrl, + url?.formattedFbUrl, + if (badge == "0") null else badge, + countDetails + ) override val isValid: Boolean get() = !name.isNullOrBlank() && !url.isNullOrBlank() } -data class MenuFooter(val data: List = emptyList(), - val smallData: List = emptyList()) { +data class MenuFooter( + val data: List = emptyList(), + val smallData: List = emptyList() +) { val hasContent get() = data.isNotEmpty() || smallData.isNotEmpty() - } -data class MenuFooterItem(val name: String? = null, - val url: String? = null, - val isSmall: Boolean = false) : MenuItemData { +data class MenuFooterItem( + val name: String? = null, + val url: String? = null, + val isSmall: Boolean = false +) : MenuItemData { override val isValid: Boolean get() = name != null && url != null -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Messages.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Messages.kt index 0e37a61e..f350c547 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Messages.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/requests/Messages.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.facebook.requests import com.pitchedapps.frost.facebook.FB_URL_BASE @@ -10,10 +26,10 @@ fun RequestAuth.sendMessage(group: String, content: String): FrostRequest. + */ package com.pitchedapps.frost.facebook.requests import com.pitchedapps.frost.facebook.FB_URL_BASE @@ -8,11 +24,11 @@ import com.pitchedapps.frost.facebook.FB_URL_BASE fun RequestAuth.markNotificationRead(notifId: Long): FrostRequest { val body = listOf( - "click_type" to "notification_click", - "id" to notifId, - "target_id" to "null", - "fb_dtsg" to fb_dtsg, - "__user" to userId + "click_type" to "notification_click", + "id" to notifId, + "target_id" to "null", + "fb_dtsg" to fb_dtsg, + "__user" to userId ).withEmptyData("m_sess", "__dyn", "__req", "__ajax__") return frostRequest(::executeForNoError) { @@ -22,6 +38,6 @@ fun RequestAuth.markNotificationRead(notifId: Long): FrostRequest { } fun RequestAuth.markNotificationsRead(vararg notifId: Long) = - notifId.toTypedArray().zip( - { it.all { self -> self } }, - { markNotificationRead(it).invoke() }) \ No newline at end of file + notifId.toTypedArray().zip( + { it.all { self -> self } }, + { markNotificationRead(it).invoke() }) diff --git a/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt b/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt index 34e28c2e..98e28bd3 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt @@ -1,15 +1,31 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.fragments import android.content.Context import android.os.Bundle -import com.google.android.material.floatingactionbutton.FloatingActionButton -import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.fragment.app.Fragment import ca.allanwang.kau.utils.fadeScaleTransition import ca.allanwang.kau.utils.setIcon import ca.allanwang.kau.utils.withArguments +import com.google.android.material.floatingactionbutton.FloatingActionButton import com.mikepenz.iconics.typeface.IIcon import com.pitchedapps.frost.contracts.DynamicUiContract import com.pitchedapps.frost.contracts.FrostContentParent @@ -17,7 +33,12 @@ import com.pitchedapps.frost.contracts.MainActivityContract import com.pitchedapps.frost.contracts.MainFabContract import com.pitchedapps.frost.enums.FeedSort import com.pitchedapps.frost.facebook.FbItem -import com.pitchedapps.frost.utils.* +import com.pitchedapps.frost.utils.ARG_URL +import com.pitchedapps.frost.utils.L +import com.pitchedapps.frost.utils.Prefs +import com.pitchedapps.frost.utils.REQUEST_REFRESH +import com.pitchedapps.frost.utils.REQUEST_TEXT_ZOOM +import com.pitchedapps.frost.utils.frostEvent import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.Disposable @@ -33,12 +54,17 @@ abstract class BaseFragment : Fragment(), FragmentContract, DynamicUiContract { private const val ARG_POSITION = "arg_position" private const val ARG_VALID = "arg_valid" - internal operator fun invoke(base: () -> BaseFragment, useFallback: Boolean, data: FbItem, position: Int): BaseFragment { + internal operator fun invoke( + base: () -> BaseFragment, + useFallback: Boolean, + data: FbItem, + position: Int + ): BaseFragment { val fragment = if (!useFallback) base() else WebFragment() val d = if (data == FbItem.FEED) FeedSort(Prefs.feedSort).item else data fragment.withArguments( - ARG_URL to d.url, - ARG_POSITION to position + ARG_URL to d.url, + ARG_POSITION to position ) d.put(fragment.arguments!!) return fragment @@ -55,8 +81,10 @@ abstract class BaseFragment : Fragment(), FragmentContract, DynamicUiContract { if (value || this is WebFragment) return arguments!!.putBoolean(ARG_VALID, value) L.e { "Invalidating position $position" } - frostEvent("Native Fallback", - "Item" to baseEnum.name) + frostEvent( + "Native Fallback", + "Item" to baseEnum.name + ) (context as MainActivityContract).reloadFragment(this) } @@ -75,10 +103,14 @@ abstract class BaseFragment : Fragment(), FragmentContract, DynamicUiContract { throw IllegalArgumentException("${this::class.java.simpleName} is not attached to a context implementing MainActivityContract") } - final override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + final override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { val view = inflater.inflate(layoutRes, container, false) - val content = view as? FrostContentParent - ?: throw IllegalArgumentException("layoutRes for fragment must return view implementing FrostContentParent") + val content = view as? FrostContentParent + ?: throw IllegalArgumentException("layoutRes for fragment must return view implementing FrostContentParent") this.content = content content.bind(this) return view @@ -113,28 +145,28 @@ abstract class BaseFragment : Fragment(), FragmentContract, DynamicUiContract { } override fun attachMainObservable(contract: MainActivityContract): Disposable = - contract.fragmentSubject.observeOn(AndroidSchedulers.mainThread()).subscribe { - when (it) { - REQUEST_REFRESH -> { - core?.apply { - clearHistory() - firstLoad = true - firstLoadRequest() - } - } - position -> { - contract.setTitle(baseEnum.titleId) - updateFab(contract) - core?.active = true - } - -(position + 1) -> { - core?.active = false - } - REQUEST_TEXT_ZOOM -> { - reloadTextSize() + contract.fragmentSubject.observeOn(AndroidSchedulers.mainThread()).subscribe { + when (it) { + REQUEST_REFRESH -> { + core?.apply { + clearHistory() + firstLoad = true + firstLoadRequest() } } + position -> { + contract.setTitle(baseEnum.titleId) + updateFab(contract) + core?.active = true + } + -(position + 1) -> { + core?.active = false + } + REQUEST_TEXT_ZOOM -> { + reloadTextSize() + } } + } override fun updateFab(contract: MainFabContract) { contract.hideFab() // default @@ -197,4 +229,3 @@ abstract class BaseFragment : Fragment(), FragmentContract, DynamicUiContract { override fun onTabClick(): Unit = content?.core?.onTabClicked() ?: Unit } - diff --git a/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentContract.kt b/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentContract.kt index 6555e076..e24e8308 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentContract.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentContract.kt @@ -1,6 +1,26 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.fragments -import com.pitchedapps.frost.contracts.* +import com.pitchedapps.frost.contracts.FrostContentContainer +import com.pitchedapps.frost.contracts.FrostContentCore +import com.pitchedapps.frost.contracts.FrostContentParent +import com.pitchedapps.frost.contracts.MainActivityContract +import com.pitchedapps.frost.contracts.MainFabContract import com.pitchedapps.frost.views.FrostRecyclerView import io.reactivex.disposables.Disposable @@ -74,8 +94,6 @@ interface FragmentContract : FrostContentContainer { fun onBackPressed(): Boolean fun onTabClick() - - } interface RecyclerContentContract { @@ -88,5 +106,4 @@ interface RecyclerContentContract { * Callback returns [true] for success, [false] otherwise */ fun reload(progress: (Int) -> Unit, callback: (Boolean) -> Unit) - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragmentBase.kt b/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragmentBase.kt index 4f9133a6..f77f83ea 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragmentBase.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragmentBase.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.fragments import ca.allanwang.kau.adapters.fastAdapter @@ -65,7 +81,6 @@ abstract class GenericRecyclerFragment> : RecyclerFragment * Create the fast adapter to bind to the recyclerview */ open fun getAdapter(): FastAdapter> = fastAdapter(this.adapter) - } abstract class FrostParserFragment> : RecyclerFragment() { diff --git a/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragments.kt b/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragments.kt index 4f597731..ff37b66d 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragments.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragments.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.fragments import com.mikepenz.fastadapter.IItem @@ -6,8 +22,18 @@ import com.pitchedapps.frost.facebook.FbItem import com.pitchedapps.frost.facebook.parsers.FrostNotifs import com.pitchedapps.frost.facebook.parsers.NotifParser import com.pitchedapps.frost.facebook.parsers.ParseResponse -import com.pitchedapps.frost.facebook.requests.* -import com.pitchedapps.frost.iitems.* +import com.pitchedapps.frost.facebook.requests.MenuFooterItem +import com.pitchedapps.frost.facebook.requests.MenuHeader +import com.pitchedapps.frost.facebook.requests.MenuItem +import com.pitchedapps.frost.facebook.requests.MenuItemData +import com.pitchedapps.frost.facebook.requests.fbRequest +import com.pitchedapps.frost.facebook.requests.getMenuData +import com.pitchedapps.frost.iitems.ClickableIItemContract +import com.pitchedapps.frost.iitems.MenuContentIItem +import com.pitchedapps.frost.iitems.MenuFooterIItem +import com.pitchedapps.frost.iitems.MenuFooterSmallIItem +import com.pitchedapps.frost.iitems.MenuHeaderIItem +import com.pitchedapps.frost.iitems.NotificationIItem import com.pitchedapps.frost.utils.frostJsoup import com.pitchedapps.frost.views.FrostRecyclerView import org.jetbrains.anko.doAsync @@ -23,7 +49,7 @@ class NotificationFragment : FrostParserFragment override fun getDoc(cookie: String?) = frostJsoup(cookie, "${FbItem.NOTIFICATIONS.url}?more") override fun toItems(response: ParseResponse): List = - response.data.notifs.map { NotificationIItem(it, response.cookie) } + response.data.notifs.map { NotificationIItem(it, response.cookie) } override fun bindImpl(recyclerView: FrostRecyclerView) { NotificationIItem.bindEvents(adapter) @@ -61,4 +87,4 @@ class MenuFragment : GenericRecyclerFragment>() { } } } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/fragments/WebFragments.kt b/app/src/main/kotlin/com/pitchedapps/frost/fragments/WebFragments.kt index d9edda78..72367eaa 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/fragments/WebFragments.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/WebFragments.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.fragments import android.webkit.WebView @@ -43,4 +59,4 @@ class WebFragment : BaseFragment() { } super.updateFab(contract) } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/glide/GlideUtils.kt b/app/src/main/kotlin/com/pitchedapps/frost/glide/GlideUtils.kt index 50d4d7b4..0c471c63 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/glide/GlideUtils.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/glide/GlideUtils.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.glide import android.content.Context @@ -30,11 +46,11 @@ object FrostGlide { } fun RequestBuilder.transform(vararg transformation: BitmapTransformation): RequestBuilder = - when (transformation.size) { - 0 -> this - 1 -> apply(RequestOptions.bitmapTransform(transformation[0])) - else -> apply(RequestOptions.bitmapTransform(MultiTransformation(*transformation))) - } + when (transformation.size) { + 0 -> this + 1 -> apply(RequestOptions.bitmapTransform(transformation[0])) + else -> apply(RequestOptions.bitmapTransform(MultiTransformation(*transformation))) + } @GlideModule class FrostGlideModule : AppGlideModule() { @@ -48,7 +64,7 @@ class FrostGlideModule : AppGlideModule() { } private fun getFrostHttpClient(): OkHttpClient = - OkHttpClient.Builder().addInterceptor(FrostCookieInterceptor()).build() + OkHttpClient.Builder().addInterceptor(FrostCookieInterceptor()).build() class FrostCookieInterceptor : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { @@ -58,4 +74,4 @@ class FrostCookieInterceptor : Interceptor { val request = origRequest.newBuilder().addHeader("Cookie", cookie).build() return chain.proceed(request) } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/glide/RoundCornerTransformation.kt b/app/src/main/kotlin/com/pitchedapps/frost/glide/RoundCornerTransformation.kt index 5eded159..564224ea 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/glide/RoundCornerTransformation.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/glide/RoundCornerTransformation.kt @@ -1,12 +1,32 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.glide -import android.graphics.* +import android.graphics.Bitmap +import android.graphics.BitmapShader +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.RectF +import android.graphics.Shader import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool import com.bumptech.glide.load.resource.bitmap.BitmapTransformation import com.pitchedapps.frost.utils.Prefs import java.security.MessageDigest - /** * Created by Allan Wang on 27/12/17. */ @@ -25,17 +45,17 @@ class RoundCornerTransformation : BitmapTransformation() { bitmap.setHasAlpha(true) val radius = Math.min(width, height).toFloat() / - (if (Prefs.showRoundedIcons) 2f else 10f) + (if (Prefs.showRoundedIcons) 2f else 10f) val canvas = Canvas(bitmap) val paint = Paint() paint.isAntiAlias = true paint.shader = BitmapShader(toTransform, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP) - canvas.drawRoundRect(RectF(0f, 0f, width.toFloat(), height.toFloat()), - radius, radius, paint) + canvas.drawRoundRect( + RectF(0f, 0f, width.toFloat(), height.toFloat()), + radius, radius, paint + ) return bitmap } - - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/iitems/GenericIItems.kt b/app/src/main/kotlin/com/pitchedapps/frost/iitems/GenericIItems.kt index 1211b742..6eacf48e 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/iitems/GenericIItems.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/iitems/GenericIItems.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.iitems import android.content.Context @@ -32,25 +48,25 @@ interface ClickableIItemContract { companion object { fun bindEvents(adapter: IAdapter>) { adapter.fastAdapter.withSelectable(false) - .withOnClickListener { v, _, item, _ -> - if (item is ClickableIItemContract) { - item.click(v!!.context) - true - } else - false - } + .withOnClickListener { v, _, item, _ -> + if (item is ClickableIItemContract) { + item.click(v!!.context) + true + } else + false + } } } - } /** * Generic header item * Not clickable with an accent color */ -open class HeaderIItem(val text: String?, - itemId: Int = R.layout.iitem_header) - : KauIItem(R.layout.iitem_header, ::ViewHolder, itemId) { +open class HeaderIItem( + val text: String?, + itemId: Int = R.layout.iitem_header +) : KauIItem(R.layout.iitem_header, ::ViewHolder, itemId) { class ViewHolder(itemView: View) : FastAdapter.ViewHolder(itemView) { @@ -66,18 +82,18 @@ open class HeaderIItem(val text: String?, text.text = null } } - } /** * Generic text item * Clickable with text color */ -open class TextIItem(val text: String?, - override val url: String?, - itemId: Int = R.layout.iitem_text) - : KauIItem(R.layout.iitem_text, ::ViewHolder, itemId), - ClickableIItemContract { +open class TextIItem( + val text: String?, + override val url: String?, + itemId: Int = R.layout.iitem_text +) : KauIItem(R.layout.iitem_text, ::ViewHolder, itemId), + ClickableIItemContract { class ViewHolder(itemView: View) : FastAdapter.ViewHolder(itemView) { @@ -93,5 +109,4 @@ open class TextIItem(val text: String?, text.text = null } } - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/iitems/MenuIItem.kt b/app/src/main/kotlin/com/pitchedapps/frost/iitems/MenuIItem.kt index 4a7356b0..651a4a2a 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/iitems/MenuIItem.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/iitems/MenuIItem.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.iitems import android.view.View @@ -21,9 +37,9 @@ import com.pitchedapps.frost.utils.Prefs /** * Created by Allan Wang on 30/12/17. */ -class MenuContentIItem(val data: MenuItem) - : KauIItem(R.layout.iitem_menu, ::ViewHolder), - ClickableIItemContract { +class MenuContentIItem(val data: MenuItem) : + KauIItem(R.layout.iitem_menu, ::ViewHolder), + ClickableIItemContract { override val url: String? get() = data.url @@ -42,9 +58,9 @@ class MenuContentIItem(val data: MenuItem) val iconUrl = item.data.pic if (iconUrl != null) GlideApp.with(itemView) - .load(iconUrl) - .transform(FrostGlide.roundCorner) - .into(icon.visible()) + .load(iconUrl) + .transform(FrostGlide.roundCorner) + .into(icon.visible()) else icon.gone() content.text = item.data.name @@ -59,12 +75,11 @@ class MenuContentIItem(val data: MenuItem) } } -class MenuHeaderIItem(val data: MenuHeader) : HeaderIItem(data.header, - itemId = R.id.item_menu_header) - -class MenuFooterIItem(val data: MenuFooterItem) - : TextIItem(data.name, data.url, R.id.item_menu_footer) +class MenuHeaderIItem(val data: MenuHeader) : HeaderIItem( + data.header, + itemId = R.id.item_menu_header +) -class MenuFooterSmallIItem(val data: MenuFooterItem) - : TextIItem(data.name, data.url, R.id.item_menu_footer_small) +class MenuFooterIItem(val data: MenuFooterItem) : TextIItem(data.name, data.url, R.id.item_menu_footer) +class MenuFooterSmallIItem(val data: MenuFooterItem) : TextIItem(data.name, data.url, R.id.item_menu_footer_small) diff --git a/app/src/main/kotlin/com/pitchedapps/frost/iitems/NotificationIItem.kt b/app/src/main/kotlin/com/pitchedapps/frost/iitems/NotificationIItem.kt index 06bc0604..e8332955 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/iitems/NotificationIItem.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/iitems/NotificationIItem.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.iitems import android.view.View @@ -26,23 +42,24 @@ import com.pitchedapps.frost.utils.launchWebOverlay /** * Created by Allan Wang on 27/12/17. */ -class NotificationIItem(val notification: FrostNotif, val cookie: String) : KauIItem( +class NotificationIItem(val notification: FrostNotif, val cookie: String) : + KauIItem( R.layout.iitem_notification, ::ViewHolder -) { + ) { companion object { fun bindEvents(adapter: ItemAdapter) { adapter.fastAdapter.withSelectable(false) - .withOnClickListener { v, _, item, position -> - val notif = item.notification - if (notif.unread) { - FrostRunnable.markNotificationRead(v!!.context, notif.id, item.cookie) - adapter.set(position, NotificationIItem(notif.copy(unread = false), item.cookie)) - } - // TODO temp fix. If url is dependent, we cannot load it directly - v!!.context.launchWebOverlay(if (notif.url.isIndependent) notif.url else FbItem.NOTIFICATIONS.url) - true + .withOnClickListener { v, _, item, position -> + val notif = item.notification + if (notif.unread) { + FrostRunnable.markNotificationRead(v!!.context, notif.id, item.cookie) + adapter.set(position, NotificationIItem(notif.copy(unread = false), item.cookie)) } + // TODO temp fix. If url is dependent, we cannot load it directly + v!!.context.launchWebOverlay(if (notif.url.isIndependent) notif.url else FbItem.NOTIFICATIONS.url) + true + } } //todo see if necessary @@ -52,12 +69,17 @@ class NotificationIItem(val notification: FrostNotif, val cookie: String) : KauI private class Diff : DiffCallback { override fun areItemsTheSame(oldItem: NotificationIItem, newItem: NotificationIItem) = - oldItem.notification.id == newItem.notification.id + oldItem.notification.id == newItem.notification.id override fun areContentsTheSame(oldItem: NotificationIItem, newItem: NotificationIItem) = - oldItem.notification == newItem.notification + oldItem.notification == newItem.notification - override fun getChangePayload(oldItem: NotificationIItem, oldItemPosition: Int, newItem: NotificationIItem, newItemPosition: Int): Any? { + override fun getChangePayload( + oldItem: NotificationIItem, + oldItemPosition: Int, + newItem: NotificationIItem, + newItemPosition: Int + ): Any? { return newItem } } @@ -75,15 +97,17 @@ class NotificationIItem(val notification: FrostNotif, val cookie: String) : KauI override fun bindView(item: NotificationIItem, payloads: MutableList) { val notif = item.notification - frame.background = createSimpleRippleDrawable(Prefs.textColor, - Prefs.nativeBgColor(notif.unread)) + frame.background = createSimpleRippleDrawable( + Prefs.textColor, + Prefs.nativeBgColor(notif.unread) + ) content.setTextColor(Prefs.textColor) date.setTextColor(Prefs.textColor.withAlpha(150)) val glide = glide glide.load(notif.img) - .transform(FrostGlide.roundCorner) - .into(avatar) + .transform(FrostGlide.roundCorner) + .into(avatar) if (notif.thumbnailUrl != null) glide.load(notif.thumbnailUrl).into(thumbnail.visible()) @@ -101,4 +125,4 @@ class NotificationIItem(val notification: FrostNotif, val cookie: String) : KauI date.text = null } } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/iitems/TabIItem.kt b/app/src/main/kotlin/com/pitchedapps/frost/iitems/TabIItem.kt index 506d1cab..51201d09 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/iitems/TabIItem.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/iitems/TabIItem.kt @@ -1,10 +1,30 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.iitems import android.view.View import android.widget.ImageView import android.widget.TextView import ca.allanwang.kau.iitems.KauIItem -import ca.allanwang.kau.utils.* +import ca.allanwang.kau.utils.bindView +import ca.allanwang.kau.utils.invisible +import ca.allanwang.kau.utils.setIcon +import ca.allanwang.kau.utils.visible +import ca.allanwang.kau.utils.withAlpha import com.mikepenz.fastadapter.FastAdapter import com.mikepenz.fastadapter.IItem import com.mikepenz.fastadapter_extensions.drag.IDraggable @@ -16,8 +36,8 @@ import com.pitchedapps.frost.utils.Prefs * Created by Allan Wang on 26/11/17. */ class TabIItem(val item: FbItem) : KauIItem( - R.layout.iitem_tab_preview, - { ViewHolder(it) } + R.layout.iitem_tab_preview, + { ViewHolder(it) } ), IDraggable> { override fun withIsDraggable(draggable: Boolean): TabIItem = this @@ -45,6 +65,5 @@ class TabIItem(val item: FbItem) : KauIItem( image.setImageDrawable(null) text.visible().text = null } - } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt index 033e482f..de19f99c 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt @@ -1,14 +1,35 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.injectors import android.graphics.Color import android.webkit.WebView import ca.allanwang.kau.kotlin.lazyContext -import ca.allanwang.kau.utils.* +import ca.allanwang.kau.utils.adjustAlpha +import ca.allanwang.kau.utils.colorToBackground +import ca.allanwang.kau.utils.colorToForeground +import ca.allanwang.kau.utils.toRgbaString +import ca.allanwang.kau.utils.use +import ca.allanwang.kau.utils.withAlpha import com.pitchedapps.frost.utils.L import com.pitchedapps.frost.utils.Prefs import java.io.BufferedReader import java.io.FileNotFoundException -import java.util.* +import java.util.Locale /** * Created by Allan Wang on 2017-05-31. @@ -32,17 +53,17 @@ enum class CssAssets(val folder: String = "themes") : InjectorContract { val bb = Prefs.bgColor.colorToForeground(0.35f) content = content - .replace("\$T\$", Prefs.textColor.toRgbaString()) - .replace("\$TT\$", Prefs.textColor.colorToBackground(0.05f).toRgbaString()) - .replace("\$A\$", Prefs.accentColor.toRgbaString()) - .replace("\$B\$", Prefs.bgColor.toRgbaString()) - .replace("\$BT\$", bt) - .replace("\$BBT\$", bb.withAlpha(51).toRgbaString()) - .replace("\$O\$", Prefs.bgColor.withAlpha(255).toRgbaString()) - .replace("\$OO\$", bb.withAlpha(255).toRgbaString()) - .replace("\$D\$", Prefs.textColor.adjustAlpha(0.3f).toRgbaString()) - .replace("\$TI\$", bb.withAlpha(60).toRgbaString()) - .replace("\$C\$", bt) + .replace("\$T\$", Prefs.textColor.toRgbaString()) + .replace("\$TT\$", Prefs.textColor.colorToBackground(0.05f).toRgbaString()) + .replace("\$A\$", Prefs.accentColor.toRgbaString()) + .replace("\$B\$", Prefs.bgColor.toRgbaString()) + .replace("\$BT\$", bt) + .replace("\$BBT\$", bb.withAlpha(51).toRgbaString()) + .replace("\$O\$", Prefs.bgColor.withAlpha(255).toRgbaString()) + .replace("\$OO\$", bb.withAlpha(255).toRgbaString()) + .replace("\$D\$", Prefs.textColor.adjustAlpha(0.3f).toRgbaString()) + .replace("\$TI\$", bb.withAlpha(60).toRgbaString()) + .replace("\$C\$", bt) } JsBuilder().css(content).build() } catch (e: FileNotFoundException) { @@ -58,5 +79,4 @@ enum class CssAssets(val folder: String = "themes") : InjectorContract { fun reset() { injector.invalidate() } - } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssHider.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssHider.kt index 5444fad8..7da6295f 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssHider.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssHider.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.injectors import android.webkit.WebView @@ -9,10 +25,14 @@ import android.webkit.WebView */ enum class CssHider(vararg val items: String) : InjectorContract { CORE("[data-sigil=m_login_upsell]", "[role=progressbar]"), - HEADER("#header", "#mJewelNav", "[data-sigil=MTopBlueBarHeader]", - "#header-notices", "[data-sigil*=m-promo-jewel-header]"), - ADS("article[data-xt*=sponsor]", - "article[data-store*=sponsor]"), + HEADER( + "#header", "#mJewelNav", "[data-sigil=MTopBlueBarHeader]", + "#header-notices", "[data-sigil*=m-promo-jewel-header]" + ), + ADS( + "article[data-xt*=sponsor]", + "article[data-store*=sponsor]" + ), PEOPLE_YOU_MAY_KNOW("article._d2r"), SUGGESTED_GROUPS("article[data-ft*=\"ei\":]"), COMPOSER("#MComposer"), @@ -22,11 +42,10 @@ enum class CssHider(vararg val items: String) : InjectorContract { val injector: JsInjector by lazy { JsBuilder().css("${items.joinToString(separator = ",")}{display:none !important}") - .single(name).build() + .single(name).build() } override fun inject(webView: WebView, callback: (() -> Unit)?) { injector.inject(webView, callback) } - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt index 1ab00153..e64d4faa 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.injectors import android.webkit.WebView @@ -27,10 +43,9 @@ enum class JsActions(body: String) : InjectorContract { val function = "(function(){$body})();" override fun inject(webView: WebView, callback: (() -> Unit)?) = - JsInjector(function).inject(webView, callback) - + JsInjector(function).inject(webView, callback) } @Suppress("NOTHING_TO_INLINE") private inline fun clickBySelector(selector: String): String = - """document.querySelector("$selector").click()""" \ No newline at end of file + """document.querySelector("$selector").click()""" diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsAssets.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsAssets.kt index 980481a4..0dccc751 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsAssets.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsAssets.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.injectors import android.webkit.WebView @@ -5,7 +21,7 @@ import ca.allanwang.kau.kotlin.lazyContext import com.pitchedapps.frost.utils.L import java.io.BufferedReader import java.io.FileNotFoundException -import java.util.* +import java.util.Locale /** * Created by Allan Wang on 2017-05-31. @@ -31,5 +47,4 @@ enum class JsAssets : InjectorContract { override fun inject(webView: WebView, callback: (() -> Unit)?) { injector(webView.context).inject(webView, callback) } - } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt index acda2d9b..8ae3a2f4 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.injectors import android.webkit.WebView @@ -8,7 +24,7 @@ import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.Disposable import io.reactivex.subjects.SingleSubject import org.apache.commons.text.StringEscapeUtils -import java.util.* +import java.util.Locale class JsBuilder { private val css = StringBuilder() @@ -90,10 +106,10 @@ fun WebView.jsInject(vararg injectors: InjectorContract, callback: ((Int) -> Uni } val observables = Array(validInjectors.size) { SingleSubject.create() } val disposable = Single.zip(observables.asList()) { it.size } - .observeOn(AndroidSchedulers.mainThread()) - .subscribe { res, _ -> - callback(res) - } + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { res, _ -> + callback(res) + } (0 until validInjectors.size).forEach { i -> validInjectors[i].inject(this) { observables[i].onSuccess(Unit) @@ -102,8 +118,10 @@ fun WebView.jsInject(vararg injectors: InjectorContract, callback: ((Int) -> Uni return disposable } -fun FrostWebViewClient.jsInject(vararg injectors: InjectorContract, - callback: ((Int) -> Unit)? = null) = web.jsInject(*injectors, callback = callback) +fun FrostWebViewClient.jsInject( + vararg injectors: InjectorContract, + callback: ((Int) -> Unit)? = null +) = web.jsInject(*injectors, callback = callback) /** * Wrapper class to convert a function into an injector @@ -112,4 +130,4 @@ class JsInjector(val function: String) : InjectorContract { override fun inject(webView: WebView, callback: (() -> Unit)?) { webView.evaluateJavascript(function) { callback?.invoke() } } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroFragmentTheme.kt b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroFragmentTheme.kt index 3e40b6ba..afa8df35 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroFragmentTheme.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroFragmentTheme.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.intro import android.os.Bundle @@ -17,7 +33,11 @@ class IntroFragmentTheme : BaseIntroFragment(R.layout.intro_theme) { val themeList get() = listOf(intro_theme_light, intro_theme_dark, intro_theme_amoled, intro_theme_glass) - override fun viewArray(): Array> = arrayOf(arrayOf(title), arrayOf(intro_theme_light, intro_theme_dark), arrayOf(intro_theme_amoled, intro_theme_glass)) + override fun viewArray(): Array> = arrayOf( + arrayOf(title), + arrayOf(intro_theme_light, intro_theme_dark), + arrayOf(intro_theme_amoled, intro_theme_glass) + ) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -40,5 +60,4 @@ class IntroFragmentTheme : BaseIntroFragment(R.layout.intro_theme) { themeList.forEach { it.animate().scaleXY(if (it == this) 1.6f else 0.8f).start() } } } - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroImageFragments.kt b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroImageFragments.kt index c0ccd649..1fd8c76e 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroImageFragments.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroImageFragments.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.intro import android.graphics.drawable.Drawable @@ -5,7 +21,12 @@ import android.graphics.drawable.LayerDrawable import android.os.Bundle import android.view.View import android.widget.ImageView -import ca.allanwang.kau.utils.* +import ca.allanwang.kau.utils.bindViewResettable +import ca.allanwang.kau.utils.colorToForeground +import ca.allanwang.kau.utils.setIcon +import ca.allanwang.kau.utils.tint +import ca.allanwang.kau.utils.visible +import ca.allanwang.kau.utils.withAlpha import com.mikepenz.google_material_typeface_library.GoogleMaterial import com.pitchedapps.frost.R import com.pitchedapps.frost.utils.Prefs @@ -15,9 +36,9 @@ import com.pitchedapps.frost.utils.launchTabCustomizerActivity * Created by Allan Wang on 2017-07-28. */ abstract class BaseImageIntroFragment( - val titleRes: Int, - val imageRes: Int, - val descRes: Int + val titleRes: Int, + val imageRes: Int, + val descRes: Int ) : BaseIntroFragment(R.layout.intro_image) { val imageDrawable: LayerDrawable by lazyResettableRegistered { image.drawable as LayerDrawable } @@ -68,7 +89,7 @@ abstract class BaseImageIntroFragment( } class IntroAccountFragment : BaseImageIntroFragment( - R.string.intro_multiple_accounts, R.drawable.intro_phone_nav, R.string.intro_multiple_accounts_desc + R.string.intro_multiple_accounts, R.drawable.intro_phone_nav, R.string.intro_multiple_accounts_desc ) { override fun themeFragmentImpl() { @@ -85,7 +106,7 @@ class IntroAccountFragment : BaseImageIntroFragment( } class IntroTabTouchFragment : BaseImageIntroFragment( - R.string.intro_easy_navigation, R.drawable.intro_phone_tab, R.string.intro_easy_navigation_desc + R.string.intro_easy_navigation, R.drawable.intro_phone_tab, R.string.intro_easy_navigation_desc ) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -98,14 +119,20 @@ class IntroTabTouchFragment : BaseImageIntroFragment( override fun themeFragmentImpl() { super.themeFragmentImpl() - themeImageComponent(Prefs.iconColor, R.id.intro_phone_icon_1, R.id.intro_phone_icon_2, R.id.intro_phone_icon_3, R.id.intro_phone_icon_4) + themeImageComponent( + Prefs.iconColor, + R.id.intro_phone_icon_1, + R.id.intro_phone_icon_2, + R.id.intro_phone_icon_3, + R.id.intro_phone_icon_4 + ) themeImageComponent(Prefs.headerColor, R.id.intro_phone_tab) themeImageComponent(Prefs.textColor.withAlpha(80), R.id.intro_phone_icon_ripple) } } class IntroTabContextFragment : BaseImageIntroFragment( - R.string.intro_context_aware, R.drawable.intro_phone_long_press, R.string.intro_context_aware_desc + R.string.intro_context_aware, R.drawable.intro_phone_long_press, R.string.intro_context_aware_desc ) { override fun themeFragmentImpl() { @@ -115,11 +142,16 @@ class IntroTabContextFragment : BaseImageIntroFragment( themeImageComponent(Prefs.bgColor.colorToForeground(0.2f), R.id.intro_phone_like, R.id.intro_phone_share) themeImageComponent(Prefs.bgColor.colorToForeground(0.3f), R.id.intro_phone_comment) themeImageComponent(Prefs.bgColor.colorToForeground(0.1f), R.id.intro_phone_card_1, R.id.intro_phone_card_2) - themeImageComponent(Prefs.textColor, R.id.intro_phone_image_indicator, R.id.intro_phone_comment_indicator, R.id.intro_phone_card_indicator) + themeImageComponent( + Prefs.textColor, + R.id.intro_phone_image_indicator, + R.id.intro_phone_comment_indicator, + R.id.intro_phone_card_indicator + ) } override fun onPageScrolledImpl(positionOffset: Float) { super.onPageScrolledImpl(positionOffset) lastImageFragmentTransition(positionOffset) } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroMainFragments.kt b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroMainFragments.kt index 6e953777..a4f9e193 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroMainFragments.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroMainFragments.kt @@ -1,15 +1,31 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.intro import android.annotation.SuppressLint import android.content.res.ColorStateList import android.os.Bundle -import androidx.constraintlayout.widget.ConstraintLayout -import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.fragment.app.Fragment import ca.allanwang.kau.kotlin.LazyResettableRegistry import ca.allanwang.kau.utils.Kotterknife import ca.allanwang.kau.utils.bindViewResettable @@ -99,7 +115,6 @@ abstract class BaseIntroFragment(val layoutRes: Int) : Fragment() { } protected open fun onPageSelectedImpl() { - } } @@ -131,4 +146,4 @@ class IntroFragmentEnd : BaseIntroFragment(R.layout.intro_end) { (activity as IntroActivity).finish(event.x, event.y) } } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/rx/RxFlyweight.kt b/app/src/main/kotlin/com/pitchedapps/frost/rx/RxFlyweight.kt index e8373dd6..25f6d6aa 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/rx/RxFlyweight.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/rx/RxFlyweight.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.rx import io.reactivex.Single @@ -72,9 +88,9 @@ abstract class RxFlyweight { * you likely won't have a need for flyweights */ protected open fun createNewSource(input: T): Single = - Single.fromCallable { call(input) } - .timeout(15, TimeUnit.SECONDS) - .subscribeOn(Schedulers.io()) + Single.fromCallable { call(input) } + .timeout(15, TimeUnit.SECONDS) + .subscribeOn(Schedulers.io()) fun reset() { synchronized(lock) { @@ -82,5 +98,4 @@ abstract class RxFlyweight { conditionals.clear() } } - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt b/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt index ededaad4..ee515a55 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.services import android.app.Notification @@ -26,8 +42,12 @@ import com.pitchedapps.frost.facebook.parsers.NotifParser import com.pitchedapps.frost.facebook.parsers.ParseNotification import com.pitchedapps.frost.glide.FrostGlide import com.pitchedapps.frost.glide.GlideApp -import com.pitchedapps.frost.utils.* -import java.util.* +import com.pitchedapps.frost.utils.ARG_USER_ID +import com.pitchedapps.frost.utils.L +import com.pitchedapps.frost.utils.Prefs +import com.pitchedapps.frost.utils.frostEvent +import com.pitchedapps.frost.utils.isIndependent +import java.util.Locale /** * Created by Allan Wang on 2017-07-08. @@ -40,33 +60,38 @@ private val _40_DP = 40.dpToPx * Enum to handle notification creations */ enum class NotificationType( - private val channelId: String, - private val overlayContext: OverlayContext, - private val fbItem: FbItem, - private val parser: FrostParser, - private val getTime: (notif: NotificationModel) -> Long, - private val putTime: (notif: NotificationModel, time: Long) -> NotificationModel, - private val ringtone: () -> String) { + private val channelId: String, + private val overlayContext: OverlayContext, + private val fbItem: FbItem, + private val parser: FrostParser, + private val getTime: (notif: NotificationModel) -> Long, + private val putTime: (notif: NotificationModel, time: Long) -> NotificationModel, + private val ringtone: () -> String +) { - GENERAL(NOTIF_CHANNEL_GENERAL, - OverlayContext.NOTIFICATION, - FbItem.NOTIFICATIONS, - NotifParser, - NotificationModel::epoch, - { notif, time -> notif.copy(epoch = time) }, - Prefs::notificationRingtone) { + GENERAL( + NOTIF_CHANNEL_GENERAL, + OverlayContext.NOTIFICATION, + FbItem.NOTIFICATIONS, + NotifParser, + NotificationModel::epoch, + { notif, time -> notif.copy(epoch = time) }, + Prefs::notificationRingtone + ) { override fun bindRequest(content: NotificationContent, cookie: String) = - FrostRunnable.prepareMarkNotificationRead(content.id, cookie) + FrostRunnable.prepareMarkNotificationRead(content.id, cookie) }, - MESSAGE(NOTIF_CHANNEL_MESSAGES, - OverlayContext.MESSAGE, - FbItem.MESSAGES, - MessageParser, - NotificationModel::epochIm, - { notif, time -> notif.copy(epochIm = time) }, - Prefs::messageRingtone); + MESSAGE( + NOTIF_CHANNEL_MESSAGES, + OverlayContext.MESSAGE, + FbItem.MESSAGES, + MessageParser, + NotificationModel::epochIm, + { notif, time -> notif.copy(epochIm = time) }, + Prefs::messageRingtone + ); private val groupPrefix = "frost_${name.toLowerCase(Locale.CANADA)}" @@ -133,13 +158,15 @@ enum class NotificationType( } fun debugNotification(context: Context, data: CookieModel) { - val content = NotificationContent(data, - System.currentTimeMillis(), - "https://github.com/AllanWang/Frost-for-Facebook", - "Debug Notif", - "Test 123", - System.currentTimeMillis() / 1000, - "https://www.iconexperience.com/_img/v_collection_png/256x256/shadow/dog.png") + val content = NotificationContent( + data, + System.currentTimeMillis(), + "https://github.com/AllanWang/Frost-for-Facebook", + "Debug Notif", + "Test 123", + System.currentTimeMillis() / 1000, + "https://www.iconexperience.com/_img/v_collection_png/256x256/shadow/dog.png" + ) createNotification(context, content).notify(context) } @@ -147,44 +174,43 @@ enum class NotificationType( * Create and submit a new notification with the given [content] */ private fun createNotification(context: Context, content: NotificationContent): FrostNotification = - with(content) { - val intent = Intent(context, FrostWebActivity::class.java) - // TODO temp fix; we will show notification page for dependent urls. We can trigger a click next time - intent.data = Uri.parse(if (href.isIndependent) href else FbItem.NOTIFICATIONS.url) - intent.putExtra(ARG_USER_ID, data.id) - overlayContext.put(intent) - bindRequest(intent, content, data.cookie) + with(content) { + val intent = Intent(context, FrostWebActivity::class.java) + // TODO temp fix; we will show notification page for dependent urls. We can trigger a click next time + intent.data = Uri.parse(if (href.isIndependent) href else FbItem.NOTIFICATIONS.url) + intent.putExtra(ARG_USER_ID, data.id) + overlayContext.put(intent) + bindRequest(intent, content, data.cookie) - val group = "${groupPrefix}_${data.id}" - val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT) - val notifBuilder = context.frostNotification(channelId) - .setContentTitle(title ?: context.string(R.string.frost_name)) - .setContentText(text) - .setContentIntent(pendingIntent) - .setCategory(Notification.CATEGORY_SOCIAL) - .setSubText(data.name) - .setGroup(group) + val group = "${groupPrefix}_${data.id}" + val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT) + val notifBuilder = context.frostNotification(channelId) + .setContentTitle(title ?: context.string(R.string.frost_name)) + .setContentText(text) + .setContentIntent(pendingIntent) + .setCategory(Notification.CATEGORY_SOCIAL) + .setSubText(data.name) + .setGroup(group) - if (timestamp != -1L) notifBuilder.setWhen(timestamp * 1000) - L.v { "Notif load $content" } + if (timestamp != -1L) notifBuilder.setWhen(timestamp * 1000) + L.v { "Notif load $content" } - if (profileUrl != null) { - try { - val profileImg = GlideApp.with(context) - .asBitmap() - .load(profileUrl) - .transform(FrostGlide.circleCrop) - .submit(_40_DP, _40_DP) - .get() - notifBuilder.setLargeIcon(profileImg) - } catch (e: Exception) { - L.e { "Failed to get image $profileUrl" } - } + if (profileUrl != null) { + try { + val profileImg = GlideApp.with(context) + .asBitmap() + .load(profileUrl) + .transform(FrostGlide.circleCrop) + .submit(_40_DP, _40_DP) + .get() + notifBuilder.setLargeIcon(profileImg) + } catch (e: Exception) { + L.e { "Failed to get image $profileUrl" } } - - FrostNotification(group, notifId, notifBuilder) } + FrostNotification(group, notifId, notifBuilder) + } /** * Create a summary notification to wrap the previous ones @@ -198,12 +224,12 @@ enum class NotificationType( val group = "${groupPrefix}_$userId" val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT) val notifBuilder = context.frostNotification(channelId) - .setContentTitle(context.string(R.string.frost_name)) - .setContentText("$count ${context.string(fbItem.titleId)}") - .setGroup(group) - .setGroupSummary(true) - .setContentIntent(pendingIntent) - .setCategory(Notification.CATEGORY_SOCIAL) + .setContentTitle(context.string(R.string.frost_name)) + .setContentText("$count ${context.string(fbItem.titleId)}") + .setGroup(group) + .setGroupSummary(true) + .setContentIntent(pendingIntent) + .setCategory(Notification.CATEGORY_SOCIAL) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { notifBuilder.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_CHILDREN) @@ -211,31 +237,33 @@ enum class NotificationType( return FrostNotification(group, 1, notifBuilder) } - } /** * Notification data holder */ -data class NotificationContent(val data: CookieModel, - val id: Long, - val href: String, - val title: String? = null, // defaults to frost title - val text: String, - val timestamp: Long, - val profileUrl: String?) { +data class NotificationContent( + val data: CookieModel, + val id: Long, + val href: String, + val title: String? = null, // defaults to frost title + val text: String, + val timestamp: Long, + val profileUrl: String? +) { val notifId = Math.abs(id.toInt()) - } /** * Wrapper for a complete notification builder and identifier * which can be immediately notified when given a [Context] */ -data class FrostNotification(private val tag: String, - private val id: Int, - val notif: NotificationCompat.Builder) { +data class FrostNotification( + private val tag: String, + private val id: Int, + val notif: NotificationCompat.Builder +) { fun withAlert(enable: Boolean, ringtone: String): FrostNotification { notif.setFrostAlert(enable, ringtone) @@ -243,15 +271,15 @@ data class FrostNotification(private val tag: String, } fun notify(context: Context) = - NotificationManagerCompat.from(context).notify(tag, id, notif.build()) + NotificationManagerCompat.from(context).notify(tag, id, notif.build()) } const val NOTIFICATION_PERIODIC_JOB = 7 fun Context.scheduleNotifications(minutes: Long): Boolean = - scheduleJob(NOTIFICATION_PERIODIC_JOB, minutes) + scheduleJob(NOTIFICATION_PERIODIC_JOB, minutes) const val NOTIFICATION_JOB_NOW = 6 fun Context.fetchNotifications(): Boolean = - fetchJob(NOTIFICATION_JOB_NOW) \ No newline at end of file + fetchJob(NOTIFICATION_JOB_NOW) diff --git a/app/src/main/kotlin/com/pitchedapps/frost/services/FrostRequestService.kt b/app/src/main/kotlin/com/pitchedapps/frost/services/FrostRequestService.kt index b2ccaea2..22acc9fb 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/services/FrostRequestService.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/services/FrostRequestService.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.services import android.app.job.JobInfo @@ -37,10 +53,10 @@ private enum class FrostRequestCommands : EnumBundle { } override fun propagate(bundle: BaseBundle) = - FrostRunnable.prepareMarkNotificationRead( - bundle.getLong(ARG_0), - bundle.getCookie()) - + FrostRunnable.prepareMarkNotificationRead( + bundle.getLong(ARG_0), + bundle.getCookie() + ) }; override val bundleContract: EnumBundleCompanion @@ -58,7 +74,6 @@ private enum class FrostRequestCommands : EnumBundle { abstract fun propagate(bundle: BaseBundle): BaseBundle.() -> Unit companion object : EnumCompanion("frost_arg_commands", values()) - } private const val ARG_COMMAND = "frost_request_command" @@ -99,8 +114,10 @@ object FrostRunnable { L.d { "Invalid notification id $id for marking as read" } return false } - return schedule(context, FrostRequestCommands.NOTIF_READ, - prepareMarkNotificationRead(id, cookie)) + return schedule( + context, FrostRequestCommands.NOTIF_READ, + prepareMarkNotificationRead(id, cookie) + ) } fun propagate(context: Context, intent: Intent?) { @@ -112,9 +129,11 @@ object FrostRunnable { schedule(context, command, builder) } - private fun schedule(context: Context, - command: FrostRequestCommands, - bundleBuilder: PersistableBundle.() -> Unit): Boolean { + private fun schedule( + context: Context, + command: FrostRequestCommands, + bundleBuilder: PersistableBundle.() -> Unit + ): Boolean { val scheduler = context.getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler val serviceComponent = ComponentName(context, FrostRequestService::class.java) val bundle = PersistableBundle() @@ -127,10 +146,10 @@ object FrostRunnable { } val builder = JobInfo.Builder(JOB_REQUEST_BASE + command.ordinal, serviceComponent) - .setMinimumLatency(0L) - .setExtras(bundle) - .setOverrideDeadline(2000L) - .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) + .setMinimumLatency(0L) + .setExtras(bundle) + .setOverrideDeadline(2000L) + .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) val result = scheduler.schedule(builder.build()) if (result <= 0) { L.eThrow("FrostRequestService scheduler failed for ${command.name}") @@ -139,7 +158,6 @@ object FrostRunnable { L.d { "Scheduled ${command.name}" } return true } - } class FrostRequestService : JobService() { @@ -183,4 +201,4 @@ class FrostRequestService : JobService() { } return true } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt b/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt index f15df482..4ede5163 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.services import android.app.job.JobParameters @@ -31,10 +47,12 @@ class NotificationService : JobService() { override fun onStopJob(params: JobParameters?): Boolean { val time = System.currentTimeMillis() - startTime L.d { "Notification service has finished abruptly in $time ms" } - frostEvent("NotificationTime", - "Type" to "Service force stop", - "IM Included" to Prefs.notificationsInstantMessages, - "Duration" to time) + frostEvent( + "NotificationTime", + "Type" to "Service force stop", + "IM Included" to Prefs.notificationsInstantMessages, + "Duration" to time + ) future?.cancel(true) future = null return false @@ -43,10 +61,12 @@ class NotificationService : JobService() { fun finish(params: JobParameters?) { val time = System.currentTimeMillis() - startTime L.i { "Notification service has finished in $time ms" } - frostEvent("NotificationTime", - "Type" to "Service", - "IM Included" to Prefs.notificationsInstantMessages, - "Duration" to time) + frostEvent( + "NotificationTime", + "Type" to "Service", + "IM Included" to Prefs.notificationsInstantMessages, + "Duration" to time + ) jobFinished(params, false) future?.cancel(true) future = null @@ -61,11 +81,13 @@ class NotificationService : JobService() { var notifCount = 0 cookies.forEach { val current = it.id == currentId - if (Prefs.notificationsGeneral - && (current || Prefs.notificationAllAccounts)) + if (Prefs.notificationsGeneral && + (current || Prefs.notificationAllAccounts) + ) notifCount += fetch(jobId, NotificationType.GENERAL, it) - if (Prefs.notificationsInstantMessages - && (current || Prefs.notificationsImAllAccounts)) + if (Prefs.notificationsInstantMessages && + (current || Prefs.notificationsImAllAccounts) + ) notifCount += fetch(jobId, NotificationType.MESSAGE, it) } @@ -99,10 +121,9 @@ class NotificationService : JobService() { private fun generalNotification(id: Int, textRes: Int, withDefaults: Boolean) { val notifBuilder = frostNotification(NOTIF_CHANNEL_GENERAL) - .setFrostAlert(withDefaults, Prefs.notificationRingtone) - .setContentTitle(string(R.string.frost_name)) - .setContentText(string(textRes)) + .setFrostAlert(withDefaults, Prefs.notificationRingtone) + .setContentTitle(string(R.string.frost_name)) + .setContentText(string(textRes)) NotificationManagerCompat.from(this).notify(id, notifBuilder.build()) } - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationUtils.kt b/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationUtils.kt index 707220f6..20a497e3 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationUtils.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationUtils.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.services import android.app.Notification @@ -31,11 +47,11 @@ fun setupNotificationChannels(c: Context) { val appName = c.string(R.string.frost_name) val msg = c.string(R.string.messages) manager.notificationChannels - .filter { - it.id != NOTIF_CHANNEL_GENERAL - && it.id != NOTIF_CHANNEL_MESSAGES - } - .forEach { manager.deleteNotificationChannel(it.id) } + .filter { + it.id != NOTIF_CHANNEL_GENERAL && + it.id != NOTIF_CHANNEL_MESSAGES + } + .forEach { manager.deleteNotificationChannel(it.id) } manager.createNotificationChannel(NOTIF_CHANNEL_GENERAL, appName) manager.createNotificationChannel(NOTIF_CHANNEL_MESSAGES, "$appName: $msg") L.d { "Created notification channels: ${manager.notificationChannels.size} channels, ${manager.notificationChannelGroups.size} groups" } @@ -43,8 +59,10 @@ fun setupNotificationChannels(c: Context) { @RequiresApi(Build.VERSION_CODES.O) private fun NotificationManager.createNotificationChannel(id: String, name: String): NotificationChannel { - val channel = NotificationChannel(id, - name, NotificationManager.IMPORTANCE_DEFAULT) + val channel = NotificationChannel( + id, + name, NotificationManager.IMPORTANCE_DEFAULT + ) channel.enableLights(true) channel.lightColor = Prefs.accentColor channel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC @@ -53,14 +71,14 @@ private fun NotificationManager.createNotificationChannel(id: String, name: Stri } fun Context.frostNotification(id: String) = - NotificationCompat.Builder(this, id) - .apply { - setSmallIcon(R.drawable.frost_f_24) - setAutoCancel(true) - setOnlyAlertOnce(true) - setStyle(NotificationCompat.BigTextStyle()) - color = color(R.color.frost_notification_accent) - } + NotificationCompat.Builder(this, id) + .apply { + setSmallIcon(R.drawable.frost_f_24) + setAutoCancel(true) + setOnlyAlertOnce(true) + setStyle(NotificationCompat.BigTextStyle()) + color = color(R.color.frost_notification_accent) + } /** * Dictates whether a notification should have sound/vibration/lights or not @@ -70,8 +88,9 @@ fun Context.frostNotification(id: String) = fun NotificationCompat.Builder.setFrostAlert(enable: Boolean, ringtone: String): NotificationCompat.Builder { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { setGroupAlertBehavior( - if (enable) NotificationCompat.GROUP_ALERT_CHILDREN - else NotificationCompat.GROUP_ALERT_SUMMARY) + if (enable) NotificationCompat.GROUP_ALERT_CHILDREN + else NotificationCompat.GROUP_ALERT_SUMMARY + ) } else if (!enable) { setDefaults(0) } else { @@ -111,10 +130,10 @@ inline fun Context.scheduleJob(id: Int, minutes: Long): if (minutes < 0L) return true val serviceComponent = ComponentName(this, T::class.java) val builder = JobInfo.Builder(id, serviceComponent) - .setPeriodic(minutes * 60000) - .setExtras(id) - .setPersisted(true) - .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) //TODO add options + .setPeriodic(minutes * 60000) + .setExtras(id) + .setPersisted(true) + .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) //TODO add options val result = scheduler.schedule(builder.build()) if (result <= 0) { L.eThrow("${T::class.java.simpleName} scheduler failed") @@ -130,10 +149,10 @@ inline fun Context.fetchJob(id: Int): Boolean { val scheduler = getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler val serviceComponent = ComponentName(this, T::class.java) val builder = JobInfo.Builder(id, serviceComponent) - .setMinimumLatency(0L) - .setExtras(id) - .setOverrideDeadline(2000L) - .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) + .setMinimumLatency(0L) + .setExtras(id) + .setOverrideDeadline(2000L) + .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) val result = scheduler.schedule(builder.build()) if (result <= 0) { L.eThrow("${T::class.java.simpleName} instant scheduler failed") diff --git a/app/src/main/kotlin/com/pitchedapps/frost/services/UpdateReceiver.kt b/app/src/main/kotlin/com/pitchedapps/frost/services/UpdateReceiver.kt index 59df9ed7..2d86f3b9 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/services/UpdateReceiver.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/services/UpdateReceiver.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.services import android.content.BroadcastReceiver @@ -18,5 +34,4 @@ class UpdateReceiver : BroadcastReceiver() { L.d { "Frost has updated" } context.scheduleNotifications(Prefs.notificationFreq) //Update notifications } - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Appearance.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Appearance.kt index 9253d926..538e20f1 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Appearance.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Appearance.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.settings import ca.allanwang.kau.kpref.activity.KPrefAdapterBuilder @@ -10,7 +26,16 @@ import com.pitchedapps.frost.activities.SettingsActivity import com.pitchedapps.frost.enums.MainActivityLayout import com.pitchedapps.frost.enums.Theme import com.pitchedapps.frost.injectors.CssAssets -import com.pitchedapps.frost.utils.* +import com.pitchedapps.frost.utils.Prefs +import com.pitchedapps.frost.utils.REQUEST_NAV +import com.pitchedapps.frost.utils.REQUEST_REFRESH +import com.pitchedapps.frost.utils.REQUEST_TEXT_ZOOM +import com.pitchedapps.frost.utils.frostEvent +import com.pitchedapps.frost.utils.frostNavigationBar +import com.pitchedapps.frost.utils.frostSnackbar +import com.pitchedapps.frost.utils.launchTabCustomizerActivity +import com.pitchedapps.frost.utils.materialDialogThemed +import com.pitchedapps.frost.utils.setFrostTheme import com.pitchedapps.frost.views.KPrefTextSeekbar /** @@ -74,7 +99,6 @@ fun SettingsActivity.getAppearancePrefs(): KPrefAdapterBuilder.() -> Unit = { allowCustomAlpha = false } - colorPicker(R.string.background_color, Prefs::customBackgroundColor, { Prefs.customBackgroundColor = it bgCanvas.ripple(it, duration = 500L) @@ -146,17 +170,20 @@ fun SettingsActivity.getAppearancePrefs(): KPrefAdapterBuilder.() -> Unit = { descRes = R.string.tint_nav_desc } - list.add(KPrefTextSeekbar( + list.add( + KPrefTextSeekbar( KPrefSeekbar.KPrefSeekbarBuilder( - globalOptions, - R.string.web_text_scaling, Prefs::webTextScaling) { + globalOptions, + R.string.web_text_scaling, Prefs::webTextScaling + ) { Prefs.webTextScaling = it setFrostResult(REQUEST_TEXT_ZOOM) - })) + }) + ) checkbox(R.string.enforce_black_media_bg, Prefs::blackMediaBg, { Prefs.blackMediaBg = it }) { descRes = R.string.enforce_black_media_bg_desc } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Behaviour.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Behaviour.kt index 02a86e58..10fa5c99 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Behaviour.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Behaviour.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.settings import ca.allanwang.kau.kpref.activity.KPrefAdapterBuilder @@ -15,7 +31,10 @@ fun SettingsActivity.getBehaviourPrefs(): KPrefAdapterBuilder.() -> Unit = { descRes = R.string.fancy_animations_desc } - checkbox(R.string.overlay_swipe, Prefs::overlayEnabled, { Prefs.overlayEnabled = it; setFrostResult(REQUEST_REFRESH) }) { + checkbox( + R.string.overlay_swipe, + Prefs::overlayEnabled, + { Prefs.overlayEnabled = it; setFrostResult(REQUEST_REFRESH) }) { descRes = R.string.overlay_swipe_desc } @@ -46,5 +65,4 @@ fun SettingsActivity.getBehaviourPrefs(): KPrefAdapterBuilder.() -> Unit = { checkbox(R.string.analytics, Prefs::analytics, { Prefs.analytics = it }) { descRes = R.string.analytics_desc } - } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Debug.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Debug.kt index 91dac242..4b538e87 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Debug.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Debug.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.settings import android.content.Context @@ -77,25 +93,26 @@ fun SettingsActivity.getDebugPrefs(): KPrefAdapterBuilder.() -> Unit = { } } } - } } } private fun Context.createEmail(parser: FrostParser<*>, content: Any?) = - sendFrostEmail("${string(R.string.debug_report)}: ${parser::class.java.simpleName}") { - addItem("Url", parser.url) - addItem("Contents", "$content") - } + sendFrostEmail("${string(R.string.debug_report)}: ${parser::class.java.simpleName}") { + addItem("Url", parser.url) + addItem("Contents", "$content") + } private const val ZIP_NAME = "debug" fun SettingsActivity.sendDebug(url: String, html: String?) { - val downloader = OfflineWebsite(url, FbCookie.webCookie ?: "", - baseUrl = FB_URL_BASE, - html = html, - baseDir = DebugActivity.baseDir(this)) + val downloader = OfflineWebsite( + url, FbCookie.webCookie ?: "", + baseUrl = FB_URL_BASE, + html = html, + baseDir = DebugActivity.baseDir(this) + ) val md = materialDialog { title(R.string.parsing_data) @@ -114,7 +131,8 @@ fun SettingsActivity.sendDebug(url: String, html: String?) { it.dismiss() if (success) { val zipUri = it.context.frostUriFromFile( - File(downloader.baseDir, "$ZIP_NAME.zip")) + File(downloader.baseDir, "$ZIP_NAME.zip") + ) L.i { "Sending debug zip with uri $zipUri" } sendFrostEmail(R.string.debug_report_email_title) { addItem("Url", url) @@ -128,7 +146,5 @@ fun SettingsActivity.sendDebug(url: String, html: String?) { } } } - } - } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Experimental.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Experimental.kt index fe95e7f1..e0d314a8 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Experimental.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Experimental.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.settings import android.util.Log @@ -24,7 +40,6 @@ fun SettingsActivity.getExperimentalPrefs(): KPrefAdapterBuilder.() -> Unit = { // Experimental content starts here ------------------ - // Experimental content ends here -------------------- checkbox(R.string.verbose_logging, Prefs::verboseLogging, { @@ -41,4 +56,4 @@ fun SettingsActivity.getExperimentalPrefs(): KPrefAdapterBuilder.() -> Unit = { finish() } } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Feed.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Feed.kt index 402322ad..ff0badf0 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Feed.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Feed.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.settings import ca.allanwang.kau.kpref.activity.KPrefAdapterBuilder @@ -66,4 +82,4 @@ fun SettingsActivity.getFeedPrefs(): KPrefAdapterBuilder.() -> Unit = { }) { descRes = R.string.facebook_ads_desc } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Network.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Network.kt index b5515a52..a1ec33e6 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Network.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Network.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.settings import ca.allanwang.kau.kpref.activity.KPrefAdapterBuilder @@ -10,8 +26,10 @@ import com.pitchedapps.frost.utils.Prefs */ fun SettingsActivity.getNetworkPrefs(): KPrefAdapterBuilder.() -> Unit = { - checkbox(R.string.network_media_on_metered, { !Prefs.loadMediaOnMeteredNetwork }, { Prefs.loadMediaOnMeteredNetwork = !it }) { + checkbox( + R.string.network_media_on_metered, + { !Prefs.loadMediaOnMeteredNetwork }, + { Prefs.loadMediaOnMeteredNetwork = !it }) { descRes = R.string.network_media_on_metered_desc } - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt index 1f9411e4..0200f109 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Notifications.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.settings import android.annotation.SuppressLint @@ -22,7 +38,6 @@ import com.pitchedapps.frost.utils.frostSnackbar import com.pitchedapps.frost.utils.materialDialogThemed import com.pitchedapps.frost.views.Keywords - /** * Created by Allan Wang on 2017-06-29. */ @@ -66,33 +81,33 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = { } checkbox(R.string.notification_general, Prefs::notificationsGeneral, - { - Prefs.notificationsGeneral = it - reloadByTitle(R.string.notification_general_all_accounts) - if (!Prefs.notificationsInstantMessages) - reloadByTitle(R.string.notification_frequency) - }) { + { + Prefs.notificationsGeneral = it + reloadByTitle(R.string.notification_general_all_accounts) + if (!Prefs.notificationsInstantMessages) + reloadByTitle(R.string.notification_frequency) + }) { descRes = R.string.notification_general_desc } checkbox(R.string.notification_general_all_accounts, Prefs::notificationAllAccounts, - { Prefs.notificationAllAccounts = it }) { + { Prefs.notificationAllAccounts = it }) { descRes = R.string.notification_general_all_accounts_desc enabler = Prefs::notificationsGeneral } checkbox(R.string.notification_messages, Prefs::notificationsInstantMessages, - { - Prefs.notificationsInstantMessages = it - reloadByTitle(R.string.notification_messages_all_accounts) - if (!Prefs.notificationsGeneral) - reloadByTitle(R.string.notification_frequency) - }) { + { + Prefs.notificationsInstantMessages = it + reloadByTitle(R.string.notification_messages_all_accounts) + if (!Prefs.notificationsGeneral) + reloadByTitle(R.string.notification_frequency) + }) { descRes = R.string.notification_messages_desc } checkbox(R.string.notification_messages_all_accounts, Prefs::notificationsImAllAccounts, - { Prefs.notificationsImAllAccounts = it }) { + { Prefs.notificationsImAllAccounts = it }) { descRes = R.string.notification_messages_all_accounts_desc enabler = Prefs::notificationsInstantMessages } @@ -102,15 +117,17 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = { descRes = R.string.notification_channel_desc onClick = { val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS) - .putExtra(Settings.EXTRA_APP_PACKAGE, packageName) + .putExtra(Settings.EXTRA_APP_PACKAGE, packageName) startActivity(intent) } } } else { checkbox(R.string.notification_sound, Prefs::notificationSound, { Prefs.notificationSound = it - reloadByTitle(R.string.notification_ringtone, - R.string.message_ringtone) + reloadByTitle( + R.string.notification_ringtone, + R.string.message_ringtone + ) }) fun KPrefText.KPrefTextContract.ringtone(code: Int) { @@ -118,8 +135,8 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = { textGetter = { if (it.isBlank()) string(R.string.kau_default) else RingtoneManager.getRingtone(this@getNotificationPrefs, Uri.parse(it)) - ?.getTitle(this@getNotificationPrefs) - ?: "---" //todo figure out why this happens + ?.getTitle(this@getNotificationPrefs) + ?: "---" //todo figure out why this happens } onClick = { val intent = Intent(RingtoneManager.ACTION_RINGTONE_PICKER).apply { @@ -135,20 +152,20 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = { } text(R.string.notification_ringtone, Prefs::notificationRingtone, - { Prefs.notificationRingtone = it }) { + { Prefs.notificationRingtone = it }) { ringtone(SettingsActivity.REQUEST_NOTIFICATION_RINGTONE) } text(R.string.message_ringtone, Prefs::messageRingtone, - { Prefs.messageRingtone = it }) { + { Prefs.messageRingtone = it }) { ringtone(SettingsActivity.REQUEST_MESSAGE_RINGTONE) } checkbox(R.string.notification_vibrate, Prefs::notificationVibrate, - { Prefs.notificationVibrate = it }) + { Prefs.notificationVibrate = it }) checkbox(R.string.notification_lights, Prefs::notificationLights, - { Prefs.notificationLights = it }) + { Prefs.notificationLights = it }) } if (BuildConfig.DEBUG) { @@ -165,10 +182,9 @@ fun SettingsActivity.getNotificationPrefs(): KPrefAdapterBuilder.() -> Unit = { descRes = R.string.notification_fetch_now_desc onClick = { val text = - if (fetchNotifications()) R.string.notification_fetch_success - else R.string.notification_fetch_fail + if (fetchNotifications()) R.string.notification_fetch_success + else R.string.notification_fetch_fail frostSnackbar(text) } } - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/AdBlocker.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/AdBlocker.kt index 1bb0449b..61a90024 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/AdBlocker.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/AdBlocker.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.utils import android.content.Context @@ -45,4 +61,4 @@ open class AdBlocker(val assetPath: String) { if (host.contains(host)) return true return isAdHost(host.substring(index + 1)) } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/AnimatedVectorDelegate.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/AnimatedVectorDelegate.kt index 223eed3f..c9e64eb3 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/AnimatedVectorDelegate.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/AnimatedVectorDelegate.kt @@ -1,8 +1,24 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.utils import android.graphics.drawable.AnimatedVectorDrawable -import androidx.annotation.DrawableRes import android.widget.ImageView +import androidx.annotation.DrawableRes import ca.allanwang.kau.utils.drawable /** @@ -23,23 +39,23 @@ interface AnimatedVectorContract { } class AnimatedVectorDelegate( - /** - * The res for the starting resource; must have parent tag animated-vector - */ - @param:DrawableRes val avdStart: Int, - /** - * The res for the ending resource; must have parent tag animated-vector - */ - @param:DrawableRes val avdEnd: Int, - /** - * The delegate will automatically set the start resource when bound - * If [emitOnBind] is true, it will also trigger the listener - */ - val emitOnBind: Boolean = true, - /** - * The optional listener that will be triggered every time the avd is switched by the delegate - */ - override var animatedVectorListener: ((avd: AnimatedVectorDrawable, forwards: Boolean) -> Unit)? = null + /** + * The res for the starting resource; must have parent tag animated-vector + */ + @param:DrawableRes val avdStart: Int, + /** + * The res for the ending resource; must have parent tag animated-vector + */ + @param:DrawableRes val avdEnd: Int, + /** + * The delegate will automatically set the start resource when bound + * If [emitOnBind] is true, it will also trigger the listener + */ + val emitOnBind: Boolean = true, + /** + * The optional listener that will be triggered every time the avd is switched by the delegate + */ + override var animatedVectorListener: ((avd: AnimatedVectorDrawable, forwards: Boolean) -> Unit)? = null ) : AnimatedVectorContract { lateinit var view: ImageView @@ -55,9 +71,9 @@ class AnimatedVectorDelegate( override fun bind(view: ImageView) { this.view = view view.context.drawable(avdStart) as? AnimatedVectorDrawable - ?: throw IllegalArgumentException("AnimatedVectorDelegate has a starting drawable that isn't an avd") + ?: throw IllegalArgumentException("AnimatedVectorDelegate has a starting drawable that isn't an avd") view.context.drawable(avdEnd) as? AnimatedVectorDrawable - ?: throw IllegalArgumentException("AnimatedVectorDelegate has an ending drawable that isn't an avd") + ?: throw IllegalArgumentException("AnimatedVectorDelegate has an ending drawable that isn't an avd") view.setImageResource(avdStart) if (emitOnBind) animatedVectorListener?.invoke(avd!!, false) } @@ -70,15 +86,11 @@ class AnimatedVectorDelegate( private fun animateImpl(toStart: Boolean) { if ((atStart == toStart)) return L.d { "AVD already at ${if (toStart) "start" else "end"}" } - if (avd == null) return L.d { "AVD null resource" }//no longer using animated vector; do not modify + if (avd == null) return L.d { "AVD null resource" } //no longer using animated vector; do not modify avd?.stop() view.setImageResource(if (toStart) avdEnd else avdStart) animatedVectorListener?.invoke(avd!!, !toStart) atStart = toStart avd?.start() } - } - - - diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/BuildUtils.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/BuildUtils.kt index c9a2f285..33da56f2 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/BuildUtils.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/BuildUtils.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.utils object BuildUtils { @@ -18,8 +34,7 @@ object BuildUtils { } fun getAllStages(): Array = - arrayOf(BUILD_PRODUCTION, BUILD_TEST, BUILD_GITHUB, BUILD_RELEASE, BUILD_UNNAMED) + arrayOf(BUILD_PRODUCTION, BUILD_TEST, BUILD_GITHUB, BUILD_RELEASE, BUILD_UNNAMED) fun getStage(build: String): String = build.takeIf { it in getAllStages() } ?: BUILD_UNNAMED - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/Const.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/Const.kt index 0cb57ed5..3c76759c 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Const.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Const.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.utils /** @@ -15,4 +31,4 @@ const val REQUEST_TEXT_ZOOM = 1 shl 14 const val REQUEST_NAV = 1 shl 15 const val REQUEST_SEARCH = 1 shl 16 -const val MAIN_TIMEOUT_DURATION = 30 * 60 * 1000 // 30 min \ No newline at end of file +const val MAIN_TIMEOUT_DURATION = 30 * 60 * 1000 // 30 min diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/Downloader.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/Downloader.kt index 16b1d149..f4baa242 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Downloader.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Downloader.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.utils import android.app.DownloadManager @@ -16,26 +32,29 @@ import com.pitchedapps.frost.R import com.pitchedapps.frost.dbflow.loadFbCookie import com.pitchedapps.frost.facebook.USER_AGENT_BASIC - /** * Created by Allan Wang on 2017-08-04. * * With reference to Stack Overflow */ -fun Context.frostDownload(url: String?, - userAgent: String = USER_AGENT_BASIC, - contentDisposition: String? = null, - mimeType: String? = null, - contentLength: Long = 0L) { +fun Context.frostDownload( + url: String?, + userAgent: String = USER_AGENT_BASIC, + contentDisposition: String? = null, + mimeType: String? = null, + contentLength: Long = 0L +) { url ?: return frostDownload(Uri.parse(url), userAgent, contentDisposition, mimeType, contentLength) } -fun Context.frostDownload(uri: Uri?, - userAgent: String = USER_AGENT_BASIC, - contentDisposition: String? = null, - mimeType: String? = null, - contentLength: Long = 0L) { +fun Context.frostDownload( + uri: Uri?, + userAgent: String = USER_AGENT_BASIC, + contentDisposition: String? = null, + mimeType: String? = null, + contentLength: Long = 0L +) { uri ?: return L.d { "Received download request" } if (uri.scheme != "http" && uri.scheme != "https") { @@ -75,4 +94,4 @@ fun Context.frostDownload(uri: Uri?, } } -private const val DOWNLOAD_MANAGER_PACKAGE = "com.android.providers.downloads" \ No newline at end of file +private const val DOWNLOAD_MANAGER_PACKAGE = "com.android.providers.downloads" diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/EnumUtils.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/EnumUtils.kt index 2a562ba2..b6d9b833 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/EnumUtils.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/EnumUtils.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.utils import android.content.Intent @@ -39,12 +55,12 @@ interface EnumBundleCompanion> { operator fun get(bundle: BaseBundle?) = get(bundle?.getString(argTag)) operator fun get(intent: Intent?) = get(intent?.getStringExtra(argTag)) - } open class EnumCompanion>( - final override val argTag: String, - final override val values: Array) : EnumBundleCompanion { + final override val argTag: String, + final override val values: Array +) : EnumBundleCompanion { final override val valueMap: Map = values.map { it.name to it }.toMap() @@ -53,5 +69,4 @@ open class EnumCompanion>( final override fun get(bundle: BaseBundle?) = super.get(bundle) final override fun get(intent: Intent?) = super.get(intent) - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/JsoupCleaner.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/JsoupCleaner.kt index da8672f4..c783a842 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/JsoupCleaner.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/JsoupCleaner.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.utils import org.jsoup.Jsoup @@ -21,8 +37,10 @@ internal fun String.cleanJsoup(): String = Jsoup.clean(this, PrivacyWhitelist()) class PrivacyWhitelist : Whitelist() { val blacklistAttrs = arrayOf("style", "aria-label", "rel") - val blacklistTags = arrayOf("body", "html", "head", "i", "b", "u", "style", "script", - "br", "p", "span", "ul", "ol", "li") + val blacklistTags = arrayOf( + "body", "html", "head", "i", "b", "u", "style", "script", + "br", "p", "span", "ul", "ol", "li" + ) override fun isSafeAttribute(tagName: String, el: Element, attr: Attribute): Boolean { val key = attr.key diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt index bee2f49b..8364c34e 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.utils import android.util.Log @@ -5,7 +21,6 @@ import ca.allanwang.kau.logging.KauLogger import com.bugsnag.android.Bugsnag import com.pitchedapps.frost.BuildConfig - /** * Created by Allan Wang on 2017-05-28. * @@ -45,5 +60,4 @@ object L : KauLogger("Frost", { Bugsnag.notify(t) } } - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt index 9f068a58..303142af 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.utils import android.graphics.Color @@ -71,8 +87,8 @@ object Prefs : KPref() { get() = Prefs.bgColor.withAlpha(30) fun nativeBgColor(unread: Boolean) = Prefs.bgColor - .colorToForeground(if (unread) 0.7f else 0.0f) - .withAlpha(30) + .colorToForeground(if (unread) 0.7f else 0.0f) + .withAlpha(30) val bgColor: Int get() = t.bgColor diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/Showcase.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/Showcase.kt index cafba223..27016018 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Showcase.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Showcase.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.utils import ca.allanwang.kau.kpref.KPref @@ -21,4 +37,3 @@ object Showcase : KPref() { override fun deleteKeys() = arrayOf("shown_release") } - diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt index 650f277b..56c1d6d9 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.utils import android.annotation.SuppressLint @@ -8,33 +24,59 @@ import android.content.Intent import android.graphics.Color import android.graphics.drawable.ColorDrawable import android.net.Uri -import androidx.annotation.StringRes -import com.google.android.material.snackbar.Snackbar -import androidx.core.content.FileProvider -import androidx.appcompat.widget.Toolbar import android.view.View import android.widget.FrameLayout import android.widget.TextView +import androidx.annotation.StringRes +import androidx.appcompat.widget.Toolbar +import androidx.core.content.FileProvider import ca.allanwang.kau.email.EmailBuilder import ca.allanwang.kau.email.sendEmail import ca.allanwang.kau.mediapicker.createMediaFile import ca.allanwang.kau.mediapicker.createPrivateMediaFile -import ca.allanwang.kau.utils.* +import ca.allanwang.kau.utils.adjustAlpha +import ca.allanwang.kau.utils.colorToForeground +import ca.allanwang.kau.utils.darken +import ca.allanwang.kau.utils.isColorDark +import ca.allanwang.kau.utils.lighten +import ca.allanwang.kau.utils.navigationBarColor +import ca.allanwang.kau.utils.snackbar +import ca.allanwang.kau.utils.startActivity +import ca.allanwang.kau.utils.startActivityForResult +import ca.allanwang.kau.utils.statusBarColor +import ca.allanwang.kau.utils.string +import ca.allanwang.kau.utils.with +import ca.allanwang.kau.utils.withAlpha +import ca.allanwang.kau.utils.withMinAlpha import ca.allanwang.kau.xml.showChangelog import com.afollestad.materialdialogs.MaterialDialog +import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.SnackbarContentLayout import com.pitchedapps.frost.BuildConfig import com.pitchedapps.frost.R -import com.pitchedapps.frost.activities.* +import com.pitchedapps.frost.activities.ImageActivity +import com.pitchedapps.frost.activities.LoginActivity +import com.pitchedapps.frost.activities.SelectorActivity +import com.pitchedapps.frost.activities.SettingsActivity +import com.pitchedapps.frost.activities.TabCustomizerActivity +import com.pitchedapps.frost.activities.WebOverlayActivity +import com.pitchedapps.frost.activities.WebOverlayActivityBase +import com.pitchedapps.frost.activities.WebOverlayBasicActivity import com.pitchedapps.frost.dbflow.CookieModel -import com.pitchedapps.frost.facebook.* +import com.pitchedapps.frost.facebook.FACEBOOK_COM +import com.pitchedapps.frost.facebook.FBCDN_NET +import com.pitchedapps.frost.facebook.FbCookie +import com.pitchedapps.frost.facebook.FbItem import com.pitchedapps.frost.facebook.FbUrlFormatter.Companion.VIDEO_REDIRECT +import com.pitchedapps.frost.facebook.USER_AGENT_BASIC +import com.pitchedapps.frost.facebook.formattedFbUrl import org.apache.commons.text.StringEscapeUtils import org.jsoup.Jsoup import org.jsoup.nodes.Element import java.io.File import java.io.IOException -import java.util.* +import java.util.ArrayList +import java.util.Locale /** * Created by Allan Wang on 2017-06-03. @@ -46,7 +88,10 @@ const val ARG_IMAGE_URL = "arg_image_url" const val ARG_TEXT = "arg_text" const val ARG_COOKIE = "arg_cookie" -inline fun Context.launchNewTask(cookieList: ArrayList = arrayListOf(), clearStack: Boolean = false) { +inline fun Context.launchNewTask( + cookieList: ArrayList = arrayListOf(), + clearStack: Boolean = false +) { startActivity(clearStack, intentBuilder = { putParcelableArrayListExtra(EXTRA_COOKIES, cookieList) }) @@ -81,8 +126,10 @@ fun Context.launchWebOverlay(url: String) = launchWebOverlayImpl(url) -private fun Context.fadeBundle() = ActivityOptions.makeCustomAnimation(this, - android.R.anim.fade_in, android.R.anim.fade_out).toBundle() +private fun Context.fadeBundle() = ActivityOptions.makeCustomAnimation( + this, + android.R.anim.fade_in, android.R.anim.fade_out +).toBundle() fun Context.launchImageActivity(imageUrl: String, text: String? = null, cookie: String? = null) { startActivity(intentBuilder = { @@ -174,7 +221,6 @@ inline fun Activity.setFrostColors(builder: ActivityThemeUtils.() -> Unit) { themer.theme(this) } - fun frostEvent(name: String, vararg events: Pair) { // todo bind L.v { "Event: $name ${events.joinToString(", ")}" } @@ -189,9 +235,11 @@ fun Throwable?.logFrostEvent(text: String) { frostEvent("Errors", "text" to text, "message" to (this?.message ?: "NA")) } -fun Activity.frostSnackbar(@StringRes text: Int, builder: Snackbar.() -> Unit = {}) = snackbar(text, Snackbar.LENGTH_LONG, frostSnackbar(builder)) +fun Activity.frostSnackbar(@StringRes text: Int, builder: Snackbar.() -> Unit = {}) = + snackbar(text, Snackbar.LENGTH_LONG, frostSnackbar(builder)) -fun View.frostSnackbar(@StringRes text: Int, builder: Snackbar.() -> Unit = {}) = snackbar(text, Snackbar.LENGTH_LONG, frostSnackbar(builder)) +fun View.frostSnackbar(@StringRes text: Int, builder: Snackbar.() -> Unit = {}) = + snackbar(text, Snackbar.LENGTH_LONG, frostSnackbar(builder)) @SuppressLint("RestrictedApi") private inline fun frostSnackbar(crossinline builder: Snackbar.() -> Unit): Snackbar.() -> Unit = { @@ -240,7 +288,7 @@ inline val String?.isFacebookUrl */ inline val String.isVideoUrl get() = startsWith(VIDEO_REDIRECT) || - (startsWith("https://video-") && contains(FBCDN_NET)) + (startsWith("https://video-") && contains(FBCDN_NET)) /** * [true] if url directly leads to a usable image @@ -271,22 +319,22 @@ inline val String?.isIndependent: Boolean } val dependentSegments = arrayOf( - "photoset_token", "direct_action_execute", "messages/?pageNum", "sharer.php", - "events/permalink", "events/feed/watch", - /* - * Add new members to groups - */ - "madminpanel", - /** - * Editing images - */ - "/confirmation/?", - /* - * Facebook messages have the following cases for the tid query - * mid* or id* for newer threads, which can be launched in new windows - * or a hash for old threads, which must be loaded on old threads - */ - "messages/read/?tid=id", "messages/read/?tid=mid" + "photoset_token", "direct_action_execute", "messages/?pageNum", "sharer.php", + "events/permalink", "events/feed/watch", + /* + * Add new members to groups + */ + "madminpanel", + /** + * Editing images + */ + "/confirmation/?", + /* + * Facebook messages have the following cases for the tid query + * mid* or id* for newer threads, which can be launched in new windows + * or a hash for old threads, which must be loaded on old threads + */ + "messages/read/?tid=id", "messages/read/?tid=mid" ) inline val String?.isExplicitIntent @@ -297,16 +345,20 @@ fun Context.frostChangelog() = showChangelog(R.xml.frost_changelog, Prefs.textCo } fun Context.frostUriFromFile(file: File): Uri = - FileProvider.getUriForFile(this, - BuildConfig.APPLICATION_ID + ".provider", - file) - -inline fun Context.sendFrostEmail(@StringRes subjectId: Int, crossinline builder: EmailBuilder.() -> Unit) = sendFrostEmail(string(subjectId), builder) - -inline fun Context.sendFrostEmail(subjectId: String, crossinline builder: EmailBuilder.() -> Unit) = sendEmail(string(R.string.dev_email), subjectId) { - builder() - addFrostDetails() -} + FileProvider.getUriForFile( + this, + BuildConfig.APPLICATION_ID + ".provider", + file + ) + +inline fun Context.sendFrostEmail(@StringRes subjectId: Int, crossinline builder: EmailBuilder.() -> Unit) = + sendFrostEmail(string(subjectId), builder) + +inline fun Context.sendFrostEmail(subjectId: String, crossinline builder: EmailBuilder.() -> Unit) = + sendEmail(string(R.string.dev_email), subjectId) { + builder() + addFrostDetails() + } fun EmailBuilder.addFrostDetails() { addItem("Prev version", Prefs.prevVersionCode.toString()) @@ -318,7 +370,8 @@ fun EmailBuilder.addFrostDetails() { fun frostJsoup(url: String) = frostJsoup(FbCookie.webCookie, url) -fun frostJsoup(cookie: String?, url: String) = Jsoup.connect(url).cookie(FACEBOOK_COM, cookie).userAgent(USER_AGENT_BASIC).get()!! +fun frostJsoup(cookie: String?, url: String) = + Jsoup.connect(url).cookie(FACEBOOK_COM, cookie).userAgent(USER_AGENT_BASIC).get()!! fun Element.first(vararg select: String): Element? { select.forEach { @@ -346,6 +399,6 @@ fun File.createFreshDir(): Boolean { } fun String.unescapeHtml(): String = - StringEscapeUtils.unescapeXml(this) - .replace("\\u003C", "<") - .replace("\\\"", "\"") + StringEscapeUtils.unescapeXml(this) + .replace("\\u003C", "<") + .replace("\\\"", "\"") diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/WebContextMenu.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/WebContextMenu.kt index dc2d7549..62330e4d 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/WebContextMenu.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/WebContextMenu.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.utils import android.content.Context @@ -41,7 +57,9 @@ class WebContext(val unformattedUrl: String, val text: String?) { enum class WebContextType(val textId: Int, val onClick: (c: Context, wc: WebContext) -> Unit) { OPEN_LINK(R.string.open_link, { c, wc -> c.launchWebOverlay(wc.unformattedUrl) }), COPY_LINK(R.string.copy_link, { c, wc -> c.copyToClipboard(wc.url) }), - COPY_TEXT(R.string.copy_text, { c, wc -> if (wc.text != null) c.copyToClipboard(wc.text) else c.toast(R.string.no_text) }), + COPY_TEXT( + R.string.copy_text, + { c, wc -> if (wc.text != null) c.copyToClipboard(wc.text) else c.toast(R.string.no_text) }), SHARE_LINK(R.string.share_link, { c, wc -> c.shareText(wc.url) }), DEBUG_LINK(R.string.debug_link, { c, wc -> c.materialDialogThemed { @@ -63,4 +81,4 @@ enum class WebContextType(val textId: Int, val onClick: (c: Context, wc: WebCont val values = values() operator fun get(index: Int) = values[index] } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/AccountItem.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/AccountItem.kt index 9f6d0c06..d7a7de0e 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/AccountItem.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/AccountItem.kt @@ -1,12 +1,32 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.views import android.graphics.drawable.Drawable -import androidx.appcompat.widget.AppCompatTextView -import androidx.recyclerview.widget.RecyclerView import android.view.View import android.widget.ImageView +import androidx.appcompat.widget.AppCompatTextView +import androidx.recyclerview.widget.RecyclerView import ca.allanwang.kau.iitems.KauIItem -import ca.allanwang.kau.utils.* +import ca.allanwang.kau.utils.bindView +import ca.allanwang.kau.utils.fadeIn +import ca.allanwang.kau.utils.invisible +import ca.allanwang.kau.utils.toDrawable +import ca.allanwang.kau.utils.visible import com.bumptech.glide.load.DataSource import com.bumptech.glide.load.engine.GlideException import com.bumptech.glide.request.RequestListener @@ -23,7 +43,7 @@ import com.pitchedapps.frost.utils.Prefs * Created by Allan Wang on 2017-06-05. */ class AccountItem(val cookie: CookieModel?) : KauIItem -(R.layout.view_account, { ViewHolder(it) }, R.id.item_account) { + (R.layout.view_account, { ViewHolder(it) }, R.id.item_account) { override fun bindView(viewHolder: ViewHolder, payloads: MutableList) { super.bindView(viewHolder, payloads) @@ -33,20 +53,37 @@ class AccountItem(val cookie: CookieModel?) : KauIItem { - override fun onResourceReady(resource: Drawable?, model: Any?, target: Target?, dataSource: DataSource?, isFirstResource: Boolean): Boolean { - text.fadeIn() - return false - } + .transform(FrostGlide.roundCorner).listener(object : RequestListener { + override fun onResourceReady( + resource: Drawable?, + model: Any?, + target: Target?, + dataSource: DataSource?, + isFirstResource: Boolean + ): Boolean { + text.fadeIn() + return false + } - override fun onLoadFailed(e: GlideException?, model: Any?, target: Target?, isFirstResource: Boolean): Boolean { - text.fadeIn() - return false - } - }).into(image) + override fun onLoadFailed( + e: GlideException?, + model: Any?, + target: Target?, + isFirstResource: Boolean + ): Boolean { + text.fadeIn() + return false + } + }).into(image) } else { text.visible() - image.setImageDrawable(GoogleMaterial.Icon.gmd_add_circle_outline.toDrawable(itemView.context, 100, Prefs.textColor)) + image.setImageDrawable( + GoogleMaterial.Icon.gmd_add_circle_outline.toDrawable( + itemView.context, + 100, + Prefs.textColor + ) + ) text.text = itemView.context.getString(R.string.kau_add_account) } } @@ -64,4 +101,4 @@ class AccountItem(val cookie: CookieModel?) : KauIItem. + */ package com.pitchedapps.frost.views import android.content.Context import android.graphics.drawable.GradientDrawable -import androidx.constraintlayout.widget.ConstraintLayout import android.util.AttributeSet -import ca.allanwang.kau.utils.* +import androidx.constraintlayout.widget.ConstraintLayout +import ca.allanwang.kau.utils.colorToForeground +import ca.allanwang.kau.utils.dpToPx +import ca.allanwang.kau.utils.gone +import ca.allanwang.kau.utils.toDrawable +import ca.allanwang.kau.utils.visible +import ca.allanwang.kau.utils.withAlpha import com.mikepenz.iconics.typeface.IIcon import com.pitchedapps.frost.R import com.pitchedapps.frost.utils.Prefs import kotlinx.android.synthetic.main.view_badged_icon.view.* - /** * Created by Allan Wang on 2017-06-19. */ class BadgedIcon @JvmOverloads constructor( - context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 ) : ConstraintLayout(context, attrs, defStyleAttr) { init { inflate(context, R.layout.view_badged_icon, this) val badgeColor = Prefs.mainActivityLayout.backgroundColor().withAlpha(255).colorToForeground(0.2f) - val badgeBackground = GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP, intArrayOf(badgeColor, badgeColor)) + val badgeBackground = + GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP, intArrayOf(badgeColor, badgeColor)) badgeBackground.cornerRadius = 13.dpToPx.toFloat() badge_text.background = badgeBackground badge_text.setTextColor(Prefs.mainActivityLayout.iconColor()) @@ -30,7 +53,13 @@ class BadgedIcon @JvmOverloads constructor( var iicon: IIcon? = null set(value) { field = value - badge_image.setImageDrawable(value?.toDrawable(context, sizeDp = 20, color = Prefs.mainActivityLayout.iconColor())) + badge_image.setImageDrawable( + value?.toDrawable( + context, + sizeDp = 20, + color = Prefs.mainActivityLayout.iconColor() + ) + ) } fun setAllAlpha(alpha: Float) { @@ -46,5 +75,4 @@ class BadgedIcon @JvmOverloads constructor( if (value != null && value != "0") badge_text.visible() else badge_text.gone() } - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt index c44a8188..d17a424c 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostContentView.kt @@ -1,13 +1,36 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.views import android.content.Context import android.os.Build -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import android.util.AttributeSet import android.view.View import android.widget.FrameLayout import android.widget.ProgressBar -import ca.allanwang.kau.utils.* +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout +import ca.allanwang.kau.utils.bindView +import ca.allanwang.kau.utils.circularReveal +import ca.allanwang.kau.utils.fadeIn +import ca.allanwang.kau.utils.fadeOut +import ca.allanwang.kau.utils.invisibleIf +import ca.allanwang.kau.utils.isVisible +import ca.allanwang.kau.utils.tint +import ca.allanwang.kau.utils.withAlpha import com.pitchedapps.frost.R import com.pitchedapps.frost.contracts.FrostContentContainer import com.pitchedapps.frost.contracts.FrostContentCore @@ -24,25 +47,32 @@ import io.reactivex.subjects.BehaviorSubject import io.reactivex.subjects.PublishSubject class FrostContentWeb @JvmOverloads constructor( - context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, defStyleRes: Int = 0 + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0, + defStyleRes: Int = 0 ) : FrostContentView(context, attrs, defStyleAttr, defStyleRes) { override val layoutRes: Int = R.layout.view_content_base_web - } class FrostContentRecycler @JvmOverloads constructor( - context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, defStyleRes: Int = 0 + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0, + defStyleRes: Int = 0 ) : FrostContentView(context, attrs, defStyleAttr, defStyleRes) { override val layoutRes: Int = R.layout.view_content_base_recycler - } abstract class FrostContentView @JvmOverloads constructor( - context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, defStyleRes: Int = 0 + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0, + defStyleRes: Int = 0 ) : FrameLayout(context, attrs, defStyleAttr, defStyleRes), - FrostContentParent where T : View, T : FrostContentCore { + FrostContentParent where T : View, T : FrostContentCore { private val refresh: SwipeRefreshLayout by bindView(R.id.content_refresh) private val progress: ProgressBar by bindView(R.id.content_progress) @@ -88,15 +118,14 @@ abstract class FrostContentView @JvmOverloads constructor( }.addTo(compositeDisposable) refreshObservable - .observeOn(AndroidSchedulers.mainThread()) - .subscribe { - refresh.isRefreshing = it - refresh.isEnabled = true - }.addTo(compositeDisposable) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { + refresh.isRefreshing = it + refresh.isEnabled = true + }.addTo(compositeDisposable) refresh.setOnRefreshListener { coreView.reload(true) } reloadThemeSelf() - } override fun bind(container: FrostContentContainer) { @@ -151,24 +180,24 @@ abstract class FrostContentView @JvmOverloads constructor( var loading = dispose != null dispose?.dispose() dispose = refreshObservable - .observeOn(AndroidSchedulers.mainThread()) - .subscribe { - if (it) { - loading = true - transitionStart = System.currentTimeMillis() - clearAnimation() - if (isVisible) - fadeOut(duration = 200L) - } else if (loading) { - loading = false - if (animate && Prefs.animate) circularReveal(offset = WEB_LOAD_DELAY) - else fadeIn(duration = 200L, offset = WEB_LOAD_DELAY) - L.v { "Transition loaded in ${System.currentTimeMillis() - transitionStart} ms" } - dispose?.dispose() - dispose = null - } + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { + if (it) { + loading = true + transitionStart = System.currentTimeMillis() + clearAnimation() + if (isVisible) + fadeOut(duration = 200L) + } else if (loading) { + loading = false + if (animate && Prefs.animate) circularReveal(offset = WEB_LOAD_DELAY) + else fadeIn(duration = 200L, offset = WEB_LOAD_DELAY) + L.v { "Transition loaded in ${System.currentTimeMillis() - transitionStart} ms" } + dispose?.dispose() + dispose = null } + } } return true } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostRecyclerView.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostRecyclerView.kt index 19869426..2b9e8f9c 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostRecyclerView.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostRecyclerView.kt @@ -1,10 +1,26 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.views import android.content.Context -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView import android.util.AttributeSet import android.view.View +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import ca.allanwang.kau.utils.circularReveal import ca.allanwang.kau.utils.fadeOut import com.pitchedapps.frost.contracts.FrostContentContainer @@ -18,9 +34,11 @@ import com.pitchedapps.frost.utils.Prefs * */ class FrostRecyclerView @JvmOverloads constructor( - context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 ) : RecyclerView(context, attrs, defStyleAttr), - FrostContentCore { + FrostContentCore { override fun reload(animate: Boolean) = reloadBase(animate) @@ -102,5 +120,4 @@ class FrostRecyclerView @JvmOverloads constructor( override fun reloadTextSizeSelf() { // todo } - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoView.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoView.kt index 85dc7e18..6ee34a2b 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoView.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoView.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.views import android.annotation.SuppressLint @@ -27,7 +43,9 @@ import com.pitchedapps.frost.utils.Prefs * Parent must have layout with both height & width as match_parent */ class FrostVideoView @JvmOverloads constructor( - context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 ) : VideoView(context, attrs, defStyleAttr) { /** @@ -105,7 +123,10 @@ class FrostVideoView @JvmOverloads constructor( videoDimensions.set(dimen, dimen) } val portrait = height > width - val scale = Math.min(height / (if (portrait) 4f else 2.3f) / videoDimensions.y, width / (if (portrait) 2.3f else 4f) / videoDimensions.x) + val scale = Math.min( + height / (if (portrait) 4f else 2.3f) / videoDimensions.y, + width / (if (portrait) 2.3f else 4f) / videoDimensions.x + ) val desiredHeight = scale * videoDimensions.y val desiredWidth = scale * videoDimensions.x val padding = containerContract.lowerVideoPadding @@ -151,8 +172,8 @@ class FrostVideoView @JvmOverloads constructor( /** * Only remap if not expanded and if dimensions have changed */ - val shouldRemap = !isExpanded - && (videoDimensions.x != ratio * intrinsicWidth || videoDimensions.y != ratio * intrinsicHeight) + val shouldRemap = !isExpanded && + (videoDimensions.x != ratio * intrinsicWidth || videoDimensions.y != ratio * intrinsicHeight) videoDimensions.set(ratio * intrinsicWidth, ratio * intrinsicHeight) if (shouldRemap) updateLocation() } @@ -226,7 +247,8 @@ class FrostVideoView @JvmOverloads constructor( * ------------------------------------------------------------------- */ - private inner class FrameTouchListener(context: Context) : GestureDetector.SimpleOnGestureListener(), View.OnTouchListener { + private inner class FrameTouchListener(context: Context) : GestureDetector.SimpleOnGestureListener(), + View.OnTouchListener { private val gestureDetector: GestureDetector = GestureDetector(context, this) @@ -252,7 +274,8 @@ class FrostVideoView @JvmOverloads constructor( /** * Monitors the view click events to show and hide the video controls if they have been specified. */ - private inner class VideoTouchListener(context: Context) : GestureDetector.SimpleOnGestureListener(), View.OnTouchListener { + private inner class VideoTouchListener(context: Context) : GestureDetector.SimpleOnGestureListener(), + View.OnTouchListener { private val gestureDetector: GestureDetector = GestureDetector(context, this) private val downLoc = PointF() @@ -315,4 +338,4 @@ class FrostVideoView @JvmOverloads constructor( return true } } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoViewer.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoViewer.kt index b2796999..c2535940 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoViewer.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoViewer.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.views import android.content.Context @@ -8,11 +24,22 @@ import android.util.AttributeSet import android.view.MotionEvent import android.view.ViewTreeObserver import android.widget.FrameLayout -import ca.allanwang.kau.utils.* +import ca.allanwang.kau.utils.fadeIn +import ca.allanwang.kau.utils.fadeOut +import ca.allanwang.kau.utils.gone +import ca.allanwang.kau.utils.goneIf +import ca.allanwang.kau.utils.inflate +import ca.allanwang.kau.utils.isColorDark +import ca.allanwang.kau.utils.isGone +import ca.allanwang.kau.utils.isVisible +import ca.allanwang.kau.utils.setIcon +import ca.allanwang.kau.utils.setMenuIcons +import ca.allanwang.kau.utils.visible +import ca.allanwang.kau.utils.withMinAlpha import com.devbrackets.android.exomedia.listener.VideoControlsVisibilityListener import com.mikepenz.google_material_typeface_library.GoogleMaterial -import com.pitchedapps.frost.utils.L import com.pitchedapps.frost.R +import com.pitchedapps.frost.utils.L import com.pitchedapps.frost.utils.Prefs import com.pitchedapps.frost.utils.frostDownload import kotlinx.android.synthetic.main.view_video.view.* @@ -21,7 +48,9 @@ import kotlinx.android.synthetic.main.view_video.view.* * Created by Allan Wang on 2017-10-13. */ class FrostVideoViewer @JvmOverloads constructor( - context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 ) : FrameLayout(context, attrs, defStyleAttr), FrostVideoViewerContract { companion object { @@ -51,16 +80,18 @@ class FrostVideoViewer @JvmOverloads constructor( inflate(R.layout.view_video, true) alpha = 0f video_background.setBackgroundColor( - if (!Prefs.blackMediaBg && Prefs.bgColor.isColorDark) - Prefs.bgColor.withMinAlpha(200) - else - Color.BLACK) + if (!Prefs.blackMediaBg && Prefs.bgColor.isColorDark) + Prefs.bgColor.withMinAlpha(200) + else + Color.BLACK + ) video.setViewerContract(this) video.pause() video_toolbar.inflateMenu(R.menu.menu_video) - context.setMenuIcons(video_toolbar.menu, Prefs.iconColor, - R.id.action_pip to GoogleMaterial.Icon.gmd_picture_in_picture_alt, - R.id.action_download to GoogleMaterial.Icon.gmd_file_download + context.setMenuIcons( + video_toolbar.menu, Prefs.iconColor, + R.id.action_pip to GoogleMaterial.Icon.gmd_picture_in_picture_alt, + R.id.action_download to GoogleMaterial.Icon.gmd_file_download ) video_toolbar.setOnMenuItemClickListener { when (it.itemId) { @@ -141,7 +172,6 @@ class FrostVideoViewer @JvmOverloads constructor( if (!video_toolbar.isGone) video_toolbar.fadeOut(duration = CONTROL_ANIMATION_DURATION) { video_toolbar.gone() } } - } interface FrostVideoViewerContract : VideoControlsVisibilityListener { @@ -171,4 +201,4 @@ interface FrostVideoContainerContract { * Called once the video has stopped & should be removed */ fun onVideoFinished() -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostViewPager.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostViewPager.kt index 18b7ae49..bf2f771d 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostViewPager.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostViewPager.kt @@ -1,10 +1,26 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.views import android.annotation.SuppressLint import android.content.Context -import androidx.viewpager.widget.ViewPager import android.util.AttributeSet import android.view.MotionEvent +import androidx.viewpager.widget.ViewPager import com.pitchedapps.frost.utils.Prefs /** @@ -12,21 +28,22 @@ import com.pitchedapps.frost.utils.Prefs * * Basic override to allow us to control swiping */ -class FrostViewPager @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : ViewPager(context, attrs) { +class FrostViewPager @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : + ViewPager(context, attrs) { var enableSwipe = true override fun onInterceptTouchEvent(ev: MotionEvent?) = - try { - Prefs.viewpagerSwipe && enableSwipe && super.onInterceptTouchEvent(ev) - } catch (e: IllegalArgumentException) { - false - } + try { + Prefs.viewpagerSwipe && enableSwipe && super.onInterceptTouchEvent(ev) + } catch (e: IllegalArgumentException) { + false + } @SuppressLint("ClickableViewAccessibility") override fun onTouchEvent(ev: MotionEvent?): Boolean = - try { - Prefs.viewpagerSwipe && enableSwipe && super.onTouchEvent(ev) - } catch (e: IllegalArgumentException) { - false - } -} \ No newline at end of file + try { + Prefs.viewpagerSwipe && enableSwipe && super.onTouchEvent(ev) + } catch (e: IllegalArgumentException) { + false + } +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostWebView.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostWebView.kt index 8230c338..b15ad5cf 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostWebView.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostWebView.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.views import android.animation.ValueAnimator @@ -16,16 +32,22 @@ import com.pitchedapps.frost.facebook.USER_AGENT_BASIC import com.pitchedapps.frost.fragments.WebFragment import com.pitchedapps.frost.utils.Prefs import com.pitchedapps.frost.utils.frostDownload -import com.pitchedapps.frost.web.* +import com.pitchedapps.frost.web.FrostChromeClient +import com.pitchedapps.frost.web.FrostJSI +import com.pitchedapps.frost.web.FrostWebViewClient +import com.pitchedapps.frost.web.NestedWebView +import com.pitchedapps.frost.web.shouldUseBasicAgent /** * Created by Allan Wang on 2017-05-29. * */ class FrostWebView @JvmOverloads constructor( - context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 ) : NestedWebView(context, attrs, defStyleAttr), - FrostContentCore { + FrostContentCore { override fun reload(animate: Boolean) { if (parent.registerTransition(false, animate)) @@ -59,7 +81,6 @@ class FrostWebView @JvmOverloads constructor( return this } - /** * Wrapper to the main userAgentString to cache it. * This decouples it from the UiThread @@ -168,4 +189,4 @@ class FrostWebView @JvmOverloads constructor( super.destroy() } } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/KPrefTextSeekbar.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/KPrefTextSeekbar.kt index 14f77e72..7f0d792a 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/KPrefTextSeekbar.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/KPrefTextSeekbar.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.views import android.annotation.SuppressLint @@ -43,4 +59,4 @@ class KPrefTextSeekbar(builder: KPrefSeekbarContract) : KPrefSeekbar(builder) { holder.desc?.setTextSize(TypedValue.COMPLEX_UNIT_PX, descOriginalSize) super.unbindView(holder) } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/Keywords.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/Keywords.kt index c171ce77..e63fcc21 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/Keywords.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/Keywords.kt @@ -1,15 +1,31 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.views import android.content.Context import android.graphics.drawable.Drawable -import androidx.constraintlayout.widget.ConstraintLayout +import android.util.AttributeSet +import android.view.View +import android.widget.ImageView import androidx.appcompat.widget.AppCompatEditText import androidx.appcompat.widget.AppCompatTextView +import androidx.constraintlayout.widget.ConstraintLayout import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import android.util.AttributeSet -import android.view.View -import android.widget.ImageView import ca.allanwang.kau.utils.bindView import ca.allanwang.kau.utils.string import ca.allanwang.kau.utils.tint @@ -23,12 +39,13 @@ import com.mikepenz.iconics.typeface.IIcon import com.pitchedapps.frost.R import com.pitchedapps.frost.utils.Prefs - /** * Created by Allan Wang on 2017-06-19. */ class Keywords @JvmOverloads constructor( - context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 ) : ConstraintLayout(context, attrs, defStyleAttr) { val editText: AppCompatEditText by bindView(R.id.edit_text) @@ -51,7 +68,8 @@ class Keywords @JvmOverloads constructor( recycler.layoutManager = LinearLayoutManager(context) recycler.adapter = adapter adapter.withEventHook(object : ClickEventHook() { - override fun onBind(viewHolder: RecyclerView.ViewHolder): View? = (viewHolder as? KeywordItem.ViewHolder)?.delete + override fun onBind(viewHolder: RecyclerView.ViewHolder): View? = + (viewHolder as? KeywordItem.ViewHolder)?.delete override fun onClick(v: View, position: Int, fastAdapter: FastAdapter, item: KeywordItem) { adapter.remove(position) @@ -62,7 +80,6 @@ class Keywords @JvmOverloads constructor( fun save() { Prefs.notificationKeywords = adapter.adapterItems.mapTo(mutableSetOf()) { it.keyword } } - } private fun IIcon.keywordDrawable(context: Context): Drawable = toDrawable(context, 20, Prefs.textColor) @@ -94,4 +111,4 @@ class KeywordItem(val keyword: String) : AbstractItem. + */ package com.pitchedapps.frost.web import android.annotation.SuppressLint import android.content.Context import android.graphics.Bitmap import android.graphics.Color -import androidx.annotation.WorkerThread import android.util.AttributeSet import android.view.View import android.webkit.WebView +import androidx.annotation.WorkerThread import com.pitchedapps.frost.facebook.USER_AGENT_BASIC import com.pitchedapps.frost.injectors.CssAssets import com.pitchedapps.frost.injectors.CssHider @@ -25,7 +41,9 @@ import java.io.File * A barebone webview with a refresh listener */ class DebugWebView @JvmOverloads constructor( - context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 ) : WebView(context, attrs, defStyleAttr) { var onPageFinished: (String?) -> Unit = {} @@ -71,25 +89,27 @@ class DebugWebView @JvmOverloads constructor( private fun injectBackgroundColor() { setBackgroundColor( - if (url.isFacebookUrl) Prefs.bgColor.withAlpha(255) - else Color.WHITE) + if (url.isFacebookUrl) Prefs.bgColor.withAlpha(255) + else Color.WHITE + ) } - override fun onPageCommitVisible(view: WebView, url: String?) { super.onPageCommitVisible(view, url) injectBackgroundColor() if (url.isFacebookUrl) view.jsInject( - CssAssets.ROUND_ICONS.maybe(Prefs.showRoundedIcons), + CssAssets.ROUND_ICONS.maybe(Prefs.showRoundedIcons), // CssHider.CORE, - CssHider.COMPOSER.maybe(!Prefs.showComposer), - CssHider.PEOPLE_YOU_MAY_KNOW.maybe(!Prefs.showSuggestedFriends), - CssHider.SUGGESTED_GROUPS.maybe(!Prefs.showSuggestedGroups), - Prefs.themeInjector, - CssHider.NON_RECENT.maybe((url?.contains("?sk=h_chr") ?: false) - && Prefs.aggressiveRecents)) + CssHider.COMPOSER.maybe(!Prefs.showComposer), + CssHider.PEOPLE_YOU_MAY_KNOW.maybe(!Prefs.showSuggestedFriends), + CssHider.SUGGESTED_GROUPS.maybe(!Prefs.showSuggestedGroups), + Prefs.themeInjector, + CssHider.NON_RECENT.maybe( + (url?.contains("?sk=h_chr") ?: false) && + Prefs.aggressiveRecents + ) + ) } } - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt index 3c3c063a..12df8000 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt @@ -1,7 +1,27 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.web import android.net.Uri -import android.webkit.* +import android.webkit.ConsoleMessage +import android.webkit.GeolocationPermissions +import android.webkit.ValueCallback +import android.webkit.WebChromeClient +import android.webkit.WebView import ca.allanwang.kau.permissions.PERMISSION_ACCESS_FINE_LOCATION import ca.allanwang.kau.permissions.kauRequestPermissions import com.pitchedapps.frost.R @@ -12,7 +32,6 @@ import com.pitchedapps.frost.views.FrostWebView import io.reactivex.subjects.BehaviorSubject import io.reactivex.subjects.Subject - /** * Created by Allan Wang on 2017-05-31. * @@ -45,9 +64,13 @@ class FrostChromeClient(web: FrostWebView) : WebChromeClient() { progress.onNext(newProgress) } - override fun onShowFileChooser(webView: WebView, filePathCallback: ValueCallback?>, fileChooserParams: FileChooserParams): Boolean { + override fun onShowFileChooser( + webView: WebView, + filePathCallback: ValueCallback?>, + fileChooserParams: FileChooserParams + ): Boolean { activity?.openFileChooser(filePathCallback, fileChooserParams) - ?: webView.frostSnackbar(R.string.file_chooser_not_found) + ?: webView.frostSnackbar(R.string.file_chooser_not_found) return activity != null } @@ -58,6 +81,4 @@ class FrostChromeClient(web: FrostWebView) : WebChromeClient() { callback(origin, granted, true) } } - - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt index 564b0e04..2afb28c9 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.web import android.webkit.JavascriptInterface @@ -5,11 +21,16 @@ import com.pitchedapps.frost.activities.MainActivity import com.pitchedapps.frost.contracts.MainActivityContract import com.pitchedapps.frost.contracts.VideoViewHolder import com.pitchedapps.frost.facebook.FbCookie -import com.pitchedapps.frost.utils.* +import com.pitchedapps.frost.utils.L +import com.pitchedapps.frost.utils.Prefs +import com.pitchedapps.frost.utils.WebContext +import com.pitchedapps.frost.utils.cookies +import com.pitchedapps.frost.utils.isIndependent +import com.pitchedapps.frost.utils.launchImageActivity +import com.pitchedapps.frost.utils.showWebContextMenu import com.pitchedapps.frost.views.FrostWebView import io.reactivex.subjects.Subject - /** * Created by Allan Wang on 2017-06-01. */ @@ -31,15 +52,15 @@ class FrostJSI(val web: FrostWebView) { @JavascriptInterface fun loadVideo(url: String?, isGif: Boolean): Boolean = - if (url != null && Prefs.enablePip) { - web.post { - (context as? VideoViewHolder)?.showVideo(url, isGif) - ?: L.e { "Could not load video; contract not implemented" } - } - true - } else { - false + if (url != null && Prefs.enablePip) { + web.post { + (context as? VideoViewHolder)?.showVideo(url, isGif) + ?: L.e { "Could not load video; contract not implemented" } } + true + } else { + false + } @JavascriptInterface fun reloadBaseUrl(animate: Boolean) { @@ -113,5 +134,4 @@ class FrostJSI(val web: FrostWebView) { html ?: return header?.onNext(html) } - -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt index 4e4df027..bd696b02 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.web import android.webkit.WebResourceRequest @@ -8,14 +24,19 @@ import com.pitchedapps.frost.utils.L import okhttp3.HttpUrl import java.io.ByteArrayInputStream - /** * Created by Allan Wang on 2017-07-13. * * Handler to decide when a request should be done by us * This is the crux of Frost's optimizations for the web browser */ -private val blankResource: WebResourceResponse by lazy { WebResourceResponse("text/plain", "utf-8", ByteArrayInputStream("".toByteArray())) } +private val blankResource: WebResourceResponse by lazy { + WebResourceResponse( + "text/plain", + "utf-8", + ByteArrayInputStream("".toByteArray()) + ) +} fun WebView.shouldFrostInterceptRequest(request: WebResourceRequest): WebResourceResponse? { val requestUrl = request.url?.toString() ?: return null @@ -46,12 +67,13 @@ val WebResourceRequest.isMedia: Boolean * Generic filter passthrough * If Resource is already nonnull, pass it, otherwise check if filter is met and override the response accordingly */ -fun WebResourceResponse?.filter(request: WebResourceRequest, filter: (url: String) -> Boolean) = filter(request.query { filter(it) }) +fun WebResourceResponse?.filter(request: WebResourceRequest, filter: (url: String) -> Boolean) = + filter(request.query { filter(it) }) fun WebResourceResponse?.filter(filter: Boolean): WebResourceResponse? = this - ?: if (filter) blankResource else null + ?: if (filter) blankResource else null -fun WebResourceResponse?.filterCss(request: WebResourceRequest): WebResourceResponse? = filter(request) { it.endsWith(".css") } +fun WebResourceResponse?.filterCss(request: WebResourceRequest): WebResourceResponse? = + filter(request) { it.endsWith(".css") } fun WebResourceResponse?.filterImage(request: WebResourceRequest): WebResourceResponse? = filter(request.isImage) - diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostUrlOverlayValidator.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostUrlOverlayValidator.kt index b83002a3..e2d294f7 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostUrlOverlayValidator.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostUrlOverlayValidator.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.web import com.pitchedapps.frost.activities.WebOverlayActivity @@ -8,7 +24,15 @@ import com.pitchedapps.frost.facebook.FbCookie import com.pitchedapps.frost.facebook.FbItem import com.pitchedapps.frost.facebook.USER_AGENT_BASIC import com.pitchedapps.frost.facebook.formattedFbUrl -import com.pitchedapps.frost.utils.* +import com.pitchedapps.frost.utils.L +import com.pitchedapps.frost.utils.Prefs +import com.pitchedapps.frost.utils.isImageUrl +import com.pitchedapps.frost.utils.isIndependent +import com.pitchedapps.frost.utils.isIndirectImageUrl +import com.pitchedapps.frost.utils.isVideoUrl +import com.pitchedapps.frost.utils.launchImageActivity +import com.pitchedapps.frost.utils.launchWebOverlay +import com.pitchedapps.frost.utils.launchWebOverlayBasic import com.pitchedapps.frost.views.FrostWebView import org.jetbrains.anko.runOnUiThread @@ -77,14 +101,14 @@ fun FrostWebView.requestWebOverlay(url: String): Boolean { * If the url contains any one of the whitelist segments, switch to the chat overlay */ val messageWhitelist: Set = - setOf(FbItem.MESSAGES, FbItem.CHAT, FbItem.FEED_MOST_RECENT, FbItem.FEED_TOP_STORIES) - .mapTo(mutableSetOf(), FbItem::url) + setOf(FbItem.MESSAGES, FbItem.CHAT, FbItem.FEED_MOST_RECENT, FbItem.FEED_TOP_STORIES) + .mapTo(mutableSetOf(), FbItem::url) val String.shouldUseBasicAgent: Boolean get() { - if (contains("story.php")) // do not use basic for comment section + if (contains("story.php")) // do not use basic for comment section return false - if (contains("/events/")) // do not use for events (namely the map) + if (contains("/events/")) // do not use for events (namely the map) return false - return true // use for everything else - } \ No newline at end of file + return true // use for everything else + } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt index 8824e635..d75f03bb 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.web import android.graphics.Bitmap @@ -10,8 +26,19 @@ import com.pitchedapps.frost.facebook.FB_URL_BASE import com.pitchedapps.frost.facebook.FbCookie import com.pitchedapps.frost.facebook.FbItem import com.pitchedapps.frost.facebook.formattedFbUrl -import com.pitchedapps.frost.injectors.* -import com.pitchedapps.frost.utils.* +import com.pitchedapps.frost.injectors.CssAssets +import com.pitchedapps.frost.injectors.CssHider +import com.pitchedapps.frost.injectors.JsActions +import com.pitchedapps.frost.injectors.JsAssets +import com.pitchedapps.frost.injectors.jsInject +import com.pitchedapps.frost.utils.L +import com.pitchedapps.frost.utils.Prefs +import com.pitchedapps.frost.utils.isExplicitIntent +import com.pitchedapps.frost.utils.isFacebookUrl +import com.pitchedapps.frost.utils.isImageUrl +import com.pitchedapps.frost.utils.isIndirectImageUrl +import com.pitchedapps.frost.utils.launchImageActivity +import com.pitchedapps.frost.utils.resolveActivityForUri import com.pitchedapps.frost.views.FrostWebView import io.reactivex.subjects.Subject import org.jetbrains.anko.withAlpha @@ -28,8 +55,8 @@ import org.jetbrains.anko.withAlpha */ open class BaseWebViewClient : WebViewClient() { - override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse? = view.shouldFrostInterceptRequest(request) - + override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse? = + view.shouldFrostInterceptRequest(request) } /** @@ -51,11 +78,11 @@ open class FrostWebViewClient(val web: FrostWebView) : BaseWebViewClient() { private fun injectBackgroundColor() { web.setBackgroundColor( - when { - isMain -> Color.TRANSPARENT - web.url.isFacebookUrl -> Prefs.bgColor.withAlpha(255) - else -> Color.WHITE - } + when { + isMain -> Color.TRANSPARENT + web.url.isFacebookUrl -> Prefs.bgColor.withAlpha(255) + else -> Color.WHITE + } ) } @@ -64,21 +91,24 @@ open class FrostWebViewClient(val web: FrostWebView) : BaseWebViewClient() { injectBackgroundColor() if (url.isFacebookUrl) view.jsInject( - CssAssets.ROUND_ICONS.maybe(Prefs.showRoundedIcons), + CssAssets.ROUND_ICONS.maybe(Prefs.showRoundedIcons), // CssHider.CORE, - CssHider.HEADER, - CssHider.COMPOSER.maybe(!Prefs.showComposer), - CssHider.PEOPLE_YOU_MAY_KNOW.maybe(!Prefs.showSuggestedFriends), - CssHider.SUGGESTED_GROUPS.maybe(!Prefs.showSuggestedGroups), - Prefs.themeInjector, - CssHider.NON_RECENT.maybe((web.url?.contains("?sk=h_chr") ?: false) - && Prefs.aggressiveRecents), - JsAssets.DOCUMENT_WATCHER, - JsAssets.CLICK_A, - CssHider.ADS.maybe(!Prefs.showFacebookAds), - JsAssets.CONTEXT_A, + CssHider.HEADER, + CssHider.COMPOSER.maybe(!Prefs.showComposer), + CssHider.PEOPLE_YOU_MAY_KNOW.maybe(!Prefs.showSuggestedFriends), + CssHider.SUGGESTED_GROUPS.maybe(!Prefs.showSuggestedGroups), + Prefs.themeInjector, + CssHider.NON_RECENT.maybe( + (web.url?.contains("?sk=h_chr") ?: false) && + Prefs.aggressiveRecents + ), + JsAssets.DOCUMENT_WATCHER, + JsAssets.CLICK_A, + CssHider.ADS.maybe(!Prefs.showFacebookAds), + JsAssets.CONTEXT_A, // JsAssets.HEADER_HIDER, - JsAssets.MEDIA) + JsAssets.MEDIA + ) else refresh.onNext(false) } @@ -104,9 +134,10 @@ open class FrostWebViewClient(val web: FrostWebView) : BaseWebViewClient() { refresh.onNext(false) injectBackgroundColor() web.jsInject( - JsActions.LOGIN_CHECK, - JsAssets.TEXTAREA_LISTENER, - JsAssets.HEADER_BADGES.maybe(isMain)) + JsActions.LOGIN_CHECK, + JsAssets.TEXTAREA_LISTENER, + JsAssets.HEADER_BADGES.maybe(isMain) + ) } open fun handleHtml(html: String?) { @@ -151,7 +182,6 @@ open class FrostWebViewClient(val web: FrostWebView) : BaseWebViewClient() { if (Prefs.linksInDefaultApp && view.context.resolveActivityForUri(request.url)) return true return super.shouldOverrideUrlLoading(view, request) } - } private const val EMIT_THEME = 0b1 @@ -189,4 +219,4 @@ class FrostWebViewClientMenu(web: FrostWebView) : FrostWebViewClient(web) { v { "Should inject ${url.shouldInjectMenu}" } if (!url.shouldInjectMenu) injectAndFinish() } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt index 1f22f303..392cb353 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.web import android.annotation.SuppressLint @@ -5,7 +21,11 @@ import android.content.Context import android.graphics.Color import android.util.AttributeSet import android.view.View -import android.webkit.* +import android.webkit.ConsoleMessage +import android.webkit.CookieManager +import android.webkit.WebChromeClient +import android.webkit.WebResourceRequest +import android.webkit.WebView import ca.allanwang.kau.utils.fadeIn import ca.allanwang.kau.utils.isVisible import com.pitchedapps.frost.dbflow.CookieModel @@ -26,7 +46,9 @@ import org.jetbrains.anko.uiThread * Created by Allan Wang on 2017-05-29. */ class LoginWebView @JvmOverloads constructor( - context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 ) : WebView(context, attrs, defStyleAttr) { private lateinit var loginCallback: (CookieModel) -> Unit @@ -73,9 +95,11 @@ class LoginWebView @JvmOverloads constructor( L.d { "Login page commit visible" } view.setBackgroundColor(Color.TRANSPARENT) if (url.isFacebookUrl) - view.jsInject(JsAssets.HEADER_HIDER, - CssHider.CORE, - Prefs.themeInjector) + view.jsInject( + JsAssets.HEADER_HIDER, + CssHider.CORE, + Prefs.themeInjector + ) } override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean { @@ -97,4 +121,4 @@ class LoginWebView @JvmOverloads constructor( progressCallback(newProgress) } } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/NestedWebView.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/NestedWebView.kt index 760d81fc..6e7fc0b6 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/web/NestedWebView.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/web/NestedWebView.kt @@ -1,14 +1,29 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.web import android.annotation.SuppressLint import android.content.Context -import androidx.core.view.NestedScrollingChild -import androidx.core.view.NestedScrollingChildHelper -import androidx.core.view.ViewCompat import android.util.AttributeSet import android.view.MotionEvent import android.webkit.WebView - +import androidx.core.view.NestedScrollingChild +import androidx.core.view.NestedScrollingChildHelper +import androidx.core.view.ViewCompat /** * Created by Allan Wang on 20/12/17. @@ -16,7 +31,9 @@ import android.webkit.WebView * Webview extension that handles nested scrolls */ open class NestedWebView @JvmOverloads constructor( - context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 ) : WebView(context, attrs, defStyleAttr), NestedScrollingChild { private lateinit var childHelper: NestedScrollingChildHelper @@ -99,11 +116,20 @@ open class NestedWebView @JvmOverloads constructor( final override fun hasNestedScrollingParent() = childHelper.hasNestedScrollingParent() - final override fun dispatchNestedScroll(dxConsumed: Int, dyConsumed: Int, dxUnconsumed: Int, dyUnconsumed: Int, offsetInWindow: IntArray?) = childHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow) + final override fun dispatchNestedScroll( + dxConsumed: Int, + dyConsumed: Int, + dxUnconsumed: Int, + dyUnconsumed: Int, + offsetInWindow: IntArray? + ) = childHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow) - final override fun dispatchNestedPreScroll(dx: Int, dy: Int, consumed: IntArray?, offsetInWindow: IntArray?) = childHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow) + final override fun dispatchNestedPreScroll(dx: Int, dy: Int, consumed: IntArray?, offsetInWindow: IntArray?) = + childHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow) - final override fun dispatchNestedFling(velocityX: Float, velocityY: Float, consumed: Boolean) = childHelper.dispatchNestedFling(velocityX, velocityY, consumed) + final override fun dispatchNestedFling(velocityX: Float, velocityY: Float, consumed: Boolean) = + childHelper.dispatchNestedFling(velocityX, velocityY, consumed) - final override fun dispatchNestedPreFling(velocityX: Float, velocityY: Float) = childHelper.dispatchNestedPreFling(velocityX, velocityY) -} \ No newline at end of file + final override fun dispatchNestedPreFling(velocityX: Float, velocityY: Float) = + childHelper.dispatchNestedPreFling(velocityX, velocityY) +} diff --git a/app/src/test/kotlin/com/pitchedapps/frost/MiscTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/MiscTest.kt index d730b933..20610b2a 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/MiscTest.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/MiscTest.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost import com.pitchedapps.frost.facebook.requests.zip @@ -19,12 +35,14 @@ class MiscTest { val now = System.currentTimeMillis() val base = 1 val data: LongArray = (0..15).map { Math.random() + base } - .toTypedArray().zip(List::toLongArray) { - Thread.sleep((it * 1000).toLong()) - System.currentTimeMillis() - now - }.blockingGet() + .toTypedArray().zip(List::toLongArray) { + Thread.sleep((it * 1000).toLong()) + System.currentTimeMillis() - now + }.blockingGet() println(data.contentToString()) - assertTrue(data.all { it >= base * 1000 && it < base * 1000 * 5 }, - "zip did not seem to work on different threads") + assertTrue( + data.all { it >= base * 1000 && it < base * 1000 * 5 }, + "zip did not seem to work on different threads" + ) } -} \ No newline at end of file +} diff --git a/app/src/test/kotlin/com/pitchedapps/frost/debugger/OfflineWebsiteTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/debugger/OfflineWebsiteTest.kt index e30ec174..f7dad4d3 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/debugger/OfflineWebsiteTest.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/debugger/OfflineWebsiteTest.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.debugger import com.pitchedapps.frost.facebook.FB_URL_BASE @@ -16,11 +32,10 @@ class OfflineWebsiteTest { val countdown = CountDownLatch(1) val buildPath = if (File(".").parentFile?.name == "app") "build/offline_test" else "app/build/offline_test" OfflineWebsite(FB_URL_BASE, COOKIE, baseDir = File(buildPath)) - .loadAndZip("test") { - println("Outcome $it") - countdown.countDown() - } + .loadAndZip("test") { + println("Outcome $it") + countdown.countDown() + } countdown.await() } - -} \ No newline at end of file +} diff --git a/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbDomTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbDomTest.kt index ce748907..9472adfe 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbDomTest.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbDomTest.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.facebook import com.pitchedapps.frost.internal.authDependent @@ -22,5 +38,4 @@ class FbDomTest { assertNotNull(doc.getElementById("header")) assertNotNull(doc.getElementById("mJewelNav")) } - -} \ No newline at end of file +} diff --git a/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbRegexTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbRegexTest.kt index 08853466..f872cfc7 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbRegexTest.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbRegexTest.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.facebook import org.apache.commons.text.StringEscapeUtils @@ -18,7 +34,8 @@ class FbRegexTest { @Test fun fbDtsgRegex() { val fb_dtsg = "readme" - val input = "data-sigil=\"mbasic_inline_feed_composer\">\u003Cinput type=\"hidden\" name=\"fb_dtsg\" value=\"$fb_dtsg\" autocomplete=\"off\" \\/>\u003Cinput type=\"hidden\" name=\"privacyx\" value=\"12345\"" + val input = + "data-sigil=\"mbasic_inline_feed_composer\">\u003Cinput type=\"hidden\" name=\"fb_dtsg\" value=\"$fb_dtsg\" autocomplete=\"off\" \\/>\u003Cinput type=\"hidden\" name=\"privacyx\" value=\"12345\"" assertEquals(fb_dtsg, FB_DTSG_MATCHER.find(input)[1]) } @@ -56,5 +73,4 @@ class FbRegexTest { val img = "https://scontent-yyz1-1.xx.fbcdn.net/v/t31.0-8/fr/cp0/e15/q65/89056_${id}_98239_o.jpg" assertEquals(id, FB_IMAGE_ID_MATCHER.find(img)[1]?.toLongOrNull()) } - -} \ No newline at end of file +} diff --git a/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbUrlTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbUrlTest.kt index beda26ef..3bd59fd3 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbUrlTest.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbUrlTest.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.facebook import com.pitchedapps.frost.utils.isImageUrl @@ -7,7 +23,6 @@ import kotlin.test.assertEquals import kotlin.test.assertFalse import kotlin.test.assertTrue - /** * Created by Allan Wang on 2017-07-07. */ @@ -63,16 +78,17 @@ class FbUrlTest { @Test fun video() { //note that the video numbers have been changed to maintain privacy - val url = "/video_redirect/?src=https%3A%2F%2Fvideo-yyz1-1.xx.fbcdn.net%2Fv%2Ft42.1790-2%2F2349078999904_n.mp4%3Fefg%3DeyJ87J9%26oh%3Df5777784%26oe%3D56FD4&source=media_collage&id=1735049&refid=8&_ft_=qid.6484464%3Amf_story_key.-43172431214%3Atop_level_post_id.102773&__tn__=FEH-R" - val expected = "https://video-yyz1-1.xx.fbcdn.net/v/t42.1790-2/2349078999904_n.mp4?efg=eyJ87J9&oh=f5777784&oe=56FD4&source=media_collage&id=1735049&_ft_=qid.6484464:mf_story_key.-43172431214:top_level_post_id.102773&__tn__=FEH-R" + val url = + "/video_redirect/?src=https%3A%2F%2Fvideo-yyz1-1.xx.fbcdn.net%2Fv%2Ft42.1790-2%2F2349078999904_n.mp4%3Fefg%3DeyJ87J9%26oh%3Df5777784%26oe%3D56FD4&source=media_collage&id=1735049&refid=8&_ft_=qid.6484464%3Amf_story_key.-43172431214%3Atop_level_post_id.102773&__tn__=FEH-R" + val expected = + "https://video-yyz1-1.xx.fbcdn.net/v/t42.1790-2/2349078999904_n.mp4?efg=eyJ87J9&oh=f5777784&oe=56FD4&source=media_collage&id=1735049&_ft_=qid.6484464:mf_story_key.-43172431214:top_level_post_id.102773&__tn__=FEH-R" assertFbFormat(expected, url) } - @Test fun image() { arrayOf( - "https://scontent-yyz1-1.xx.fbcdn.net/v/t1.0-9/fr/cp0/e15/q65/229_546131_836546862_n.jpg?efg=e343J9&oh=d4245b1&oe=5453" + "https://scontent-yyz1-1.xx.fbcdn.net/v/t1.0-9/fr/cp0/e15/q65/229_546131_836546862_n.jpg?efg=e343J9&oh=d4245b1&oe=5453" // "/photo/view_full_size/?fbid=1523&ref_component=mbasic_photo_permalink&ref_page=%2Fwap%2Fphoto.php&refid=153&_ft_=...", // "#!/photo/view_full_size/?fbid=1523&ref_component=mbasic_photo_permalink&ref_page=%2Fwap%2Fphoto.php&refid=153&_ft_=..." ).forEach { @@ -83,7 +99,7 @@ class FbUrlTest { @Test fun indirectImage() { arrayOf( - "#!/photo/view_full_size/?fbid=107368839645039" + "#!/photo/view_full_size/?fbid=107368839645039" ).forEach { assertTrue(it.isIndirectImageUrl, "Failed to match indirect image for $it") } @@ -92,13 +108,12 @@ class FbUrlTest { @Test fun antiImageRegex() { arrayOf( - "http...fbcdn.net...mp4", - "/photo/...png", - "https://www.google.ca" + "http...fbcdn.net...mp4", + "/photo/...png", + "https://www.google.ca" ).forEach { assertFalse(it.isImageUrl, "Should not have matched image for $it") } - } @Test @@ -112,5 +127,4 @@ class FbUrlTest { // val urlBase = "photo/view_full_size/?fbid=1234&ref_component=mbasic_photo_permalink&ref_page=%2Fwap%2Fphoto.php&refid=13&_ft_=qid.1234%3Amf_story_key.1234%3Atop_level_post_id" // assertFbFormat("$FB_URL_BASE$urlBase", "#!/$urlBase") // } - -} \ No newline at end of file +} diff --git a/app/src/test/kotlin/com/pitchedapps/frost/facebook/parsers/FbParseTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/facebook/parsers/FbParseTest.kt index 3307c72e..075f045e 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/facebook/parsers/FbParseTest.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/facebook/parsers/FbParseTest.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.facebook.parsers import com.pitchedapps.frost.internal.COOKIE @@ -24,11 +40,11 @@ class FbParseTest { } private inline fun FrostParser.test(action: T.() -> Unit = {}) = - parse(COOKIE).test(url, action) + parse(COOKIE).test(url, action) private inline fun ParseResponse?.test(url: String, action: T.() -> Unit = {}) { val response = this - ?: fail("${T::class.simpleName} parser returned null for $url") + ?: fail("${T::class.simpleName} parser returned null for $url") println(response) response.data.action() } @@ -58,4 +74,4 @@ class FbParseTest { } notifs.map(FrostNotif::time).assertDescending("notif time values") } -} \ No newline at end of file +} diff --git a/app/src/test/kotlin/com/pitchedapps/frost/facebook/requests/FbFullImageTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/facebook/requests/FbFullImageTest.kt index c4e51d41..4eb90d74 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/facebook/requests/FbFullImageTest.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/facebook/requests/FbFullImageTest.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.facebook.requests import com.pitchedapps.frost.internal.COOKIE @@ -26,4 +42,4 @@ class FbFullImageTest { assertNotNull(result) println(result) } -} \ No newline at end of file +} diff --git a/app/src/test/kotlin/com/pitchedapps/frost/facebook/requests/FbRequestTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/facebook/requests/FbRequestTest.kt index c5fc8e8e..3a7abec4 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/facebook/requests/FbRequestTest.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/facebook/requests/FbRequestTest.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.facebook.requests import com.fasterxml.jackson.databind.ObjectMapper @@ -8,7 +24,11 @@ import com.pitchedapps.frost.internal.authDependent import okhttp3.Call import org.junit.BeforeClass import org.junit.Test -import kotlin.test.* +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertNotNull +import kotlin.test.assertTrue +import kotlin.test.fail /** * Created by Allan Wang on 21/12/17. diff --git a/app/src/test/kotlin/com/pitchedapps/frost/injectors/InjectorTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/injectors/InjectorTest.kt index 76b37afe..f38f03bb 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/injectors/InjectorTest.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/injectors/InjectorTest.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.injectors import org.junit.Test diff --git a/app/src/test/kotlin/com/pitchedapps/frost/internal/Internal.kt b/app/src/test/kotlin/com/pitchedapps/frost/internal/Internal.kt index 81175b19..061e7c38 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/internal/Internal.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/internal/Internal.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.internal import com.pitchedapps.frost.facebook.FB_USER_MATCHER @@ -11,7 +27,7 @@ import org.junit.Assume import org.junit.Test import java.io.File import java.io.FileInputStream -import java.util.* +import java.util.Properties import java.util.concurrent.TimeUnit import kotlin.reflect.full.starProjectedType import kotlin.test.assertEquals @@ -111,4 +127,4 @@ class InternalTest { } catch (e: Exception) { // pass } -} \ No newline at end of file +} diff --git a/app/src/test/kotlin/com/pitchedapps/frost/rx/ResettableFlyweightTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/rx/ResettableFlyweightTest.kt index a520e9e3..26a5a8de 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/rx/ResettableFlyweightTest.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/rx/ResettableFlyweightTest.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.rx import com.pitchedapps.frost.internal.concurrentTest @@ -54,6 +70,4 @@ class ResettableFlyweightTest { } } } - - -} \ No newline at end of file +} diff --git a/app/src/test/kotlin/com/pitchedapps/frost/utils/BuildUtilsTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/utils/BuildUtilsTest.kt index 92bd5bec..b3d44d69 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/utils/BuildUtilsTest.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/utils/BuildUtilsTest.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.utils import com.pitchedapps.frost.BuildConfig @@ -19,4 +35,4 @@ class BuildUtilsTest { fun androidTests() { assertNotNull(BuildUtils.match(BuildConfig.VERSION_NAME)) } -} \ No newline at end of file +} diff --git a/app/src/test/kotlin/com/pitchedapps/frost/utils/JsoupCleanerTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/utils/JsoupCleanerTest.kt index 4ec09ea6..72cca836 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/utils/JsoupCleanerTest.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/utils/JsoupCleanerTest.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.utils import org.junit.Test @@ -47,10 +63,10 @@ class JsoupCleanerTest { @Test fun kau() { - val html = """
KAU

An extensive collection of Kotlin Android Utils

KAUclose
  • Huge package of one line extension functions
  • Custom UI views
  • Adapter items and animators
  • SearchView
  • Custom delegates
""" - val expected = """
""" + val html = + """
KAU

An extensive collection of Kotlin Android Utils

KAUclose
  • Huge package of one line extension functions
  • Custom UI views
  • Adapter items and animators
  • SearchView
  • Custom delegates
""" + val expected = + """
""" html.assertCleanHtml(expected) } - } - diff --git a/app/src/test/kotlin/com/pitchedapps/frost/utils/PrefsTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/utils/PrefsTest.kt index 56ec4c02..088a7fbe 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/utils/PrefsTest.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/utils/PrefsTest.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.utils import org.junit.Before @@ -38,4 +54,4 @@ class PrefsTest { test = 3L assertEquals(3L, file) } -} \ No newline at end of file +} diff --git a/app/src/test/kotlin/com/pitchedapps/frost/utils/StringEscapeUtilsTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/utils/StringEscapeUtilsTest.kt index 86bd4ce5..f5ea56ae 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/utils/StringEscapeUtilsTest.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/utils/StringEscapeUtilsTest.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.utils import org.junit.Test @@ -13,4 +29,4 @@ class StringEscapeUtilsTest { val escaped = "\\u003Chead> color=\\\"#3b5998\\\"" assertEquals(" color=\"#3b5998\"", escaped.unescapeHtml()) } -} \ No newline at end of file +} diff --git a/app/src/test/kotlin/com/pitchedapps/frost/utils/UrlTests.kt b/app/src/test/kotlin/com/pitchedapps/frost/utils/UrlTests.kt index 109387a0..44e8377a 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/utils/UrlTests.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/utils/UrlTests.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2018 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package com.pitchedapps.frost.utils import com.pitchedapps.frost.facebook.FACEBOOK_COM @@ -17,19 +33,21 @@ class UrlTests { fun independence() { mapOf( - GOOGLE to true, - FACEBOOK_COM to true, - "#!/photos/viewer/?photoset_token=pcb.1234" to false, - "#test-id" to false, - "#" to false, - "#!" to false, - "#!/" to false, - "#!/events/permalink/going/?event_id=" to false, - "/this/is/valid" to true, - "#!/facebook/segment" to true + GOOGLE to true, + FACEBOOK_COM to true, + "#!/photos/viewer/?photoset_token=pcb.1234" to false, + "#test-id" to false, + "#" to false, + "#!" to false, + "#!/" to false, + "#!/events/permalink/going/?event_id=" to false, + "/this/is/valid" to true, + "#!/facebook/segment" to true ).forEach { (url, valid) -> - assertEquals(valid, url.isIndependent, - "Independence test failed for $url; should be $valid") + assertEquals( + valid, url.isIndependent, + "Independence test failed for $url; should be $valid" + ) } } @@ -38,4 +56,4 @@ class UrlTests { assertFalse(GOOGLE.isFacebookUrl, "google") assertTrue(FACEBOOK_COM.isFacebookUrl, "facebook") } -} \ No newline at end of file +} diff --git a/build.gradle b/build.gradle index ef1dc448..64e324d2 100644 --- a/build.gradle +++ b/build.gradle @@ -12,6 +12,7 @@ buildscript { classpath "com.android.tools.build:gradle:${ANDROID_GRADLE}" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${KOTLIN}" classpath "com.bugsnag:bugsnag-android-gradle-plugin:${BUGSNAG_PLUGIN}" + classpath "com.diffplug.spotless:spotless-plugin-gradle:${SPOTLESS}" classpath "com.getkeepsafe.dexcount:dexcount-gradle-plugin:${DEX_PLUGIN}" classpath "gradle.plugin.com.gladed.gradle.androidgitversion:gradle-android-git-version:${GIT_PLUGIN}" } diff --git a/gradle.properties b/gradle.properties index f708598c..1af54944 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,6 +20,9 @@ KOTLIN=1.3.11 # https://mvnrepository.com/artifact/com.android.tools.build/gradle?repo=google ANDROID_GRADLE=3.2.1 +# https://github.com/diffplug/spotless/blob/master/plugin-gradle/CHANGES.md +SPOTLESS=3.17.0 + # https://github.com/bugsnag/bugsnag-android/releases BUGSNAG=4.9.3 # https://github.com/bugsnag/bugsnag-android-gradle-plugin/releases diff --git a/spotless.gradle b/spotless.gradle new file mode 100644 index 00000000..22dba3a8 --- /dev/null +++ b/spotless.gradle @@ -0,0 +1,11 @@ +apply plugin: "com.diffplug.gradle.spotless" + +spotless { + kotlin { + target "**/*.kt" + ktlint() + licenseHeaderFile '../spotless.license.kt' + trimTrailingWhitespace() + endWithNewline() + } +} \ No newline at end of file diff --git a/spotless.license.kt b/spotless.license.kt new file mode 100644 index 00000000..35d16571 --- /dev/null +++ b/spotless.license.kt @@ -0,0 +1,16 @@ +/* + * Copyright $YEAR Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ \ No newline at end of file -- cgit v1.2.3