diff --git a/app/apps/api/serializers.py b/app/apps/api/serializers.py index e69add839008d6dc165a8575f89a6b53b472510a..220b4642cad65332ddbcfe54e75cdc545788d109 100644 --- a/app/apps/api/serializers.py +++ b/app/apps/api/serializers.py @@ -19,6 +19,7 @@ from core.models import (Document, LineTranscription, BlockType, LineType, + Script, OcrModel) from core.tasks import (segtrain, train, segment, transcribe) @@ -51,6 +52,12 @@ class ImageField(serializers.ImageField): return data +class ScriptSerializer(serializers.ModelSerializer): + class Meta: + model = Script + fields = '__all__' + + class PartMoveSerializer(serializers.ModelSerializer): index = serializers.IntegerField() @@ -99,6 +106,8 @@ class LineTypeSerializer(serializers.ModelSerializer): class DocumentSerializer(serializers.ModelSerializer): + main_script = serializers.SlugRelatedField(slug_field='name', + queryset=Script.objects.all()) transcriptions = TranscriptionSerializer(many=True, read_only=True) valid_block_types = BlockTypeSerializer(many=True, read_only=True) valid_line_types = LineTypeSerializer(many=True, read_only=True) @@ -106,12 +115,18 @@ class DocumentSerializer(serializers.ModelSerializer): class Meta: model = Document - fields = ('pk', 'name', 'transcriptions', + fields = ('pk', 'name', 'transcriptions', 'main_script', 'read_direction', 'valid_block_types', 'valid_line_types', 'parts_count') def get_parts_count(self, document): return document.parts.count() + def validate_main_script(self, value): + try: + return Script.objects.get(name=value) + except Script.DoesNotExist: + raise serializers.ValidationError('This script does not exists in the database.') + class PartSerializer(serializers.ModelSerializer): image = ImageField(required=False, thumbnails=['card', 'large']) @@ -133,7 +148,8 @@ class PartSerializer(serializers.ModelSerializer): 'workflow', 'order', 'recoverable', - 'transcription_progress' + 'transcription_progress', + 'source' ) def create(self, data): diff --git a/app/apps/api/urls.py b/app/apps/api/urls.py index 5c68c75144c91691322606062c09a3df48437534..928ec985a8265e478e0bdf05e380b396641746cc 100644 --- a/app/apps/api/urls.py +++ b/app/apps/api/urls.py @@ -11,9 +11,11 @@ from api.views import (DocumentViewSet, BlockTypeViewSet, LineTypeViewSet, LineTranscriptionViewSet, + ScriptViewSet, OcrModelViewSet) router = routers.DefaultRouter() +router.register(r'scripts', ScriptViewSet) router.register(r'documents', DocumentViewSet) router.register(r'user', UserViewSet) router.register(r'types/block', BlockTypeViewSet) diff --git a/app/apps/api/views.py b/app/apps/api/views.py index 23722ea8683c7e712fc6e4761100ada5eac108f5..f33ba76d4db9f3d9c3e0acd681d53083e812252e 100644 --- a/app/apps/api/views.py +++ b/app/apps/api/views.py @@ -11,7 +11,7 @@ from django.urls import reverse from rest_framework.decorators import action from rest_framework.response import Response from rest_framework import status -from rest_framework.viewsets import ModelViewSet +from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet from rest_framework.pagination import PageNumberPagination from rest_framework.serializers import PrimaryKeyRelatedField @@ -31,6 +31,7 @@ from api.serializers import (UserOnboardingSerializer, SegmentSerializer, TrainSerializer, SegTrainSerializer, + ScriptSerializer, TranscribeSerializer, OcrModelSerializer) @@ -43,6 +44,7 @@ from core.models import (Document, Transcription, LineTranscription, OcrModel, + Script, AlreadyProcessingException) from core.tasks import recalculate_masks @@ -67,6 +69,12 @@ class UserViewSet(ModelViewSet): return Response(status=status.HTTP_200_OK) +class ScriptViewSet(ReadOnlyModelViewSet): + queryset = Script.objects.all() + paginate_by = 20 + serializer_class = ScriptSerializer + + class DocumentViewSet(ModelViewSet): queryset = Document.objects.all() serializer_class = DocumentSerializer diff --git a/app/apps/core/models.py b/app/apps/core/models.py index 680f26f313b5a88b18c3f5133f0737c4cf062fef..9299c1bcd024634896fdecc6d9dfc2630aeef831 100644 --- a/app/apps/core/models.py +++ b/app/apps/core/models.py @@ -187,7 +187,8 @@ class Document(models.Model): read_direction = models.CharField( max_length=3, choices=READ_DIRECTION_CHOICES, - default=READ_DIRECTION_LTR + default=READ_DIRECTION_LTR, + help_text=_("The read direction describes the order of the elements in the document, in opposition with the text direction which describes the order of the words in a line and is set by the script.") ) typology = models.ForeignKey(DocumentType, null=True, blank=True, on_delete=models.SET_NULL) diff --git a/app/apps/users/urls.py b/app/apps/users/urls.py index e3aa844ec11047910b94461f1c68f1593fadcdae..fe7530b32fee6445352088bf05dfde2cb79cddc9 100644 --- a/app/apps/users/urls.py +++ b/app/apps/users/urls.py @@ -1,7 +1,8 @@ from django.urls import path, include from users.views import (SendInvitation, AcceptInvitation, AcceptGroupInvitation, ContactUsView, - ProfileInfos, ProfileGroupListCreate, ProfileApiKey, ProfileFiles, + ProfileInfos, ProfileGroupListCreate, ProfileApiKey, + ProfileFiles, ProfileInvitations, GroupDetail, RemoveFromGroup, LeaveGroup, TransferGroupOwnership) from django.contrib.auth.decorators import permission_required @@ -11,6 +12,7 @@ urlpatterns = [ path('profile/apikey/', ProfileApiKey.as_view(), name='profile-api-key'), path('profile/files/', ProfileFiles.as_view(), name='profile-files'), path('profile/teams/', ProfileGroupListCreate.as_view(), name='profile-team-list'), + path('profile/invitations/', ProfileInvitations.as_view(), name='profile-invites-list'), path('teams/<int:pk>/', GroupDetail.as_view(), name='team-detail'), path('teams/<int:pk>/remove/', RemoveFromGroup.as_view(), name='team-remove-user'), path('teams/<int:pk>/leave/', LeaveGroup.as_view(), name='team-leave'), diff --git a/app/apps/users/views.py b/app/apps/users/views.py index 9eb56f23eeca70d38f8f6f06788949cbd5eb7442..03cd6379dd38bf3034fcdabce3255a8d71243bfa 100644 --- a/app/apps/users/views.py +++ b/app/apps/users/views.py @@ -189,6 +189,19 @@ class ProfileFiles(LoginRequiredMixin, TemplateView): return context +class ProfileInvitations(LoginRequiredMixin, TemplateView): + template_name = 'users/profile_invitations.html' + + def get_context_data(self, *args, **kwargs): + context = super().get_context_data(*args, **kwargs) + invites = self.request.user.invitations_sent.all() + paginator = Paginator(invites, 25) + context['is_paginated'] = paginator.count != 0 + page_number = self.request.GET.get('page') + context['page_obj'] = paginator.get_page(page_number) + return context + + class ProfileGroupListCreate(LoginRequiredMixin, SuccessMessageMixin, CreateView): """ Both were we create new groups and list them diff --git a/app/escriptorium/templates/core/document_form.html b/app/escriptorium/templates/core/document_form.html index c6cb28d666d63a1c89d28614d54c6a430688aad3..baaf9abf1a7800e52d5d28bdbb5248ad876f6e8b 100644 --- a/app/escriptorium/templates/core/document_form.html +++ b/app/escriptorium/templates/core/document_form.html @@ -1,5 +1,5 @@ {% extends 'core/document_nav.html' %} -{% load i18n staticfiles bootstrap %} +{% load i18n staticfiles bootstrap json %} {% block head_title %}{% if object %}{% trans "Update a Document" %}{% else %}{% trans "Create a new Document" %}{% endif %}{% endblock %} {% block nav-doc-active %}active{% endblock %} @@ -173,9 +173,11 @@ </script> {{ block.super }} <script type="text/javascript"> - $(document).ready(function(){ - bootDocumentForm(); - bootHelp(); - }); + $(document).ready(function(){ + var scripts = { {% for script in form.fields.main_script.queryset %} + '{{script.pk}}':'{{script.text_direction}}',{% endfor %} }; + bootDocumentForm(scripts); + bootHelp(); + }); </script> {% endblock %} diff --git a/app/escriptorium/templates/export/alto.xml b/app/escriptorium/templates/export/alto.xml index ed28bb0e81b8cc6b01fdc868ec76cd11740c2e7e..80b0afbab80e820df539b3e032c8a7bbf8b6e665 100644 --- a/app/escriptorium/templates/export/alto.xml +++ b/app/escriptorium/templates/export/alto.xml @@ -1,11 +1,12 @@ {% load export_tags %}<?xml version="1.0" encoding="UTF-8"?> <alto xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.loc.gov/standards/alto/ns-v4#" - xsi:schemaLocation="http://www.loc.gov/standards/alto/ns-v4# https://gitlab.inria.fr/scripta/escriptorium/-/raw/develop/app/escriptorium/static/alto-4-1-baselines.xsd"> + xsi:schemaLocation="http://www.loc.gov/standards/alto/ns-v4# http://www.loc.gov/standards/alto/v4/alto-4-2.xsd"> <Description> <MeasurementUnit>pixel</MeasurementUnit> <sourceImageInformation> <fileName>{{ part.filename }}</fileName> + {% if part.source %}<fileIdentifier>{{ part.source }}</fileIdentifier>{% endif %} </sourceImageInformation> </Description> {% if valid_block_types or valid_line_types %} diff --git a/app/escriptorium/templates/export/pagexml.xml b/app/escriptorium/templates/export/pagexml.xml index f0be96718103b82a48bed29cefaaa2b8f6f4cdb9..73ded4ccf75b09cd5f0d11aecafaf9dffd502ed8 100644 --- a/app/escriptorium/templates/export/pagexml.xml +++ b/app/escriptorium/templates/export/pagexml.xml @@ -1,9 +1,10 @@ {% load export_tags %}<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <PcGts xmlns="http://schema.primaresearch.org/PAGE/gts/pagecontent/2019-07-15" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schema.primaresearch.org/PAGE/gts/pagecontent/2019-07-15 http://schema.primaresearch.org/PAGE/gts/pagecontent/2019-07-15/pagecontent.xsd"> - <Metadata> + <Metadata{% if part.source %} externalRef="{{part.source}}"{% endif %}> <Creator>escriptorium</Creator> <Created>{% current_time %}</Created> - <LastChange>{% current_time %}</LastChange> + <LastChange>{% current_time %}</LastChange> + </Metadata> <Page imageFilename="{{ part.filename }}" imageWidth="{{ part.image.width }}" imageHeight="{{ part.image.height }}"> diff --git a/app/escriptorium/templates/users/profile.html b/app/escriptorium/templates/users/profile.html index 7d950acd7edff5bab0ef3acf7f8f1589718b72f6..eb4f04990abeb040adee7c241e796a16b3f976b3 100644 --- a/app/escriptorium/templates/users/profile.html +++ b/app/escriptorium/templates/users/profile.html @@ -9,6 +9,7 @@ <a class="nav-link {% block key-tab-active %}{% endblock %}" id="nav-key-tab" href="{% url 'profile-api-key' %}" role="tab">{% trans "Api key" %}</a> <a class="nav-link {% block files-tab-active %}{% endblock %}" id="nav-files-tab" href="{% url 'profile-files' %}" role="tab">{% trans "Files" %}</a> <a class="nav-link {% block team-tab-active %}{% endblock %}" id="nav-infos-tab" href="{% url 'profile-team-list' %}" role="tab">{% trans "Teams" %}</a> + <a class="nav-link {% block invites-tab-active %}{% endblock %}" id="nav-infos-tab" href="{% url 'profile-invites-list' %}" role="tab">{% trans "Invitations" %}</a> </div> <div class="col-md-8 tab-content" id="v-pills-tabContent"> diff --git a/app/escriptorium/templates/users/profile_api_key.html b/app/escriptorium/templates/users/profile_api_key.html index 48e1fe1d5cbb66397545879cc9a0fa2acce3d709..59f1529846168610bf208627c5726f3e28476b4a 100644 --- a/app/escriptorium/templates/users/profile_api_key.html +++ b/app/escriptorium/templates/users/profile_api_key.html @@ -3,8 +3,6 @@ {% block infos-tab-active %}{% endblock %} {% block key-tab-active %}active{% endblock %} -{% block files-tab-active %}{% endblock %} -{% block team-tab-active %}{% endblock %} {% block tab-content %} {% trans "API Authentication Token:" %} {{ api_auth_token.key }} diff --git a/app/escriptorium/templates/users/profile_files.html b/app/escriptorium/templates/users/profile_files.html index 9849d42183ac7c6a189a0f0ff225190301ccb432..a4277c5a9b15299ae8087e4768cae7e9779fbafc 100644 --- a/app/escriptorium/templates/users/profile_files.html +++ b/app/escriptorium/templates/users/profile_files.html @@ -2,9 +2,7 @@ {% load i18n static %} {% block infos-tab-active %}{% endblock %} -{% block key-tab-active %}{% endblock %} {% block files-tab-active %}active{% endblock %} -{% block team-tab-active %}{% endblock %} {% block tab-content %} {% for fpath, fname in page_obj %} diff --git a/app/escriptorium/templates/users/profile_group_list.html b/app/escriptorium/templates/users/profile_group_list.html index 3a7b855f17bd40eab0a437e2a3a1458c85a5ff31..728f47a4b08703bfdba6f47ebee51a410102d9f6 100644 --- a/app/escriptorium/templates/users/profile_group_list.html +++ b/app/escriptorium/templates/users/profile_group_list.html @@ -2,12 +2,9 @@ {% load i18n bootstrap static %} {% block infos-tab-active %}{% endblock %} -{% block key-tab-active %}{% endblock %} -{% block files-tab-active %}{% endblock %} {% block team-tab-active %}active{% endblock %} {% block tab-content %} - <h4>{% trans "Create a new Team" %}</h4> <form method="post"> {% csrf_token %} diff --git a/app/escriptorium/templates/users/profile_invitations.html b/app/escriptorium/templates/users/profile_invitations.html new file mode 100644 index 0000000000000000000000000000000000000000..60be1c3a9718c12709ea15767ae84106d7fb1b26 --- /dev/null +++ b/app/escriptorium/templates/users/profile_invitations.html @@ -0,0 +1,21 @@ +{% extends "users/profile.html" %} +{% load i18n static %} + +{% block infos-tab-active %}{% endblock %} +{% block invites-tab-active %}active{% endblock %} + +{% block tab-content %} +<table class="table"> +{% for invite in page_obj %} + <tr> + <td>{{invite.recipient_email|default:invite.recipient}}</td> + <td title="Into group">{{invite.group|default:""}}</td> + <td>{{invite.get_workflow_state_display}}</td> + </tr> +{% empty %} +{% trans "You didn't send any invitations yet." %} +{% endfor %} +</table> + +{% include "includes/pagination.html" %} +{% endblock %} diff --git a/app/requirements.txt b/app/requirements.txt index 578411a956c52c1b8fe894d5f9f3482d30970226..cb1e62c76e846723fabffbe31e541d9e96e63c70 100644 --- a/app/requirements.txt +++ b/app/requirements.txt @@ -12,7 +12,7 @@ django-redis==4.10.0 psycopg2-binary==2.7.6 django-ordered-model==3.1.1 easy-thumbnails==2.5 -git+https://github.com/mittagessen/kraken.git@3.0b23#egg=kraken +git+https://github.com/mittagessen/kraken.git@3.0b24#egg=kraken django-cleanup==5.1.0 djangorestframework==3.9.2 drf-nested-routers==0.91 diff --git a/docker-compose.override.yml_example b/docker-compose.override.yml_example index 706d9693becda40e375477fa80e6643d964c879e..4e5e10e99352c1a29897c9265f9fce7188894196 100644 --- a/docker-compose.override.yml_example +++ b/docker-compose.override.yml_example @@ -3,8 +3,6 @@ version: "3.9" services: ### to customize the homepage, uncomment this #app: - # environment: - # - CUSTOM_HOME=True # volumes: # - $PWD/app/homepage diff --git a/docker-compose.yml b/docker-compose.yml index f8f155c8789579ec25ded7040881e93d8e578c79..a42c9720634017078f1931cbbca79f0b62c0415b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,7 +18,6 @@ services: expose: - 8000 - channelserver: <<: *app command: daphne --bind 0.0.0.0 --port 5000 -v 1 escriptorium.asgi:application diff --git a/front/src/document_form.js b/front/src/document_form.js index 20d352c7312ac10395e7f1dae68c0c3bc9f7bab3..a4461987d3cfb63acb7a495ec7596732cfb1c1aa 100644 --- a/front/src/document_form.js +++ b/front/src/document_form.js @@ -1,6 +1,6 @@ 'use strict'; /**** Metadata stuff ****/ -export function bootDocumentForm() { +export function bootDocumentForm(scripts) { // delete a metadata row $('.js-metadata-delete').click(function(ev) { var btn = ev.target; @@ -119,4 +119,19 @@ export function bootDocumentForm() { window.location.hash = this.hash; } }); + + // When selecting a rtl script, select rtl read direction + // flash shortly the read direction to tell the user when it changed + $('#id_main_script').on('change', function(ev) { + let dir = scripts[ev.target.value]; + if (dir=='horizontal-rl') { + if ($('#id_read_direction').val() !== 'rtl') { + $('#id_read_direction').val('rtl').addClass('is-valid').removeClass('is-valid', 1000); + } + } else { + if ($('#id_read_direction').val() !== 'ltr') { + $('#id_read_direction').val('ltr').addClass('is-valid').removeClass('is-valid', 1000); + } + } + }); } diff --git a/front/src/editor/store/document.js b/front/src/editor/store/document.js index ee3ffe0a4963cec7ce16f41ce070b43f7b240b5e..d24aac332cc0ddc933b456c30578fdafd4f69b15 100644 --- a/front/src/editor/store/document.js +++ b/front/src/editor/store/document.js @@ -14,10 +14,10 @@ export const initialState = () => ({ // Manage panels visibility through booleans // Those values are initially populated by localStorage visible_panels: { - source: userProfile.get('source-panel'), - segmentation: userProfile.get('segmentation-panel'), - visualisation: userProfile.get('visualisation-panel'), - diplomatic: userProfile.get('diplomatic-panel') + source: userProfile.get('visible-panels')?userProfile.get('visible-panels').source:false, + segmentation: userProfile.get('visible-panels')?userProfile.get('visible-panels').segmentation:true, + visualisation: userProfile.get('visible-panels')?userProfile.get('visible-panels').visualisation:true, + diplomatic: userProfile.get('visible-panels')?userProfile.get('visible-panels').diplomatic:false }, }) @@ -70,7 +70,7 @@ export const actions = { commit('setVisiblePanels', update) // Persist final value in user profile - userProfile.set(panel + '-panel', state.visible_panels[panel]) + userProfile.set('visible-panels', state.visible_panels) } } diff --git a/front/vue/components/SegPanel.vue b/front/vue/components/SegPanel.vue index f8d605c26b3268cfbe86053fd51878c37fecbe95..1538bce2f5c31c1374e82d2c8bc09a5f946c6844 100644 --- a/front/vue/components/SegPanel.vue +++ b/front/vue/components/SegPanel.vue @@ -94,7 +94,7 @@ class="btn btn-sm btn-info fas fa-question help nav-item ml-2"> </button> <div id="segmentation-help" class="alert alert-primary help-text collapse"> - <button type="button" class="close" aria-label="Close"> + <button type="button" data-toggle="collapse" data-target="#segmentation-help" class="close" aria-label="Close"> <span aria-hidden="true">×</span> </button> <help></help> diff --git a/front/vue/components/TranscriptionModal.vue b/front/vue/components/TranscriptionModal.vue index 5cb968f7afa9f6580d7c78900bb27bcfc6a32970..9cfb95a8b41b5cece45d5c526c73168258d4c7bc 100644 --- a/front/vue/components/TranscriptionModal.vue +++ b/front/vue/components/TranscriptionModal.vue @@ -10,16 +10,16 @@ <button v-if="$store.state.document.readDirection == 'rtl'" type="button" id="next-btn" - @click="$store.dispatch('lines/editLine', 'next')" - title="Next" + @click="editLine('next')" + title="Next (up arrow)" class="btn btn-sm mr-1 btn-secondary"> <i class="fas fa-arrow-circle-left"></i> </button> <button v-else type="button" id="prev-btn" - @click="$store.dispatch('lines/editLine', 'previous')" - title="Previous" + @click="editLine('previous')" + title="Previous (up arrow)" class="btn btn-sm mr-1 btn-secondary"> <i class="fas fa-arrow-circle-left"></i> </button> @@ -27,16 +27,16 @@ <button v-if="$store.state.document.readDirection == 'rtl'" type="button" id="prev-btn" - @click="$store.dispatch('lines/editLine', 'previous')" - title="Previous" + @click="editLine('previous')" + title="Previous (down arrow)" class="btn btn-sm mr-1 btn-secondary"> <i class="fas fa-arrow-circle-right"></i> </button> <button v-else type="button" id="next-btn" - @click="$store.dispatch('lines/editLine', 'next')" - title="Next" + @click="editLine('next')" + title="Next (down arrow)" class="btn btn-sm mr-1 btn-secondary"> <i class="fas fa-arrow-circle-right"></i> </button> @@ -71,9 +71,9 @@ <div id="trans-input-container" ref="transInputContainer"> <input v-if="$store.state.document.mainTextDirection != 'ttb'" - v-on:keyup.down="$store.dispatch('lines/editLine', 'next')" - v-on:keyup.up="$store.dispatch('lines/editLine', 'previous')" - v-on:keyup.enter="$store.dispatch('lines/editLine', 'next')" + v-on:keyup.down="editLine('next')" + v-on:keyup.up="editLine('previous')" + v-on:keyup.enter="editLine('next')" id="trans-input" ref="transInput" name="content" @@ -83,9 +83,9 @@ autofocus/> <!--Hidden input for ttb text: --> <input v-else - id="trans-input" + id="trans-input" ref="transInput" - name="content" + name="content" type="hidden" v-model.lazy="localTranscription" autocomplete="off" /> @@ -95,9 +95,9 @@ <div id="textInputBorderWrapper" class="form-control mb-2"> <div v-on:blur="localTranscription = $event.target.textContent" v-on:keyup="recomputeInputCharsScaleY()" - v-on:keyup.right="$store.dispatch('lines/editLine', 'next')" - v-on:keyup.left="$store.dispatch('lines/editLine', 'previous')" - v-on:keyup.enter="cleanHTMLTags();recomputeInputCharsScaleY();$store.dispatch('lines/editLine', 'next')" + v-on:keyup.right="editLine('next')" + v-on:keyup.left="editLine('previous')" + v-on:keyup.enter="cleanHTMLTags();recomputeInputCharsScaleY();editLine('next')" v-html="localTranscription" id="vertical_text_input" contenteditable="true"> @@ -217,8 +217,8 @@ export default Vue.extend({ // no need to make focus on hiden input with a ttb text if(this.$store.state.document.mainTextDirection != 'ttb'){ input.focus(); - }else{ // avoid some br or other html tag for a copied text on an editable input div (vertical_text_input): - // + }else{ // avoid some br or other html tag for a copied text on an editable input div (vertical_text_input): + // document.getElementById("vertical_text_input").addEventListener("paste", function(e) { // cancel paste to treat its content before inserting it @@ -283,11 +283,18 @@ export default Vue.extend({ close() { $(this.$refs.transModal).modal('hide'); }, + + editLine(direction) { + // making sure the line is saved (it isn't in case of shortcut usage) + this.localTranscription = this.$refs.transInput.value; + this.$store.dispatch('lines/editLine', direction); + }, + cleanHTMLTags(){ document.getElementById("vertical_text_input").innerHTML = document.getElementById("vertical_text_input").textContent; }, recomputeInputCharsScaleY(){ - + let inputHeight = document.getElementById("vertical_text_input").clientHeight; let wrapperHeight = document.getElementById("textInputBorderWrapper").clientHeight; let textScaleY = wrapperHeight / (inputHeight + 10); @@ -342,7 +349,7 @@ export default Vue.extend({ // calculate rotation needed to get the line horizontal let target_angle = 0; // all lines should be topologically ltr if(this.$store.state.document.mainTextDirection == 'ttb') // add a 90 angle for vertical texts - target_angle = 90; + target_angle = 90; let angle = target_angle - this.getLineAngle(); // apply it to the polygon and get the resulting bbox @@ -483,8 +490,8 @@ export default Vue.extend({ //document.getElementById('vertical_text_input').style.height = 100/scaleY + '%'; // not needed here } else { verticalTextInput.style.transform = 'none'; - verticalTextInput.style.height = modalImgContainer.clientHeight + 'px'; - } + verticalTextInput.style.height = modalImgContainer.clientHeight + 'px'; + } textInputWrapper.style.height = modalImgContainer.clientHeight + 'px'; // simulate an input field border to fix it to the actual size of the image textInputBorderWrapper.style.width = verticalTextInput.clientWidth+'px'; @@ -506,7 +513,7 @@ export default Vue.extend({ // let ratio = 1; - let lineHeight = 150; + let lineHeight = 150; if(this.$store.state.document.mainTextDirection != 'ttb') { @@ -523,9 +530,9 @@ export default Vue.extend({ modalImgContainer.style.height=String(window.innerHeight-230) + "px"; // needed to fix height or ratio is nulled ratio = modalImgContainer.clientHeight / (bbox.height + (2*bbox.width*hContext)); let MAX_WIDTH = 30; - lineHeight = Math.max(30, Math.round(bbox.width*ratio)); - - if (lineHeight > MAX_WIDTH) { + lineHeight = Math.max(30, Math.round(bbox.width*ratio)); + + if (lineHeight > MAX_WIDTH) { // change the ratio so that the image can not get too big ratio = (MAX_WIDTH/lineHeight)*ratio; lineHeight = MAX_WIDTH; diff --git a/variables.env_example b/variables.env_example index 69e9c245e24702af7af536471100947411926c2d..e0b4656925645061a7faa5ac914d4be43a0b0865 100644 --- a/variables.env_example +++ b/variables.env_example @@ -20,3 +20,5 @@ FLOWER_BASIC_AUTH=flower:changeme # set shm_size in yml file! KRAKEN_TRAINING_LOAD_THREADS=8 + +# CUSTOM_HOME=True