- 表記の変更:「ブロックしたドメイン」→ 「非表示にしたドメイン」

- 添付メディアのURLを本文に付与しない
- 添付メディアがある時は本文がカラでも投稿できる
- 添付メディアのサムネイル表示のフォーカスポイント対応
This commit is contained in:
tateisu 2018-03-10 04:54:03 +09:00
parent 46ea96f591
commit 0c7bab2085
9 changed files with 163 additions and 26 deletions

View File

@ -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"

View File

@ -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)
}

View File

@ -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) {

View File

@ -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?

View File

@ -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 {

View File

@ -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 {

View File

@ -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
}

View File

@ -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
}
}
}
}

View File

@ -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>