1
0
mirror of https://github.com/AllanWang/Frost-for-Facebook.git synced 2024-11-10 04:52:38 +01:00
* Create base activity

* Created some testers

* Update theme and fix mess up

* Update theme and replace paint

* WIP intro drawables

* Create intro screens

* Clear unnecessary dependencies

* Finalize intro panels

* Clean up intro

* Attack intro to settings

* Fix lint

* Finalize intro
This commit is contained in:
Allan Wang 2017-07-30 15:57:27 -07:00 committed by GitHub
parent d94bc858c8
commit 14185936f4
46 changed files with 1334 additions and 91 deletions

View File

@ -10,7 +10,7 @@ apply plugin: 'com.github.triplet.play'
play {
jsonFile = file('../files/gplay-keys.json')
track = 'beta'
track = 'alpha'
errorOnSizeLimit = true
uploadImages = false
untrackOld = true
@ -172,4 +172,5 @@ dependencies {
compile "com.davemorrissey.labs:subsampling-scale-image-view:${SCALE_IMAGE_VIEW}"
compile "com.sothree.slidinguppanel:library:${SLIDING_PANEL}"
}

View File

@ -105,7 +105,9 @@
android:scheme="https" />
</intent-filter>
</activity>
<activity
android:name=".activities.IntroActivity"
android:theme="@style/FrostTheme.Intro" />
<activity
android:name=".activities.LoginActivity"
android:theme="@style/FrostTheme" />

View File

@ -1,17 +1,35 @@
@mixin placeholder {
::-webkit-input-placeholder {
@content
}
::-webkit-input-placeholder {
@content;
}
:-moz-placeholder {
@content
}
:-moz-placeholder {
@content;
}
::-moz-placeholder {
@content
}
::-moz-placeholder {
@content;
}
:-ms-input-placeholder {
@content
}
:-ms-input-placeholder {
@content;
}
}
@mixin keyframes($name) {
@-webkit-keyframes #{$name} {
@content;
}
@-moz-keyframes #{$name} {
@content;
}
@-ms-keyframes #{$name} {
@content;
}
@keyframes #{$name} {
@content;
}
}

View File

@ -8,4 +8,5 @@ $link: #d59ed5 !default;
$background: #451515 !default;
$background2: rgba(lighten($background, 35%), 0.2) !default;
$bg_opaque: rgba($background, 1.0) !default;
$bg_opaque2: rgba($background2, 1.0) !default;
$divider: rgba($text, 0.3) !default;

View File

@ -8,9 +8,11 @@ body, #root, #header, [style*="background-color"], ._55wo, ._1upc, input, ._2f9r
.jewel, .flyout, ._13e_, ._5-lw, ._5c0e, .jx-result, ._336p, .mentions-suggest-item, .mentions-suggest { background: #451515 !important; }
._403n, ._1-kc { background: #c74646 !important; }
button:not([style*=image]), button::before, .touch ._56bt, ._56be::before, .btnS, .touch::before, ._590n, ._4g8h, ._5xo2, ._5u5a::before, ._4u3j, ._15ks, ._5hua, ._59tt, ._41ft, .jx-tokenizer, ._55fj, .excessItem, ._4e8n, ._5pxa._3uj9, ._5n_5, ._u2d, ._56bu::before, ._5h8f, ._d00, ._2066, ._2k51, ._4qax, .aclb, ._4756, ._w34, ._56bv::before, ._5769, ._34iv, ._z-w, .acbk { background: rgba(199, 70, 70, 0.2) !important; }
[style*="color"], body, input, ._42rv, ._z-z, ._z-v, ._1e8d, ._36nl, ._36nm, ._2_11, ._2_rf, ._43mh, .touch .btn, p, span, .fcg, button, ._52j9, ._52jb, ._52ja, ._5j35, ._rnk, ._24u0, ._1g06, ._14ye, .fcb, ._56cz._56c_, ._1gk_, ._55fj, ._45fu, ._18qg, ._1_ac, textarea, ._24pi, ._4en9, ._1kb, ._5p7j, ._2klz, ._5780, ._5781, ._5782, ._3u9u, ._3u9_, ._3u9s, ._1hcx, ._2066, ._1_-1, ._cv_, ._1nbx, ._2cuh, ._4ms9, ._4ms5, ._4ms6, ._31b4, ._31b5, ._5q_r, ._idb, ._27vp, ._4nwe, ._4nw9, ._27vi, .appCenterAppInfo, .appCenterPermissions, ._3c9l, ._3c9m, ._4jn_, ._32qt, ._3mom, ._3moo, ._-7o, ._d00, ._d01, ._559g, ._2new, .appCenterCategorySelectorButton, .mentions-input, .mentions-placeholder, .fcw, ._5-7t, .fcl, ._4qas, .thread-title, .title, ._46pa, ._336p, ._1rrd, ._2om4, ._3m1m, ._2om2, ._5n_e, .appListExplanation, ._5yt8, ._8he, ._2luw, ._5rgs, h1, h2, h3, h4, h5, h6 { color: #d7b0d7 !important; }
[style*="color"], body, input, ._42rv, ._z-z, ._z-v, ._1e8d, ._36nl, ._36nm, ._2_11, ._2_rf, ._2ip_, ._403p, ._5xu2, ._3ml8, ._3mla, ._43mh, .touch .btn, p, span, .fcg, button, ._52j9, ._52jb, ._52ja, ._5j35, ._rnk, ._24u0, ._1g06, ._14ye, .fcb, ._56cz._56c_, ._1gk_, ._55fj, ._45fu, ._18qg, ._1_ac, textarea, ._24pi, ._4en9, ._1kb, ._5p7j, ._2klz, ._5780, ._5781, ._5782, ._3u9u, ._3u9_, ._3u9s, ._1hcx, ._2066, ._1_-1, ._cv_, ._1nbx, ._2cuh, ._4ms9, ._4ms5, ._4ms6, ._31b4, ._31b5, ._5q_r, ._idb, ._27vp, ._4nwe, ._4nw9, ._27vi, .appCenterAppInfo, .appCenterPermissions, ._3c9l, ._3c9m, ._4jn_, ._32qt, ._3mom, ._3moo, ._-7o, ._d00, ._d01, ._559g, ._2new, .appCenterCategorySelectorButton, .mentions-input, .mentions-placeholder, .fcw, ._5-7t, .fcl, ._4qas, .thread-title, .title, ._46pa, ._336p, ._1rrd, ._2om4, ._3m1m, ._2om2, ._5n_e, .appListExplanation, ._5yt8, ._8he, ._2luw, ._5rgs, h1, h2, h3, h4, h5, h6 { color: #d7b0d7 !important; }
._15kl::before, ._5j35::after, ._2k4b, ._3to7, ._4nw8 { border-left: 1px solid rgba(215, 176, 215, 0.3) !important; }
@ -24,7 +26,7 @@ button:not([style*=image]), button::before, .touch ._56bt, ._56be::before, .btnS
._4o58::after, .acw, .aclb, ._4qax, ._5h8f { border-color: rgba(215, 176, 215, 0.3) !important; }
._220g, ._2zh4::before, ._2ip_ ._15kk::before, ._2ip_ ._15kk + ._4u3j::before, ._58a0:before, ._43mh::before, ._43mh::after, ._1_-1::before, ._1kmv:after, ._1_ac:before { background: rgba(215, 176, 215, 0.3) !important; }
._220g, ._2zh4::before, ._2ip_ ._2zh4::before, ._2ip_ ._15kk::before, ._2ip_ ._15kk + ._4u3j::before, ._58a0:before, ._43mh::before, ._43mh::after, ._1_-1::before, ._1kmv:after, ._1_ac:before { background: rgba(215, 176, 215, 0.3) !important; }
._56bf, .touch .btn { border-radius: 0 !important; border: 0 !important; }
@ -49,3 +51,19 @@ button:not([style*=image]), button::before, .touch ._56bt, ._56be::before, .btnS
a, ._5fpq { color: #d59ed5 !important; }
.excessItem { outline: rgba(215, 176, 215, 0.3) !important; }
@-webkit-keyframes highlightFade { 0% { background: rgba(199, 70, 70, 0.2); }
50% { background: rgba(199, 70, 70, 0.2); }
100% { background: rgba(255, 0, 255, 0.02); } }
@-moz-keyframes highlightFade { 0% { background: rgba(199, 70, 70, 0.2); }
50% { background: rgba(199, 70, 70, 0.2); }
100% { background: rgba(255, 0, 255, 0.02); } }
@-ms-keyframes highlightFade { 0% { background: rgba(199, 70, 70, 0.2); }
50% { background: rgba(199, 70, 70, 0.2); }
100% { background: rgba(255, 0, 255, 0.02); } }
@keyframes highlightFade { 0% { background: rgba(199, 70, 70, 0.2); }
50% { background: rgba(199, 70, 70, 0.2); }
100% { background: rgba(255, 0, 255, 0.02); } }

View File

@ -29,6 +29,10 @@ body, #root, #header, [style*="background-color"], ._55wo, ._1upc, input, ._2f9r
background: $bg_opaque !important;
}
._403n, ._1-kc {
background: $bg_opaque2 !important;
}
button:not([style*=image]), button::before, .touch ._56bt, ._56be::before, .btnS, .touch::before, ._590n, ._4g8h,
._5xo2, ._5u5a::before, ._4u3j, ._15ks, ._5hua, ._59tt, ._41ft, .jx-tokenizer, ._55fj, .excessItem,
._4e8n, ._5pxa._3uj9, ._5n_5, ._u2d, ._56bu::before, ._5h8f, ._d00, ._2066, ._2k51,
@ -38,7 +42,7 @@ button:not([style*=image]), button::before, .touch ._56bt, ._56be::before, .btnS
}
[style*="color"], body, input, ._42rv,
._z-z, ._z-v, ._1e8d, ._36nl, ._36nm, ._2_11, ._2_rf,
._z-z, ._z-v, ._1e8d, ._36nl, ._36nm, ._2_11, ._2_rf, ._2ip_, ._403p, ._5xu2, ._3ml8, ._3mla,
._43mh, .touch .btn, p, span, .fcg, button, ._52j9, ._52jb, ._52ja, ._5j35, ._rnk, ._24u0, ._1g06, ._14ye, .fcb, ._56cz._56c_, ._1gk_, ._55fj, ._45fu, ._18qg, ._1_ac,
textarea, ._24pi, ._4en9, ._1kb, ._5p7j, ._2klz, ._5780, ._5781, ._5782, ._3u9u, ._3u9_, ._3u9s, ._1hcx, ._2066, ._1_-1, ._cv_, ._1nbx, ._2cuh, ._4ms9, ._4ms5, ._4ms6, ._31b4, ._31b5, ._5q_r, ._idb,
._27vp, ._4nwe, ._4nw9, ._27vi, .appCenterAppInfo, .appCenterPermissions, ._3c9l, ._3c9m, ._4jn_, ._32qt, ._3mom, ._3moo, ._-7o, ._d00, ._d01, ._559g, ._2new, .appCenterCategorySelectorButton,
@ -86,7 +90,7 @@ h1, h2, h3, h4, h5, h6 {
}
._220g,
._2zh4::before, ._2ip_ ._15kk::before, ._2ip_ ._15kk + ._4u3j::before, ._58a0:before, ._43mh::before, ._43mh::after, ._1_-1::before, ._1kmv:after, ._1_ac:before {
._2zh4::before, ._2ip_ ._2zh4::before, ._2ip_ ._15kk::before, ._2ip_ ._15kk + ._4u3j::before, ._58a0:before, ._43mh::before, ._43mh::after, ._1_-1::before, ._1kmv:after, ._1_ac:before {
background: $divider !important;
}
@ -138,3 +142,18 @@ a,
.excessItem {
outline: $divider !important;
}
//new comment
@include keyframes(highlightFade) {
0% {
background: $background2;
}
50% {
background: $background2;
}
100% {
background: $bg_transparent;
}
}

View File

@ -8,9 +8,11 @@ body, #root, #header, [style*="background-color"], ._55wo, ._1upc, input, ._2f9r
.jewel, .flyout, ._13e_, ._5-lw, ._5c0e, .jx-result, ._336p, .mentions-suggest-item, .mentions-suggest { background: $O$ !important; }
._403n, ._1-kc { background: $OO$ !important; }
button:not([style*=image]), button::before, .touch ._56bt, ._56be::before, .btnS, .touch::before, ._590n, ._4g8h, ._5xo2, ._5u5a::before, ._4u3j, ._15ks, ._5hua, ._59tt, ._41ft, .jx-tokenizer, ._55fj, .excessItem, ._4e8n, ._5pxa._3uj9, ._5n_5, ._u2d, ._56bu::before, ._5h8f, ._d00, ._2066, ._2k51, ._4qax, .aclb, ._4756, ._w34, ._56bv::before, ._5769, ._34iv, ._z-w, .acbk { background: $BBT$ !important; }
[style*="color"], body, input, ._42rv, ._z-z, ._z-v, ._1e8d, ._36nl, ._36nm, ._2_11, ._2_rf, ._43mh, .touch .btn, p, span, .fcg, button, ._52j9, ._52jb, ._52ja, ._5j35, ._rnk, ._24u0, ._1g06, ._14ye, .fcb, ._56cz._56c_, ._1gk_, ._55fj, ._45fu, ._18qg, ._1_ac, textarea, ._24pi, ._4en9, ._1kb, ._5p7j, ._2klz, ._5780, ._5781, ._5782, ._3u9u, ._3u9_, ._3u9s, ._1hcx, ._2066, ._1_-1, ._cv_, ._1nbx, ._2cuh, ._4ms9, ._4ms5, ._4ms6, ._31b4, ._31b5, ._5q_r, ._idb, ._27vp, ._4nwe, ._4nw9, ._27vi, .appCenterAppInfo, .appCenterPermissions, ._3c9l, ._3c9m, ._4jn_, ._32qt, ._3mom, ._3moo, ._-7o, ._d00, ._d01, ._559g, ._2new, .appCenterCategorySelectorButton, .mentions-input, .mentions-placeholder, .fcw, ._5-7t, .fcl, ._4qas, .thread-title, .title, ._46pa, ._336p, ._1rrd, ._2om4, ._3m1m, ._2om2, ._5n_e, .appListExplanation, ._5yt8, ._8he, ._2luw, ._5rgs, h1, h2, h3, h4, h5, h6 { color: $T$ !important; }
[style*="color"], body, input, ._42rv, ._z-z, ._z-v, ._1e8d, ._36nl, ._36nm, ._2_11, ._2_rf, ._2ip_, ._403p, ._5xu2, ._3ml8, ._3mla, ._43mh, .touch .btn, p, span, .fcg, button, ._52j9, ._52jb, ._52ja, ._5j35, ._rnk, ._24u0, ._1g06, ._14ye, .fcb, ._56cz._56c_, ._1gk_, ._55fj, ._45fu, ._18qg, ._1_ac, textarea, ._24pi, ._4en9, ._1kb, ._5p7j, ._2klz, ._5780, ._5781, ._5782, ._3u9u, ._3u9_, ._3u9s, ._1hcx, ._2066, ._1_-1, ._cv_, ._1nbx, ._2cuh, ._4ms9, ._4ms5, ._4ms6, ._31b4, ._31b5, ._5q_r, ._idb, ._27vp, ._4nwe, ._4nw9, ._27vi, .appCenterAppInfo, .appCenterPermissions, ._3c9l, ._3c9m, ._4jn_, ._32qt, ._3mom, ._3moo, ._-7o, ._d00, ._d01, ._559g, ._2new, .appCenterCategorySelectorButton, .mentions-input, .mentions-placeholder, .fcw, ._5-7t, .fcl, ._4qas, .thread-title, .title, ._46pa, ._336p, ._1rrd, ._2om4, ._3m1m, ._2om2, ._5n_e, .appListExplanation, ._5yt8, ._8he, ._2luw, ._5rgs, h1, h2, h3, h4, h5, h6 { color: $T$ !important; }
._15kl::before, ._5j35::after, ._2k4b, ._3to7, ._4nw8 { border-left: 1px solid $D$ !important; }
@ -24,7 +26,7 @@ button:not([style*=image]), button::before, .touch ._56bt, ._56be::before, .btnS
._4o58::after, .acw, .aclb, ._4qax, ._5h8f { border-color: $D$ !important; }
._220g, ._2zh4::before, ._2ip_ ._15kk::before, ._2ip_ ._15kk + ._4u3j::before, ._58a0:before, ._43mh::before, ._43mh::after, ._1_-1::before, ._1kmv:after, ._1_ac:before { background: $D$ !important; }
._220g, ._2zh4::before, ._2ip_ ._2zh4::before, ._2ip_ ._15kk::before, ._2ip_ ._15kk + ._4u3j::before, ._58a0:before, ._43mh::before, ._43mh::after, ._1_-1::before, ._1kmv:after, ._1_ac:before { background: $D$ !important; }
._56bf, .touch .btn { border-radius: 0 !important; border: 0 !important; }
@ -49,3 +51,19 @@ button:not([style*=image]), button::before, .touch ._56bt, ._56be::before, .btnS
a, ._5fpq { color: $TT$ !important; }
.excessItem { outline: $D$ !important; }
@-webkit-keyframes highlightFade { 0% { background: $BBT$; }
50% { background: $BBT$; }
100% { background: $BT$; } }
@-moz-keyframes highlightFade { 0% { background: $BBT$; }
50% { background: $BBT$; }
100% { background: $BT$; } }
@-ms-keyframes highlightFade { 0% { background: $BBT$; }
50% { background: $BBT$; }
100% { background: $BT$; } }
@keyframes highlightFade { 0% { background: $BBT$; }
50% { background: $BBT$; }
100% { background: $BT$; } }

View File

@ -4,6 +4,7 @@ $link: unquote('$TT$');
$background: unquote('$B$');
$background2: unquote('$BBT$');
$bg_opaque: unquote('$O$');
$bg_opaque2: unquote('$OO$');
$divider: unquote('$D$');
@import "../core/main";

View File

@ -1,11 +1,13 @@
package com.pitchedapps.frost.activities
import android.content.Intent
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import com.pitchedapps.frost.R
import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.materialDialogThemed
import com.pitchedapps.frost.utils.setFrostTheme
import org.jetbrains.anko.contentView
/**
* Created by Allan Wang on 2017-06-12.

View File

@ -122,7 +122,7 @@ class ImageActivity : AppCompatActivity() {
} else {
photo.setImage(ImageSource.uri(it))
fabAction = FabStates.DOWNLOAD
photo.animate().alpha(1f).scaleX(1f).scaleY(1f).withEndAction { fab.show() }.start()
photo.animate().alpha(1f).scaleXY(1f).withEndAction { fab.show() }.start()
}
})
} else {
@ -283,9 +283,15 @@ internal enum class FabStates(val iicon: IIcon, val iconColor: Int = Prefs.iconC
* If it's in view, give it some animations
*/
fun update(fab: FloatingActionButton) {
fab.transition {
setIcon(iicon, color = iconColor)
backgroundTintList = ColorStateList.valueOf(backgroundTint)
if (fab.isHidden) {
fab.setIcon(iicon, color = iconColor)
fab.backgroundTintList = ColorStateList.valueOf(backgroundTint)
fab.show()
} else {
fab.fadeScaleTransition {
setIcon(iicon, color = iconColor)
backgroundTintList = ColorStateList.valueOf(backgroundTint)
}
}
}

View File

@ -0,0 +1,169 @@
package com.pitchedapps.frost.activities
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 android.support.v7.app.AppCompatActivity
import android.view.View
import android.view.WindowManager
import android.widget.Button
import android.widget.ImageButton
import android.widget.ImageView
import ca.allanwang.kau.ui.views.RippleCanvas
import ca.allanwang.kau.ui.widgets.InkPageIndicator
import ca.allanwang.kau.utils.*
import com.mikepenz.google_material_typeface_library.GoogleMaterial
import com.pitchedapps.frost.R
import com.pitchedapps.frost.intro.*
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.
*/
class IntroActivity : AppCompatActivity(), ViewPager.PageTransformer, ViewPager.OnPageChangeListener {
val ripple: RippleCanvas by bindView(R.id.intro_ripple)
val viewpager: ViewPager by bindView(R.id.intro_viewpager)
lateinit var adapter: IntroPageAdapter
val indicator: InkPageIndicator by bindView(R.id.intro_indicator)
val skip: Button by bindView(R.id.intro_skip)
val next: ImageButton by bindView(R.id.intro_next)
private var barHasNext = true
val fragments = listOf(
IntroFragmentWelcome(),
IntroFragmentTheme(),
IntroAccountFragment(),
IntroTabTouchFragment(),
IntroTabContextFragment(),
IntroFragmentEnd()
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_intro)
adapter = IntroPageAdapter(supportFragmentManager, fragments)
viewpager.apply {
setPageTransformer(true, this@IntroActivity)
addOnPageChangeListener(this@IntroActivity)
adapter = this@IntroActivity.adapter
}
indicator.setViewPager(viewpager)
next.setIcon(GoogleMaterial.Icon.gmd_navigate_next)
next.setOnClickListener {
if (barHasNext) viewpager.setCurrentItem(viewpager.currentItem + 1, true)
else finish(next.x + next.pivotX, next.y + next.pivotY)
}
ripple.set(Prefs.bgColor)
theme()
}
fun theme() {
statusBarColor = Prefs.headerColor
navigationBarColor = Prefs.headerColor
skip.setTextColor(Prefs.textColor)
next.imageTintList = ColorStateList.valueOf(Prefs.textColor)
indicator.setColour(Prefs.textColor)
indicator.invalidate()
fragments.forEach { it.themeFragment() }
}
/**
* Transformations are mainly handled on a per view basis
* This sifies it by making the first fragment fade out as the second fragment comes in
* All fragments are locked in position
*/
override fun transformPage(page: View, position: Float) {
//only apply to adjacent pages
if ((position < 0 && position > -1) || (position > 0 && position < 1)) {
val pageWidth = page.width
val translateValue = position * -pageWidth
page.translationX = (if (translateValue > -pageWidth) translateValue else 0f)
page.alpha = if (position < 0) 1 + position else 1f
} else {
page.alpha = 1f
page.translationX = 0f
}
}
fun finish(x: Float, y: Float) {
val blue = color(R.color.facebook_blue)
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
ripple.ripple(blue, x, y, 600) {
postDelayed(1000) { finish() }
}
arrayOf(skip, indicator, next, fragments.last().view!!.find<View>(R.id.intro_title), fragments.last().view!!.find<View>(R.id.intro_desc)).forEach {
it.animate().alpha(0f).setDuration(600).start()
}
if (Prefs.textColor != Color.WHITE) {
val f = fragments.last().view!!.find<ImageView>(R.id.intro_image).drawable
ValueAnimator.ofFloat(0f, 1f).apply {
addUpdateListener {
f.setTint(Prefs.textColor.blendWith(Color.WHITE, it.animatedValue as Float))
}
duration = 600
start()
}
}
if (Prefs.headerColor != blue) {
ValueAnimator.ofFloat(0f, 1f).apply {
addUpdateListener {
val c = Prefs.headerColor.blendWith(blue, it.animatedValue as Float)
statusBarColor = c
navigationBarColor = c
}
duration = 600
start()
}
}
}
override fun finish() {
launchNewTask(MainActivity::class.java, cookies())
super.finish()
}
override fun onBackPressed() {
if (viewpager.currentItem > 0) viewpager.setCurrentItem(viewpager.currentItem - 1, true)
else finish()
}
override fun onPageScrollStateChanged(state: Int) {
}
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
fragments[position].onPageScrolled(positionOffset)
if (position + 1 < fragments.size)
fragments[position + 1].onPageScrolled(positionOffset - 1)
}
override fun onPageSelected(position: Int) {
fragments[position].onPageSelected()
val hasNext = position != fragments.size - 1
if (barHasNext == hasNext) return
barHasNext = hasNext
next.fadeScaleTransition {
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<BaseIntroFragment>) : FragmentPagerAdapter(fm) {
override fun getItem(position: Int): Fragment = fragments[position]
override fun getCount(): Int = fragments.size
}
}

View File

@ -96,7 +96,8 @@ class LoginActivity : BaseActivity() {
loadFbCookiesAsync {
cookies ->
Handler().postDelayed({
launchNewTask(MainActivity::class.java, ArrayList(cookies), clearStack = true)
launchNewTask(if (Showcase.intro) IntroActivity::class.java else MainActivity::class.java,
ArrayList(cookies), clearStack = true)
}, 1000)
}
}

View File

@ -86,6 +86,7 @@ class MainActivity : BaseActivity(), SearchWebView.SearchContract,
var hiddenSearchView: SearchWebView? = null
var firstLoadFinished = false
set(value) {
if (field && value) return //both vals are already true
L.d("First fragment load has finished")
field = value
if (value && hiddenSearchView == null) {
@ -160,6 +161,14 @@ class MainActivity : BaseActivity(), SearchWebView.SearchContract,
// }
setFrostColors(toolbar, themeWindow = false, headers = arrayOf(tabs, appBar), backgrounds = arrayOf(viewPager))
onCreateBilling()
if (Prefs.installDate < 1501454310304 && Showcase.intro)
materialDialogThemed {
title(R.string.intro_title)
content(R.string.intro_desc)
positiveText(R.string.kau_yes)
negativeText(R.string.kau_no)
onPositive { _, _ -> launchIntroActivity(cookies()) }
}
}
fun tabsForEachView(action: (position: Int, view: BadgedIcon) -> Unit) {
@ -383,6 +392,7 @@ class MainActivity : BaseActivity(), SearchWebView.SearchContract,
when (item.itemId) {
R.id.action_settings -> {
val intent = Intent(this, SettingsActivity::class.java)
intent.putParcelableArrayListExtra(EXTRA_COOKIES, cookies())
val bundle = ActivityOptionsCompat.makeCustomAnimation(this, R.anim.kau_slide_in_right, R.anim.kau_fade_out).toBundle()
startActivityForResult(intent, ACTIVITY_SETTINGS, bundle)
}

View File

@ -79,6 +79,11 @@ class SettingsActivity : KPrefActivity(), FrostBilling by IABSettings() {
onClick = { _, _, _ -> kauLaunchAbout(AboutActivity::class.java); true }
}
plainText(R.string.replay_intro) {
iicon = GoogleMaterial.Icon.gmd_replay
onClick = {_,_,_-> launchIntroActivity(cookies()); true}
}
if (BuildConfig.DEBUG) {
checkbox(R.string.custom_pro, { Prefs.debugPro }, { Prefs.debugPro = it })
}
@ -116,8 +121,6 @@ class SettingsActivity : KPrefActivity(), FrostBilling by IABSettings() {
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_settings, menu)
toolbar.tint(Prefs.iconColor)
@ -143,7 +146,7 @@ class SettingsActivity : KPrefActivity(), FrostBilling by IABSettings() {
}
fun setFrostResult(flag: Int) {
resultFlag = resultFlag and flag
resultFlag = resultFlag or flag
}
override fun onDestroy() {

View File

@ -38,6 +38,7 @@ enum class CssAssets(val folder: String = "themes") : InjectorContract {
.replace("\$BT\$", bt)
.replace("\$BBT\$", bbt.toRgbaString())
.replace("\$O\$", Prefs.bgColor.withAlpha(255).toRgbaString())
.replace("\$OO\$", Prefs.bgColor.colorToForeground(0.35f).withAlpha(255).toRgbaString())
.replace("\$D\$", Prefs.textColor.adjustAlpha(0.3f).toRgbaString())
}
injector = JsBuilder().css(content).build()

View File

@ -0,0 +1,51 @@
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.utils.Prefs
import com.pitchedapps.frost.utils.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)
override fun viewArray(): Array<Array<out View>>
= arrayOf(arrayOf(title), arrayOf(light, dark), arrayOf(amoled, 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)
val currentTheme = Prefs.theme - 1
if (currentTheme in 0..3)
themeList.forEachIndexed { index, v -> v.scaleXY = if (index == currentTheme) 1.6f else 0.8f }
}
private fun View.setThemeClick(theme: Theme) {
setOnClickListener {
v ->
Prefs.theme = theme.ordinal
(activity as IntroActivity).apply {
ripple.ripple(Prefs.bgColor, v.x + v.pivotX, v.y + v.pivotY)
theme()
}
themeList.forEach { it.animate().scaleXY(if (it == this) 1.6f else 0.8f).start() }
}
}
}

View File

@ -0,0 +1,112 @@
package com.pitchedapps.frost.intro
import android.graphics.drawable.Drawable
import android.graphics.drawable.LayerDrawable
import android.os.Bundle
import android.view.View
import ca.allanwang.kau.utils.colorToForeground
import ca.allanwang.kau.utils.tint
import ca.allanwang.kau.utils.withAlpha
import com.pitchedapps.frost.R
import com.pitchedapps.frost.utils.Prefs
/**
* Created by Allan Wang on 2017-07-28.
*/
abstract class BaseImageIntroFragment(val titleRes: Int, val imageRes: Int, val descRes: Int) : BaseIntroFragment(R.layout.intro_image) {
val imageDrawable: LayerDrawable by lazyResettableRegistered { image.drawable as LayerDrawable }
val phone: Drawable by lazyResettableRegistered { imageDrawable.findDrawableByLayerId(R.id.intro_phone) }
val screen: Drawable by lazyResettableRegistered { imageDrawable.findDrawableByLayerId(R.id.intro_phone_screen) }
override fun viewArray(): Array<Array<out View>>
= arrayOf(arrayOf(title), arrayOf(desc))
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
title.setText(titleRes)
image.setImageResource(imageRes)
desc.setText(descRes)
super.onViewCreated(view, savedInstanceState)
}
override fun themeFragmentImpl() {
super.themeFragmentImpl()
title.setTextColor(Prefs.textColor)
desc.setTextColor(Prefs.textColor)
phone.tint(Prefs.textColor)
screen.tint(Prefs.bgColor)
}
fun themeImageComponent(color: Int, vararg id: Int) {
id.forEach { imageDrawable.findDrawableByLayerId(it).tint(color) }
}
override fun onPageScrolledImpl(positionOffset: Float) {
super.onPageScrolledImpl(positionOffset)
val alpha = ((1 - Math.abs(positionOffset)) * 255).toInt()
//apply alpha to all layers except the phone base
(0 until imageDrawable.numberOfLayers).forEach {
val d = imageDrawable.getDrawable(it)
if (d != phone) d.alpha = alpha
}
}
fun firstImageFragmentTransition(offset: Float) {
if (offset < 0)
image.alpha = 1 + offset
}
fun lastImageFragmentTransition(offset: Float) {
if (offset > 0)
image.alpha = 1 - offset
}
}
class IntroAccountFragment : BaseImageIntroFragment(
R.string.intro_multiple_accounts, R.drawable.intro_phone_nav, R.string.intro_multiple_accounts_desc
) {
override fun themeFragmentImpl() {
super.themeFragmentImpl()
themeImageComponent(Prefs.iconColor, R.id.intro_phone_avatar_1, R.id.intro_phone_avatar_2)
themeImageComponent(Prefs.bgColor.colorToForeground(), R.id.intro_phone_nav)
themeImageComponent(Prefs.headerColor, R.id.intro_phone_header)
}
override fun onPageScrolledImpl(positionOffset: Float) {
super.onPageScrolledImpl(positionOffset)
firstImageFragmentTransition(positionOffset)
}
}
class IntroTabTouchFragment : BaseImageIntroFragment(
R.string.intro_easy_navigation, R.drawable.intro_phone_tab, R.string.intro_easy_navigation_desc
) {
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.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
) {
override fun themeFragmentImpl() {
super.themeFragmentImpl()
themeImageComponent(Prefs.headerColor, R.id.intro_phone_toolbar)
themeImageComponent(Prefs.bgColor.colorToForeground(0.1f), R.id.intro_phone_image)
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)
}
override fun onPageScrolledImpl(positionOffset: Float) {
super.onPageScrolledImpl(positionOffset)
lastImageFragmentTransition(positionOffset)
}
}

View File

@ -0,0 +1,135 @@
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 android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import ca.allanwang.kau.kotlin.LazyResettableRegistry
import ca.allanwang.kau.utils.Kotterknife
import ca.allanwang.kau.utils.bindViewResettable
import ca.allanwang.kau.utils.setOnSingleTapListener
import com.pitchedapps.frost.R
import com.pitchedapps.frost.activities.IntroActivity
import com.pitchedapps.frost.utils.Prefs
import org.jetbrains.anko.childrenSequence
/**
* Created by Allan Wang on 2017-07-28.
*
* Contains the base, start, and end fragments
*/
/**
* The core intro fragment for all other fragments
*/
abstract class BaseIntroFragment(val layoutRes: Int) : Fragment() {
val screenWidth
get() = resources.displayMetrics.widthPixels
val lazyRegistry = LazyResettableRegistry()
protected fun translate(offset: Float, views: Array<Array<out View>>) {
val maxTranslation = offset * screenWidth
val increment = maxTranslation / views.size
views.forEachIndexed { i, group ->
group.forEach {
it.translationX = if (offset > 0) -maxTranslation + i * increment else -(i + 1) * increment
it.alpha = 1 - Math.abs(offset)
}
}
}
fun <T : Any> lazyResettableRegistered(initializer: () -> T) = lazyRegistry.lazy(initializer)
/*
* Note that these ids aren't actually inside all layouts
* However, they are in most of them, so they are added here
* for convenience
*/
protected val title: TextView by bindViewResettable(R.id.intro_title)
protected val image: ImageView by bindViewResettable(R.id.intro_image)
protected val desc: TextView by bindViewResettable(R.id.intro_desc)
protected fun defaultViewArray(): Array<Array<out View>> = arrayOf(arrayOf(title), arrayOf(image), arrayOf(desc))
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(layoutRes, container, false)
return view
}
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
themeFragment()
}
override fun onDestroyView() {
super.onDestroyView()
Kotterknife.reset(this)
lazyRegistry.invalidateAll()
}
fun themeFragment() {
if (view != null) themeFragmentImpl()
}
protected open fun themeFragmentImpl() {
view?.childrenSequence()?.forEach { (it as? TextView)?.setTextColor(Prefs.textColor) }
}
protected val viewArray: Array<Array<out View>> by lazyResettableRegistered { viewArray() }
protected abstract fun viewArray(): Array<Array<out View>>
fun onPageScrolled(positionOffset: Float) {
if (view != null) onPageScrolledImpl(positionOffset)
}
protected open fun onPageScrolledImpl(positionOffset: Float) {
translate(positionOffset, viewArray)
}
fun onPageSelected() {
if (view != null) onPageSelectedImpl()
}
protected open fun onPageSelectedImpl() {
}
}
class IntroFragmentWelcome : BaseIntroFragment(R.layout.intro_welcome) {
override fun viewArray(): Array<Array<out View>> = defaultViewArray()
override fun themeFragmentImpl() {
super.themeFragmentImpl()
image.imageTintList = ColorStateList.valueOf(Prefs.textColor)
}
}
class IntroFragmentEnd : BaseIntroFragment(R.layout.intro_end) {
val container: ConstraintLayout by bindViewResettable(R.id.intro_end_container)
override fun viewArray(): Array<Array<out View>> = defaultViewArray()
override fun themeFragmentImpl() {
super.themeFragmentImpl()
image.imageTintList = ColorStateList.valueOf(Prefs.textColor)
}
@SuppressLint("ClickableViewAccessibility")
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
container.setOnSingleTapListener { _, event ->
(activity as IntroActivity).finish(event.x, event.y)
}
}
}

View File

@ -0,0 +1,82 @@
package com.pitchedapps.frost.utils
import android.graphics.drawable.AnimatedVectorDrawable
import android.support.annotation.DrawableRes
import android.widget.ImageView
import ca.allanwang.kau.utils.drawable
/**
* Created by Allan Wang on 2017-07-29.
*
* Delegate for animated vector drawables with two states (start and end)
* Drawables are added lazily depending on the animation direction, and are verified upon load
* Should the bounded view not have an animated drawable upon animating, it is assumed
* that the user has switched the resource themselves and the delegate will not switch the resource
*/
interface AnimatedVectorContract {
fun animate()
fun animateReverse()
fun animateToggle()
val isAtStart: Boolean
fun bind(view: ImageView)
var animatedVectorListener: ((avd: AnimatedVectorDrawable, forwards: Boolean) -> Unit)?
}
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
) : AnimatedVectorContract {
lateinit var view: ImageView
private var atStart = true
override val isAtStart: Boolean
get() = atStart
private val avd: AnimatedVectorDrawable?
get() = view.drawable as? AnimatedVectorDrawable
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")
view.context.drawable(avdEnd) as? AnimatedVectorDrawable ?: throw IllegalArgumentException("AnimatedVectorDelegate has an ending drawable that isn't an avd")
view.setImageResource(avdStart)
if (emitOnBind) animatedVectorListener?.invoke(avd!!, false)
}
override fun animate() = animateImpl(false)
override fun animateReverse() = animateImpl(true)
override fun animateToggle() = animateImpl(!atStart)
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
avd?.stop()
view.setImageResource(if (toStart) avdEnd else avdStart)
animatedVectorListener?.invoke(avd!!, !toStart)
atStart = toStart
avd?.start()
}
}

View File

@ -14,6 +14,8 @@ object Showcase : KPref() {
//check if this is the first time launching the web overlay; show snackbar if true
val firstWebOverlay: Boolean by kprefSingle("first_web_overlay")
val intro: Boolean by kprefSingle("intro_pages")
//not a showcase but cannot be in the same file as Prefs
var experimentalDefault: Boolean by kpref("experimental_by_default", false)
}

View File

@ -20,10 +20,7 @@ import com.crashlytics.android.answers.Answers
import com.crashlytics.android.answers.CustomEvent
import com.pitchedapps.frost.BuildConfig
import com.pitchedapps.frost.R
import com.pitchedapps.frost.activities.ImageActivity
import com.pitchedapps.frost.activities.LoginActivity
import com.pitchedapps.frost.activities.SelectorActivity
import com.pitchedapps.frost.activities.WebOverlayActivity
import com.pitchedapps.frost.activities.*
import com.pitchedapps.frost.dbflow.CookieModel
import com.pitchedapps.frost.facebook.FbTab
import com.pitchedapps.frost.facebook.formattedFbUrl
@ -68,6 +65,9 @@ fun Context.launchImageActivity(imageUrl: String, text: String?) {
})
}
fun Activity.launchIntroActivity(cookieList: ArrayList<CookieModel>)
= launchNewTask(IntroActivity::class.java, cookieList, true)
fun WebOverlayActivity.url(): String {
return intent.extras?.getString(ARG_URL) ?: FbTab.FEED.url
}
@ -140,4 +140,4 @@ fun Activity.frostNavigationBar() {
navigationBarColor = if (Prefs.tintNavBar) Prefs.headerColor else Color.BLACK
}
fun <T> RequestBuilder<T>.withRoundIcon() = apply(RequestOptions().transform(CircleCrop()))
fun <T> RequestBuilder<T>.withRoundIcon() = apply(RequestOptions().transform(CircleCrop()))!!

View File

@ -34,7 +34,7 @@ abstract class IABBinder : FrostBilling {
override fun Activity.onCreateBilling() {
activity = this
bp = BillingProcessor.newBillingProcessor(this, PUBLIC_BILLING_KEY, this@IABBinder)
bp!!.initialize()
bp?.initialize()
}
override fun onDestroyBilling() {
@ -79,10 +79,10 @@ abstract class IABBinder : FrostBilling {
L.eThrow("IAB null bp on purchase attempt")
return
}
if (!bp!!.isOneTimePurchaseSupported)
activity!!.playStorePurchaseUnsupported()
if (!(bp?.isOneTimePurchaseSupported ?: false))
activity?.playStorePurchaseUnsupported()
else
bp!!.purchase(activity, FROST_PRO)
bp?.purchase(activity, FROST_PRO)
}
}
@ -104,14 +104,14 @@ class IABSettings : IABBinder() {
*/
override fun restorePurchases() {
if (bp == null) return
val load = bp!!.loadOwnedPurchasesFromGoogle()
val load = bp?.loadOwnedPurchasesFromGoogle() ?: return
L.d("IAB settings load from google $load")
if (!bp!!.isPurchased(FROST_PRO)) {
if (Prefs.pro) activity!!.playStoreNoLongerPro()
if (!(bp?.isPurchased(FROST_PRO) ?: return)) {
if (Prefs.pro) activity.playStoreNoLongerPro()
else purchasePro()
} else {
if (!Prefs.pro) activity!!.playStoreFoundPro()
else activity!!.purchaseRestored()
if (!Prefs.pro) activity.playStoreFoundPro()
else activity?.purchaseRestored()
}
}
}
@ -138,12 +138,12 @@ class IABMain : IABBinder() {
override fun restorePurchases() {
if (restored || bp == null) return
restored = true
val load = bp!!.loadOwnedPurchasesFromGoogle()
val load = bp?.loadOwnedPurchasesFromGoogle() ?: false
L.d("IAB main load from google $load")
if (!bp!!.isPurchased(FROST_PRO)) {
if (Prefs.pro) activity!!.playStoreNoLongerPro()
if (!(bp?.isPurchased(FROST_PRO) ?: false)) {
if (Prefs.pro) activity.playStoreNoLongerPro()
} else {
if (!Prefs.pro) activity!!.playStoreFoundPro()
if (!Prefs.pro) activity.playStoreFoundPro()
}
onDestroyBilling()
}

View File

@ -31,7 +31,7 @@ private fun Activity.playRestart() {
} else restart()
}
fun Activity.playStoreNoLongerPro() {
fun Activity?.playStoreNoLongerPro() {
Prefs.pro = false
L.d("IAB No longer pro")
frostAnswers {
@ -39,6 +39,7 @@ fun Activity.playStoreNoLongerPro() {
.putCustomAttribute("result", "no longer pro")
.putSuccess(false))
}
if (this == null) return
materialDialogThemed {
title(R.string.uh_oh)
content(R.string.play_store_not_pro)
@ -49,9 +50,10 @@ fun Activity.playStoreNoLongerPro() {
}
}
fun Activity.playStoreFoundPro() {
fun Activity?.playStoreFoundPro() {
Prefs.pro = true
L.d("Found pro")
if (this == null) return
materialDialogThemed {
title(R.string.found_pro)
content(R.string.found_pro_desc)

View File

@ -1,6 +1,8 @@
package com.pitchedapps.frost.views
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.GradientDrawable
import android.support.constraint.ConstraintLayout
import android.util.AttributeSet

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:bottom="149.9dp">
<shape>
<corners
android:topLeftRadius="5dp"
android:topRightRadius="5dp" />
<size
android:width="90dp"
android:height="10.1dp" />
<solid android:color="#888" />
</shape>
</item>
<item android:top="149.9dp">
<shape>
<corners
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp" />
<size
android:width="90dp"
android:height="10.1dp" />
<solid android:color="#888" />
</shape>
</item>
<item
android:bottom="10dp"
android:right="87dp"
android:top="10dp">
<shape>
<size
android:width="3dp"
android:height="140dp" />
<solid android:color="#888" />
</shape>
</item>
<item
android:bottom="10dp"
android:left="87dp"
android:top="10dp">
<shape>
<size
android:width="3dp"
android:height="140dp" />
<solid android:color="#888" />
</shape>
</item>
</layer-list>

View File

@ -0,0 +1,109 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@id/intro_phone"
android:drawable="@drawable/intro_phone_case" />
<item
android:id="@id/intro_phone_screen"
android:drawable="@drawable/intro_phone_screen" />
<item
android:id="@+id/intro_phone_toolbar"
android:bottom="135dp"
android:left="3dp"
android:right="3dp"
android:top="10dp">
<shape>
<solid android:color="#f0f" />
</shape>
</item>
<item
android:id="@+id/intro_phone_image"
android:bottom="65dp"
android:left="3dp"
android:right="3dp"
android:top="30dp">
<shape>
<solid android:color="#f0f" />
</shape>
</item>
<item
android:id="@+id/intro_phone_image_indicator"
android:bottom="95.5dp"
android:left="43dp"
android:right="43dp"
android:top="60.5dp">
<shape android:shape="oval">
<solid android:color="#800000ff" />
</shape>
</item>
<item
android:id="@+id/intro_phone_like"
android:bottom="57dp"
android:left="3dp"
android:right="60dp"
android:top="95dp">
<shape>
<solid android:color="#f00" />
</shape>
</item>
<item
android:id="@+id/intro_phone_comment"
android:bottom="57dp"
android:left="30dp"
android:right="30dp"
android:top="95dp">
<shape>
<solid android:color="#ddff0000" />
</shape>
</item>
<item
android:id="@+id/intro_phone_share"
android:bottom="57dp"
android:left="60dp"
android:right="3dp"
android:top="95dp">
<shape>
<solid android:color="#aaff0000" />
</shape>
</item>
<item
android:id="@+id/intro_phone_comment_indicator"
android:bottom="59dp"
android:left="43dp"
android:right="43dp"
android:top="97dp">
<shape android:shape="oval">
<solid android:color="#800000ff" />
</shape>
</item>
<item
android:id="@+id/intro_phone_card_1"
android:bottom="10dp"
android:left="3dp"
android:right="31dp"
android:top="115dp">
<shape>
<solid android:color="#aaff0000" />
</shape>
</item>
<item
android:id="@+id/intro_phone_card_2"
android:bottom="10dp"
android:left="61dp"
android:right="3dp"
android:top="115dp">
<shape>
<solid android:color="#aaff0000" />
</shape>
</item>
<item
android:id="@+id/intro_phone_card_indicator"
android:bottom="25.5dp"
android:left="43dp"
android:right="43dp"
android:top="130.5dp">
<shape android:shape="oval">
<solid android:color="#800000ff" />
</shape>
</item>
</layer-list>

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@id/intro_phone"
android:drawable="@drawable/intro_phone_case" />
<item
android:id="@id/intro_phone_screen"
android:drawable="@drawable/intro_phone_screen" />
<item
android:id="@+id/intro_phone_nav"
android:bottom="10dp"
android:left="3dp"
android:right="23dp"
android:top="50dp">
<shape>
<solid android:color="#f0f" />
</shape>
</item>
<item
android:id="@+id/intro_phone_header"
android:bottom="110dp"
android:left="3dp"
android:right="23dp"
android:top="10dp">
<shape>
<solid android:color="#f00" />
</shape>
</item>
<item
android:id="@+id/intro_phone_avatar_1"
android:bottom="130dp"
android:left="8dp"
android:right="67dp"
android:top="15dp">
<shape android:shape="oval">
<solid android:color="#f0f" />
</shape>
</item>
<item
android:id="@+id/intro_phone_avatar_2"
android:bottom="135dp"
android:left="53dp"
android:right="27dp"
android:top="15dp">
<shape android:shape="oval">
<solid android:color="#f0f" />
</shape>
</item>
</layer-list>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:bottom="10dp"
android:left="3dp"
android:right="3dp"
android:top="10dp">
<shape>
<solid android:color="#000" />
</shape>
</item>
</layer-list>

View File

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@id/intro_phone"
android:drawable="@drawable/intro_phone_case" />
<item
android:id="@id/intro_phone_screen"
android:drawable="@drawable/intro_phone_screen" />
<item
android:id="@+id/intro_phone_tab"
android:bottom="135dp"
android:left="3dp"
android:right="3dp"
android:top="10dp">
<shape>
<solid android:color="#f0f" />
</shape>
</item>
<item
android:id="@+id/intro_phone_icon_1"
android:bottom="140dp"
android:left="11dp"
android:right="74dp"
android:top="15dp">
<shape>
<corners android:radius="1.5dp" />
<solid android:color="#f00" />
</shape>
</item>
<item
android:id="@+id/intro_phone_icon_2"
android:bottom="140dp"
android:left="32dp"
android:right="53dp"
android:top="15dp">
<shape>
<corners android:radius="1.5dp" />
<solid android:color="#f00" />
</shape>
</item>
<item
android:id="@+id/intro_phone_icon_3"
android:bottom="140dp"
android:left="53dp"
android:right="32dp"
android:top="15dp">
<shape>
<corners android:radius="1.5dp" />
<solid android:color="#f00" />
</shape>
</item>
<item
android:id="@+id/intro_phone_icon_4"
android:bottom="140dp"
android:left="74dp"
android:right="11dp"
android:top="15dp">
<shape>
<corners android:radius="1.5dp" />
<solid android:color="#f00" />
</shape>
</item>
<item
android:id="@+id/intro_phone_icon_ripple"
android:bottom="129dp"
android:left="0dp"
android:right="63dp"
android:top="4dp">
<shape android:shape="oval">
<solid android:color="#800000ff" />
</shape>
</item>
</layer-list>

View File

@ -24,7 +24,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="@dimen/fab_margin"
android:layout_margin="@dimen/kau_fab_margin"
android:visibility="invisible" />
</android.support.design.widget.CoordinatorLayout>

View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<ca.allanwang.kau.ui.views.RippleCanvas
android:id="@+id/intro_ripple"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.constraint.Guideline
android:id="@+id/intro_bar_guide"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_end="@dimen/intro_bar_height" />
<android.support.v4.view.ViewPager
android:id="@+id/intro_viewpager"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/intro_bar_guide"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/intro_skip"
style="@style/IntroBarButton"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:text="@string/skip"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/intro_bar_guide" />
<ca.allanwang.kau.ui.widgets.InkPageIndicator
android:id="@+id/intro_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/intro_bar_guide"
app:layout_constraintVertical_bias="0.5" />
<ImageButton
android:id="@+id/intro_next"
style="@style/IntroBarButton"
android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/intro_bar_guide" />
</android.support.constraint.ConstraintLayout>

View File

@ -43,7 +43,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="@dimen/fab_margin"
android:layout_margin="@dimen/kau_fab_margin"
android:visibility="gone" />
</android.support.design.widget.CoordinatorLayout>

View File

@ -5,17 +5,17 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/container"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingEnd="@dimen/activity_horizontal_margin"
android:paddingStart="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
android:paddingBottom="@dimen/kau_activity_vertical_margin"
android:paddingEnd="@dimen/kau_activity_horizontal_margin"
android:paddingStart="@dimen/kau_activity_horizontal_margin"
android:paddingTop="@dimen/kau_activity_vertical_margin">
<android.support.v7.widget.AppCompatTextView
android:id="@+id/text_select_account"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="@dimen/activity_vertical_margin"
android:layout_marginTop="@dimen/kau_activity_vertical_margin"
android:text="@string/select_facebook_account"
android:textColor="@android:color/white"
app:layout_constraintEnd_toEndOf="parent"

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:id="@+id/intro_end_container"
android:layout_height="match_parent">
<TextView
android:id="@id/intro_title"
style="@style/IntroTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/intro_end"
app:layout_constraintBottom_toTopOf="@+id/intro_image"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="spread" />
<ImageView
android:id="@id/intro_image"
android:layout_width="120dp"
android:layout_height="120dp"
android:scaleType="fitCenter"
android:src="@drawable/frost_f_256"
app:layout_constraintBottom_toTopOf="@id/intro_desc"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/intro_title"
tools:layout_editor_absoluteX="112dp" />
<TextView
android:id="@id/intro_desc"
style="@style/IntroSubTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/intro_tap_to_exit"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/intro_image" />
</android.support.constraint.ConstraintLayout>

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@id/intro_title"
style="@style/IntroTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:lines="1"
android:padding="@dimen/kau_padding_large"
app:layout_constraintBottom_toTopOf="@id/intro_image"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="spread" />
<ImageView
android:id="@id/intro_image"
android:layout_width="0dp"
android:layout_height="0dp"
android:padding="@dimen/kau_padding_large"
android:scaleType="fitCenter"
app:layout_constraintBottom_toTopOf="@id/intro_desc"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/intro_title"
tools:layout_editor_absoluteX="112dp" />
<TextView
android:id="@id/intro_desc"
style="@style/IntroSubTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:lines="3"
android:padding="@dimen/kau_padding_large"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/intro_image" />
</android.support.constraint.ConstraintLayout>

View File

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@id/intro_title"
style="@style/IntroTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/intro_select_theme"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintVertical_bias="0.15"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/intro_theme_light"
style="@style/IntroButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/kau_light"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.25"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/intro_title"
app:layout_constraintVertical_bias="0.33"
tools:layout_editor_absoluteX="112dp" />
<Button
android:id="@+id/intro_theme_dark"
style="@style/IntroButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/kau_dark"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.75"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/intro_title"
app:layout_constraintVertical_bias="0.33"
tools:layout_editor_absoluteX="112dp" />
<Button
android:id="@+id/intro_theme_amoled"
style="@style/IntroButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/kau_amoled"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.25"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/intro_title"
app:layout_constraintVertical_bias="0.66"
tools:layout_editor_absoluteX="112dp" />
<Button
android:id="@+id/intro_theme_glass"
style="@style/IntroButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/kau_glass"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.75"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/intro_title"
app:layout_constraintVertical_bias="0.66"
tools:layout_editor_absoluteX="112dp" />
</android.support.constraint.ConstraintLayout>

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@id/intro_title"
style="@style/IntroTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/intro_welcome_to_frost"
app:layout_constraintBottom_toTopOf="@id/intro_image"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="spread" />
<ImageView
android:id="@id/intro_image"
android:layout_width="120dp"
android:layout_height="120dp"
android:scaleType="fitCenter"
android:src="@drawable/frost_f_256"
app:layout_constraintBottom_toTopOf="@id/intro_desc"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/intro_title"
tools:layout_editor_absoluteX="112dp" />
<TextView
android:id="@id/intro_desc"
style="@style/IntroSubTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/intro_slide_to_continue"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/intro_image" />
</android.support.constraint.ConstraintLayout>

View File

@ -3,7 +3,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/activity_vertical_margin">
android:padding="@dimen/kau_activity_vertical_margin">
<ImageView
android:id="@+id/account_image"

View File

@ -1,15 +1,9 @@
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="dialog_margin">24dp</dimen>
<dimen name="dialog_margin_bottom">16dp</dimen>
<dimen name="fab_margin">16dp</dimen>
<dimen name="appbar_padding_top">8dp</dimen>
<dimen name="splash_logo">16dp</dimen>
<dimen name="progress_bar_height">1dip</dimen>
<dimen name="account_image_size">100dp</dimen>
<dimen name="context_menu_height">60dp</dimen>
<dimen name="intro_bar_height">64dp</dimen>
</resources>

View File

@ -3,4 +3,10 @@
<item name="item_account" type="id" />
<item name="item_keyword" type="id" />
<item name="item_about_links" type="id" />
<item name="intro_phone" type="id" />
<item name="intro_phone_screen" type="id" />
<item name="intro_title" type="id" />
<item name="intro_image" type="id" />
<item name="intro_desc" type="id" />
</resources>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="skip">Skip</string>
<string name="intro_welcome_to_frost">Welcome to Frost</string>
<string name="intro_slide_to_continue">Slide to continue</string>
<string name="intro_select_theme">Select a theme</string>
<string name="intro_multiple_accounts">Multiple Accounts</string>
<string name="intro_multiple_accounts_desc">Add and switch accounts directly from the navigation bar.\nTap the current avatar to jump to your profile.</string>
<string name="intro_easy_navigation">Easy Navigation</string>
<string name="intro_easy_navigation_desc">Slide between views with a swipe, and click the tab icon to go back to the top.\nClick the icon again to reload the page.</string>
<string name="intro_context_aware">Context Aware</string>
<string name="intro_context_aware_desc">Long press links to copy and share them.\nLong press images to zoom and download.\nLong press cards to scroll horizontally.</string>
<string name="intro_end">Let\'s Begin!</string>
<string name="intro_tap_to_exit">Tap anywhere to exit</string>
</resources>

View File

@ -1,26 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="define_dbflow" />
<!-- Author section -->
<string name="library_dbflow_author">Raizlabs</string>
<string name="library_dbflow_authorWebsite">https://www.raizlabs.com/</string>
<!-- Library section -->
<string name="library_dbflow_libraryName">DbFlow</string>
<string name="library_dbflow_libraryDescription">
<![CDATA[
A robust, powerful, and very simple ORM android database library with <b>annotation processing</b>.
<br/><br/>
The library is built on speed, performance, and approachability. It not only eliminates most boiler-plate code for dealing with databases, but also provides a powerful and simple API to manage interactions.
Let DBFlow make SQL code <i>flow</i> like a steady stream so you can focus on writing amazing apps.
]]>
</string>
<string name="library_dbflow_libraryWebsite">https://github.com/Raizlabs/DBFlow</string>
<string name="library_dbflow_libraryVersion">4.0.4</string>
<!-- OpenSource section -->
<string name="library_dbflow_isOpenSource">true</string>
<string name="library_dbflow_repositoryLink">https://github.com/Raizlabs/DBFlow</string>
<!-- ClassPath for autoDetect section -->
<string name="library_dbflow_classPath">com.raizlabs.android.dbflow</string>
<!-- License section -->
<string name="library_dbflow_licenseId">mit</string>
</resources>

View File

@ -16,4 +16,5 @@
<string name="get_pro">Get Frost Pro</string>
<string name="get_pro_desc">Purchase or restore pro and unlock the full potential of Frost! Includes ad blockers, custom themes, full configurations, and much more to come!</string>
<string name="replay_intro">Replay Introduction</string>
</resources>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="intro_title">Frost now has an intro screen</string>
<string name="intro_desc">Would you like to see it? You can always replay it under settings</string>
</resources>

View File

@ -56,8 +56,34 @@
<item name="colorAccent">@color/frost_splash_background</item>
</style>
<style name="FrostTheme.Intro" parent="FrostTheme.Transparent" />
<style name="FrostProgressBar" parent="Widget.AppCompat.ProgressBar.Horizontal">
<item name="android:minHeight">@dimen/progress_bar_height</item>
<item name="android:maxHeight">@dimen/progress_bar_height</item>
</style>
<style name="IntroBarButton" parent="Widget.AppCompat.Button.Borderless">
<item name="android:elevation">0dp</item>
<item name="android:minWidth">100dp</item>
<item name="android:layout_marginStart">@dimen/kau_padding_small</item>
<item name="android:layout_marginEnd">@dimen/kau_padding_small</item>
</style>
<style name="IntroTitle" parent="TextAppearance.AppCompat.Title">
<item name="android:textSize">20sp</item>
<item name="android:textAlignment">center</item>
</style>
<style name="IntroSubTitle" parent="TextAppearance.AppCompat.Subhead">
<item name="android:textSize">18sp</item>
<item name="android:textAlignment">center</item>
</style>
<style name="IntroButton" parent="TextAppearance.AppCompat.Button">
<item name="android:elevation">0dp</item>
<item name="android:background">?android:selectableItemBackgroundBorderless</item>
<item name="android:padding">@dimen/kau_padding_large</item>
</style>
</resources>

View File

@ -17,7 +17,7 @@ MIN_SDK=21
TARGET_SDK=26
BUILD_TOOLS=26.0.1
KAU=ab2036f
KAU=bbaa795
KOTLIN=1.1.3-2
CRASHLYTICS=2.6.8
DBFLOW=4.0.5