-
-
Notifications
You must be signed in to change notification settings - Fork 388
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add UI for image-attachment "focus" #2620
Conversation
…s. Choose "Set focus" in the attachment menu, tap once to select focus point (no visual feedback currently), tap "OK". Works in tests.
@@ -324,11 +325,12 @@ class ComposeViewModel @Inject constructor( | |||
return combineLiveData(deletionObservable, sendFlow.asLiveData()) { _, _ -> } | |||
} | |||
|
|||
suspend fun updateDescription(localId: Int, description: String): Boolean { | |||
// Updates a QueuedMedia item arbitrarily, then sends description and focus to server | |||
suspend fun updateMediaItem(localId: Int, mutator: (QueuedMedia) -> QueuedMedia): Boolean { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be private?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes
Commit 613358e removes the code duplication in ComposeViewModel which I wanted, removes the function duplication in MastodonApi which Conny wanted, and has now been aggressively tested (IE change caption then focus, change focus then caption, change both more than once, everything is correct in the end) |
Refocusing thumbnails and visual feedback definitely, the third is not that important for a first version. Maybe also show the selected focus point on the thumbnail? How about a simple circle in primary color with theme background color as outline as indicator?
I like "set focus point" most.
I think fullscreen would be better, but it isn't important.
If you want, definitely not needed for a first version |
… ProgressImageView now inherits from MediaPreviewImageView.
The attachment previews in the compose view now focus properly where appropriate. ProgressImageView now inherits from MediaPreviewImageView to accomplish this. I also discovered Attachment.Focus and replaced my uses of PointF with it. |
… on code from RoundedCorners builtin from Glide
Now have "previews" working, a focus is drawn when you tap in the focus-set dialog and in the normal message view the attachment previews center on the focus points. I styled the preview in the dialog to look as much as possible like the equivalent dialog in Mastodon.social web client (I think it looks good, though it's too bad the "center point" is always white since it's not visible on a white background. (Maybe it should be drawn as an inversion? But that might look uglier than it just sometimes not being visible)). Click for full versions: I am going to take this PR out of draft mode because I think this is the "minimum viable" version of the feature, but it is still pretty janky and it may be worth more improvements before merging. Warning, I am not sure I can fix all of the remaining steps myself with my current knowledge of Android GUI and the codebase. I think the remaining "should happen before putting this in a release" are:
Feedback welcomed on message text / how the focus selection looks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
asdfadsffg i didn't mean to click this button
import java.security.MessageDigest | ||
import java.util.concurrent.locks.Lock | ||
|
||
// Private, but necessary to implement BitmapTransformation, function extracted from Glide |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file now contains rather a lot of code adapted from Glide. There was no sample code for creating a custom BitmapTransformation in their docs so I used the RoundedCorners class and the TransformationUtils.roundedCorners method as bases. getAlphaSafeBitmap
and getAlphaSafeConfig
are taken direct from Glide TransformationUtils (but converted to Kotlin) and the "boilerplate" methods are almost identical to the ones from RoundedCorners. I do not think this introduces license issues because (1) we are already bound to the Glide license and (2) the code taken is "minimal" in the sense that it practically could not be any different than it is.
I am going to file a bug on Glide asking them to make getAlphaSafeBitmap and getAlphaSafeConfig public methods as I do not think it is possible to implement a BitmapTransformation without them.
val strokePaint = Paint(Paint.ANTI_ALIAS_FLAG) | ||
strokePaint.setAntiAlias(true) | ||
strokePaint.setStyle(Paint.Style.STROKE) | ||
val strokeWidth = 10.0f |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As described above this should not be a fixed number
val result = pool[toTransform.width, toTransform.height, safeConfig] | ||
|
||
val plainPaint = Paint() | ||
val strokePaint = Paint(Paint.ANTI_ALIAS_FLAG) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very unclear if ANTI_ALIAS_FLAG is required, I tried it both ways and I THINK it looks better with but it's hard to tell
} | ||
|
||
if (!toTransform.equals(inBitmap)) { | ||
pool.put(toTransform) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am very, VERY confused if this is desirable or not. I think it's good because this will cache the image with the circle/shadow drawn on so if the set focus dialog is opened a second time it will open faster.
…editor looks and feels right
Took in Conny's commit and I think this is mergeable? One last question: |
curtainPaint.style = Paint.Style.FILL | ||
|
||
strokePaint.setStyle(Paint.Style.STROKE) | ||
strokePaint.setStrokeWidth(strokeWidth) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this be in display-independent pixels or do I need to add * getResources().getDisplayMetrics().density
?
EDIT: RESOLVED, it's not display-independent
Is it possible to apply the focus point to the preview in the compose dialog? (could be a followup after merging) |
It does this as of 7b3fd74, there is no unique indicator that a focus is present but the preview image does focus at the appropriate point |
Oh, I think I see - is it possible that the focal point is getting reversed in this scenario? Here, I'm setting the focal point in the upper left, and the preview is panning to the right edge. (This is against f4e4f8b ) |
…behaves on wide aspect ratio screens)
@Tak Ahh, thank you, good catch-- the X axis was inverted but the testcase I used on the previous push only tested the Y axis...! I have a fix which I will push tomorrow. |
…nd drafts (but draft focus is lost on post)
…posted in that order
@@ -169,6 +170,7 @@ class ComposeActivity : | |||
uriNew, | |||
size, | |||
itemOld.description, | |||
null, // Intentionally reset focus when cropping |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the best approach? We could do something weird where we try to calculate where/whether the focal point is within the cropped area, but this feels like second guessing the user so I just reset.
@@ -185,7 +187,7 @@ class ComposeViewModel @Inject constructor( | |||
return mediaItem | |||
} | |||
|
|||
private fun addUploadedMedia(id: String, type: QueuedMedia.Type, uri: Uri, description: String?) { | |||
private fun addUploadedMedia(id: String, type: QueuedMedia.Type, uri: Uri, description: String?, focus: Attachment.Focus?) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Long term observation: Adding focus to "travel along with" description when attachments hibernate/resurrect required adding plumbing in a LOT of places. It might make more sense to make a "Metadata" struct like the one already in Attachment and pass that around instead of description (although not Attachment.Meta itself, as that includes "duration", a metadata returned from the server but not tracked by us when composing attachments), in case later there is some third thing that we track per attachment (a low res version, I don't know)
holder.imageView.setImageResource(R.drawable.ic_music_box_preview_24dp) | ||
} else { | ||
Glide.with(holder.itemView.context) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Long term observation: This clause has (and had before I started changing it) significant code duplication VS MediaPreviewAdapter. Maybe it's worth a refactor here
New changes:
Will post some screenshots of the new window sizing after I fix merging and do some exhaustive tests. |
I've tested this version and I think it is a candidate for merging. The only remaining issues/questions:
|
It works so well now, I love it. Thank you very much.
We had the same problem for the caption dialog, see here how it was fixed. It is no big deal though.
You mean the "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails." that the web interface has? Would be nice, yes but it is also no blocker for merging this. Android studio gives me a lot of code style warnings, can you fix those please? It is mostly property access syntax vs getter/setter and Kotlin functions instead of java |
I'm finding it a little hard to get full lists of Android Studio warnings, but I think those last two commits fix all the warnings in code the PR touches. I left some warnings as-is:
I also explicitly @SuppressLint'd and commented an accessibility warning because FocusIndicatorView implements a touch event but not the "click" event from the screen reader and there's legitimately nothing that can be done with the screen reader click. FocusIndicatorView interaction is not meaningful without an x,y position. If there's something better I should do here instead (implement performClick but return false because we didn't handle it? hide focus select from screen readers completely? or is there actually a way to make this pane accessible?) I'd be happy to do that instead. I wouldn't mind trying to replicate the CaptionDialog refactor at some later point, but I'd prefer to merge this PR first so that the PR does not develop conflicts with the develop branch. |
I'm not sure. I'd leave it for now and wait for feedback from people using Tusky with screenreaders. |
Choose "Set focus" in the attachment menu, tap once to select focus point, tap "OK". Has been successfully tested with mastodon.social (image has two identical very tall image attachments, but in one the focus point is set near the top and in the other it is set near the bottom).
Currently very ugly, no visual feedback of where/whether you tapped and I think a naive user would be totally confused by what the dialog even does:See new screenshotsBut, it works, so should be a good starting point for a more complete attempt.
Things I think should change before submit:
Thumbnails in compose view should refocus on focus pointSome visual feedback of tap, a bullseye or somethingI need to do more aggressive testing (changing focus points multiple times, changing caption before and after etc)Things I'm 50% sure should change before submit:
It would be nice if you could drag a finger to move around the focus point instead of only taps working (this may require replacing chrisbanes.photoview)Currently if you tap outside the photo view (like slightly to the right or left) the tap does not register. That's very bad (may require replacing chrisbanes.photoview)LATE EDIT IN: Circle thickness is a fixed 10 pixels, but in my testing (see below) this appears to be relative to the underlying image. It should be a fixed thickness relative to the screen size.Things I'm not sure about at all:
What should the menu item say? Currently it's "Set focus". Would something like "Image focus" or "Set focus point" be better?TODO item in ComposeViewModel.ktLATE EDIT IN: If you zoom in, then tap, it zooms all the way back out. This is functionally kind of good but feels "janky".