mirror of
https://github.com/tateisu/SubwayTooter
synced 2025-01-28 01:29:23 +01:00
- 表記の変更:「ブロックしたドメイン」→ 「非表示にしたドメイン」
- 添付メディアのURLを本文に付与しない - 添付メディアがある時は本文がカラでも投稿できる - 添付メディアのサムネイル表示のフォーカスポイント対応
This commit is contained in:
parent
46ea96f591
commit
0c7bab2085
@ -12,8 +12,8 @@ android {
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 27
|
||||
|
||||
versionCode 221
|
||||
versionName "2.2.1"
|
||||
versionCode 222
|
||||
versionName "2.2.2"
|
||||
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
|
||||
|
@ -1442,17 +1442,17 @@ class ActPost : AppCompatActivity(), View.OnClickListener, PostAttachment.Callba
|
||||
showToast(this@ActPost, false, R.string.attachment_uploaded)
|
||||
|
||||
// 投稿欄の末尾に追記する
|
||||
val selStart = etContent.selectionStart
|
||||
val selEnd = etContent.selectionEnd
|
||||
val e = etContent.editableText
|
||||
val len = e.length
|
||||
val last_char = if(len <= 0) ' ' else e[len - 1]
|
||||
if(! CharacterGroup.isWhitespace(last_char.toInt())) {
|
||||
e.append(" ").append(a.text_url)
|
||||
} else {
|
||||
e.append(a.text_url)
|
||||
}
|
||||
etContent.setSelection(selStart, selEnd)
|
||||
// val selStart = etContent.selectionStart
|
||||
// val selEnd = etContent.selectionEnd
|
||||
// val e = etContent.editableText
|
||||
// val len = e.length
|
||||
// val last_char = if(len <= 0) ' ' else e[len - 1]
|
||||
// if(! CharacterGroup.isWhitespace(last_char.toInt())) {
|
||||
// e.append(" ").append(a.text_url)
|
||||
// } else {
|
||||
// e.append(a.text_url)
|
||||
// }
|
||||
// etContent.setSelection(selStart, selEnd)
|
||||
|
||||
}
|
||||
|
||||
|
@ -737,8 +737,14 @@ internal class ItemViewHolder(
|
||||
val url = ta.urlForThumbnail
|
||||
if(url != null && url.isNotEmpty()) {
|
||||
iv.visibility = View.VISIBLE
|
||||
iv.scaleType =
|
||||
if(Pref.bpDontCropMediaThumb(App1.pref)) ImageView.ScaleType.FIT_CENTER else ImageView.ScaleType.CENTER_CROP
|
||||
|
||||
iv.setFocusPoint( ta.focusX, ta.focusY )
|
||||
|
||||
if( Pref.bpDontCropMediaThumb(App1.pref) ){
|
||||
iv.scaleType = ImageView.ScaleType.FIT_CENTER
|
||||
}else{
|
||||
iv.setScaleTypeForMedia()
|
||||
}
|
||||
|
||||
val mediaType = ta.type
|
||||
when(mediaType) {
|
||||
|
@ -5,11 +5,23 @@ import android.content.SharedPreferences
|
||||
import org.json.JSONObject
|
||||
|
||||
import jp.juggler.subwaytooter.Pref
|
||||
import jp.juggler.subwaytooter.util.clipRange
|
||||
import jp.juggler.subwaytooter.util.parseLong
|
||||
import jp.juggler.subwaytooter.util.parseString
|
||||
|
||||
class TootAttachment(src : JSONObject) : TootAttachmentLike {
|
||||
|
||||
companion object {
|
||||
private fun parseFocusValue(parent : JSONObject?, key : String) : Float {
|
||||
if(parent != null) {
|
||||
val dv = parent.optDouble(key)
|
||||
if(dv.isFinite()) return clipRange(- 1f, 1f, dv.toFloat())
|
||||
}
|
||||
return 0f
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
val json : JSONObject
|
||||
|
||||
// ID of the attachment
|
||||
@ -33,6 +45,11 @@ class TootAttachment(src : JSONObject) : TootAttachmentLike {
|
||||
// ALT text (Mastodon 2.0.0 or later)
|
||||
override val description : String?
|
||||
|
||||
override val focusX : Float
|
||||
override val focusY : Float
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
override fun hasUrl(url : String) : Boolean = when(url) {
|
||||
this.preview_url, this.remote_url, this.url, this.text_url -> true
|
||||
else -> false
|
||||
@ -47,6 +64,10 @@ class TootAttachment(src : JSONObject) : TootAttachmentLike {
|
||||
preview_url = src.parseString("preview_url")
|
||||
text_url = src.parseString("text_url")
|
||||
description = src.parseString("description")
|
||||
|
||||
val focus = src.optJSONObject("meta")?.optJSONObject("focus")
|
||||
focusX = parseFocusValue(focus, "x")
|
||||
focusY = parseFocusValue(focus, "y")
|
||||
}
|
||||
|
||||
override val urlForThumbnail : String?
|
||||
|
@ -6,6 +6,9 @@ interface TootAttachmentLike{
|
||||
val description : String?
|
||||
val urlForThumbnail : String?
|
||||
|
||||
val focusX : Float
|
||||
val focusY : Float
|
||||
|
||||
fun hasUrl(url:String):Boolean
|
||||
|
||||
companion object {
|
||||
|
@ -17,6 +17,12 @@ class TootAttachmentMSP(
|
||||
override val urlForThumbnail : String?
|
||||
get() = preview_url
|
||||
|
||||
override val focusX : Float
|
||||
get() = 0f
|
||||
|
||||
override val focusY : Float
|
||||
get() = 0f
|
||||
|
||||
override fun hasUrl(url:String):Boolean = (url == this.preview_url)
|
||||
|
||||
companion object {
|
||||
|
@ -86,7 +86,9 @@ class PostHelper(
|
||||
val enquete_items = this.enquete_items
|
||||
var visibility = this.visibility ?: ""
|
||||
|
||||
if(content.isEmpty()) {
|
||||
val hasAttachment = attachment_list?.isNotEmpty() ?: false
|
||||
|
||||
if(!hasAttachment && content.isEmpty()) {
|
||||
showToast(activity, true, R.string.post_error_contents_empty)
|
||||
return
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Matrix
|
||||
import android.graphics.drawable.Animatable
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
@ -14,6 +15,7 @@ import android.util.AttributeSet
|
||||
import android.view.ViewGroup
|
||||
import android.support.v7.widget.AppCompatImageView
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.RequestManager
|
||||
@ -27,6 +29,7 @@ import com.bumptech.glide.request.transition.Transition
|
||||
|
||||
import jp.juggler.subwaytooter.Pref
|
||||
import jp.juggler.subwaytooter.util.LogCategory
|
||||
import jp.juggler.subwaytooter.util.clipRange
|
||||
|
||||
class MyNetworkImageView : AppCompatImageView {
|
||||
|
||||
@ -51,6 +54,7 @@ class MyNetworkImageView : AppCompatImageView {
|
||||
private var mTarget : BaseTarget<*>? = null
|
||||
|
||||
private val proc_load_image : Runnable = Runnable { loadImageIfNecessary() }
|
||||
private val proc_focus_point : Runnable = Runnable { updateFocusPoint() }
|
||||
|
||||
private var media_type_drawable : Drawable? = null
|
||||
private var media_type_bottom : Int = 0
|
||||
@ -111,7 +115,7 @@ class MyNetworkImageView : AppCompatImageView {
|
||||
return null
|
||||
}
|
||||
|
||||
private fun cancelLoading(defaultDrawable: Drawable?) {
|
||||
private fun cancelLoading(defaultDrawable : Drawable?) {
|
||||
|
||||
val d = drawable
|
||||
if(d is Animatable) {
|
||||
@ -137,10 +141,10 @@ class MyNetworkImageView : AppCompatImageView {
|
||||
}
|
||||
|
||||
// デフォルト画像かnull
|
||||
private fun getDefaultDrawable(context:Context?):Drawable? {
|
||||
return if(context!= null && mDefaultImageId != 0) {
|
||||
private fun getDefaultDrawable(context : Context?) : Drawable? {
|
||||
return if(context != null && mDefaultImageId != 0) {
|
||||
ContextCompat.getDrawable(context, mDefaultImageId)
|
||||
}else {
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
@ -163,7 +167,7 @@ class MyNetworkImageView : AppCompatImageView {
|
||||
cancelLoading(getDefaultDrawable(context))
|
||||
|
||||
// 非表示状態ならロードを延期する
|
||||
if(!isShown) return
|
||||
if(! isShown) return
|
||||
|
||||
var wrapWidth = false
|
||||
var wrapHeight = false
|
||||
@ -372,6 +376,7 @@ class MyNetworkImageView : AppCompatImageView {
|
||||
override fun onSizeChanged(w : Int, h : Int, oldw : Int, oldh : Int) {
|
||||
super.onSizeChanged(w, h, oldw, oldh)
|
||||
post(proc_load_image)
|
||||
post(proc_focus_point)
|
||||
}
|
||||
|
||||
override fun onLayout(changed : Boolean, left : Int, top : Int, right : Int, bottom : Int) {
|
||||
@ -419,7 +424,7 @@ class MyNetworkImageView : AppCompatImageView {
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
}
|
||||
|
||||
|
||||
// media type の描画
|
||||
val media_type_drawable = this.media_type_drawable
|
||||
if(media_type_drawable != null) {
|
||||
@ -466,4 +471,98 @@ class MyNetworkImageView : AppCompatImageView {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
private var focusX : Float = 0f
|
||||
private var focusY : Float = 0f
|
||||
|
||||
fun setFocusPoint(focusX : Float, focusY : Float) {
|
||||
// フォーカスポイントは上がプラスで下がマイナス
|
||||
// https://github.com/jonom/jquery-focuspoint#1-calculate-your-images-focus-point
|
||||
// このタイミングで正規化してしまう
|
||||
|
||||
this.focusX = clipRange(- 1f, 1f, focusX)
|
||||
this.focusY = - clipRange(- 1f, 1f, focusY)
|
||||
}
|
||||
|
||||
override fun setImageBitmap(bm : Bitmap?) {
|
||||
super.setImageBitmap(bm)
|
||||
updateFocusPoint()
|
||||
}
|
||||
|
||||
override fun setImageDrawable(drawable : Drawable?) {
|
||||
super.setImageDrawable(drawable)
|
||||
updateFocusPoint()
|
||||
}
|
||||
|
||||
private fun updateFocusPoint() {
|
||||
|
||||
// ビューのサイズが0より大きい
|
||||
val view_w = width.toFloat()
|
||||
val view_h = height.toFloat()
|
||||
if(view_w <= 0 || view_h <= 0) return
|
||||
|
||||
// 画像のサイズが0より大きい
|
||||
val drawable = this.drawable ?: return
|
||||
val drawable_w = drawable.intrinsicWidth.toFloat()
|
||||
val drawable_h = drawable.intrinsicHeight.toFloat()
|
||||
if(drawable_w <= 0 || drawable_h <= 0) return
|
||||
|
||||
when(scaleType) {
|
||||
ImageView.ScaleType.CENTER_CROP, ImageView.ScaleType.MATRIX -> {
|
||||
val view_aspect = view_w / view_h
|
||||
val drawable_aspect = drawable_w / drawable_h
|
||||
|
||||
if(drawable_aspect >= view_aspect) {
|
||||
// ビューより画像の方が横長
|
||||
val focus_x = this.focusX
|
||||
if(focus_x == 0f) {
|
||||
scaleType = ImageView.ScaleType.CENTER_CROP
|
||||
} else {
|
||||
val matrix = Matrix()
|
||||
val scale = view_h / drawable_h
|
||||
val delta = focus_x * ((drawable_w * scale) - view_w)
|
||||
log.d("updateFocusPoint x delta=$delta")
|
||||
matrix.postTranslate(drawable_w / - 2f, drawable_h / - 2f)
|
||||
matrix.postScale(scale, scale)
|
||||
matrix.postTranslate((view_w - delta) / 2f, view_h / 2f)
|
||||
scaleType = ImageView.ScaleType.MATRIX
|
||||
imageMatrix = matrix
|
||||
}
|
||||
} else {
|
||||
// ビューより画像の方が縦長
|
||||
val focus_y = this.focusY
|
||||
if(focus_y == 0f) {
|
||||
scaleType = ImageView.ScaleType.CENTER_CROP
|
||||
} else {
|
||||
val matrix = Matrix()
|
||||
val scale = view_w / drawable_w
|
||||
val delta = focus_y * ((drawable_h * scale) - view_h)
|
||||
matrix.postTranslate(drawable_w / - 2f, drawable_h / - 2f)
|
||||
matrix.postScale(scale, scale)
|
||||
matrix.postTranslate(view_w / 2f, (view_h - delta) / 2f)
|
||||
scaleType = ImageView.ScaleType.MATRIX
|
||||
imageMatrix = matrix
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
log.d("updateFocusPoint: scaleType not match.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun setScaleTypeForMedia() {
|
||||
when(scaleType) {
|
||||
ImageView.ScaleType.CENTER_CROP, ImageView.ScaleType.MATRIX -> {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
else -> {
|
||||
scaleType = ImageView.ScaleType.CENTER_CROP
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -650,10 +650,10 @@
|
||||
<string name="prior_chrome_custom_tabs">Chrome Custom Tabs を優先的に利用する</string>
|
||||
<string name="enable_speech">読み上げを有効にする</string>
|
||||
<string name="url_omitted">(URL略)</string>
|
||||
<string name="block_domain_that">\"%1$s\" ドメインをブロック</string>
|
||||
<string name="blocked_domains">ブロックしたドメイン</string>
|
||||
<string name="confirm_block_domain">ドメイン \"%1$s\" 全体をブロックします。よろしいですか?</string>
|
||||
<string name="confirm_unblock_domain">ドメイン \"%1$s\" のブロックを解除しますか?</string>
|
||||
<string name="block_domain_that">\"%1$s\" ドメインを非表示</string>
|
||||
<string name="blocked_domains">非表示にしたドメイン</string>
|
||||
<string name="confirm_block_domain">ドメイン \"%1$s\" を非表示にします。よろしいですか?</string>
|
||||
<string name="confirm_unblock_domain">ドメイン \"%1$s\" の非表示を解除しますか?</string>
|
||||
|
||||
<string name="text_to_speech_initializing">TextToSpeechの初期化中…</string>
|
||||
<string name="text_to_speech_initialize_failed">TextToSpeechの初期化に失敗。status=%1$s</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user