package jp.juggler.subwaytooter.actmain import android.app.AlertDialog import android.text.Spannable import android.view.View import android.widget.TextView import androidx.core.view.GravityCompat import jp.juggler.subwaytooter.ActMain import jp.juggler.subwaytooter.R import jp.juggler.subwaytooter.action.openColumnList import jp.juggler.subwaytooter.action.openPost import jp.juggler.subwaytooter.api.entity.TootAccountRef import jp.juggler.subwaytooter.api.entity.TootTag.Companion.findHashtagFromUrl import jp.juggler.subwaytooter.appsetting.appSettingRoot import jp.juggler.subwaytooter.column.Column import jp.juggler.subwaytooter.columnviewholder.ColumnViewHolder import jp.juggler.subwaytooter.columnviewholder.TabletColumnViewHolder import jp.juggler.subwaytooter.columnviewholder.ViewHolderHeaderBase import jp.juggler.subwaytooter.columnviewholder.ViewHolderItem import jp.juggler.subwaytooter.dialog.ActionsDialog import jp.juggler.subwaytooter.itemviewholder.ItemViewHolder import jp.juggler.subwaytooter.pref.* import jp.juggler.subwaytooter.span.MyClickableSpan import jp.juggler.subwaytooter.util.openCustomTab import jp.juggler.util.data.addTo import jp.juggler.util.data.cast import jp.juggler.util.data.notEmpty import jp.juggler.util.log.LogCategory import jp.juggler.util.log.showToast import java.util.concurrent.TimeUnit private val log = LogCategory("ActMainActions") fun ActMain.onBackPressedImpl() { // メニューが開いていたら閉じる if (drawer.isDrawerOpen(GravityCompat.START)) { drawer.closeDrawer(GravityCompat.START) return } // カラムが0個ならアプリを終了する if (appState.columnCount == 0) { finish() return } // カラム設定が開いているならカラム設定を閉じる if (closeColumnSetting()) { return } fun getClosableColumnList(): List { val visibleColumnList = ArrayList() phoneTab({ env -> try { appState.column(env.pager.currentItem)?.addTo(visibleColumnList) } catch (ex: Throwable) { log.e(ex, "getClosableColumnList failed.") } }, { env -> visibleColumnList.addAll(env.visibleColumns) }) return visibleColumnList.filter { !it.dontClose } } // カラムが1個以上ある場合は設定に合わせて挙動を変える when (PrefI.ipBackButtonAction.invoke(pref)) { PrefI.BACK_EXIT_APP -> finish() PrefI.BACK_OPEN_COLUMN_LIST -> openColumnList() PrefI.BACK_CLOSE_COLUMN -> { val closeableColumnList = getClosableColumnList() when (closeableColumnList.size) { 0 -> when { PrefB.bpExitAppWhenCloseProtectedColumn(pref) && PrefB.bpDontConfirmBeforeCloseColumn.invoke(pref) -> finish() else -> showToast(false, R.string.missing_closeable_column) } 1 -> closeColumn(closeableColumnList.first()) else -> showToast( false, R.string.cant_close_column_by_back_button_when_multiple_column_shown ) } } else /* PrefI.BACK_ASK_ALWAYS */ -> { val closeableColumnList = getClosableColumnList() val dialog = ActionsDialog() if (closeableColumnList.size == 1) { val column = closeableColumnList.first() dialog.addAction(getString(R.string.close_column)) { closeColumn(column, bConfirmed = true) } } dialog.addAction(getString(R.string.open_column_list)) { openColumnList() } dialog.addAction(getString(R.string.app_exit)) { finish() } dialog.show(this, null) } } } fun ActMain.onClickImpl(v: View) { when (v.id) { R.id.btnToot -> openPost() R.id.btnQuickToot -> performQuickPost(null) R.id.btnQuickTootMenu -> toggleQuickPostMenu() R.id.btnMenu -> if (!drawer.isDrawerOpen(GravityCompat.START)) { drawer.openDrawer(GravityCompat.START) } } } fun ActMain.onMyClickableSpanClickedImpl(viewClicked: View, span: MyClickableSpan) { // ビュー階層を下から辿って文脈を取得する var column: Column? = null var whoRef: TootAccountRef? = null var view = viewClicked loop@ while (true) { when (val tag = view.tag) { is ItemViewHolder -> { column = tag.column whoRef = tag.getAccount() break@loop } is ViewHolderItem -> { column = tag.ivh.column whoRef = tag.ivh.getAccount() break@loop } is ColumnViewHolder -> { column = tag.column whoRef = null break@loop } is ViewHolderHeaderBase -> { column = tag.column whoRef = tag.getAccount() break@loop } is TabletColumnViewHolder -> { column = tag.columnViewHolder.column break@loop } else -> when (val parent = view.parent) { is View -> view = parent else -> break@loop } } } val hashtagList = ArrayList().apply { try { val cs = viewClicked.cast()?.text if (cs is Spannable) { for (s in cs.getSpans(0, cs.length, MyClickableSpan::class.java)) { val li = s.linkInfo val pair = li.url.findHashtagFromUrl() if (pair != null) add(if (li.text.startsWith('#')) li.text else "#${pair.first}") } } } catch (ex: Throwable) { log.e(ex, "can't create hashtagList") } } val linkInfo = span.linkInfo openCustomTab( this, nextPosition(column), linkInfo.url, accessInfo = column?.accessInfo, tagList = hashtagList.notEmpty(), whoRef = whoRef, linkInfo = linkInfo ) } fun ActMain.themeDefaultChangedDialog() { val lpThemeDefaultChangedWarnTime = PrefL.lpThemeDefaultChangedWarnTime val ipUiTheme = PrefI.ipUiTheme val now = System.currentTimeMillis() // テーマが未定義でなければ警告しない if (pref.getInt(ipUiTheme.key, -1) != -1) { log.i("themeDefaultChangedDialog: theme was set.") return } // 頻繁には警告しない if (now - lpThemeDefaultChangedWarnTime.invoke(pref) < TimeUnit.DAYS.toMillis(60L)) { log.i("themeDefaultChangedDialog: avoid frequently check.") return } pref.edit().put(lpThemeDefaultChangedWarnTime, now).apply() // 色がすべてデフォルトなら警告不要 val customizedKeys = ArrayList() appSettingRoot.items.find { it.caption == R.string.color }?.scan { item -> item.pref?.let { p -> when { p == PrefS.spBoostAlpha -> Unit p.hasNonDefaultValue(pref) -> customizedKeys.add(p.key) } } } log.w("themeDefaultChangedDialog: customizedKeys=${customizedKeys.joinToString(",")}") if (customizedKeys.isEmpty()) { pref.edit().put(ipUiTheme, ipUiTheme.defVal).apply() return } AlertDialog.Builder(this) .setMessage(R.string.color_theme_changed) .setPositiveButton(android.R.string.ok, null) .show() }