package jp.juggler.subwaytooter import android.content.Context import android.content.SharedPreferences import android.graphics.Color import androidx.preference.PreferenceManager import jp.juggler.util.optInt fun Context.pref() : SharedPreferences = PreferenceManager.getDefaultSharedPreferences(this) @Suppress("EqualsOrHashCode") abstract class BasePref(val key : String, val defVal : T) { init { if(Pref.map[key] != null) error("Preference key duplicate: ${key}") else @Suppress("LeakingThis") Pref.map[key] = this } abstract fun put(editor : SharedPreferences.Editor, v : T) abstract fun invoke(pref : SharedPreferences) : T override fun equals(other : Any?) = this === other operator fun invoke(context : Context) : T = invoke(context.pref()) fun remove(e : SharedPreferences.Editor) : SharedPreferences.Editor = e.remove(key) fun removeDefault(pref : SharedPreferences, e : SharedPreferences.Editor) = if(pref.contains(key) && this.invoke(pref) == defVal) { e.remove(key) true }else { false } } fun SharedPreferences.Editor.remove(item : BasePref<*>) : SharedPreferences.Editor { item.remove(this) return this } class BooleanPref(key : String, defVal : Boolean) : BasePref(key, defVal) { override operator fun invoke(pref : SharedPreferences) : Boolean { return pref.getBoolean(key, defVal) } // put if value is not default, remove if value is same to default override fun put(editor : SharedPreferences.Editor, v : Boolean) { if(v == defVal) editor.remove(key) else editor.putBoolean(key, v) } } class IntPref(key : String, defVal : Int) : BasePref(key, defVal) { override operator fun invoke(pref : SharedPreferences) : Int { return pref.getInt(key, defVal) } override fun put(editor : SharedPreferences.Editor, v : Int) { if(v == defVal) editor.remove(key) else editor.putInt(key, v) } } class LongPref(key : String, defVal : Long) : BasePref(key, defVal) { override operator fun invoke(pref : SharedPreferences) : Long { return pref.getLong(key, defVal) } override fun put(editor : SharedPreferences.Editor, v : Long) { if(v == defVal) editor.remove(key) else editor.putLong(key, v) } } class FloatPref(key : String, defVal : Float) : BasePref(key, defVal) { override operator fun invoke(pref : SharedPreferences) : Float { return pref.getFloat(key, defVal) } override fun put(editor : SharedPreferences.Editor, v : Float) { if(v == defVal) editor.remove(key) else editor.putFloat(key, v) } } class StringPref( key : String, defVal : String, val skipImport : Boolean = false ) : BasePref(key, defVal) { override operator fun invoke(pref : SharedPreferences) : String { return pref.getString(key, defVal) ?: defVal } override fun put(editor : SharedPreferences.Editor, v : String) { if(v == defVal) editor.remove(key) else editor.putString(key, v) } fun toInt(pref : SharedPreferences) = invoke(pref).optInt() ?: defVal.toInt() } fun SharedPreferences.Editor.put(item : BooleanPref, v : Boolean) = this.apply { item.put(this, v) } fun SharedPreferences.Editor.put(item : StringPref, v : String) = this.apply { item.put(this, v) } fun SharedPreferences.Editor.put(item : IntPref, v : Int) = this.apply { item.put(this, v) } fun SharedPreferences.Editor.put(item : LongPref, v : Long) = this.apply { item.put(this, v) } fun SharedPreferences.Editor.put(item : FloatPref, v : Float) = this.apply { item.put(this, v) } object Pref { // キー名と設定項目のマップ。インポートやアプリ設定で使う val map = HashMap>() // boolean val bpDisableEmojiAnimation = BooleanPref( "disable_emoji_animation", false ) // val bpDisableFastScroller = BooleanPref("disable_fast_scroller", true, 0) // R.id.swDisableFastScroller) val bpDisableTabletMode = BooleanPref( "disable_tablet_mode", false ) val bpDontConfirmBeforeCloseColumn = BooleanPref( "DontConfirmBeforeCloseColumn", false ) val bpDontCropMediaThumb = BooleanPref( "DontCropMediaThumb", true ) val bpDontDuplicationCheck = BooleanPref( "dont_duplication_check", false ) val bpDontRefreshOnResume = BooleanPref( "dont_refresh_on_resume", false ) val bpDontRound = BooleanPref( "dont_round", false ) val bpDontScreenOff = BooleanPref( "dont_screen_off", false ) val bpDontUseActionButtonWithQuickTootBar = BooleanPref( "dont_use_action_button", false ) val bpDontUseStreaming = BooleanPref( "dont_use_streaming", false ) val bpEnableGifAnimation = BooleanPref( "enable_gif_animation", false ) val bpExitAppWhenCloseProtectedColumn = BooleanPref( "ExitAppWhenCloseProtectedColumn", false ) val bpMentionFullAcct = BooleanPref( "mention_full_acct", false ) val bpNotificationLED = BooleanPref( "notification_led", true ) val bpNotificationSound = BooleanPref( "notification_sound", true ) val bpNotificationVibration = BooleanPref( "notification_vibration", true ) val bpPostButtonBarTop = BooleanPref( "post_button_bar_at_top", true ) val bpPriorChrome = BooleanPref( "prior_chrome", true ) val bpDontUseCustomTabs = BooleanPref( "DontUseCustomTabs", false ) val bpPriorLocalURL = BooleanPref( "prior_local_url", false ) val bpQuickTootBar = BooleanPref( "quick_toot_bar", false ) val bpRelativeTimestamp = BooleanPref( "relative_timestamp", true ) val bpShortAcctLocalUser = BooleanPref( "short_acct_local_user", true ) val bpShowFollowButtonInButtonBar = BooleanPref( "ShowFollowButtonInButtonBar", false ) val bpSimpleList = BooleanPref( "simple_list", true ) val bpUseInternalMediaViewer = BooleanPref( "use_internal_media_viewer", true ) val bpShowAppName = BooleanPref( "show_app_name", false ) val bpShowLanguage = BooleanPref( "ShowLanguage", false ) val bpForceGap = BooleanPref( "force_gap", false ) val bpShareViewPool = BooleanPref( "ShareViewPool", true ) val bpAllowColumnDuplication = BooleanPref( "AllowColumnDuplication", true ) val bpAppendAttachmentUrlToContent = BooleanPref( "AppendAttachmentUrlToContent", false ) val bpVerticalArrangeThumbnails = BooleanPref( "VerticalArrangeThumbnails", false ) val bpDontShowPreviewCard = BooleanPref( "DontShowPreviewCard", false ) val bpScrollTopFromColumnStrip = BooleanPref( "ScrollTopFromColumnStrip", false ) val bpOpenSticker = BooleanPref( "InstanceTicker", // 歴史的な理由でキー名が異なる false ) val bpLinksInContextMenu = BooleanPref( "LinksInContextMenu", false ) val bpMoveNotificationsQuickFilter = BooleanPref( "MoveNotificationsQuickFilter", false ) val bpShowAcctInSystemNotification = BooleanPref( "ShowAcctInSystemNotification", false ) val bpShowLinkUnderline = BooleanPref( "ShowLinkUnderline", false ) val bpShowSearchClear = BooleanPref( "ShowSearchClear", false ) val bpDontRemoveDeletedToot = BooleanPref( "DontRemoveDeletedToot", false ) val bpDontShowColumnBackgroundImage = BooleanPref( "DontShowColumnBackgroundImage", false ) val bpCustomEmojiSeparatorZwsp = BooleanPref( "CustomEmojiSeparatorZwsp", false ) val bpShowTranslateButton = BooleanPref( "ShowTranslateButton", false ) val bpDirectoryLastActive = BooleanPref( "DirectoryLastActive", true ) val bpDirectoryFollowers = BooleanPref( "DirectoryFollowers", true ) val bpDirectoryTootCount = BooleanPref( "DirectoryTootCount", true ) val bpDirectoryNote = BooleanPref( "DirectoryNote", true ) val bpWarnHashtagAsciiAndNonAscii = BooleanPref( "WarnHashtagAsciiAndNonAscii", false ) val bpEnablePixelfed = BooleanPref( "EnablePixelfed", false ) val bpQuickTootOmitAccountSelection = BooleanPref( "QuickTootOmitAccountSelection", false ) val bpSeparateReplyNotificationGroup = BooleanPref( "SeparateReplyNotificationGroup", false ) val bpAlwaysExpandContextMenuItems = BooleanPref( "AlwaysExpandContextMenuItems", false ) val bpShowBookmarkButton = BooleanPref( "ShowBookmarkButton2", true ) val bpShowFilteredWord = BooleanPref( "ShowFilteredWord", false ) val bpEnableDomainTimeline = BooleanPref( "EnableDomainTimeline", false ) val bpDivideNotification = BooleanPref( "DivideNotification", false ) val bpHideFollowCount = BooleanPref( "HideFollowCount", false ) val bpEmojioneShortcode = BooleanPref( "EmojioneShortcode", true ) val bpEmojiPickerCloseOnSelected = BooleanPref( "EmojiPickerCloseOnSelected", true ) val bpCheckBetaVersion = BooleanPref( "CheckBetaVersion", false ) val bpIgnoreTextInSharedMedia = BooleanPref( "IgnoreTextInSharedMedia", false ) val bpEmojiPickerCategoryOther = BooleanPref( "EmojiPickerCategoryOther", false ) val bpInAppUnicodeEmoji = BooleanPref( "InAppUnicodeEmoji", true ) // int val ipBackButtonAction = IntPref("back_button_action", 0) @Suppress("unused") const val BACK_ASK_ALWAYS = 0 const val BACK_CLOSE_COLUMN = 1 const val BACK_OPEN_COLUMN_LIST = 2 const val BACK_EXIT_APP = 3 val ipUiTheme = IntPref("ui_theme", 0) // val ipResizeImage = IntPref("resize_image", 4) const val RC_SIMPLE = 0 const val RC_ACTUAL = 1 @Suppress("unused") const val RC_NONE = 2 val ipRepliesCount = IntPref("RepliesCount", RC_SIMPLE) val ipBoostsCount = IntPref("BoostsCount", RC_ACTUAL) val ipFavouritesCount = IntPref("FavouritesCount", RC_ACTUAL) val ipRefreshAfterToot = IntPref("refresh_after_toot", 0) const val RAT_REFRESH_SCROLL = 0 @Suppress("unused") const val RAT_REFRESH_DONT_SCROLL = 1 const val RAT_DONT_REFRESH = 2 @Suppress("unused") const val VS_BY_ACCOUNT = 0 const val VS_MASTODON = 1 const val VS_MISSKEY = 2 val ipVisibilityStyle = IntPref("ipVisibilityStyle", VS_BY_ACCOUNT) const val ABP_TOP = 0 @Suppress("unused") const val ABP_BOTTOM = 1 const val ABP_START = 2 const val ABP_END = 3 val ipAdditionalButtonsPosition = IntPref("AdditionalButtonsPosition", ABP_END) val ipFooterButtonBgColor = IntPref("footer_button_bg_color", 0) val ipFooterButtonFgColor = IntPref("footer_button_fg_color", 0) val ipFooterTabBgColor = IntPref("footer_tab_bg_color", 0) val ipFooterTabDividerColor = IntPref("footer_tab_divider_color", 0) val ipFooterTabIndicatorColor = IntPref("footer_tab_indicator_color", 0) val ipListDividerColor = IntPref("listDividerColor", 0) val ipLastColumnPos = IntPref("last_column_pos", - 1) val ipBoostButtonJustify = IntPref("ipBoostButtonJustify", 0) // 0=左,1=中央,2=右 private const val JWCP_DEFAULT = 0 const val JWCP_START = 1 const val JWCP_END = 2 val ipJustifyWindowContentPortrait = IntPref("JustifyWindowContentPortrait", JWCP_DEFAULT) // 0=default,1=start,2=end const val GSP_HEAD = 0 private const val GSP_TAIL = 1 val ipGapHeadScrollPosition = IntPref("GapHeadScrollPosition", GSP_TAIL) val ipGapTailScrollPosition = IntPref("GapTailScrollPosition", GSP_TAIL) val ipLinkColor = IntPref("LinkColor", 0) val ipSwitchOnColor = IntPref("SwitchOnColor", Color.BLACK or 0x0080ff) val ipButtonBoostedColor = IntPref("ButtonBoostedColor", 0) val ipButtonFavoritedColor = IntPref("ButtonFavoritedColor", 0) val ipButtonBookmarkedColor = IntPref("ButtonBookmarkedColor", 0) val ipButtonFollowingColor = IntPref("ButtonFollowingColor", 0) val ipButtonFollowRequestColor = IntPref("ButtonFollowRequestColor", 0) val ipButtonReactionedColor = IntPref("ButtonReactionedColor", 0) val ipStatusBarColor = IntPref("StatusBarColor", 0) val ipNavigationBarColor = IntPref("NavigationBarColor", 0) val ipTootColorUnlisted = IntPref("ipTootColorUnlisted", 0) val ipTootColorFollower = IntPref("ipTootColorFollower", 0) val ipTootColorDirectUser = IntPref("ipTootColorDirectUser", 0) val ipTootColorDirectMe = IntPref("ipTootColorDirectMe", 0) val ipEventBgColorBoost = IntPref("EventBgColorBoost", 0) val ipEventBgColorFavourite = IntPref("EventBgColorFavourite", 0) val ipEventBgColorBookmark = IntPref("EventBgColorBookmark", 0) val ipEventBgColorFollow = IntPref("EventBgColorFollow", 0) val ipEventBgColorMention = IntPref("EventBgColorMention", 0) val ipEventBgColorUnfollow = IntPref("EventBgColorUnfollow", 0) val ipEventBgColorReaction = IntPref("EventBgColorReaction", 0) val ipEventBgColorQuote = IntPref("EventBgColorQuote", 0) val ipEventBgColorVote = IntPref("EventBgColorVote", 0) val ipEventBgColorFollowRequest = IntPref("EventBgColorFollowRequest", 0) val ipEventBgColorStatus = IntPref("EventBgColorStatus", 0) val ipEventBgColorGap = IntPref("EventBgColorGap", 0) val ipCcdHeaderBg = IntPref("ipCcdHeaderBg", 0) val ipCcdHeaderFg = IntPref("ipCcdHeaderFg", 0) val ipCcdContentBg = IntPref("ipCcdContentBg", 0) val ipCcdContentAcct = IntPref("ipCcdContentAcct", 0) val ipCcdContentText = IntPref("ipCcdContentText", 0) val ipSearchBgColor = IntPref("SearchBgColor", 0) val ipAnnouncementsBgColor = IntPref("AnnouncementsBgColor", 0) val ipConversationMainTootBgColor = IntPref("ConversationMainTootBgColor", 0) val ipVerifiedLinkBgColor = IntPref("VerifiedLinkBgColor", 0) val ipVerifiedLinkFgColor = IntPref("VerifiedLinkFgColor", 0) // val ipTrendTagCountShowing = IntPref("TrendTagCountShowing", 0) // const val TTCS_WEEKLY = 0 // const val TTCS_DAILY = 1 // string val spColumnWidth = StringPref("ColumnWidth", "") val spMediaThumbHeight = StringPref("MediaThumbHeight", "") val spClientName = StringPref("client_name", "") val spQuoteNameFormat = StringPref("quote_name_format", "") val spAutoCWLines = StringPref("auto_cw_lines", "0") val spCardDescriptionLength = StringPref("CardDescriptionLength", "64") val spAvatarIconSize = StringPref("avatar_icon_size", "48") val spNotificationTlIconSize = StringPref("notification_tl_icon_size", "24") val spBoostButtonSize = StringPref("BoostButtonSize", "35") val spReplyIconSize = StringPref("ReplyIconSize", "24") val spHeaderIconSize = StringPref("HeaderIconSize", "24") val spStripIconSize = StringPref("StripIconSize", "30") // val spMediaSizeMax = StringPref("max_media_size", "8") // val spMovieSizeMax = StringPref("max_movie_size", "40") // val spMediaSizeMaxPixelfed = StringPref("MediaSizeMaxPixelfed", "15") val spTimelineFont = StringPref("timeline_font", "", skipImport = true) val spTimelineFontBold = StringPref("timeline_font_bold", "", skipImport = true) val spMspUserToken = StringPref("mastodon_search_portal_user_token", "") val spEmojiPickerRecent = StringPref("emoji_picker_recent", "") val spRoundRatio = StringPref("round_ratio", "33") val spBoostAlpha = StringPref("BoostAlpha", "60") val spScreenBottomPadding = StringPref("ScreenBottomPadding", "8") val spPullNotificationCheckInterval = StringPref("PullNotificationCheckInterval", "15") val spUserAgent = StringPref("UserAgent", "") val spMediaReadTimeout = StringPref("spMediaReadTimeout", "60") val spAgreedPrivacyPolicyDigest = StringPref("spAgreedPrivacyPolicyDigest", "") val spTimeZone = StringPref("TimeZone", "") val spQuickTootMacro = StringPref("QuickTootMacro", "") val spQuickTootVisibility = StringPref("QuickTootVisibility", "") val spTranslateAppComponent = StringPref("TranslateAppComponent", "") val spCustomShare1 = StringPref("CustomShare1", "") val spCustomShare2 = StringPref("CustomShare2", "") val spCustomShare3 = StringPref("CustomShare3", "") val spWebBrowser = StringPref("WebBrowser", "") val spTimelineSpacing = StringPref("TimelineSpacing", "") // long val lpTabletTootDefaultAccount = LongPref("tablet_toot_default_account", - 1L) // float val fpTimelineFontSize = FloatPref("timeline_font_size", Float.NaN) val fpAcctFontSize = FloatPref("acct_font_size", Float.NaN) val fpNotificationTlFontSize = FloatPref("notification_tl_font_size", Float.NaN) val fpHeaderTextSize = FloatPref("HeaderTextSize", Float.NaN) internal const val default_timeline_font_size = 14f internal const val default_acct_font_size = 12f internal const val default_notification_tl_font_size = 14f internal const val default_header_font_size = 14f }