This commit is contained in:
tateisu 2020-01-31 16:46:30 +09:00
parent ac943ddf19
commit b7b7d4470f
17 changed files with 2566 additions and 2307 deletions

View File

@ -13,6 +13,7 @@
<w>atmark</w>
<w>autofill</w>
<w>basi</w>
<w>bindable</w>
<w>blockee</w>
<w>blockquote</w>
<w>blurhash</w>

View File

@ -168,13 +168,6 @@
<activity
android:name=".ActAppSetting"
android:label="@string/app_setting"
android:windowSoftInputMode="adjustResize|stateAlwaysHidden"
/>
<activity
android:name=".ActAppSettingChild"
android:label="@string/app_setting"
android:windowSoftInputMode="adjustResize|stateAlwaysHidden"
/>

View File

@ -261,7 +261,7 @@ class ActAccountSetting
Styler.fixHorizontalPadding(root)
ActAppSettingChild.setSwitchColor(this, pref, root)
ActAppSetting.setSwitchColor(this, pref, root)
tvInstance = findViewById(R.id.tvInstance)
tvUser = findViewById(R.id.tvUser)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -7,14 +7,18 @@ import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.content.res.ColorStateList
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.graphics.Color
import android.graphics.PorterDuff
import android.net.Uri
import android.os.Build
import android.util.Log
import android.view.View
import android.view.WindowManager
import android.widget.Switch
import androidx.appcompat.app.AppCompatActivity
import androidx.browser.customtabs.CustomTabsIntent
import com.bumptech.glide.Glide
import com.bumptech.glide.GlideBuilder
@ -741,5 +745,143 @@ class App1 : Application() {
} // else: need restart app.
}
}
fun setSwitchColor1(
activity : AppCompatActivity,
pref : SharedPreferences,
view : Switch?
) {
fun mixColor(col1 : Int, col2 : Int) : Int = Color.rgb(
(Color.red(col1) + Color.red(col2)) ushr 1,
(Color.green(col1) + Color.green(col2)) ushr 1,
(Color.blue(col1) + Color.blue(col2)) ushr 1
)
val colorBg = getAttributeColor(activity, R.attr.colorWindowBackground)
val colorOn = Pref.ipSwitchOnColor(pref)
val colorOff = /* Pref.ipSwitchOffColor(pref).notZero() ?: */
getAttributeColor(activity, android.R.attr.colorPrimary)
val colorDisabled = mixColor(colorBg, colorOff)
val colorTrackDisabled = mixColor(colorBg, colorDisabled)
val colorTrackOn = mixColor(colorBg, colorOn)
val colorTrackOff = mixColor(colorBg, colorOff)
// set Switch Color
// https://stackoverflow.com/a/25635526/9134243
val thumbStates = ColorStateList(
arrayOf(
intArrayOf(- android.R.attr.state_enabled),
intArrayOf(android.R.attr.state_checked),
intArrayOf()
),
intArrayOf(
colorDisabled,
colorOn,
colorOff
)
)
val trackStates = ColorStateList(
arrayOf(
intArrayOf(- android.R.attr.state_enabled),
intArrayOf(android.R.attr.state_checked),
intArrayOf()
),
intArrayOf(
colorTrackDisabled,
colorTrackOn,
colorTrackOff
)
)
view?.apply {
if(Build.VERSION.SDK_INT < 23) {
// android 5
thumbDrawable?.setTintList(thumbStates)
trackDrawable?.setTintList(thumbStates) // not trackState
} else {
// android 6
thumbTintList = thumbStates
if(Build.VERSION.SDK_INT >= 24) {
// android 7
trackTintList = trackStates
trackTintMode = PorterDuff.Mode.SRC_OVER
}
}
}
}
fun setSwitchColor(activity : AppCompatActivity, pref : SharedPreferences, root : View?) {
fun mixColor(col1 : Int, col2 : Int) : Int = Color.rgb(
(Color.red(col1) + Color.red(col2)) ushr 1,
(Color.green(col1) + Color.green(col2)) ushr 1,
(Color.blue(col1) + Color.blue(col2)) ushr 1
)
val colorBg = getAttributeColor(activity, R.attr.colorWindowBackground)
val colorOn = Pref.ipSwitchOnColor(pref)
val colorOff = /* Pref.ipSwitchOffColor(pref).notZero() ?: */
getAttributeColor(activity, android.R.attr.colorPrimary)
val colorDisabled = mixColor(colorBg, colorOff)
val colorTrackDisabled = mixColor(colorBg, colorDisabled)
val colorTrackOn = mixColor(colorBg, colorOn)
val colorTrackOff = mixColor(colorBg, colorOff)
// set Switch Color
// https://stackoverflow.com/a/25635526/9134243
val thumbStates = ColorStateList(
arrayOf(
intArrayOf(- android.R.attr.state_enabled),
intArrayOf(android.R.attr.state_checked),
intArrayOf()
),
intArrayOf(
colorDisabled,
colorOn,
colorOff
)
)
val trackStates = ColorStateList(
arrayOf(
intArrayOf(- android.R.attr.state_enabled),
intArrayOf(android.R.attr.state_checked),
intArrayOf()
),
intArrayOf(
colorTrackDisabled,
colorTrackOn,
colorTrackOff
)
)
root?.scan {
(it as? Switch)?.apply {
if(Build.VERSION.SDK_INT < 23) {
// android 5
thumbDrawable?.setTintList(thumbStates)
trackDrawable?.setTintList(thumbStates) // not trackState
} else {
// android 6
thumbTintList = thumbStates
if(Build.VERSION.SDK_INT >= 24) {
// android 7
trackTintList = trackStates
trackTintMode = PorterDuff.Mode.SRC_OVER
}
}
}
}
}
}
}

View File

@ -0,0 +1,923 @@
package jp.juggler.subwaytooter
import android.content.Intent
import android.content.res.ColorStateList
import android.os.Build
import android.view.View
import android.widget.ImageView
import android.widget.Spinner
import android.widget.TextView
import androidx.annotation.StringRes
import androidx.appcompat.widget.AppCompatImageView
import jp.juggler.subwaytooter.action.CustomShareTarget
import jp.juggler.util.*
enum class SettingType(val id : Int) {
Path(0),
Divider(1),
Switch(2),
EditText(3),
Spinner(4),
ColorOpaque(5),
ColorAlpha(6),
Action(7),
Sample(8),
Group(9),
TextWithSelector(10),
CheckBox(11),
Section(12)
}
open class AppSettingItem(
val parent : AppSettingItem?,
val type : SettingType,
val pref : BasePref<*>?,
@StringRes val caption : Int
) {
@StringRes
var desc : Int = 0
var descClickSet = false
var descClick : ActAppSetting.() -> Unit = {}
set(value) {
field = value
descClickSet = true
}
var getError : ActAppSetting.(String) -> String? = { null }
// may be open exportAppData() or importAppData()
var action : ActAppSetting.() -> Unit = {}
var changed : ActAppSetting.() -> Unit = {}
// used for EditText
var inputType = InputTypeEx.text
var sampleLayoutId : Int = 0
var sampleUpdate : (ActAppSetting, View) -> Unit = { _, _ -> }
var spinnerArgs : IntArray? = null
var spinnerArgsProc : (ActAppSetting) -> List<String> = { _ -> emptyList() }
var spinnerInitializer : ActAppSetting.(Spinner) -> Unit = {}
var spinnerOnSelected : ActAppSetting.(Spinner, Int) -> Unit = { _, _ -> }
var enabled : Boolean = true
var onClickEdit : ActAppSetting.() -> Unit = {}
var onClickReset : ActAppSetting.() -> Unit = {}
var showTextView : ActAppSetting.(TextView) -> Unit = {}
// for EditText
var hint : String? = null
var filter : (String) -> String = { it.trim() }
var captionFontSize : ActAppSetting.() -> Float? = { null }
var captionSpacing : ActAppSetting.() -> Float? = { null }
// cast before save
var toFloat : ActAppSetting.(String) -> Float = { 0f }
var fromFloat : ActAppSetting.(Float) -> String = { it.toString() }
companion object {
var SAMPLE_CCD_HEADER : AppSettingItem? = null
var SAMPLE_CCD_BODY : AppSettingItem? = null
var SAMPLE_FOOTER : AppSettingItem? = null
var CUSTOM_TRANSLATE : AppSettingItem? = null
var CUSTOM_SHARE_1 : AppSettingItem? = null
var CUSTOM_SHARE_2 : AppSettingItem? = null
var CUSTOM_SHARE_3 : AppSettingItem? = null
var TIMELINE_FONT : AppSettingItem? = null
var TIMELINE_FONT_BOLD : AppSettingItem? = null
var FONT_SIZE_TIMELINE : AppSettingItem? = null
var FONT_SIZE_NOTIFICATION_TL : AppSettingItem? = null
}
}
class AppSettingGroup(
parent : AppSettingGroup?,
type : SettingType,
@StringRes caption : Int
) : AppSettingItem(
parent = parent,
type = type,
pref = null,
caption = caption
) {
val items = ArrayList<AppSettingItem>()
fun section(
@StringRes caption : Int,
initializer : AppSettingGroup.() -> Unit = {}
) {
items.add(AppSettingGroup(this, SettingType.Section, caption).apply { initializer() })
}
fun group(
@StringRes caption : Int,
initializer : AppSettingGroup.() -> Unit = {}
) {
items.add(AppSettingGroup(this, SettingType.Group, caption).apply { initializer() })
}
fun item(
type : SettingType,
pref : BasePref<*>?,
@StringRes caption : Int,
initializer : AppSettingItem.() -> Unit = {}
) : AppSettingItem {
val item = AppSettingItem(this, type, pref, caption).apply { initializer() }
items.add(item)
return item
}
fun spinner(
pref : IntPref,
@StringRes caption : Int,
vararg args : Int
) = item(SettingType.Spinner, pref, caption) {
spinnerArgs = args
}
fun spinner(
pref : IntPref,
@StringRes caption : Int,
argsProc : (ActAppSetting) -> List<String>
) = item(SettingType.Spinner, pref, caption) {
spinnerArgsProc = argsProc
}
fun sw(
pref : BooleanPref,
@StringRes caption : Int,
initializer : AppSettingItem.() -> Unit = {}
) = item(SettingType.Switch, pref, caption, initializer)
fun checkbox(
pref : BooleanPref,
@StringRes caption : Int,
initializer : AppSettingItem.() -> Unit = {}
) = item(SettingType.CheckBox, pref, caption, initializer)
fun action(
@StringRes caption : Int,
initializer : AppSettingItem.() -> Unit = {}
) = item(SettingType.Action, null, caption, initializer)
fun colorOpaque(
pref : IntPref,
@StringRes caption : Int,
initializer : AppSettingItem.() -> Unit = {}
) = item(SettingType.ColorOpaque, pref, caption, initializer)
fun colorAlpha(
pref : IntPref,
@StringRes caption : Int,
initializer : AppSettingItem.() -> Unit = {}
) = item(SettingType.ColorAlpha, pref, caption, initializer)
fun text(
pref : StringPref,
@StringRes caption : Int,
inputType : Int,
initializer : AppSettingItem.() -> Unit = {}
) = item(SettingType.EditText, pref, caption) {
this.inputType = inputType
this.initializer()
}
fun textX(
pref : BasePref<*>,
@StringRes caption : Int,
inputType : Int,
initializer : AppSettingItem.() -> Unit = {}
) = item(SettingType.EditText, pref, caption) {
this.inputType = inputType
this.initializer()
}
fun sample(
sampleLayoutId : Int = 0,
sampleUpdate : (ActAppSetting, View) -> Unit = { _, _ -> }
// ,initializer : AppSettingItem.() -> Unit = {}
) = item(SettingType.Sample, pref, caption) {
this.sampleLayoutId = sampleLayoutId
this.sampleUpdate = sampleUpdate
}
}
val appSettingRoot = AppSettingGroup(null, SettingType.Section, R.string.app_setting).apply {
// TODO項目一覧に漏れがないか確認すること
section(R.string.notifications) {
group(R.string.notification_style_before_oreo) {
checkbox(Pref.bpNotificationSound, R.string.sound) {
enabled = Build.VERSION.SDK_INT < 26
}
checkbox(Pref.bpNotificationVibration, R.string.vibration) {
enabled = Build.VERSION.SDK_INT < 26
}
checkbox(Pref.bpNotificationLED, R.string.led) {
enabled = Build.VERSION.SDK_INT < 26
}
sample(R.layout.setting_sample_notification_desc)
}
text(
Pref.spPullNotificationCheckInterval,
R.string.pull_notification_check_interval,
InputTypeEx.number
)
sw(Pref.bpShowAcctInSystemNotification, R.string.show_acct_in_system_notification)
sw(Pref.bpSeparateReplyNotificationGroup, R.string.separate_notification_group_for_reply) {
enabled = Build.VERSION.SDK_INT >= 26
}
sw(Pref.bpDivideNotification, R.string.divide_notification)
}
section(R.string.behavior) {
sw(Pref.bpDontConfirmBeforeCloseColumn, R.string.dont_confirm_before_close_column)
spinner(
Pref.ipBackButtonAction,
R.string.back_button_action,
R.string.ask_always,
R.string.close_column,
R.string.open_column_list,
R.string.app_exit
)
sw(Pref.bpExitAppWhenCloseProtectedColumn, R.string.exit_app_when_close_protected_column)
sw(Pref.bpScrollTopFromColumnStrip, R.string.scroll_top_from_column_strip)
sw(Pref.bpDontScreenOff, R.string.dont_screen_off)
sw(Pref.bpDontUseCustomTabs, R.string.dont_use_custom_tabs)
sw(Pref.bpPriorChrome, R.string.prior_chrome_custom_tabs)
sw(Pref.bpAllowColumnDuplication, R.string.allow_column_duplication)
sw(Pref.bpForceGap, R.string.force_gap_when_refresh)
text(Pref.spClientName, R.string.client_name, InputTypeEx.text)
text(Pref.spUserAgent, R.string.user_agent, InputTypeEx.textMultiLine) {
hint = App1.userAgentDefault
filter = { it.replace(ActAppSetting.reLinefeed, " ").trim() }
getError = {
val m = App1.reNotAllowedInUserAgent.matcher(it)
when(m.find()) {
true -> getString(R.string.user_agent_error, m.group())
else -> null
}
}
}
sw(Pref.bpDontRemoveDeletedToot, R.string.dont_remove_deleted_toot_from_timeline)
sw(Pref.bpCustomEmojiSeparatorZwsp, R.string.custom_emoji_separator_zwsp)
sw(Pref.bpShowTranslateButton, R.string.show_translate_button)
AppSettingItem.CUSTOM_TRANSLATE = item(
SettingType.TextWithSelector,
Pref.spTranslateAppComponent,
R.string.translation_app
) {
val target = CustomShareTarget.Translate
onClickEdit = { openCustomShareChooser(target) }
onClickReset = { setCustomShare(target, "") }
showTextView = { showCustomShareIcon(it, target) }
}
AppSettingItem.CUSTOM_SHARE_1 = item(
SettingType.TextWithSelector,
Pref.spCustomShare1,
R.string.custom_share_button_1
) {
val target = CustomShareTarget.CustomShare1
onClickEdit = { openCustomShareChooser(target) }
onClickReset = { setCustomShare(target, "") }
showTextView = { showCustomShareIcon(it, target) }
}
AppSettingItem.CUSTOM_SHARE_2 = item(
SettingType.TextWithSelector,
Pref.spCustomShare2,
R.string.custom_share_button_2
) {
val target = CustomShareTarget.CustomShare2
onClickEdit = { openCustomShareChooser(target) }
onClickReset = { setCustomShare(target, "") }
showTextView = { showCustomShareIcon(it, target) }
}
AppSettingItem.CUSTOM_SHARE_3 = item(
SettingType.TextWithSelector,
Pref.spCustomShare3,
R.string.custom_share_button_3
) {
val target = CustomShareTarget.CustomShare3
onClickEdit = { openCustomShareChooser(target) }
onClickReset = { setCustomShare(target, "") }
showTextView = { showCustomShareIcon(it, target) }
}
spinner(
Pref.ipAdditionalButtonsPosition,
R.string.additional_buttons_position,
R.string.top,
R.string.bottom,
R.string.start,
R.string.end
)
sw(Pref.bpEnablePixelfed, R.string.enable_connect_to_pixelfed_server)
sw(Pref.bpShowFilteredWord, R.string.show_filtered_word)
sw(Pref.bpEnableDomainTimeline, R.string.enable_domain_timeline)
}
section(R.string.post) {
spinner(Pref.ipResizeImage, R.string.resize_image) { activity ->
ActPost.resizeConfigList.map {
when(it.type) {
ResizeType.None -> activity.getString(R.string.dont_resize)
ResizeType.LongSide -> activity.getString(R.string.long_side_pixel, it.size)
ResizeType.SquarePixel -> activity.getString(
R.string.resize_square_pixels,
it.size * it.size,
it.size
)
}
}
}
text(Pref.spMediaSizeMax, R.string.media_attachment_max_byte_size, InputTypeEx.number)
text(Pref.spMovieSizeMax, R.string.media_attachment_max_byte_size_movie, InputTypeEx.number)
text(
Pref.spMediaSizeMaxPixelfed,
R.string.media_attachment_max_byte_size_pixelfed,
InputTypeEx.number
)
spinner(
Pref.ipRefreshAfterToot,
R.string.refresh_after_toot,
R.string.refresh_scroll_to_toot,
R.string.refresh_no_scroll,
R.string.dont_refresh
)
sw(Pref.bpPostButtonBarTop, R.string.show_post_button_bar_top)
sw(
Pref.bpDontDuplicationCheck,
R.string.dont_add_duplication_check_header
)
sw(Pref.bpQuickTootBar, R.string.show_quick_toot_bar)
sw(
Pref.bpDontUseActionButtonWithQuickTootBar,
R.string.dont_use_action_button_with_quick_toot_bar
)
text(Pref.spQuoteNameFormat, R.string.format_of_quote_name, InputTypeEx.text) {
filter = { it } // don't trim
}
sw(
Pref.bpAppendAttachmentUrlToContent,
R.string.append_attachment_url_to_content
)
sw(
Pref.bpWarnHashtagAsciiAndNonAscii,
R.string.warn_hashtag_ascii_and_non_ascii
)
}
section(R.string.tablet_mode) {
sw(Pref.bpDisableTabletMode, R.string.disable_tablet_mode)
text(Pref.spColumnWidth, R.string.minimum_column_width, InputTypeEx.number)
item(
SettingType.Spinner,
Pref.lpTabletTootDefaultAccount,
R.string.toot_button_default_account
) {
val lp = pref.cast<LongPref>() !!
spinnerInitializer = { spinner ->
val adapter = AccountAdapter()
spinner.adapter = adapter
spinner.setSelection(adapter.getIndexFromId(lp(pref)))
}
spinnerOnSelected = { spinner, index ->
val adapter = spinner.adapter.cast<ActAppSetting.AccountAdapter>()
?: error("spinnerOnSelected: missing AccountAdapter")
pref.edit().put(lp, adapter.getIdFromIndex(index)).apply()
}
}
sw(
Pref.bpQuickTootOmitAccountSelection,
R.string.quick_toot_omit_account_selection
)
spinner(
Pref.ipJustifyWindowContentPortrait,
R.string.justify_window_content_portrait,
R.string.default_,
R.string.start,
R.string.end
)
}
section(R.string.media_attachment) {
sw(Pref.bpUseInternalMediaViewer, R.string.use_internal_media_viewer)
sw(Pref.bpPriorLocalURL, R.string.prior_local_url_when_open_attachment)
text(Pref.spMediaThumbHeight, R.string.media_thumbnail_height, InputTypeEx.number)
sw(Pref.bpDontCropMediaThumb, R.string.dont_crop_media_thumbnail)
sw(Pref.bpVerticalArrangeThumbnails, R.string.thumbnails_arrange_vertically)
}
section(R.string.animation) {
sw(Pref.bpEnableGifAnimation, R.string.enable_gif_animation)
sw(Pref.bpDisableEmojiAnimation, R.string.disable_custom_emoji_animation)
}
section(R.string.appearance) {
sw(Pref.bpSimpleList, R.string.simple_list)
sw(Pref.bpShowFollowButtonInButtonBar, R.string.show_follow_button_in_button_bar)
sw(Pref.bpDontShowPreviewCard, R.string.dont_show_preview_card)
sw(Pref.bpShortAcctLocalUser, R.string.short_acct_local_user)
sw(Pref.bpMentionFullAcct, R.string.mention_full_acct)
sw(Pref.bpRelativeTimestamp, R.string.relative_timestamp)
item(
SettingType.Spinner,
Pref.spTimeZone,
R.string.timezone
) {
val sp : StringPref = pref.cast() !!
spinnerInitializer = { spinner ->
val adapter = TimeZoneAdapter()
spinner.adapter = adapter
spinner.setSelection(adapter.getIndexFromId(sp(pref)))
}
spinnerOnSelected = { spinner, index ->
val adapter = spinner.adapter.cast<ActAppSetting.TimeZoneAdapter>()
?: error("spinnerOnSelected: missing TimeZoneAdapter")
pref.edit().put(sp, adapter.getIdFromIndex(index)).apply()
}
}
sw(Pref.bpShowAppName, R.string.always_show_application)
sw(Pref.bpShowLanguage, R.string.always_show_language)
text(Pref.spAutoCWLines, R.string.auto_cw, InputTypeEx.number)
text(Pref.spCardDescriptionLength, R.string.card_description_length, InputTypeEx.number)
spinner(
Pref.ipRepliesCount,
R.string.display_replies_count,
R.string.replies_count_simple,
R.string.replies_count_actual,
R.string.replies_count_none
)
spinner(
Pref.ipVisibilityStyle,
R.string.visibility_style,
R.string.visibility_style_by_account,
R.string.mastodon,
R.string.misskey
)
AppSettingItem.TIMELINE_FONT = item(
SettingType.TextWithSelector,
Pref.spTimelineFont,
R.string.timeline_font
) {
val item = this
onClickEdit = {
try {
val intent = intentOpenDocument("*/*")
startActivityForResult(intent, ActAppSetting.REQUEST_CODE_TIMELINE_FONT)
} catch(ex : Throwable) {
showToast(this, ex, "could not open picker for font")
}
}
onClickReset = {
pref.edit().remove(item.pref?.key).apply()
showTimelineFont(item)
}
showTextView = { showTimelineFont(item, it) }
}
AppSettingItem.TIMELINE_FONT_BOLD = item(
SettingType.TextWithSelector,
Pref.spTimelineFontBold,
R.string.timeline_font_bold
) {
val item = this
onClickEdit = {
try {
val intent = intentOpenDocument("*/*")
startActivityForResult(intent, ActAppSetting.REQUEST_CODE_TIMELINE_FONT_BOLD)
} catch(ex : Throwable) {
showToast(this, ex, "could not open picker for font")
}
}
onClickReset = {
pref.edit().remove(item.pref?.key).apply()
showTimelineFont(AppSettingItem.TIMELINE_FONT_BOLD)
}
showTextView = { showTimelineFont(item, it) }
}
AppSettingItem.FONT_SIZE_TIMELINE = textX(
Pref.fpTimelineFontSize,
R.string.timeline_font_size,
InputTypeEx.numberDecimal
) {
val item = this
val fp : FloatPref = item.pref.cast() !!
toFloat = { parseFontSize(it) }
fromFloat = { formatFontSize(it) }
captionFontSize = {
val fv = fp(pref)
when {
! fv.isFinite() -> Pref.default_timeline_font_size
fv < 1f -> 1f
else -> fv
}
}
captionSpacing = {
Pref.spTimelineSpacing(pref).toFloatOrNull()
}
changed = {
findItemViewHolder(item)?.updateCaption()
}
}
textX(Pref.fpAcctFontSize, R.string.acct_font_size, InputTypeEx.numberDecimal) {
val item = this
val fp : FloatPref = item.pref.cast() !!
toFloat = { parseFontSize(it) }
fromFloat = { formatFontSize(it) }
captionFontSize = {
val fv = fp(pref)
when {
! fv.isFinite() -> Pref.default_acct_font_size
fv < 1f -> 1f
else -> fv
}
}
changed = { findItemViewHolder(item)?.updateCaption() }
}
AppSettingItem.FONT_SIZE_NOTIFICATION_TL = textX(
Pref.fpNotificationTlFontSize,
R.string.notification_tl_font_size,
InputTypeEx.numberDecimal
) {
val item = this
val fp : FloatPref = item.pref.cast() !!
toFloat = { parseFontSize(it) }
fromFloat = { formatFontSize(it) }
captionFontSize = {
val fv = fp(pref)
when {
! fv.isFinite() -> Pref.default_notification_tl_font_size
fv < 1f -> 1f
else -> fv
}
}
captionSpacing = {
Pref.spTimelineSpacing(pref).toFloatOrNull()
}
changed = {
findItemViewHolder(item)?.updateCaption()
}
}
text(
Pref.spNotificationTlIconSize,
R.string.notification_tl_icon_size,
InputTypeEx.numberDecimal
)
text(Pref.spTimelineSpacing, R.string.timeline_line_spacing, InputTypeEx.numberDecimal) {
changed = {
findItemViewHolder(AppSettingItem.FONT_SIZE_TIMELINE)?.updateCaption()
findItemViewHolder(AppSettingItem.FONT_SIZE_NOTIFICATION_TL)?.updateCaption()
}
}
text(Pref.spBoostButtonSize, R.string.boost_button_size, InputTypeEx.numberDecimal)
spinner(
Pref.ipBoostButtonJustify,
R.string.boost_button_alignment,
R.string.start,
R.string.center,
R.string.end
)
text(Pref.spAvatarIconSize, R.string.avatar_icon_size, InputTypeEx.numberDecimal)
text(Pref.spRoundRatio, R.string.avatar_icon_round_ratio, InputTypeEx.numberDecimal)
sw(Pref.bpDontRound, R.string.avatar_icon_dont_round)
text(Pref.spReplyIconSize, R.string.reply_icon_size, InputTypeEx.numberDecimal)
text(Pref.spHeaderIconSize, R.string.header_icon_size, InputTypeEx.numberDecimal)
textX(Pref.fpHeaderTextSize, R.string.header_text_size, InputTypeEx.numberDecimal) {
val item = this
val fp : FloatPref = item.pref.cast() !!
toFloat = { parseFontSize(it) }
fromFloat = { formatFontSize(it) }
captionFontSize = {
val fv = fp(pref)
when {
! fv.isFinite() -> Pref.default_header_font_size
fv < 1f -> 1f
else -> fv
}
}
changed = {
findItemViewHolder(item)?.updateCaption()
}
}
text(Pref.spStripIconSize, R.string.strip_icon_size, InputTypeEx.numberDecimal)
sw(Pref.bpInstanceTicker, R.string.show_instance_ticker) {
desc = R.string.instance_ticker_copyright
descClick = {
App1.openBrowser(
this,
"https://github.com/MiyonMiyon/InstanceTicker_List"
)
}
}
sw(Pref.bpLinksInContextMenu, R.string.show_links_in_context_menu)
sw(Pref.bpShowLinkUnderline, R.string.show_link_underline)
sw(
Pref.bpMoveNotificationsQuickFilter,
R.string.move_notifications_quick_filter_to_column_setting
)
sw(Pref.bpShowSearchClear, R.string.show_clear_button_in_search_bar)
sw(
Pref.bpDontShowColumnBackgroundImage,
R.string.dont_show_column_background_image
)
group(R.string.show_in_directory) {
checkbox(Pref.bpDirectoryLastActive, R.string.last_active)
checkbox(Pref.bpDirectoryFollowers, R.string.followers)
checkbox(Pref.bpDirectoryTootCount, R.string.toot_count)
checkbox(Pref.bpDirectoryNote, R.string.note)
}
sw(
Pref.bpAlwaysExpandContextMenuItems,
R.string.always_expand_context_menu_sub_items
)
sw(Pref.bpShowBookmarkButton, R.string.show_bookmark_button)
sw(Pref.bpHideFollowCount, R.string.hide_followers_count)
sw(Pref.bpEmojioneShortcode, R.string.emojione_shortcode_support) {
desc = R.string.emojione_shortcode_support_desc
}
}
section(R.string.color) {
spinner(
Pref.ipUiTheme,
R.string.ui_theme,
R.string.theme_light,
R.string.theme_dark
)
colorAlpha(Pref.ipListDividerColor, R.string.list_divider_color)
colorAlpha(Pref.ipLinkColor, R.string.link_color)
group(R.string.toot_background_color) {
colorAlpha(Pref.ipTootColorUnlisted, R.string.unlisted_visibility)
colorAlpha(Pref.ipTootColorFollower, R.string.followers_visibility)
colorAlpha(Pref.ipTootColorDirectUser, R.string.direct_with_user_visibility)
colorAlpha(Pref.ipTootColorDirectMe, R.string.direct_only_me_visibility)
}
group(R.string.event_background_color) {
colorAlpha(Pref.ipEventBgColorBoost, R.string.boost)
colorAlpha(Pref.ipEventBgColorFavourite, R.string.favourites)
colorAlpha(Pref.ipEventBgColorMention, R.string.reply)
colorAlpha(Pref.ipEventBgColorFollow, R.string.follow)
colorAlpha(Pref.ipEventBgColorUnfollow, R.string.unfollow_misskey)
colorAlpha(Pref.ipEventBgColorFollowRequest, R.string.follow_request)
colorAlpha(Pref.ipEventBgColorReaction, R.string.reaction)
colorAlpha(Pref.ipEventBgColorQuote, R.string.quote_renote)
colorAlpha(Pref.ipEventBgColorVote, R.string.vote_polls)
}
group(R.string.column_color_default) {
AppSettingItem.SAMPLE_CCD_HEADER =
sample(R.layout.setting_sample_column_header) { activity, viewRoot ->
val llColumnHeader : View = viewRoot.findViewById(R.id.llColumnHeader)
val ivColumnHeader : ImageView = viewRoot.findViewById(R.id.ivColumnHeader)
val tvColumnName : TextView = viewRoot.findViewById(R.id.tvColumnName)
val color_column_header_bg = Pref.ipCcdHeaderBg(activity.pref)
val color_column_header_fg = Pref.ipCcdHeaderFg(activity.pref)
val header_bg = when {
color_column_header_bg != 0 -> color_column_header_bg
else -> getAttributeColor(activity, R.attr.color_column_header)
}
val header_fg = when {
color_column_header_fg != 0 -> color_column_header_fg
else -> getAttributeColor(activity, R.attr.colorColumnHeaderName)
}
llColumnHeader.background = getAdaptiveRippleDrawable(header_bg, header_fg)
tvColumnName.setTextColor(header_fg)
ivColumnHeader.setImageResource(R.drawable.ic_bike)
ivColumnHeader.imageTintList = ColorStateList.valueOf(header_fg)
}
colorOpaque(Pref.ipCcdHeaderBg, R.string.header_background_color) {
changed = { showSample(AppSettingItem.SAMPLE_CCD_HEADER) }
}
colorOpaque(Pref.ipCcdHeaderFg, R.string.header_foreground_color) {
changed = { showSample(AppSettingItem.SAMPLE_CCD_HEADER) }
}
AppSettingItem.SAMPLE_CCD_BODY =
sample(R.layout.setting_sample_column_body) { activity, viewRoot ->
val flColumnBackground : View = viewRoot.findViewById(R.id.flColumnBackground)
val tvSampleAcct : TextView = viewRoot.findViewById(R.id.tvSampleAcct)
val tvSampleContent : TextView = viewRoot.findViewById(R.id.tvSampleContent)
val color_column_bg = Pref.ipCcdContentBg(activity.pref)
val color_column_acct = Pref.ipCcdContentAcct(activity.pref)
val color_column_text = Pref.ipCcdContentText(activity.pref)
flColumnBackground.setBackgroundColor(color_column_bg) // may 0
tvSampleAcct.setTextColor(
color_column_acct.notZero()
?: getAttributeColor(activity, R.attr.colorTimeSmall)
)
tvSampleContent.setTextColor(
color_column_text.notZero()
?: getAttributeColor(activity, R.attr.colorContentText)
)
}
colorOpaque(Pref.ipCcdContentBg, R.string.content_background_color) {
changed = { showSample(AppSettingItem.SAMPLE_CCD_BODY) }
}
colorAlpha(Pref.ipCcdContentAcct, R.string.content_acct_color) {
changed = { showSample(AppSettingItem.SAMPLE_CCD_BODY) }
}
colorAlpha(Pref.ipCcdContentText, R.string.content_text_color) {
changed = { showSample(AppSettingItem.SAMPLE_CCD_BODY) }
}
}
text(Pref.spBoostAlpha, R.string.boost_button_alpha, InputTypeEx.numberDecimal)
group(R.string.footer_color) {
AppSettingItem.SAMPLE_FOOTER =
sample(R.layout.setting_sample_footer) { activity, viewRoot ->
val pref = activity.pref
val footer_button_bg_color = Pref.ipFooterButtonBgColor(pref)
val footer_button_fg_color = Pref.ipFooterButtonFgColor(pref)
val footer_tab_bg_color = Pref.ipFooterTabBgColor(pref)
val footer_tab_divider_color = Pref.ipFooterTabDividerColor(pref)
val footer_tab_indicator_color = Pref.ipFooterTabIndicatorColor(pref)
val ivFooterToot : AppCompatImageView = viewRoot.findViewById(R.id.ivFooterToot)
val ivFooterMenu : AppCompatImageView = viewRoot.findViewById(R.id.ivFooterMenu)
val llFooterBG : View = viewRoot.findViewById(R.id.llFooterBG)
val vFooterDivider1 : View = viewRoot.findViewById(R.id.vFooterDivider1)
val vFooterDivider2 : View = viewRoot.findViewById(R.id.vFooterDivider2)
val vIndicator : View = viewRoot.findViewById(R.id.vIndicator)
val colorBg = footer_button_bg_color.notZero() ?: getAttributeColor(
activity,
R.attr.colorStatusButtonsPopupBg
)
val colorRipple =
footer_button_fg_color.notZero() ?: getAttributeColor(
activity,
R.attr.colorRippleEffect
)
ivFooterToot.background = getAdaptiveRippleDrawable(colorBg, colorRipple)
ivFooterMenu.background = getAdaptiveRippleDrawable(colorBg, colorRipple)
val csl = ColorStateList.valueOf(
footer_button_fg_color.notZero()
?: getAttributeColor(activity, R.attr.colorVectorDrawable)
)
ivFooterToot.imageTintList = csl
ivFooterMenu.imageTintList = csl
llFooterBG.setBackgroundColor(
footer_tab_bg_color.notZero()
?: getAttributeColor(activity, R.attr.colorColumnStripBackground)
)
val c =
footer_tab_divider_color.notZero() ?: getAttributeColor(
activity,
R.attr.colorImageButton
)
vFooterDivider1.setBackgroundColor(c)
vFooterDivider2.setBackgroundColor(c)
vIndicator.setBackgroundColor(
footer_tab_indicator_color.notZero()
?: getAttributeColor(activity, R.attr.colorAccent)
)
}
colorOpaque(Pref.ipFooterButtonBgColor, R.string.button_background_color) {
changed = { showSample(AppSettingItem.SAMPLE_FOOTER) }
}
colorOpaque(Pref.ipFooterButtonFgColor, R.string.button_foreground_color) {
changed = { showSample(AppSettingItem.SAMPLE_FOOTER) }
}
colorOpaque(Pref.ipFooterTabBgColor, R.string.quick_toot_bar_background_color) {
changed = { showSample(AppSettingItem.SAMPLE_FOOTER) }
}
colorOpaque(Pref.ipFooterTabDividerColor, R.string.tab_divider_color) {
changed = { showSample(AppSettingItem.SAMPLE_FOOTER) }
}
colorAlpha(Pref.ipFooterTabIndicatorColor, R.string.tab_indicator_color) {
changed = { showSample(AppSettingItem.SAMPLE_FOOTER) }
}
}
colorOpaque(Pref.ipSwitchOnColor, R.string.switch_button_color) {
changed = { setSwitchColor() }
}
colorOpaque(Pref.ipStatusBarColor, R.string.status_bar_color) {
changed = { App1.setStatusBarColor(this) }
}
colorOpaque(Pref.ipNavigationBarColor, R.string.navigation_bar_color) {
changed = { App1.setStatusBarColor(this) }
}
}
section(R.string.performance) {
sw(Pref.bpShareViewPool, R.string.share_view_pool)
sw(Pref.bpDontUseStreaming, R.string.dont_use_streaming_api)
sw(Pref.bpDontRefreshOnResume, R.string.dont_refresh_on_activity_resume)
text(Pref.spMediaReadTimeout, R.string.timeout_for_embed_media_viewer, InputTypeEx.number)
}
section(R.string.developer_options) {
action(R.string.drawable_list) {
action = { startActivity(Intent(this, ActDrawableList::class.java)) }
}
}
action(R.string.app_data_export) {
action = { exportAppData() }
}
action(R.string.app_data_import) {
action = { importAppData1() }
desc = R.string.app_data_import_desc
}
}

View File

@ -116,6 +116,10 @@ fun SharedPreferences.Editor.put(item : BooleanPref, v : Boolean) : SharedPrefer
item.put(this, v)
return this
}
fun SharedPreferences.Editor.putOrRemove(item : BooleanPref, v : Boolean) : SharedPreferences.Editor {
item.putOrRemove(this, v)
return this
}
fun SharedPreferences.Editor.put(item : StringPref, v : String) : SharedPreferences.Editor {
item.put(this, v)

View File

@ -0,0 +1,124 @@
package jp.juggler.util
import android.text.InputType
@Suppress("unused")
object InputTypeEx {
// For entering a date.
const val date = InputType.TYPE_CLASS_DATETIME or InputType.TYPE_DATETIME_VARIATION_DATE
// For entering a date and time.
const val datetime = InputType.TYPE_CLASS_DATETIME or InputType.TYPE_DATETIME_VARIATION_NORMAL
// There is no content type. The text is not editable.
const val none = 0
// A numeric only field.
const val number = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL
// Can be combined with number and its other options to allow a decimal (fractional) number.
const val numberDecimal = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL
// A numeric password field. .
const val numberPassword =
InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_PASSWORD
// Can be combined with number and its other options to allow a signed number.
const val numberSigned = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_SIGNED
// For entering a phone number.
const val phone = InputType.TYPE_CLASS_PHONE
// Just plain old text.
const val text = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_NORMAL
// Can be combined with text and its variations to
// specify that this field will be doing its own auto-completion
// and talking with the input method appropriately.
const val textAutoComplete = text or InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE
// Can be combined with text and its variations to
// request auto-correction of text being input.
const val textAutoCorrect = text or InputType.TYPE_TEXT_FLAG_AUTO_CORRECT
// Can be combined with text and its variations to
// request capitalization of all characters.
const val textCapCharacters = text or InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
// Can be combined with text and its variations to
// request capitalization of the first character of every sentence.
const val textCapSentences = text or InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
// Can be combined with text and its variations to
// request capitalization of the first character of every word.
const val textCapWords = text or InputType.TYPE_TEXT_FLAG_CAP_WORDS
// Text that will be used as an e-mail address.
const val textEmailAddress =
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
// Text that is being supplied as the subject of an e-mail.
const val textEmailSubject =
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_EMAIL_SUBJECT
// Text that is filtering some other data.
const val textFilter = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_FILTER
// Can be combined with text and its variations to indicate that though
// the regular text view should not be multiple lines,
// the IME should provide multiple lines if it can.
const val textImeMultiLine = text or InputType.TYPE_TEXT_FLAG_IME_MULTI_LINE
// Text that is the content of a long message.
const val textLongMessage =
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_LONG_MESSAGE
// Can be combined with text and its variations to allow multiple lines of text in the field.
// If this flag is not set, the text field will be constrained to a single line.
const val textMultiLine = text or InputType.TYPE_TEXT_FLAG_MULTI_LINE
// Can be combined with text and its variations to indicate that
// the IME should not show any dictionary-based word suggestions.
const val textNoSuggestions = text or InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
// Text that is a password.
const val textPassword = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
// Text that is the name of a person.
const val textPersonName =
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PERSON_NAME
// Text that is for phonetic pronunciation, such as a phonetic name field in a contact entry.
const val textPhonetic = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PHONETIC
// Text that is being supplied as a postal mailing address.
const val textPostalAddress =
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_POSTAL_ADDRESS
// Text that is the content of a short message.
const val textShortMessage =
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE
// Text that will be used as a URI.
const val textUri = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_URI
// Text that is a password that should be visible.
const val textVisiblePassword =
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
// Text that is being supplied as text in a web form.
const val textWebEditText =
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT
// Text that will be used as an e-mail address on a web form.
const val textWebEmailAddress =
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS
// Text that will be used as a password on a web form.
const val textWebPassword =
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD
// For entering a time.
const val time = InputType.TYPE_CLASS_DATETIME or InputType.TYPE_DATETIME_VARIATION_TIME
}

View File

@ -1,139 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/llContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorSearchFormBackground"
android:orientation="horizontal"
android:paddingStart="12dp"
android:paddingTop="6dp"
android:paddingEnd="12dp"
android:paddingBottom="6dp">
<EditText
android:id="@+id/etSearch"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="@string/search"
android:importantForAutofill="no"
android:inputType="text" />
<ImageButton
android:id="@+id/btnSearchReset"
android:background="@drawable/btn_bg_transparent"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginStart="6dp"
android:contentDescription="@string/reset"
android:padding="8dp"
android:src="@drawable/ic_close"
android:tint="?attr/colorVectorDrawable" />
</LinearLayout>
<ListView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/lvList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarStyle="outsideOverlay"
android:layout_height="0dp"
android:layout_weight="1"
android:clipToPadding="false"
android:paddingBottom="128dp"
android:divider="@null"
android:dividerHeight="0dp"
android:paddingStart="12dp"
android:paddingTop="12dp"
/>
android:paddingEnd="12dp"
android:paddingBottom="128dp"
android:scrollbarStyle="outsideOverlay" />
</LinearLayout>
<!--<LinearLayout-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content"-->
<!--android:orientation="vertical"-->
<!--&gt;-->
<!--<Button-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent"-->
<!--android:textAllCaps="false"-->
<!--android:text="@string/appearance"-->
<!--android:id="@+id/btnAppearance"-->
<!--/>-->
<!--<Button-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent"-->
<!--android:textAllCaps="false"-->
<!--android:text="@string/behavior"-->
<!--android:id="@+id/btnBehavior"-->
<!--/>-->
<!--<Button-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent"-->
<!--android:textAllCaps="false"-->
<!--android:text="@string/emoji"-->
<!--android:id="@+id/btnEmoji"-->
<!--/>-->
<!--<Button-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent"-->
<!--android:textAllCaps="false"-->
<!--android:text="@string/media_attachment"-->
<!--android:id="@+id/btnMediaAttachment"-->
<!--/>-->
<!--<Button-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent"-->
<!--android:textAllCaps="false"-->
<!--android:text="@string/notifications"-->
<!--android:id="@+id/btnNotifications"-->
<!--/>-->
<!--<Button-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent"-->
<!--android:textAllCaps="false"-->
<!--android:text="@string/performance"-->
<!--android:id="@+id/btnPerformance"-->
<!--/>-->
<!--<Button-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent"-->
<!--android:textAllCaps="false"-->
<!--android:text="@string/post"-->
<!--android:id="@+id/btnPost"-->
<!--/>-->
<!--<Button-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent"-->
<!--android:textAllCaps="false"-->
<!--android:text="@string/tablet_mode"-->
<!--android:id="@+id/btnTabletMode"-->
<!--/>-->
<!--<View style="@style/setting_divider"/>-->
<!--&lt;!&ndash; =============================================== &ndash;&gt;-->
<!--<TextView-->
<!--style="@style/setting_group_header"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content"-->
<!--android:text="@string/actions"-->
<!--/>-->
<!--<View style="@style/setting_divider"/>-->
<!--<TextView-->
<!--style="@style/setting_row_label"-->
<!--android:text="@string/actions"-->
<!--/>-->
<!--<LinearLayout style="@style/setting_row_form">-->
<!--<Button-->
<!--android:id="@+id/btnSettingExport"-->
<!--android:layout_width="wrap_content"-->
<!--android:layout_height="wrap_content"-->
<!--android:text="@string/"-->
<!--android:textAllCaps="false"-->
<!--/>-->
<!--</LinearLayout>-->
<!--<LinearLayout style="@style/setting_row_form">-->
<!--<Button-->
<!--android:id="@+id/btnSettingImport"-->
<!--android:layout_width="wrap_content"-->
<!--android:layout_height="wrap_content"-->
<!--android:text="@string/"-->
<!--android:textAllCaps="false"-->
<!--/>-->
<!--</LinearLayout>-->
<!--<LinearLayout style="@style/setting_row_form">-->
<!--<TextView-->
<!--android:layout_width="wrap_content"-->
<!--android:layout_height="wrap_content"-->
<!--android:text="@string/"-->
<!--android:textAllCaps="false"-->
<!--/>-->
<!--</LinearLayout>-->
<!--<View style="@style/setting_divider"/>-->
<!--</LinearLayout>-->
<!--</ListView>-->

View File

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
style="@style/setting_row_label"
android:id="@+id/tvCaption" />
<Button
android:id="@+id/btnAction"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/btn_bg_transparent_round6dp"
android:gravity="start|center_vertical"
android:minHeight="48dp"
android:paddingTop="6dp"
android:paddingBottom="6dp"
android:paddingStart="6dp"
android:textAllCaps="false" />
<CheckBox
android:id="@+id/checkBox"
style="@style/setting_row_form" />
<Switch
android:id="@+id/swSwitch"
style="@style/setting_row_form"
android:gravity="center"
android:minHeight="40dp"
/>
<Spinner
android:id="@+id/spSpinner"
style="@style/setting_row_form"
android:minHeight="40dp"
/>
<EditText
android:id="@+id/etEditText"
style="@style/setting_row_form"
android:gravity="center"
/>
<TextView
android:id="@+id/tvError"
style="@style/setting_row_form"
android:textColor="?attr/colorRegexFilterError"
/>
<TextView
android:id="@+id/textView1"
style="@style/setting_row_form" />
<LinearLayout
style="@style/setting_row_form"
android:id="@+id/llButtonBar"
android:orientation="horizontal"
android:gravity="center_vertical"
>
<Button
android:id="@+id/btnEdit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/edit"
android:textAllCaps="false"
/>
<Button
android:id="@+id/btnReset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/reset"
android:textAllCaps="false"
/>
<View android:id="@+id/vColor"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="8dp"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/llExtra"
android:orientation="vertical"
style="@style/setting_row_form">
</LinearLayout>
<TextView
style="@style/setting_row_form"
android:id="@+id/tvDesc"
/>
</LinearLayout>

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<FrameLayout
android:id="@+id/flColumnBackground"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="12dp">
<TextView
android:id="@+id/tvSampleAcct"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="start"
android:maxLines="1"
android:text="@string/acct_sample"
android:textColor="?attr/colorTimeSmall"
android:textSize="12sp" />
<jp.juggler.subwaytooter.view.MyTextView
android:id="@+id/tvSampleContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:gravity="start"
android:lineSpacingMultiplier="1.1"
android:text="@string/content_sample"
android:textColor="?attr/colorContentText" />
</LinearLayout>
</FrameLayout>
</merge>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:id="@+id/llColumnHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="6dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="12dp"
android:paddingTop="3dp"
android:paddingEnd="12dp"
android:paddingBottom="3dp">
<ImageView
android:id="@+id/ivColumnHeader"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginEnd="4dp"
android:importantForAccessibility="no"
android:src="@drawable/ic_bike" />
<TextView
android:id="@+id/tvColumnName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/federate_timeline" />
</LinearLayout>
</merge>

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/llFooterBG"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="?attr/colorColumnStripBackground"
android:orientation="horizontal">
<ImageView
android:id="@+id/ivFooterMenu"
android:layout_width="48dp"
android:layout_height="48dp"
android:importantForAccessibility="no"
android:src="@drawable/ic_hamburger" />
<View
android:id="@+id/vFooterDivider1"
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="?attr/colorImageButton" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<HorizontalScrollView
android:id="@+id/svColumnStrip"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:cacheColorHint="#00000000"
android:fadingEdge="horizontal"
android:fadingEdgeLength="20dp"
android:fillViewport="true"
android:scrollbars="none">
<LinearLayout
android:id="@+id/llColumnStrip"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
</LinearLayout>
</HorizontalScrollView>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<View
android:id="@+id/vFooterDivider2"
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="?attr/colorImageButton" />
<ImageView
android:id="@+id/ivFooterToot"
android:layout_width="48dp"
android:layout_height="48dp"
android:contentDescription="@string/toot"
android:src="@drawable/ic_edit" />
</LinearLayout>
<View
android:id="@+id/vIndicator"
android:layout_width="48dp"
android:layout_height="2dp"
android:layout_gravity="center_horizontal" />
</FrameLayout>
</merge>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/notification_on_off_desc" />
</merge>

View File

@ -130,11 +130,11 @@
<item name="android:orientation">horizontal</item>
<item name="android:baselineAligned">true</item>
<item name="android:paddingLeft">48dp</item>
<item name="android:paddingRight">0dp</item>
<item name="android:layout_marginLeft">32dp</item>
<item name="android:layout_marginRight">0dp</item>
<item name="android:paddingStart" tools:ignore="NewApi">48dp</item>
<item name="android:paddingEnd" tools:ignore="NewApi">0dp</item>
<item name="android:layout_marginStart" tools:ignore="NewApi">32dp</item>
<item name="android:layout_marginEnd" tools:ignore="NewApi">0dp</item>
</style>
@ -156,10 +156,10 @@
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:paddingLeft">12dp</item>
<item name="android:paddingLeft">0dp</item>
<item name="android:paddingRight">0dp</item>
<item name="android:paddingStart" tools:ignore="NewApi">12dp</item>
<item name="android:paddingStart" tools:ignore="NewApi">0dp</item>
<item name="android:paddingEnd" tools:ignore="NewApi">0dp</item>
<item name="android:textSize">14sp</item>

View File

@ -37,7 +37,7 @@ while(<$fh>){
my $branch=$1;
print "# branch=$branch\n";
$branch eq 'master'
or die "current branch is not master.\n";
or warn "!!!! current branch is not master !!!!\n";
# }else{
# warn "working tree is not clean.\n";
# cmd "git status";