ハッシュタグカラムに追加のタグの指定を追加
This commit is contained in:
parent
778798d5c0
commit
d9bbc1f038
|
@ -178,6 +178,9 @@ class Column(
|
|||
private const val KEY_PROFILE_TAB = "tab"
|
||||
private const val KEY_STATUS_ID = "status_id"
|
||||
private const val KEY_HASHTAG = "hashtag"
|
||||
private const val KEY_HASHTAG_ANY = "hashtag_any"
|
||||
private const val KEY_HASHTAG_ALL = "hashtag_all"
|
||||
private const val KEY_HASHTAG_NONE = "hashtag_none"
|
||||
private const val KEY_SEARCH_QUERY = "search_query"
|
||||
private const val KEY_SEARCH_RESOLVE = "search_resolve"
|
||||
private const val KEY_INSTANCE_URI = "instance_uri"
|
||||
|
@ -240,6 +243,12 @@ class Column(
|
|||
return params[idx] as T
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private inline fun <reified T> getParamAtNullable(params : Array<out Any>, idx : Int) : T? {
|
||||
if(idx >= params.size) return null
|
||||
return params[idx] as T
|
||||
}
|
||||
|
||||
fun loadAccount(context : Context, src : JSONObject) : SavedAccount {
|
||||
val account_db_id = src.parseLong(KEY_ACCOUNT_ROW_ID) ?: - 1L
|
||||
return if(account_db_id >= 0) {
|
||||
|
@ -561,8 +570,13 @@ class Column(
|
|||
TYPE_DIRECT_MESSAGES -> "/api/v1/streaming/?stream=direct"
|
||||
|
||||
TYPE_HASHTAG -> when(instance_local) {
|
||||
true -> "/api/v1/streaming/?stream=" + Uri.encode("hashtag:local") + "&tag=" + hashtag.encodePercent()
|
||||
else -> "/api/v1/streaming/?stream=hashtag&tag=" + hashtag.encodePercent()
|
||||
true -> {
|
||||
"/api/v1/streaming/?stream=" + Uri.encode("hashtag:local") +
|
||||
"&tag=" + hashtag.encodePercent() + makeHashtagExtraQuery()
|
||||
}
|
||||
|
||||
else -> "/api/v1/streaming/?stream=hashtag&tag=" + hashtag.encodePercent() +
|
||||
makeHashtagExtraQuery()
|
||||
// タグ先頭の#を含まない
|
||||
}
|
||||
else -> null
|
||||
|
@ -622,8 +636,11 @@ class Column(
|
|||
|
||||
internal var search_query : String = ""
|
||||
internal var search_resolve : Boolean = false
|
||||
private var hashtag : String = ""
|
||||
internal var instance_uri : String = ""
|
||||
private var hashtag : String = ""
|
||||
internal var hashtag_any : String = ""
|
||||
internal var hashtag_all : String = ""
|
||||
internal var hashtag_none : String = ""
|
||||
|
||||
// プロフカラムでのアカウント情報
|
||||
@Volatile
|
||||
|
@ -834,7 +851,12 @@ class Column(
|
|||
profile_id = EntityId.mayNull(src.parseString(KEY_PROFILE_ID))
|
||||
}
|
||||
|
||||
TYPE_HASHTAG -> hashtag = src.optString(KEY_HASHTAG)
|
||||
TYPE_HASHTAG -> {
|
||||
hashtag = src.optString(KEY_HASHTAG)
|
||||
hashtag_any = src.optString(KEY_HASHTAG_ANY)
|
||||
hashtag_all = src.optString(KEY_HASHTAG_ALL)
|
||||
hashtag_none = src.optString(KEY_HASHTAG_NONE)
|
||||
}
|
||||
|
||||
TYPE_SEARCH -> {
|
||||
search_query = src.optString(KEY_SEARCH_QUERY)
|
||||
|
@ -899,7 +921,12 @@ class Column(
|
|||
TYPE_LIST_MEMBER, TYPE_LIST_TL ->
|
||||
dst.put(KEY_PROFILE_ID, profile_id.toString())
|
||||
|
||||
TYPE_HASHTAG -> dst.put(KEY_HASHTAG, hashtag)
|
||||
TYPE_HASHTAG -> {
|
||||
dst.put(KEY_HASHTAG, hashtag)
|
||||
dst.put(KEY_HASHTAG_ANY, hashtag_any)
|
||||
dst.put(KEY_HASHTAG_ALL, hashtag_all)
|
||||
dst.put(KEY_HASHTAG_NONE, hashtag_none)
|
||||
}
|
||||
|
||||
TYPE_SEARCH -> dst.put(KEY_SEARCH_QUERY, search_query).put(
|
||||
KEY_SEARCH_RESOLVE,
|
||||
|
@ -932,7 +959,12 @@ class Column(
|
|||
TYPE_CONVERSATION, TYPE_BOOSTED_BY, TYPE_FAVOURITED_BY, TYPE_LOCAL_AROUND, TYPE_FEDERATED_AROUND, TYPE_ACCOUNT_AROUND ->
|
||||
status_id == EntityId(getParamAt(params, 0))
|
||||
|
||||
TYPE_HASHTAG -> getParamAt<String>(params, 0) == hashtag
|
||||
TYPE_HASHTAG -> {
|
||||
(getParamAt<String>(params, 0) == hashtag)
|
||||
&& ((getParamAtNullable<String>(params, 1) ?: "") == hashtag_any)
|
||||
&& ((getParamAtNullable<String>(params, 2) ?: "") == hashtag_all)
|
||||
&& ((getParamAtNullable<String>(params, 3) ?: "") == hashtag_none)
|
||||
}
|
||||
|
||||
TYPE_SEARCH -> getParamAt<String>(params, 0) == search_query && getParamAt<Boolean>(
|
||||
params,
|
||||
|
@ -995,7 +1027,29 @@ class Column(
|
|||
(status_id?.toString() ?: "null")
|
||||
)
|
||||
|
||||
TYPE_HASHTAG -> context.getString(R.string.hashtag_of, hashtag)
|
||||
TYPE_HASHTAG -> {
|
||||
val sb = StringBuilder(context.getString(R.string.hashtag_of, hashtag))
|
||||
|
||||
if(hashtag_any.isNotBlank()) sb.append(' ').append(
|
||||
context.getString(
|
||||
R.string.hashtag_title_any,
|
||||
hashtag_any
|
||||
)
|
||||
)
|
||||
if(hashtag_all.isNotBlank()) sb.append(' ').append(
|
||||
context.getString(
|
||||
R.string.hashtag_title_all,
|
||||
hashtag_all
|
||||
)
|
||||
)
|
||||
if(hashtag_none.isNotBlank()) sb.append(' ').append(
|
||||
context.getString(
|
||||
R.string.hashtag_title_none,
|
||||
hashtag_none
|
||||
)
|
||||
)
|
||||
sb.toString()
|
||||
}
|
||||
|
||||
TYPE_SEARCH ->
|
||||
if(bLong) context.getString(R.string.search_of, search_query)
|
||||
|
@ -2998,14 +3052,12 @@ class Column(
|
|||
TYPE_HASHTAG -> return if(isMisskey) {
|
||||
getStatuses(
|
||||
client
|
||||
, makeHashtagUrl(hashtag)
|
||||
, misskeyParams = makeMisskeyTimelineParameter(parser)
|
||||
.put("tag", hashtag)
|
||||
.put("limit", MISSKEY_HASHTAG_LIMIT)
|
||||
, makeHashtagUrl()
|
||||
, misskeyParams = makeHashtagParams(parser)
|
||||
|
||||
)
|
||||
} else {
|
||||
getStatuses(client, makeHashtagUrl(hashtag))
|
||||
getStatuses(client, makeHashtagUrl())
|
||||
}
|
||||
|
||||
TYPE_REPORTS -> return parseReports(client, PATH_REPORTS)
|
||||
|
@ -3538,10 +3590,10 @@ class Column(
|
|||
}
|
||||
|
||||
private fun JSONObject.putMisskeyUntil(id : EntityId?) : JSONObject {
|
||||
if(id != null){
|
||||
if(useDate){
|
||||
put("untilDate" ,id.toString().toLong() )
|
||||
}else{
|
||||
if(id != null) {
|
||||
if(useDate) {
|
||||
put("untilDate", id.toString().toLong())
|
||||
} else {
|
||||
put("untilId", id.toString())
|
||||
}
|
||||
}
|
||||
|
@ -3549,10 +3601,10 @@ class Column(
|
|||
}
|
||||
|
||||
private fun JSONObject.putMisskeySince(id : EntityId?) : JSONObject {
|
||||
if(id != null){
|
||||
if(useDate){
|
||||
put("sinceDate" ,id.toString().toLong() )
|
||||
}else{
|
||||
if(id != null) {
|
||||
if(useDate) {
|
||||
put("sinceDate", id.toString().toLong())
|
||||
} else {
|
||||
put("sinceId", id.toString())
|
||||
}
|
||||
}
|
||||
|
@ -5014,13 +5066,11 @@ class Column(
|
|||
TYPE_HASHTAG -> if(isMisskey) {
|
||||
getStatusList(
|
||||
client
|
||||
, makeHashtagUrl(hashtag)
|
||||
, misskeyParams = makeMisskeyTimelineParameter(parser)
|
||||
.put("tag", hashtag)
|
||||
.put("limit", MISSKEY_HASHTAG_LIMIT)
|
||||
, makeHashtagUrl()
|
||||
, misskeyParams = makeHashtagParams(parser)
|
||||
)
|
||||
} else {
|
||||
getStatusList(client, makeHashtagUrl(hashtag))
|
||||
getStatusList(client, makeHashtagUrl())
|
||||
}
|
||||
|
||||
TYPE_SEARCH_MSP ->
|
||||
|
@ -5938,13 +5988,11 @@ class Column(
|
|||
TYPE_HASHTAG -> if(isMisskey) {
|
||||
getStatusList(
|
||||
client
|
||||
, makeHashtagUrl(hashtag)
|
||||
, misskeyParams = makeMisskeyTimelineParameter(parser)
|
||||
.put("tag", hashtag)
|
||||
.put("limit", MISSKEY_HASHTAG_LIMIT)
|
||||
, makeHashtagUrl()
|
||||
, misskeyParams = makeHashtagParams(parser)
|
||||
)
|
||||
} else {
|
||||
getStatusList(client, makeHashtagUrl(hashtag))
|
||||
getStatusList(client, makeHashtagUrl())
|
||||
}
|
||||
|
||||
TYPE_BOOSTED_BY -> getAccountList(
|
||||
|
@ -7001,22 +7049,46 @@ class Column(
|
|||
}
|
||||
}
|
||||
|
||||
private fun makeHashtagUrl(
|
||||
hashtag : String // 先頭の#を含まない
|
||||
) : String {
|
||||
private fun makeHashtagExtraQuery() : String {
|
||||
val sb = StringBuilder()
|
||||
hashtag_any.split(" ").filter { it.isNotEmpty() }.forEach {
|
||||
sb.append("&any[]=").append(it.encodePercent())
|
||||
}
|
||||
|
||||
hashtag_all.split(" ").filter { it.isNotEmpty() }.forEach {
|
||||
sb.append("&all[]=").append(it.encodePercent())
|
||||
}
|
||||
|
||||
hashtag_none.split(" ").filter { it.isNotEmpty() }.forEach {
|
||||
sb.append("&none[]=").append(it.encodePercent())
|
||||
}
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
private fun makeHashtagUrl() : String {
|
||||
return if(isMisskey) {
|
||||
"/api/notes/search_by_tag"
|
||||
} else {
|
||||
// hashtag : String // 先頭の#を含まない
|
||||
val sb = StringBuilder("/api/v1/timelines/tag/")
|
||||
.append(hashtag.encodePercent())
|
||||
.append("?limit=")
|
||||
.append(READ_LIMIT)
|
||||
.append("?limit=").append(READ_LIMIT)
|
||||
|
||||
if(with_attachment) sb.append("&only_media=true")
|
||||
if(instance_local) sb.append("&local=true")
|
||||
sb.toString()
|
||||
|
||||
sb
|
||||
.append(makeHashtagExtraQuery())
|
||||
.toString()
|
||||
}
|
||||
}
|
||||
|
||||
private fun makeHashtagParams(parser : TootParser) : JSONObject {
|
||||
return makeMisskeyTimelineParameter(parser)
|
||||
.put("tag", hashtag)
|
||||
.put("limit", MISSKEY_HASHTAG_LIMIT)
|
||||
}
|
||||
|
||||
private fun loadFilter2(client : TootApiClient) : ArrayList<TootFilter>? {
|
||||
if(access_info.isPseudo || access_info.isMisskey) return null
|
||||
val column_context = getFilterContext()
|
||||
|
|
|
@ -134,6 +134,12 @@ class ColumnViewHolder(
|
|||
private val etListName : EditText
|
||||
private val btnListAdd : View
|
||||
|
||||
private val llHashtagExtra :LinearLayout
|
||||
private val etHashtagExtraAny:EditText
|
||||
private val etHashtagExtraAll:EditText
|
||||
private val etHashtagExtraNone :EditText
|
||||
|
||||
|
||||
private val isPageDestroyed : Boolean
|
||||
get() = column == null || activity.isFinishing
|
||||
|
||||
|
@ -347,6 +353,13 @@ class ColumnViewHolder(
|
|||
btnQuickFilterVote = viewRoot.findViewById(R.id.btnQuickFilterVote)
|
||||
val llColumnSettingInside : LinearLayout = viewRoot.findViewById(R.id.llColumnSettingInside)
|
||||
|
||||
llHashtagExtra= viewRoot.findViewById(R.id.llHashtagExtra)
|
||||
etHashtagExtraAny= viewRoot.findViewById(R.id.etHashtagExtraAny)
|
||||
etHashtagExtraAll= viewRoot.findViewById(R.id.etHashtagExtraAll)
|
||||
etHashtagExtraNone= viewRoot.findViewById(R.id.etHashtagExtraNone)
|
||||
|
||||
|
||||
|
||||
btnQuickFilterAll.setOnClickListener(this)
|
||||
btnQuickFilterMention.setOnClickListener(this)
|
||||
btnQuickFilterFavourite.setOnClickListener(this)
|
||||
|
@ -438,27 +451,6 @@ class ColumnViewHolder(
|
|||
btnColumnClose.layoutParams.height = wh
|
||||
btnColumnClose.setPaddingRelative(pad, pad, pad, pad)
|
||||
|
||||
// 入力の追跡
|
||||
etRegexFilter.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(
|
||||
s : CharSequence,
|
||||
start : Int,
|
||||
count : Int,
|
||||
after : Int
|
||||
) {
|
||||
}
|
||||
|
||||
override fun onTextChanged(s : CharSequence, start : Int, before : Int, count : Int) {}
|
||||
|
||||
override fun afterTextChanged(s : Editable) {
|
||||
if(loading_busy) return
|
||||
activity.handler.removeCallbacks(proc_start_filter)
|
||||
if(isRegexValid()) {
|
||||
activity.handler.postDelayed(proc_start_filter, 666L)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
btnSearch.setOnClickListener(this)
|
||||
etSearch.setOnEditorActionListener(TextView.OnEditorActionListener { _, actionId, _ ->
|
||||
if(! loading_busy) {
|
||||
|
@ -470,14 +462,48 @@ class ColumnViewHolder(
|
|||
false
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
private val proc_start_filter = Runnable {
|
||||
if(! isPageDestroyed && isRegexValid()) {
|
||||
val column = this.column ?: return@Runnable
|
||||
column.regex_text = etRegexFilter.text.toString()
|
||||
// 入力の追跡
|
||||
etRegexFilter.addTextChangedListener(CustomTextWatcher{
|
||||
if(!isRegexValid()) return@CustomTextWatcher
|
||||
column?.regex_text = etRegexFilter.text.toString()
|
||||
activity.app_state.saveColumnList()
|
||||
column.startLoading()
|
||||
activity.handler.removeCallbacks(proc_start_filter)
|
||||
activity.handler.postDelayed(proc_start_filter, 666L)
|
||||
})
|
||||
|
||||
etHashtagExtraAny.addTextChangedListener(CustomTextWatcher{
|
||||
column?.hashtag_any = etHashtagExtraAny.text.toString()
|
||||
activity.app_state.saveColumnList()
|
||||
activity.handler.removeCallbacks(proc_start_filter)
|
||||
activity.handler.postDelayed(proc_start_filter, 666L)
|
||||
})
|
||||
|
||||
etHashtagExtraAll.addTextChangedListener(CustomTextWatcher{
|
||||
column?.hashtag_all = etHashtagExtraAll.text.toString()
|
||||
activity.app_state.saveColumnList()
|
||||
activity.handler.removeCallbacks(proc_start_filter)
|
||||
activity.handler.postDelayed(proc_start_filter, 666L)
|
||||
})
|
||||
|
||||
etHashtagExtraNone.addTextChangedListener(CustomTextWatcher{
|
||||
column?.hashtag_none = etHashtagExtraNone.text.toString()
|
||||
activity.app_state.saveColumnList()
|
||||
activity.handler.removeCallbacks(proc_start_filter)
|
||||
activity.handler.postDelayed(proc_start_filter, 666L)
|
||||
})
|
||||
}
|
||||
|
||||
private val proc_start_filter :Runnable = object: Runnable {
|
||||
override fun run() {
|
||||
if( isPageDestroyed ) return
|
||||
val column = this@ColumnViewHolder.column ?: return
|
||||
|
||||
if( loading_busy){
|
||||
activity.handler.removeCallbacks(this)
|
||||
activity.handler.postDelayed(this, 666L)
|
||||
}else {
|
||||
column.startLoading()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -659,6 +685,12 @@ class ColumnViewHolder(
|
|||
vg(llListList, column.column_type == Column.TYPE_LIST_LIST)
|
||||
vg(cbResolve, column.column_type == Column.TYPE_SEARCH)
|
||||
|
||||
vg(llHashtagExtra,column.column_type == Column.TYPE_HASHTAG && !column.isMisskey)
|
||||
etHashtagExtraAny.setText(column.hashtag_any)
|
||||
etHashtagExtraAll.setText(column.hashtag_all)
|
||||
etHashtagExtraNone.setText(column.hashtag_none)
|
||||
|
||||
|
||||
// tvRegexFilterErrorの表示を更新
|
||||
if(bAllowFilter) {
|
||||
isRegexValid()
|
||||
|
|
|
@ -15,6 +15,8 @@ import android.graphics.drawable.shapes.RectShape
|
|||
import android.os.Build
|
||||
import android.os.SystemClock
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.util.SparseArray
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
|
@ -285,3 +287,21 @@ fun DialogInterface.dismissSafe(){
|
|||
}
|
||||
}
|
||||
|
||||
class CustomTextWatcher(
|
||||
val callback: ()->Unit
|
||||
) : TextWatcher {
|
||||
|
||||
override fun beforeTextChanged(
|
||||
s : CharSequence,
|
||||
start : Int,
|
||||
count : Int,
|
||||
after : Int
|
||||
) {
|
||||
}
|
||||
|
||||
override fun onTextChanged(s : CharSequence, start : Int, before : Int, count : Int) {}
|
||||
|
||||
override fun afterTextChanged(s : Editable) {
|
||||
callback()
|
||||
}
|
||||
}
|
|
@ -154,6 +154,66 @@
|
|||
android:id="@+id/llColumnSettingInside"
|
||||
>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/llHashtagExtra"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:labelFor="@+id/etHashtagExtraAny"
|
||||
android:text="@string/hashtag_extra_any"
|
||||
android:textColor="?attr/colorColumnHeaderPageNumber"
|
||||
/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etHashtagExtraAny"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text"
|
||||
android:maxLines="1"
|
||||
android:scrollHorizontally="true"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:labelFor="@+id/etHashtagExtraAll"
|
||||
android:text="@string/hashtag_extra_all"
|
||||
android:textColor="?attr/colorColumnHeaderPageNumber"
|
||||
/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etHashtagExtraAll"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text"
|
||||
android:maxLines="1"
|
||||
android:scrollHorizontally="true"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:labelFor="@+id/etHashtagExtraNone"
|
||||
android:text="@string/hashtag_extra_none"
|
||||
android:textColor="?attr/colorColumnHeaderPageNumber"
|
||||
/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etHashtagExtraNone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text"
|
||||
android:maxLines="1"
|
||||
android:scrollHorizontally="true"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/cbDontCloseColumn"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -857,5 +857,11 @@
|
|||
<string name="releases">更新履歴</string>
|
||||
<string name="timezone">タイムゾーン (アプリ再起動が必要)</string>
|
||||
<string name="device_timezone">端末のタイムゾーン</string>
|
||||
<string name="hashtag_extra_any">追加のタグ:いずれかを含む (タグ指定に#をつけない)</string>
|
||||
<string name="hashtag_extra_all">追加のタグ:全てを含む (タグ指定に#をつけない)</string>
|
||||
<string name="hashtag_extra_none">追加のタグ:これらを除く (タグ指定に#をつけない)</string>
|
||||
<string name="hashtag_title_any">か %1$s</string>
|
||||
<string name="hashtag_title_all">と %1$s</string>
|
||||
<string name="hashtag_title_none">(%1$s を除く)</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -879,5 +879,11 @@
|
|||
<string name="releases">Releases</string>
|
||||
<string name="timezone">Time zone (app restart required)</string>
|
||||
<string name="device_timezone">Device time zone</string>
|
||||
<string name="hashtag_extra_any">Additional tags: any (tags without #)</string>
|
||||
<string name="hashtag_extra_all">Additional tags: all (tags without #)</string>
|
||||
<string name="hashtag_extra_none">Additional tags: none (tags without #)</string>
|
||||
<string name="hashtag_title_any">or %1$s</string>
|
||||
<string name="hashtag_title_all">and %1$s</string>
|
||||
<string name="hashtag_title_none">without %1$s</string>
|
||||
|
||||
</resources>
|
Loading…
Reference in New Issue