package jp.juggler.subwaytooter import android.content.Intent import android.content.pm.PackageManager import android.graphics.drawable.StateListDrawable import android.text.Spannable import android.text.SpannableStringBuilder import android.text.style.ForegroundColorSpan import android.view.View import android.view.ViewGroup import android.widget.BaseAdapter import android.widget.FrameLayout import android.widget.ListView import android.widget.TextView import androidx.core.view.GravityCompat import androidx.drawerlayout.widget.DrawerLayout import jp.juggler.subwaytooter.action.Action_Account import jp.juggler.subwaytooter.action.Action_App import jp.juggler.subwaytooter.action.Action_Instance import jp.juggler.subwaytooter.table.SavedAccount import jp.juggler.util.createColoredDrawable import jp.juggler.util.getAttributeColor import org.jetbrains.anko.backgroundColor class SideMenuAdapter( val activity : ActMain, navigationView : ViewGroup, private val drawer : DrawerLayout ) : BaseAdapter() { private enum class ItemType(val id : Int) { IT_NORMAL(0), IT_GROUP_HEADER(1), IT_DIVIDER(2), IT_VERSION(3) } companion object { private val itemTypeCount = ItemType.values().size } private class Item( val title : Int = 0, val icon : Int = 0, val action : ActMain.() -> Unit = {} ) { internal val itemType : ItemType get() = when { title == 0 -> ItemType.IT_DIVIDER title == 1 -> ItemType.IT_VERSION icon == 0 -> ItemType.IT_GROUP_HEADER else -> ItemType.IT_NORMAL } } /* no title => section divider else no icon => section header with title else => menu item with icon and title */ private val list = arrayOf( Item(title = R.string.account), Item(title = R.string.account_add, icon = R.drawable.ic_account_add) { Action_Account.add(this) }, Item(icon = R.drawable.ic_settings, title = R.string.account_setting) { Action_Account.setting(this) }, Item(), Item(title = R.string.column), Item(icon = R.drawable.ic_list_numbered, title = R.string.column_list) { Action_App.columnList(this) }, Item(icon = R.drawable.ic_close, title = R.string.close_all_columns) { closeColumnAll() }, Item(icon = R.drawable.ic_home, title = R.string.home) { Action_Account.timeline(this, defaultInsertPosition, ColumnType.HOME) }, Item(icon = R.drawable.ic_announcement, title = R.string.notifications) { Action_Account.timeline(this, defaultInsertPosition, ColumnType.NOTIFICATIONS) }, Item(icon = R.drawable.ic_mail, title = R.string.direct_messages) { Action_Account.timeline(this, defaultInsertPosition, ColumnType.DIRECT_MESSAGES) }, Item(icon = R.drawable.ic_share, title = R.string.misskey_hybrid_timeline_long) { Action_Account.timeline(this, defaultInsertPosition, ColumnType.MISSKEY_HYBRID) }, Item(icon = R.drawable.ic_run, title = R.string.local_timeline) { Action_Account.timeline(this, defaultInsertPosition, ColumnType.LOCAL) }, Item(icon = R.drawable.ic_bike, title = R.string.federate_timeline) { Action_Account.timeline(this, defaultInsertPosition, ColumnType.FEDERATE) }, Item(icon = R.drawable.ic_list_list, title = R.string.lists) { Action_Account.timeline(this, defaultInsertPosition, ColumnType.LIST_LIST) }, Item(icon = R.drawable.ic_search, title = R.string.search) { Action_Account.timeline( this, defaultInsertPosition, ColumnType.SEARCH, args = arrayOf("", false) ) }, Item(icon = R.drawable.ic_hashtag, title = R.string.trend_tag) { Action_Account.timeline(this, defaultInsertPosition, ColumnType.TREND_TAG) }, Item(icon = R.drawable.ic_star, title = R.string.favourites) { Action_Account.timeline(this, defaultInsertPosition, ColumnType.FAVOURITES) }, Item(icon = R.drawable.ic_bookmark, title = R.string.bookmarks) { Action_Account.timeline(this, defaultInsertPosition, ColumnType.BOOKMARKS) }, Item(icon = R.drawable.ic_account_box, title = R.string.profile) { Action_Account.timeline(this, defaultInsertPosition, ColumnType.PROFILE) }, Item(icon = R.drawable.ic_follow_wait, title = R.string.follow_requests) { Action_Account.timeline(this, defaultInsertPosition, ColumnType.FOLLOW_REQUESTS) }, Item(icon = R.drawable.ic_follow_plus, title = R.string.follow_suggestion) { Action_Account.timeline(this, defaultInsertPosition, ColumnType.FOLLOW_SUGGESTION) }, Item(icon = R.drawable.ic_follow_plus, title = R.string.endorse_set) { Action_Account.timeline(this, defaultInsertPosition, ColumnType.ENDORSEMENT) }, Item(icon = R.drawable.ic_follow_plus, title = R.string.profile_directory) { Action_Instance.profileDirectoryFromSideMenu(this) }, Item(icon = R.drawable.ic_volume_off, title = R.string.muted_users) { Action_Account.timeline(this, defaultInsertPosition, ColumnType.MUTES) }, Item(icon = R.drawable.ic_block, title = R.string.blocked_users) { Action_Account.timeline(this, defaultInsertPosition, ColumnType.BLOCKS) }, Item(icon = R.drawable.ic_volume_off, title = R.string.keyword_filters) { Action_Account.timeline(this, defaultInsertPosition, ColumnType.KEYWORD_FILTER) }, Item(icon = R.drawable.ic_cloud_off, title = R.string.blocked_domains) { Action_Account.timeline(this, defaultInsertPosition, ColumnType.DOMAIN_BLOCKS) }, Item(icon = R.drawable.ic_timer, title = R.string.scheduled_status_list) { Action_Account.timeline(this, defaultInsertPosition, ColumnType.SCHEDULED_STATUS) }, Item(), Item(title = R.string.toot_search), Item(icon = R.drawable.ic_search, title = R.string.tootsearch) { addColumn(defaultInsertPosition, SavedAccount.na, ColumnType.SEARCH_TS, "") }, Item(), Item(title = R.string.setting), Item(icon = R.drawable.ic_settings, title = R.string.app_setting) { ActAppSetting.open(this, ActMain.REQUEST_CODE_APP_SETTING) }, Item(icon = R.drawable.ic_settings, title = R.string.highlight_word) { startActivity(Intent(this, ActHighlightWordList::class.java)) }, Item(icon = R.drawable.ic_volume_off, title = R.string.muted_app) { startActivity(Intent(this, ActMutedApp::class.java)) }, Item(icon = R.drawable.ic_volume_off, title = R.string.muted_word) { startActivity(Intent(this, ActMutedWord::class.java)) }, Item(icon = R.drawable.ic_volume_off, title = R.string.fav_muted_user) { startActivity(Intent(this, ActFavMute::class.java)) }, Item( icon = R.drawable.ic_volume_off, title = R.string.muted_users_from_pseudo_account ) { startActivity(Intent(this, ActMutedPseudoAccount::class.java)) }, Item(icon = R.drawable.ic_info, title = R.string.app_about) { startActivityForResult( Intent(this, ActAbout::class.java), ActMain.REQUEST_APP_ABOUT ) }, Item(icon = R.drawable.ic_info, title = 1) { App1.openCustomTab(this, "https://github.com/tateisu/SubwayTooter/releases") }, Item(icon = R.drawable.ic_info, title = R.string.oss_license) { startActivity(Intent(this, ActOSSLicense::class.java)) }, Item(icon = R.drawable.ic_hot_tub, title = R.string.app_exit) { finish() } ) private val iconColor = getAttributeColor(activity, R.attr.colorTimeSmall) private val currentVersion = try { val pInfo = activity.packageManager.getPackageInfo(activity.packageName, 0) pInfo.versionName } catch(ex : PackageManager.NameNotFoundException) { "??" } override fun getCount() : Int = list.size override fun getItem(position : Int) : Any = list[position] override fun getItemId(position : Int) : Long = 0L override fun getViewTypeCount() : Int = itemTypeCount override fun getItemViewType(position : Int) : Int = list[position].itemType.id private inline fun viewOrInflate( view : View?, parent : ViewGroup?, resId : Int ) : T = (view ?: activity.layoutInflater.inflate(resId, parent, false)) as? T ?: error("invalid view type! ${T::class.java.simpleName}") override fun getView(position : Int, view : View?, parent : ViewGroup?) : View = list[position].run { when(itemType) { ItemType.IT_DIVIDER -> viewOrInflate(view, parent, R.layout.lv_sidemenu_separator) ItemType.IT_GROUP_HEADER -> viewOrInflate(view, parent, R.layout.lv_sidemenu_group) .apply { text = activity.getString(title) } ItemType.IT_NORMAL -> viewOrInflate(view, parent, R.layout.lv_sidemenu_item) .apply { isAllCaps = false text = activity.getString(title) val drawable = createColoredDrawable(activity, icon, iconColor, 1f) setCompoundDrawablesRelativeWithIntrinsicBounds( drawable, null, null, null ) setOnClickListener { action(activity) drawer.closeDrawer(GravityCompat.START) } } ItemType.IT_VERSION -> viewOrInflate(view, parent, R.layout.lv_sidemenu_item).apply { text = SpannableStringBuilder().apply { val lastVersion = Pref.spVersionNameWhenReleaseNoteTap(activity.pref) if(lastVersion.isNotEmpty() && lastVersion != currentVersion) { append( activity.getString( R.string.release_notes_updated, lastVersion, currentVersion ) ) setSpan( ForegroundColorSpan( getAttributeColor( activity, R.attr.colorRegexFilterError ) ), 0, length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE ) } else { append( activity.getString( R.string.release_notes_latest, currentVersion ) ) } } isAllCaps = false val drawable = createColoredDrawable(activity, icon, iconColor, 1f) setCompoundDrawablesRelativeWithIntrinsicBounds( drawable, null, null, null ) setOnClickListener { activity.pref.edit() .put(Pref.spVersionNameWhenReleaseNoteTap, currentVersion) .apply() notifyDataSetChanged() action(activity) drawer.closeDrawer(GravityCompat.START) } } } } init { ListView(activity).apply { adapter = this@SideMenuAdapter layoutParams = FrameLayout.LayoutParams( FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT ) backgroundColor = getAttributeColor(activity, R.attr.colorWindowBackground) selector = StateListDrawable() divider = null dividerHeight = 0 val pad_tb = (activity.density * 12f + 0.5f).toInt() setPadding(0, pad_tb, 0, pad_tb) clipToPadding = false scrollBarStyle = ListView.SCROLLBARS_OUTSIDE_OVERLAY navigationView.addView(this) } } }