Skip to content

Commit 6d58f35

Browse files
committed
new CommonsImage component
1 parent 3f98e9d commit 6d58f35

File tree

8 files changed

+116
-22
lines changed

8 files changed

+116
-22
lines changed
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<template>
2+
<img
3+
:src="currentSrc"
4+
:alt="alt"
5+
:class="imageClass"
6+
@load="handleLoad"
7+
@error="handleError"
8+
v-bind="$attrs"
9+
/>
10+
</template>
11+
12+
<script setup>
13+
import { ref, watch, computed } from 'vue'
14+
15+
const props = defineProps({
16+
image: {
17+
type: [Object, String],
18+
required: true
19+
},
20+
width: {
21+
type: Number,
22+
default: 1280,
23+
// Use Commons standard thumbnail sizes for best performance (pre-cached):
24+
// 320, 640, 800, 1024, 1280, 2560
25+
// These sizes are already generated and cached by Wikimedia Commons
26+
},
27+
alt: {
28+
type: String,
29+
default: ''
30+
},
31+
imageClass: {
32+
type: String,
33+
default: ''
34+
}
35+
})
36+
37+
const emit = defineEmits(['load', 'error'])
38+
39+
const attemptIndex = ref(0)
40+
const hasLoaded = ref(false)
41+
42+
const imageName = computed(() => {
43+
return props.image?.entry?.name || props.image?.name || props.image
44+
})
45+
46+
const encodedName = computed(() => {
47+
return encodeURIComponent(imageName.value)
48+
})
49+
50+
// Use Special:Redirect for maximum compatibility
51+
// This works for all file types including TIFF, handles redirects, and performs format conversion
52+
const urlStrategies = computed(() => {
53+
const name = encodedName.value
54+
const width = props.width
55+
56+
return [
57+
// Strategy 1: Special:Redirect/file with width (works universally, handles TIFF → JPG conversion)
58+
`//commons.wikimedia.org/w/index.php?title=Special:Redirect/file/${name}&width=${width}`,
59+
60+
// Strategy 2: Special:Redirect/file without width (full size fallback)
61+
`//commons.wikimedia.org/w/index.php?title=Special:Redirect/file/${name}`
62+
]
63+
})
64+
65+
const currentSrc = computed(() => {
66+
return urlStrategies.value[attemptIndex.value]
67+
})
68+
69+
const handleLoad = () => {
70+
hasLoaded.value = true
71+
emit('load')
72+
}
73+
74+
const handleError = () => {
75+
// Try next strategy if available
76+
if (attemptIndex.value < urlStrategies.value.length - 1) {
77+
attemptIndex.value++
78+
} else {
79+
// All strategies failed
80+
emit('error')
81+
}
82+
}
83+
84+
// Reset attempt index when image changes
85+
watch(imageName, () => {
86+
attemptIndex.value = 0
87+
hasLoaded.value = false
88+
})
89+
</script>
90+

frontend/src/components/Vote/ImageReviewDialog.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<template>
22
<div class="vote-image-review-dialog">
33
<div class="vote-image-review-dialog-image-container">
4-
<img :src="getCommonsImageUrl(image)" class="vote-image-review-dialog-image" />
4+
<CommonsImage :image="image" :width="800" image-class="vote-image-review-dialog-image" />
55
</div>
66
<div class="vote-image-review-dialog-review-section">
77
<h3>{{ image.name.split('_').join(' ') }}</h3>
@@ -56,6 +56,7 @@ import { defineProps, defineExpose, ref, computed } from 'vue';
5656
// import { useI18n } from 'vue-i18n';
5757
import { CdxTextArea, CdxButton } from '@wikimedia/codex';
5858
import { getCommonsImageUrl } from '@/utils';
59+
import CommonsImage from '@/components/CommonsImage.vue';
5960
6061
import ImageIcon from 'vue-material-design-icons/Image.vue'
6162
import LinkIcon from 'vue-material-design-icons/Link.vue'

frontend/src/components/Vote/VoteEdit.vue

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
<heart />
5656
</div>
5757
<div class="gallery-image-container">
58-
<img :src="getCommonsImageUrl(image)" />
58+
<CommonsImage :image="image" :width="640" />
5959
</div>
6060
<div style="font-size: 14px; color: gray">
6161
<p>{{ $t('montage-voted-time', [dayjs.utc(image.date).fromNow()]) }}</p>
@@ -89,7 +89,7 @@
8989
<arrow-expand-all />
9090
</div>
9191
<div class="gallery-image-ranking-container">
92-
<img :src="getCommonsImageUrl(image)" />
92+
<CommonsImage :image="image" :width="640" />
9393
</div>
9494
<div class="gallery-footer">
9595
<h3 class="gallery-footer-name">
@@ -138,6 +138,7 @@ import jurorService from '@/services/jurorService'
138138
import alertService from '@/services/alertService'
139139
import dialogService from '@/services/dialogService'
140140
import { getCommonsImageUrl } from '@/utils'
141+
import CommonsImage from '@/components/CommonsImage.vue'
141142
142143
// Components
143144
import { CdxButton, CdxSelect } from '@wikimedia/codex'

frontend/src/components/Vote/VoteRanking.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
<arrow-expand-all />
3838
</div>
3939
<div class="vote-gallery-image-container">
40-
<img :src="getCommonsImageUrl(image)" />
40+
<CommonsImage :image="image" :width="640" />
4141
</div>
4242
<div class="vote-gallery-footer">
4343
<h3 class="vote-gallery-footer-name">
@@ -85,6 +85,7 @@ import jurorService from '@/services/jurorService'
8585
import alertService from '@/services/alertService'
8686
import dialogService from '@/services/dialogService'
8787
import { getCommonsImageUrl } from '@/utils'
88+
import CommonsImage from '@/components/CommonsImage.vue'
8889
8990
// Components
9091
import { VueDraggableNext as draggable } from 'vue-draggable-next'

frontend/src/components/Vote/VoteRating.vue

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
>
99
<div class="vote-image-container" :class="showSidebar ? 'with-sidebar' : ''">
1010
<cdx-progress-bar class="vote-image-progress-bar" v-if="imageLoading" />
11-
<img
12-
:class="`vote-image ${imageLoading ? 'vote-image-hide' : ''}`"
13-
:src="getCommonsImageUrl(rating.current)"
11+
<CommonsImage
12+
:image="rating.current"
13+
:width="1280"
14+
:image-class="`vote-image ${imageLoading ? 'vote-image-hide' : ''}`"
1415
@load="handleImageLoad"
1516
@error="handleImageLoad"
1617
/>
@@ -169,6 +170,7 @@ import { useRouter } from 'vue-router'
169170
import alertService from '@/services/alertService'
170171
import { getCommonsImageUrl } from '@/utils'
171172
173+
import CommonsImage from '@/components/CommonsImage.vue'
172174
import { CdxButton, CdxProgressBar } from '@wikimedia/codex'
173175
174176
import ImageIcon from 'vue-material-design-icons/Image.vue'

frontend/src/components/Vote/VoteYesNo.vue

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
>
99
<div class="vote-image-container" :class="showSidebar ? 'with-sidebar' : ''">
1010
<cdx-progress-bar class="vote-image-progress-bar" v-if="imageLoading" />
11-
<img
12-
:class="`vote-image ${imageLoading ? 'vote-image-hide' : ''}`"
13-
:src="getCommonsImageUrl(rating.current)"
11+
<CommonsImage
12+
:image="rating.current"
13+
:width="1280"
14+
:image-class="`vote-image ${imageLoading ? 'vote-image-hide' : ''}`"
1415
@load="handleImageLoad"
1516
@error="handleImageLoad"
1617
/>
@@ -170,6 +171,7 @@ import { useRouter } from 'vue-router'
170171
import alertService from '@/services/alertService'
171172
import { getCommonsImageUrl } from '@/utils'
172173
174+
import CommonsImage from '@/components/CommonsImage.vue'
173175
import { CdxButton, CdxProgressBar } from '@wikimedia/codex'
174176
175177
import ThumbUp from 'vue-material-design-icons/ThumbUp.vue'

frontend/src/utils.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,10 @@ export function getCommonsImageUrl(image, width = 1280) {
7272
const imageName = image.entry?.name || image.name || image
7373
const encodedName = encodeURIComponent(imageName)
7474

75-
// Use thumb.php for sized images (handles moves/redirects better)
76-
// Use Special:Redirect for full-size images
75+
// Use Special:Redirect which works universally for all file types including TIFF
76+
// It handles redirects for moved files and performs automatic format conversion
7777
if (width) {
78-
return `//commons.wikimedia.org/w/thumb.php?f=${encodedName}&w=${width}`
78+
return `//commons.wikimedia.org/w/index.php?title=Special:Redirect/file/${encodedName}&width=${width}`
7979
} else {
8080
return `//commons.wikimedia.org/w/index.php?title=Special:Redirect/file/${encodedName}`
8181
}

montage/imgutils.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
def make_mw_img_url(title, size=None):
1919
"""Returns a unicode object URL that handles file moves/renames on Wikimedia Commons.
2020
21-
Uses thumb.php for sized images (better redirect handling for moved files)
22-
and Special:Redirect for full-size images.
21+
Uses Special:Redirect which works for all file types including TIFF,
22+
handles redirects for moved files, and performs automatic format conversion.
2323
"""
2424
if isinstance(title, unicode):
2525
url_title = six.moves.urllib.parse.quote(title.encode('utf8'))
@@ -28,21 +28,18 @@ def make_mw_img_url(title, size=None):
2828
else:
2929
raise TypeError('image title must be bytes or unicode')
3030

31-
if size is None:
32-
# No size parameter = full size, use Special:Redirect
31+
if size is None or str(size).lower() == 'orig':
32+
# No size parameter = full size, use Special:Redirect without width
3333
return u'https://commons.wikimedia.org/w/index.php?title=Special:Redirect/file/%s' % url_title
3434
elif isinstance(size, int):
3535
width = size
3636
elif str(size).lower().startswith('sm'):
3737
width = 240
3838
elif str(size).lower().startswith('med'):
3939
width = 480
40-
elif str(size).lower() == 'orig':
41-
# 'orig' means full size, use Special:Redirect
42-
return u'https://commons.wikimedia.org/w/index.php?title=Special:Redirect/file/%s' % url_title
4340
else:
4441
raise ValueError('size expected one of "sm", "med", "orig",'
4542
' or an integer pixel value, not %r' % size)
4643

47-
# Use thumb.php for thumbnails - handles moved files better
48-
return u'https://commons.wikimedia.org/w/thumb.php?f=%s&w=%d' % (url_title, width)
44+
# Use Special:Redirect with width parameter - works universally for all formats
45+
return u'https://commons.wikimedia.org/w/index.php?title=Special:Redirect/file/%s&width=%d' % (url_title, width)

0 commit comments

Comments
 (0)