Skip to content
Snippets Groups Projects

Patch to add image descriptions

Closed An Darna requested to merge andarna/pleroma-fe:patch-image-descriptions into develop
9 unresolved threads

Support for image descriptions in Pleroma Front-End

This patch adds support for image descriptions to Pleroma-FE. The basic functionality is there (adding descriptions) but there is currently no limit on the size of the description.

This addresses issue #136 (closed)

I have tested this by attaching 1, 2 and 3 image in the Pleroma FE and checking that the alt text shows up on the images in the timeline, as well as in the Mastodon web interface for Pleroma and for Mastodon. I also verified that alt text on existing images shows correctly.

Changes made to the Pleroma Front-End code:

For posting a status with images

  • Added code for text input field in components/post_status_form/post_status_form.vue.

      <div class="img-desc-container">
          <label for="imageDescription">{{$t('post_status.image_description')}}
          </label>
          <input type="text" id="imageDescription"     
              :placeholder="$t('post_status.image_description')"
              v-model="newStatus.imageDescriptions[file.id]"
              class="form-img-desc">
      </div>
  • This required a new entry image_description in i18n/en.json (other languages not done):

    "post_status": {
       ...
      "image_description": "Image description",
       ...
    }    
  • Added newStatus.imageDescriptions in components/post_status_form/post_status_form.js. I changed addMediaFile() so this map gets initially populated with the filename for each file id:

    addMediaFile (fileInfo) {      
        this.newStatus.files.push(fileInfo)
        this.newStatus.imageDescriptions[fileInfo.id]
          =  fileInfo.url.split('/').pop()
        this.enableSubmit()
    },
  • Changed postStatus in src/services/status_poster/status_poster.service.js and src/services/api/api.service.js to include the imageDescriptions map. The apiService adds this to the form to be osted:

      form.append('descriptions', JSON.stringify(imageDescriptions))

For displaying alt text on images

  • Changed the Attachment template in src/components/attachment/attachment.vue to add the image description to the StillImage as title and alt:

      <a v-if="type === 'image' && (!hidden || preloadImage)"
      class="image-attachment"
      :class="{'hidden': hidden && preloadImage}"
      :href="attachment.url"
      target="_blank" :title="attachment.description">
          <StillImage
          :class="{'small': isSmall}"
          v-bind:alt="attachment.description"
          v-bind:title="attachment.description"
          referrerpolicy="no-referrer"
          :mimetype="attachment.mimetype"
          :src="attachment.large_thumb_url || attachment.url"
          />
      </a>
  • Added imageDescription to data() in src/components/attachment/attachment.js but I think it is unused.

  • Changed the StillImage template in src/components/still-image/still-image.vue to add the image description to the StillImage as title and alt:

      <template>
            <div class='still-image' :class='{ animated: animated }' >
              <canvas ref="canvas" v-if="animated"></canvas>
              <img v-bind:alt="description"
              v-bind:title="description"
              ref="src" :src="src"
              :referrerpolicy="referrerpolicy"
              v-on:load="onLoad"
              />
            </div>
      </template>
  • Added description to props: in src/components/still-image/still-image.js

Changes made to the Pleroma Back-End code:

This is a separate patch, pleroma!626 (merged)

Most of the code was already in place, all I did was change the function attachments_from_ids() in lib/pleroma/web/common_api/utils.ex to take the image descriptions as argument and add them to the name field of the attachments.

def attachments_from_ids(ids, descs_str) do
  {_,descs}=Jason.decode(descs_str)
  Enum.map(ids || [], fn media_id ->
      Map.put(Repo.get(Object, media_id).data,"name",descs[media_id])
  end)
end

The call to this function in post() in CommonAPI (web/common_api/common_api.ex) was changed to take data["descriptions"] as a second argument.

def post(user, %{"status" => status} = data) do
    visibility = get_visibility(data)
    limit = Pleroma.Config.get([:instance, :limit])
    with status <- String.trim(status),
         attachments <- attachments_from_ids(data["media_ids"],data["descriptions"]),
         ...
Edited by An Darna

Merge request reports

Pipeline #5991 passed

Pipeline passed for 03f7c439 on andarna:patch-image-descriptions

Approval is optional

Closed by kaniinikaniini 6 years ago (Feb 18, 2019 6:27am UTC)

Merge details

  • The changes were not merged into develop.

Activity

Filter activity
  • Approvals
  • Assignees & reviewers
  • Comments (from bots)
  • Comments (from users)
  • Commits & branches
  • Edits
  • Labels
  • Lock status
  • Mentions
  • Merge request status
  • Tracking
18 18
19 19 return mentions.join(' ') + ' '
20 20 }
21
21 MediaUpload
  • 10 10 <a href="#" @click.prevent="toggleHidden()">Hide</a>
    11 11 </div>
    12 12 <a v-if="type === 'image' && (!hidden || preloadImage)" class="image-attachment" :class="{'hidden': hidden && preloadImage}" :href="attachment.url" target="_blank" :title="attachment.description">
    13 <StillImage :class="{'small': isSmall}" referrerpolicy="no-referrer" :mimetype="attachment.mimetype" :src="attachment.large_thumb_url || attachment.url"/>
    13 <StillImage :class="{'small': isSmall}" v-bind:alt="attachment.description" v-bind:title="attachment.description" referrerpolicy="no-referrer" :mimetype="attachment.mimetype" :src="attachment.large_thumb_url || attachment.url"/>
  • 1 1 const StillImage = {
    2 props: [
    3 'src',
    4 'referrerpolicy',
    5 'mimetype'
    6 ],
    2 props: {
    3 src: String,
    4 referrerpolicy: String,
    5 mimetype: String,
    6 description: String
  • 232 233 }
    233 234
    234 235 this.posting = true
    236
    235 237 statusPoster.postStatus({
    236 238 status: newStatus.status,
    237 239 spoilerText: newStatus.spoilerText || null,
    238 240 visibility: newStatus.visibility,
    239 241 sensitive: newStatus.nsfw,
    240 242 media: newStatus.files,
    243 imageDescriptions: newStatus.imageDescriptions || {}, // WV added
  • 85 85 <video v-if="type(file) === 'video'" :src="file.image" controls></video>
    86 86 <audio v-if="type(file) === 'audio'" :src="file.image" controls></audio>
    87 87 <a v-if="type(file) === 'unknown'" :href="file.image">{{file.url}}</a>
    88 </div>
    89 <div class="img-desc-container">
    90 <label for="imageDescription">{{$t('post_status.image_description')}}</label>
    • Indenting looks off here.

      I haven't yet checked out how it looks (screenshot would be nice), but I have a feeling that label shouldn't be necessary if there's already the placeholder text. Also perhaps better ux would probably be letting user set the descriptions after uploading for each attachment, but I think this way will do at first.

      Edited by Shpuld Shpludson
    • Maintainer

      removing pre-filled filename text would indeed make label obsolete

    • Please register or sign in to reply
  • 1 1 <template>
    2 2 <div class='still-image' :class='{ animated: animated }' >
    3 3 <canvas ref="canvas" v-if="animated"></canvas>
    4 <img ref="src" :src="src" :referrerpolicy="referrerpolicy" v-on:load="onLoad"/>
    4 <img v-bind:alt="description" v-bind:title="description" ref="src" :src="src" :referrerpolicy="referrerpolicy" v-on:load="onLoad"/>
  • HJ
    HJ @hj started a thread on the diff
  • 182 190 line-height: 1.2;
    183 191 padding: .5em;
    184 192 }
    193
    194 // WV: Copied from form-cw
  • 182 190 line-height: 1.2;
    183 191 padding: .5em;
    184 192 }
    193
    194 // WV: Copied from form-cw
    195 .form-img-desc {
  • Maintainer

    image image

    made some screenshots.

    Doesn't look too good but i guess this will do for now. I'd rather have descriptions overlay on image, but, more importantly only show the field after clicking some button like add a pencil next to a cross or something.

  • Maintainer

    At the very least - make so that text field is empty by default, having filename in there is confusing AF. BE should handle filename-as-description as it already does.

  • HJ
    HJ @hj started a thread on the diff
  • 263 267 },
    264 268 addMediaFile (fileInfo) {
    265 269 this.newStatus.files.push(fileInfo)
    270 this.newStatus.imageDescriptions[fileInfo.id] = fileInfo.url.split('/').pop() // WV: filename as default
  • Contributor

    An overlay wouldn't be too hard to do with CSS, but I think we should make the background reasonably solid (say 30% translucency max). There have been many complaints about the Mastodon FE captioning tool not being accessible to colorblind people due to the translucency on their overlay.

  • Maintainer

    ofc. Theming engine actually gives you hints on how good or bad color is even if it's transparent (it shows how bad contrast is/could get but doesn't factor in the noisiness of background tho)

  • Just went through this thread. I'm sure any changes all of you have suggested are for the better but for most of them I don't know how to do them. Is there anything I should really change to my patch so that someone else can take it further? You would do me a great favour if you'd notify me on wim_v12e@cybre.space .

    Edited by An Darna
  • kaniini mentioned in merge request !594 (closed)

    mentioned in merge request !594 (closed)

  • Contributor

    Superceded by !594 (closed).

  • closed

  • feld mentioned in commit pleroma@94e9c8f4

    mentioned in commit pleroma@94e9c8f4

  • Please register or sign in to reply
    Loading