Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ testing = [
"django-rq>=2.5,<3.0",
"google-cloud-translate>=3.0.0",
"wagtail-modeladmin>=2.0,<3.0",
"coverage>=7.0,<8.0"
"coverage>=7.0,<8.0",
"wagtailmedia>=0.0.0,<2.0"
]
linting = [
"pre-commit>=4.2.0,<6"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import React, { FunctionComponent } from 'react';
import gettext from 'gettext';

interface MediaAPI {
result: {
id: number;
title: string;
edit_url: string;
};
}

interface MediaChooserProps {
adminBaseUrl: string;
mediaId: number | null;
}

const MediaChooser: FunctionComponent<MediaChooserProps> = ({
adminBaseUrl,
mediaId,
}) => {
const [mediaInfo, setMediaInfo] = React.useState<MediaAPI | null>(null);

React.useEffect(() => {
setMediaInfo(null);
if (mediaId) {
fetch(`${adminBaseUrl}media/chooser/${mediaId}/`)
.then((response) => response.json())
.then(setMediaInfo);
}
}, [mediaId]);

// Render
let classNames = ['chooser', 'media-chooser'];
let inner;
if (mediaId) {
if (mediaInfo) {
inner = (
<div className="chosen">
<div className="preview-media">
<strong>
{mediaInfo.result.title} (ID: {mediaInfo.result.id})
</strong>
</div>

<ul className="actions" style={{ listStyleType: 'none' }}>
<li>
<a
href={`${mediaInfo.result.edit_url}`}
className="edit-link button button-small button-secondary"
target="_blank"
rel="noopener noreferrer"
>
{gettext('Edit this media')}
</a>
</li>
</ul>
</div>
);
} else {
inner = <p>{gettext('Fetching media information...')}</p>;
}
} else {
classNames.push('blank');

inner = (
<div className="unchosen">
<button
type="button"
className="button action-choose button-small button-secondary"
>
{gettext('Choose a media')}
</button>
</div>
);
}

return <div className={classNames.join(' ')}>{inner}</div>;
};

export default MediaChooser;
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,12 @@ export interface SnippetChooserWidget {
}

export interface OtherWidgets {
type: 'text' | 'image_chooser' | 'document_chooser' | 'unknown';
type:
| 'text'
| 'image_chooser'
| 'document_chooser'
| 'media_chooser'
| 'unknown';
}

export interface SegmentCommon {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Avatar from '../../../common/components/Avatar';

import PageChooser from '../../../common/components/PageChooser';
import ImageChooser from '../../../common/components/ImageChooser';
import MediaChooser from '../../../common/components/MediaChooser';
import DocumentChooser from '../../../common/components/DocumentChooser';
import SnippetChooser from '../../../common/components/SnippetChooser';

Expand Down Expand Up @@ -705,6 +706,36 @@ const EditorSynchronisedValueSegment: FunctionComponent<
imageId={(override && override.value) || segment.value}
/>
);
} else if (widget.type == 'media_chooser') {
const onClickChangeMedia = () => {
return (window as any).ModalWorkflow({
url: (window as any).chooserUrls.mediaChooser,
onload: (window as any).MEDIA_CHOOSER_MODAL_ONLOAD_HANDLERS,
responses: {
mediaChosen: function (responseData: any) {
saveOverride(
segment,
responseData.id,
csrfToken,
dispatch
);
},
},
});
};
if (!isLocked) {
buttons.push(
<ActionButton onClick={onClickChangeMedia}>
{gettext('Change media')}
</ActionButton>
);
}
value = (
<MediaChooser
adminBaseUrl={adminBaseUrl}
mediaId={(override && override.value) || segment.value}
/>
);
} else if (widget.type == 'document_chooser') {
const onClickChangeDocument = () => {
(window as any).ModalWorkflow({
Expand Down Expand Up @@ -993,7 +1024,6 @@ const EditorSegmentList: FunctionComponent<EditorSegmentListProps> = ({
);
}
);

return <SegmentList>{segmentRendered}</SegmentList>;
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% extends "wagtailadmin/generic/edit.html" %}
{% load i18n wagtailadmin_tags %}
{% load i18n wagtailadmin_tags chooser_urls %}

{% block bodyclass %}page-editor{% endblock %}

Expand Down Expand Up @@ -49,12 +49,8 @@
{% block extra_js %}
{% include "wagtailadmin/pages/_editor_js.html" %}
<script>
if (typeof window.chooserUrls === "undefined") {
window.chooserUrls = {
imageChooser: "{% url "wagtailimages_chooser:choose" %}",
documentChooser: "{% url "wagtaildocs_chooser:choose" %}",
pageChooser: "{% url "wagtailadmin_choose_page" %}",
}
if (typeof window.chooserUrls === 'undefined') {
window.chooserUrls = {% get_chooser_urls as chooser_urls %}{{ chooser_urls|safe }};
}
</script>
<script src="{% url 'wagtail_localize:javascript_catalog' %}"></script>
Expand All @@ -65,6 +61,11 @@
<script src="{% versioned_static 'wagtaildocs/js/document-chooser-modal.js' %}"></script>
<script src="{% versioned_static 'wagtaildocs/js/document-chooser.js' %}"></script>
<script src="{% versioned_static 'wagtailadmin/js/chooser-modal.js' %}"></script>
{% wagtailmedia_is_installed as media_installed %}
{% if media_installed %}
<script src="{% versioned_static 'wagtailmedia/js/media-chooser-modal.js' %}"></script>
<script src="{% versioned_static 'wagtailmedia/js/tabs.js' %}"></script>
{% endif %}
<script src="{% versioned_static 'wagtailsnippets/js/snippet-chooser.js' %}"></script>
<script src="{% versioned_static 'wagtail_localize/js/wagtail-localize.js' %}"></script>
{% endblock %}
Expand Down
28 changes: 28 additions & 0 deletions wagtail_localize/templatetags/chooser_urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from contextlib import suppress

from django import template
from django.apps import apps
from django.urls import NoReverseMatch, reverse


register = template.Library()


@register.simple_tag
def wagtailmedia_is_installed():
return apps.is_installed("wagtailmedia")


@register.simple_tag
def get_chooser_urls():
urls = {
"imageChooser": reverse("wagtailimages_chooser:choose"),
"documentChooser": reverse("wagtaildocs_chooser:choose"),
"pageChooser": reverse("wagtailadmin_choose_page"),
}

if wagtailmedia_is_installed():
with suppress(NoReverseMatch):
urls["mediaChooser"] = reverse("wagtailmedia:chooser")

return urls
1 change: 1 addition & 0 deletions wagtail_localize/test/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
"wagtail.documents",
"wagtail.images",
"wagtail.search",
"wagtailmedia",
"wagtail.admin",
"wagtail.api.v2",
"wagtail.contrib.routable_page",
Expand Down
13 changes: 13 additions & 0 deletions wagtail_localize/views/edit_translation.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import polib

from django.apps import apps
from django.conf import settings
from django.contrib.admin.utils import quote
from django.contrib.auth import get_user_model
Expand Down Expand Up @@ -345,6 +346,12 @@ def widget_from_field(field):
"type": "text",
}

elif apps.is_installed("wagtailmedia"):
from wagtailmedia.models import AbstractMedia

if issubclass(field.related_model, AbstractMedia):
return {"type": "media_chooser"}

return {"type": "unknown"}

def widget_from_block(block, content_components=None):
Expand Down Expand Up @@ -406,6 +413,12 @@ def widget_from_block(block, content_components=None):
return widget_from_block(block.child_block, content_components[1:])
return widget_from_block(block.child_block)

elif apps.is_installed("wagtailmedia"):
from wagtailmedia.blocks import AudioChooserBlock, VideoChooserBlock

if isinstance(block, (AudioChooserBlock, VideoChooserBlock)):
return {"type": "media_chooser"}

return {"type": "unknown"}

if isinstance(field, StreamField):
Expand Down