浏览代码

translate custom filter

Felipe Mateus 2 月之前
父节点
当前提交
a676c1ffee

+ 2 - 2
resources/assets/js/components/filters/FilterCard.vue

@@ -9,10 +9,10 @@
                     </div>
                     <div class="text-muted">·</div>
                     <div v-if="filter.expires_at" class="small text-muted">
-                        Expires: {{ formatExpiry(filter.expires_at) }}
+                        {{ $t('settings.filters.expires')  }}: {{ formatExpiry(filter.expires_at) }}
                     </div>
                     <div v-else class="small text-muted">
-                        Never expires
+                        {{ $t('settings.filters.never_expires')  }}
                     </div>
                 </div>
                 <div>

+ 81 - 81
resources/assets/js/components/filters/FilterModal.vue

@@ -7,7 +7,7 @@
                     <div class="modal-header bg-light d-flex align-items-center">
                         <h5 class="modal-title font-weight-bold">
                             <i class="fal fa-filter text-dark mr-2"></i>
-                            {{ isEditing ? 'Edit Filter' : 'Create Filter' }}
+                            {{ isEditing ? $t("settings.filters.edit_filter") : $t("settings.filters.create_filter") }}
                         </h5>
                         <div class="ml-auto d-flex align-items-center">
                             <div class="custom-control custom-switch mr-3">
@@ -19,7 +19,7 @@
                                 @change="toggleWizardMode($event)"
                                 >
                                 <label class="custom-control-label" for="wizard-toggle">
-                                    <small>{{ !wizardMode ? 'Advanced Mode' : 'Simple Mode' }}</small>
+                                    <small>{{ !wizardMode ? $t("settings.filters.advance_mode") : $t("settings.filters.simple_mode") }}</small>
                                 </label>
                             </div>
                             <button type="button" class="close" @click="closeModal()">
@@ -31,13 +31,13 @@
                     <form v-if="!wizardMode" @submit.prevent="saveFilter" class="simple-wizard">
                         <div class="modal-body px-4">
                             <div class="form-group">
-                                <label for="title" class="label">Filter title</label>
+                                <label for="title" class="label">{{ $t('settings.filters.filter_title') }}</label>
                                 <input
                                     v-model="formData.title"
                                     type="text"
                                     id="title"
                                     class="form-control form-control-lg form-control-mat"
-                                    placeholder="Enter filter title"
+                                    :placeholder="$t('settings.filters.enter_filter_title')"
                                     required
                                 />
                             </div>
@@ -45,17 +45,17 @@
                             <div class="form-group">
                                 <div class="d-flex justify-content-between align-items-center">
                                     <div class="flex-grow-1">
-                                        <label class="label">Keywords</label>
+                                        <label class="label">{{ $t("settings.filters.keywords") }}</label>
                                     </div>
                                     <div class="d-flex justify-content-between align-items-center" style="gap: 1rem;">
-                                        <p class="small text-muted mb-0">Legend</p>
+                                        <p class="small text-muted mb-0">{{ $t("settings.filters.legend") }}</p>
                                         <button
                                             type="button"
                                             class="btn btn-xs rounded-pill keyword-tag keyword-tag-whole py-1 px-3"
                                             @click="showWholeWordExplanation()"
                                             >
                                             <i class="far fa-info-circle mr-1"></i>
-                                            Whole word
+                                            {{ $t("settings.filters.whole_word") }}
                                         </button>
                                         <button
                                             type="button"
@@ -63,7 +63,7 @@
                                             @click="showPartialPhraseExplanation()"
                                             >
                                             <i class="far fa-info-circle mr-1"></i>
-                                            Partial word
+                                            {{ $t("settings.filters.partial_word") }}
                                         </button>
                                     </div>
                                 </div>
@@ -97,7 +97,7 @@
                                             type="text"
                                             :maxlength="40"
                                             class="form-control border-0 bg-transparent rounded-pill flex-grow-1 mb-2"
-                                            placeholder="Add a keyword..."
+                                            :placeholder=" $t('settings.filters.add_keyword') "
                                             @keydown.enter.prevent="addKeywordFromInput"
                                             style="min-width: 150px;"
                                             />
@@ -105,12 +105,12 @@
                                 </div>
                                 <div v-if="isDuplicateError" class="alert alert-warning rounded-lg mt-2 p-2 small">
                                     <i class="fas fa-exclamation-triangle mr-1"></i>
-                                    Duplicate keywords are not allowed
+                                    {{ $t("settings.filters.duplicate_not_allowed") }}
                                 </div>
                             </div>
 
                             <div class="form-group">
-                                <label class="label">Filter Action</label>
+                                <label class="label">{{ $t("settings.filters.filter_action") }}</label>
                                 <div class="filter-action-options">
                                     <div class="custom-control custom-radio mb-2">
                                         <input
@@ -123,7 +123,7 @@
                                         />
                                         <label class="custom-control-label d-flex align-items-center" for="action-blur">
                                             <span class="badge badge-primary mr-2">Blur</span>
-                                            Hide media behind a blurbash
+                                            {{ $t("settings.filters.hide_media_blur") }}
                                         </label>
                                     </div>
                                     <div class="custom-control custom-radio mb-2">
@@ -137,7 +137,7 @@
                                         />
                                         <label class="custom-control-label d-flex align-items-center" for="action-warn">
                                             <span class="badge badge-warning mr-2">Warning</span>
-                                            Show warning before displaying content
+                                            {{ $t("settings.filters.show_warning") }}
                                         </label>
                                     </div>
                                     <div class="custom-control custom-radio mb-2">
@@ -151,14 +151,14 @@
                                         />
                                         <label class="custom-control-label d-flex align-items-center" for="action-hide">
                                             <span class="badge badge-danger mr-2">Hidden</span>
-                                            Hide content completely
+                                            {{ $t("settings.filters.hide_content_completely") }}
                                         </label>
                                     </div>
                                 </div>
                             </div>
 
                             <div class="form-group">
-                                <label class="label">Apply filters to</label>
+                                <label class="label">{{ $t("settings.filters.apply_filters_to") }}</label>
                                 <div class="row">
                                     <div v-if="contextItemKeys.includes('home')" class="col-6 mb-2">
                                         <div class="custom-control custom-checkbox">
@@ -170,7 +170,7 @@
                                             v-model="formData.context"
                                             />
                                             <label class="custom-control-label" for="context-home">
-                                                Home timeline
+                                                {{ $t("settings.filters.home_timeline") }}
                                             </label>
                                         </div>
                                     </div>
@@ -184,7 +184,7 @@
                                             v-model="formData.context"
                                             />
                                             <label class="custom-control-label" for="context-notifications">
-                                                Notifications
+                                                {{ $t("settings.filters.notifications") }}
                                             </label>
                                         </div>
                                     </div>
@@ -198,7 +198,7 @@
                                             v-model="formData.context"
                                             />
                                             <label class="custom-control-label" for="context-public">
-                                                Public timelines
+                                                {{ $t("settings.filters.public_timeline") }}
                                             </label>
                                         </div>
                                     </div>
@@ -212,7 +212,7 @@
                                             v-model="formData.context"
                                             />
                                             <label class="custom-control-label" for="context-hashtags">
-                                                Hashtags
+                                                {{ $t("settings.filters.hashtags") }}
                                             </label>
                                         </div>
                                     </div>
@@ -226,7 +226,7 @@
                                             v-model="formData.context"
                                             />
                                             <label class="custom-control-label" for="context-thread">
-                                                Conversations
+                                                {{ $t("settings.filters.conversations") }}
                                             </label>
                                         </div>
                                     </div>
@@ -240,7 +240,7 @@
                                             v-model="formData.context"
                                             />
                                             <label class="custom-control-label" for="context-groups">
-                                                Groups
+                                                {{ $t("settings.filters.groups") }}
                                             </label>
                                         </div>
                                     </div>
@@ -248,16 +248,16 @@
                             </div>
 
                             <div class="form-group">
-                                <label for="duration" class="label">Duration</label>
+                                <label for="duration" class="label"> {{ $t("settings.filters.duration") }}</label>
                                 <select v-model="selectedDuration" id="duration" class="custom-select custom-select-lg form-control-mat">
-                                    <option value="0">Forever</option>
-                                    <option value="1800">30 minutes</option>
-                                    <option value="3600">1 hour</option>
-                                    <option value="21600">6 hours</option>
-                                    <option value="43200">12 hours</option>
-                                    <option value="86400">1 day</option>
-                                    <option value="604800">1 week</option>
-                                    <option value="-1">Custom...</option>
+                                    <option value="0">{{ $t("settings.filters.forever") }}</option>
+                                    <option value="1800">{{ $t("settings.filters.30_minutes") }}</option>
+                                    <option value="3600">{{ $t("settings.filters.1_hour") }}</option>
+                                    <option value="21600">{{ $t("settings.filters.6_hours") }}</option>
+                                    <option value="43200">{{ $t("settings.filters.12_hours") }}</option>
+                                    <option value="86400">{{ $t("settings.filters.1_day") }}</option>
+                                    <option value="604800">{{ $t("settings.filters.1_week") }}</option>
+                                    <option value="-1">{{ $t("settings.filters.1_week") }}</option>
                                 </select>
                                 <div v-if="selectedDuration === '-1'" class="input-group mt-2">
                                     <input
@@ -265,7 +265,7 @@
                                     type="number"
                                     min="1"
                                     class="form-control form-control-lg form-control-mat"
-                                    placeholder="Enter duration in seconds"
+                                    :placeholder="$t('settings.filters.enter_duration_in_seconds')"
                                     />
                                     <div class="input-group-append overflow-hidden">
                                         <span class="input-group-text">seconds</span>
@@ -277,7 +277,7 @@
                         <div class="modal-footer bg-light d-flex justify-content-between align-items-center">
                             <div>
                                 <button type="button" @click="closeModal()" class="btn btn-outline-secondary font-weight-light rounded-pill">
-                                    Cancel
+                                   {{ $t('common.cancel')}}
                                 </button>
 
                                 <button
@@ -285,7 +285,7 @@
                                     type="button"
                                     class="btn btn-outline-danger font-weight-light rounded-pill"
                                     @click="deleteFilter()">
-                                    Delete
+                                    {{ $t('common.delete')}}
                                 </button>
                             </div>
                             <button type="submit" class="btn btn-primary font-weight-bold rounded-pill" :disabled="!isValid">
@@ -295,7 +295,7 @@
                                     </div>
                                 </template>
                                 <template v-else>
-                                    {{ isEditing ? 'Save Changes' : 'Create Filter' }}
+                                    {{ isEditing ? $t("settings.filters.save_changes") :  $t("settings.filters.create_filter") }}
                                 </template>
                             </button>
                         </div>
@@ -328,31 +328,31 @@
                                         <div class="step-content-info-icon">
                                             <i class="fal fa-filter fa-3x"></i>
                                         </div>
-                                        <h4>Name Your Filter</h4>
-                                        <p class="text-muted">Give your filter a name that will help you remember what content it filters.</p>
+                                        <h4>{{ $t('settings.filters.name_your_filter') }}</h4>
+                                        <p class="text-muted">{{ $t('settings.filters.give_your_filter_a_name') }}</p>
                                     </div>
                                     <div class="form-group">
-                                        <label for="wizard-title">Filter title</label>
+                                        <label for="wizard-title">{{ $t('settings.filters.filter_title') }}</label>
                                         <input
                                         v-model="formData.title"
                                         type="text"
                                         id="wizard-title"
                                         class="form-control form-control-lg"
-                                        placeholder="My filter name"
+                                        :placeholder="$t('settings.filters.my_filter_name')"
                                         required
                                         />
                                     </div>
                                     <div class="form-group">
-                                        <label for="wizard-duration">Filter Duration</label>
+                                        <label for="wizard-duration">{{ $t('settings.filters.filter_duration') }}</label>
                                         <select v-model="selectedDuration" id="wizard-duration" class="custom-select">
-                                            <option value="0">Forever</option>
-                                            <option value="1800">30 minutes</option>
-                                            <option value="3600">1 hour</option>
-                                            <option value="21600">6 hours</option>
-                                            <option value="43200">12 hours</option>
-                                            <option value="86400">1 day</option>
-                                            <option value="604800">1 week</option>
-                                            <option value="-1">Custom...</option>
+                                            <option value="0">{{ $t("settings.filters.forever") }}</option>
+                                            <option value="1800">{{ $t("settings.filters.30_minutes") }}</option>
+                                            <option value="3600">{{ $t("settings.filters.1_hour") }}</option>
+                                            <option value="21600">{{ $t("settings.filters.6_hours") }}</option>
+                                            <option value="43200">{{ $t("settings.filters.12_hours") }}</option>
+                                            <option value="86400">{{ $t("settings.filters.1_day") }}</option>
+                                            <option value="604800">{{ $t("settings.filters.1_week") }}</option>
+                                            <option value="-1">{{ $t("settings.filters.1_week") }}</option>
                                         </select>
                                         <div v-if="selectedDuration === '-1'" class="input-group mt-2">
                                             <input
@@ -361,7 +361,7 @@
                                             min="1"
                                             max="63072000"
                                             class="form-control"
-                                            placeholder="Enter duration in seconds"
+                                            :placeholder="$t('settings.filters.enter_duration_in_seconds')"
                                             />
                                             <div class="input-group-append">
                                                 <span class="input-group-text">seconds</span>
@@ -375,8 +375,8 @@
                                         <div class="step-content-info-icon">
                                             <i class="fal fa-key fa-3x"></i>
                                         </div>
-                                        <h4>Add Filter Keywords</h4>
-                                        <p class="text-muted">Add words or phrases you want to filter.<br />Content containing these words will be filtered according to your settings.</p>
+                                        <h4>{{ $t('settings.filters.add_filter_keywords')}}</h4>
+                                        <p class="text-muted"  v-html="$t('settings.filters.add_word_or_phrase')"></p>
                                     </div>
 
                                     <div class="keywords-container d-flex flex-column align-items-center">
@@ -421,7 +421,7 @@
                                             </div>
 
                                             <small class="text-muted">
-                                                {{ keyword.whole_word ? 'Whole word match - filters exact matches only (e.g. "book" won\'t match "bookstore")' : 'Partial word match - filters any content containing this text (e.g. "book" will match "bookstore")' }}
+                                                {{ keyword.whole_word ? $t('settings.filters.whole_word_match') :  $t('settings.filters.partial_word_match')}}
                                             </small>
                                         </div>
 
@@ -431,12 +431,12 @@
                                             class="btn btn-outline-primary mt-3 font-weight-light rounded-pill"
                                             @click="addKeyword"
                                         >
-                                            <i class="fas fa-plus mr-1"></i> Add another keyword
+                                            <i class="fas fa-plus mr-1"></i> {{ $t('settings.filters.add_another_keyword')}}
                                         </button>
 
                                         <div v-if="isDuplicateError" class="alert alert-warning mt-4 w-75">
                                             <i class="fas fa-exclamation-triangle mr-2"></i>
-                                            Please remove duplicate keywords before continuing
+                                            {{ $t('settings.filters.please_remove_duplicate_keywords')}}
                                         </div>
                                     </div>
                                 </div>
@@ -446,8 +446,8 @@
                                         <div class="step-content-info-icon">
                                             <i class="fal fa-shield-alt fa-3x"></i>
                                         </div>
-                                        <h4>Choose Filter Action</h4>
-                                        <p class="text-muted">How would you like to handle content that matches your filter?</p>
+                                        <h4>{{ $t('settings.filters.choose_filter_action')}}</h4>
+                                        <p class="text-muted">{{ $t('settings.filters.choose_filter_action_description')}}</p>
                                     </div>
 
                                     <div class="card-deck">
@@ -459,7 +459,7 @@
                                             <div class="card-body">
                                                 <i class="fas fa-tint fa-2x text-info mb-3"></i>
                                                 <h5 class="card-title">Blur</h5>
-                                                <p class="card-text text-muted small">Hide media behind a blurhash</p>
+                                                <p class="card-text text-muted small">{{ $t('settings.filters.hide_media_blur') }}</p>
                                             </div>
                                         </div>
                                         <div
@@ -470,7 +470,7 @@
                                             <div class="card-body">
                                                 <i class="fas fa-exclamation-triangle fa-2x text-warning mb-3"></i>
                                                 <h5 class="card-title">Warn</h5>
-                                                <p class="card-text text-muted small">Show a warning before displaying the content</p>
+                                                <p class="card-text text-muted small">{{ $t('settings.filters.show_warning') }}</p>
                                             </div>
                                         </div>
                                         <div
@@ -481,7 +481,7 @@
                                             <div class="card-body">
                                                 <i class="fas fa-eye-slash fa-2x text-danger mb-3"></i>
                                                 <h5 class="card-title">Hide</h5>
-                                                <p class="card-text text-muted small">Completely hide content that matches</p>
+                                                <p class="card-text text-muted small">{{ $t('settings.filters.hide_completely') }}</p>
                                             </div>
                                         </div>
                                     </div>
@@ -492,8 +492,8 @@
                                         <div class="step-content-info-icon">
                                             <i class="fal fa-map fa-3x"></i>
                                         </div>
-                                        <h4>Choose Where to Apply</h4>
-                                        <p class="text-muted">Select which sections of the application should use this filter.</p>
+                                        <h4>{{ $t('settings.filters.choose_where_to_apply') }}</h4>
+                                        <p class="text-muted">{{ $t('settings.filters.choose_where_to_apply_description') }}</p>
                                     </div>
                                     <div class="row">
                                         <div class="col-md-6 mb-3" v-for="item in contextItems" :key="item.value">
@@ -528,8 +528,8 @@
                                         <div class="step-content-info-icon bg-success border-success">
                                             <i class="fas fa-check fa-3x text-white"></i>
                                         </div>
-                                        <h4>Review Your Filter</h4>
-                                        <p class="text-muted">Here's a summary of the filter you've created.</p>
+                                        <h4>{{ $t('settings.filters.review_your_filter') }}</h4>
+                                        <p class="text-muted">{{ $t('settings.filters.review_your_filter_description') }}</p>
                                     </div>
                                     <div class="card shadow-none border rounded-lg mb-3">
                                         <div class="card-header bg-light">
@@ -537,7 +537,7 @@
                                         </div>
                                         <div class="card-body">
                                             <div class="row mb-3">
-                                                <div class="col-md-4 font-weight-bold">Keywords:</div>
+                                                <div class="col-md-4 font-weight-bold">{{ $t('settings.filters.keywords')  }}:</div>
                                                 <div class="col-md-8">
                                                     <div v-if="formData.keywords.length > 0">
                                                         <span
@@ -549,11 +549,11 @@
                                                             <span v-if="keyword.whole_word" class="small font-italic ml-1">(whole)</span>
                                                         </span>
                                                     </div>
-                                                    <span v-else class="text-muted">No keywords specified</span>
+                                                    <span v-else class="text-muted">{{ $t('settings.filters.no_keywords_specified')  }}</span>
                                                 </div>
                                             </div>
                                             <div class="row mb-4">
-                                                <div class="col-md-4 font-weight-bold">Action:</div>
+                                                <div class="col-md-4 font-weight-bold">{{ $t('settings.filters.action')  }}:</div>
                                                 <div class="col-md-8">
                                                     <span
                                                         class="font-weight-bold mb-1"
@@ -575,15 +575,15 @@
                                                 </div>
                                             </div>
                                             <div class="row mb-3">
-                                                <div class="col-md-4 font-weight-bold">Duration:</div>
+                                                <div class="col-md-4 font-weight-bold">{{ $t("settings.filters.duration") }}:</div>
                                                 <div class="col-md-8 text-muted small">
-                                                    <span v-if="selectedDuration === '0'">Forever</span>
-                                                    <span v-else-if="selectedDuration === '1800'">30 minutes</span>
-                                                    <span v-else-if="selectedDuration === '3600'">1 hour</span>
-                                                    <span v-else-if="selectedDuration === '21600'">6 hours</span>
-                                                    <span v-else-if="selectedDuration === '43200'">12 hours</span>
-                                                    <span v-else-if="selectedDuration === '86400'">1 day</span>
-                                                    <span v-else-if="selectedDuration === '604800'">1 week</span>
+                                                    <span v-if="selectedDuration === '0'">{{ $t("settings.filters.forever") }}</span>
+                                                    <span v-else-if="selectedDuration === '1800'">{{ $t("settings.filters.30_minutes") }}</span>
+                                                    <span v-else-if="selectedDuration === '3600'">{{ $t("settings.filters.1_hour") }}</span>
+                                                    <span v-else-if="selectedDuration === '21600'">{{ $t("settings.filters.6_hours") }}</span>
+                                                    <span v-else-if="selectedDuration === '43200'">{{ $t("settings.filters.12_hours") }}</span>
+                                                    <span v-else-if="selectedDuration === '86400'">{{ $t("settings.filters.1_day") }}</span>
+                                                    <span v-else-if="selectedDuration === '604800'">{{ $t("settings.filters.1_week") }}</span>
                                                     <span v-else-if="selectedDuration === '-1'">{{ customDuration }} seconds</span>
                                                 </div>
                                             </div>
@@ -609,7 +609,7 @@
                                     class="btn btn-outline-danger font-weight-light rounded-pill"
                                     @click="deleteFilter()"
                                 >
-                                    Delete
+                                    {{ $t('common.delete')}}
                                 </button>
                             </div>
                             <div>
@@ -620,7 +620,7 @@
                                     @click="nextStep"
                                     :disabled="!canContinue"
                                 >
-                                    Continue
+                                    {{ $t('common.continue')}}
                                 </button>
                                 <button
                                     v-else
@@ -635,7 +635,7 @@
                                         </div>
                                     </template>
                                     <template v-else>
-                                        {{ isEditing ? 'Save Changes' : 'Create Filter' }}
+                                        {{ isEditing ? $t("settings.filters.save_changes") : $t("settings.filters.create_filter")  }}
                                     </template>
                                 </button>
                             </div>
@@ -715,11 +715,11 @@
                     // },
                 ],
                 wizardSteps: [
-                    { label: 'Title', field: 'title' },
-                    { label: 'Keywords', field: 'keywords' },
-                    { label: 'Action', field: 'filter_action' },
-                    { label: 'Context', field: 'context' },
-                    { label: 'Review', field: null }
+                    { label: this.$t('settings.filters.titleAdvance'), field: 'title' },
+                    { label: this.$t('settings.filters.keywords'), field: 'keywords' },
+                    { label: this.$t('settings.filters.action'), field: 'filter_action' },
+                    { label: this.$t('settings.filters.context'), field: 'context' },
+                    { label: this.$t('settings.filters.review'), field: null }
                 ]
             }
         },

+ 12 - 13
resources/assets/js/components/filters/FiltersList.vue

@@ -3,22 +3,21 @@
         <div class="d-flex flex-column flex-md-row justify-content-between align-items-center mb-4">
             <div class="title">
                 <h3 class="font-weight-bold mb-0">
-                    Filters
+                    {{ $t("settings.filters.title")}}
                 </h3>
-                <p class="lead mb-3 mb-md-0">Manage your custom filters.</p>
+                <p class="lead mb-3 mb-md-0">{{ $t('settings.filters.manage_your_custom_filters') }}</p>
             </div>
             <button
                 @click="showAddFilterModal = true"
                 class="btn btn-primary font-weight-bold rounded-pill px-3"
                 :disabled="filters?.length >= 20">
-                <i class="fas fa-plus mr-1"></i> Add New Filter
+                <i class="fas fa-plus mr-1"></i> {{ $t('settings.filters.add_new_filter') }}
             </button>
         </div>
 
-        <!-- <p>Customize your experience with powerful content filters that screen for specific words or phrases throughout your entire account—including home and public timelines, notifications, messages, groups, hashtag feeds, and explore sections.</p> -->
-        <p>Customize your experience with powerful content filters that screen for specific words or phrases throughout your entire account - including home and public timelines, and hashtag feeds.</p>
-        <p class="text-muted mb-0">You can add up to <strong>20 filters</strong> that can have up to <strong>10 keywords</strong>.</p>
-        <p class="text-muted mb-4 small">Learn more in our <a href="/site/help">Help Center</a>.</p>
+        <p>{{ $t("settings.filters.customize_your_experience") }}</p>
+        <p class="text-muted mb-0" v-html="$t('settings.filters.limit_message', { filters_num: 20, keyword_num: 10 })"></p>
+        <p class="text-muted mb-4 small" v-html="$t('settings.filters.learn_more_help_center')"  ></p>
 
         <div v-if="loading" class="d-flex justify-content-center py-4">
             <div class="spinner-border text-primary" role="status">
@@ -29,12 +28,12 @@
         <div v-else-if="filters.length === 0" class="bg-light p-4 rounded text-center border">
             <div class="py-3">
                 <i class="fas fa-filter text-secondary fa-3x mb-3"></i>
-                <p class="font-weight-bold text-secondary">You don't have any content filters yet.</p>
+                <p class="font-weight-bold text-secondary">{{ $t("settings.filters.no_filters")}}</p>
                 <p class="text-muted small mt-2">
-                    Filters help you hide content containing specific words or phrases from your timelines.
+                    {{ $t('settings.filters.no_filters_message') }}
                 </p>
                 <button @click="showAddFilterModal = true" class="btn btn-outline-primary rounded-pill font-weight-light mt-2">
-                    <i class="fas fa-plus mr-1"></i> Create Your First Filter
+                    <i class="fas fa-plus mr-1"></i> {{ $t('settings.filters.create_first_filter') }}
                 </button>
             </div>
         </div>
@@ -67,12 +66,12 @@
             <div v-if="searchQuery && filteredFilters.length === 0" class="bg-light p-4 rounded text-center border">
                 <div class="py-3">
                     <i class="fas fa-filter text-secondary fa-3x mb-3"></i>
-                    <p class="lead text-secondary">You don't have any content filters that match <strong>{{searchQuery}}</strong>.</p>
+                    <p class="lead text-secondary" v-html="$t('settings.filters.no_matching_filters', { searchQuery })"></p>
                     <p class="text-muted small mt-2">
-                    Filters help you hide content containing specific words or phrases from your timelines.
+                        {{ $t('settings.filters.no_matching_filters_message') }}
                     </p>
                     <button @click="showAddFilterModal = true" class="btn btn-outline-primary rounded-pill font-weight-light mt-2">
-                        <i class="fas fa-plus mr-1"></i> Create new Filter
+                        <i class="fas fa-plus mr-1"></i> {{ $t('settings.filters.create_new_filter') }}
                     </button>
                 </div>
             </div>

+ 19 - 0
resources/assets/js/settings.js

@@ -0,0 +1,19 @@
+import Vue from 'vue';
+import VueI18n from 'vue-i18n';
+
+Vue.use(VueI18n);
+
+import en from './i18n/en.json';
+import pt from './i18n/pt.json';
+let locale = document.querySelector('html').getAttribute('lang');
+
+const i18n = new VueI18n({
+    locale: locale, // set locale
+    fallbackLocale: 'en',
+    messages: { en, pt }
+});
+
+new Vue({
+    el: '#content',
+    i18n
+});

+ 16 - 15
resources/lang/en/settings.php

@@ -6,6 +6,7 @@ return [
     'email' =>                  'Email',
     'invites' =>                'Invites',
     'media' =>                  'Media',
+    'filters' =>                'Filters',
     'notifications' =>          'Notifications',
     'password' =>               'Password',
     'privacy' =>                'Privacy',
@@ -18,13 +19,13 @@ return [
     'export' =>                 'Export',
     'labs' =>                   'Labs',
     'parental_controls' =>      'Parental Controls',
-  
+
     'submit' =>                 'Submit',
     'error' =>                  'Error',
     'cancel' =>                 'Cancel',
     'save' =>                   'Save',
     'download' =>               'Download',
-    
+
     'home.account_settings' =>                                          'Account Settings',
     'home.change_profile_photo' =>                                      'Change Profile Photo',
     'home.select_a_profile_photo' =>                                    'Select a profile photo',
@@ -50,21 +51,21 @@ return [
     'home.storage_used' =>                                              'Storage Used',
     'home.are_you_sure_you_want_to_delete_your_profile_photo' =>        'Are you sure you want to delete your profile photo?',
     'home.an_error_occured_please_try_again_later' =>                   'An error occured, please try again later',
-    
+
     'accessibility.reduce_motion' =>                                    'Reduce Motion',
     'accessibility.prevent_animation_effects' =>                        'Prevent animation effects.',
     'accessibility.high_contrast_mode' =>                               'High Contrast Mode',
     'accessibility.high_contrast_mode_for_the_visually_impaired' =>     'High contrast mode for the visually impaired.',
     'accessibility.disable_video_autoplay' =>                           'Disable video autoplay',
     'accessibility.prevent_videos_from_autoplaying' =>                  'Prevent videos from autoplaying.',
-    
+
     'email.email_settings' =>                                           'Email Settings',
     'email.email_address' =>                                            'Email Address',
     'email.verified' =>                                                 'Verified',
     'email.unverified' =>                                               'Unverified',
     'email.you_need_to' =>                                              'You need to',
     'email.verify_your_email' =>                                        'verify your email',
-    
+
     'media.default_license' =>                                          'Default License',
     'media.set_a_default_license_for_new_posts' =>                      'Set a default license for new posts.',
     'media.sync_licenses' =>                                            'Sync Licenses',
@@ -73,7 +74,7 @@ return [
     'media.require_media_descriptions' =>                               'Require Media Descriptions',
     'media.briefly_describe_your_media_to_improve_etc' =>               'Briefly describe your media to improve accessibility for vision impaired people.',
     'media.not_available_for_mobile_or_3rd_party_apps_etc' =>           'Not available for mobile or 3rd party apps at this time.',
-    
+
     'password.update_password' =>                                       'Update Password',
     'password.current' =>                                               'Current',
     'password.your_current_password' =>                                 'Your current password',
@@ -81,7 +82,7 @@ return [
     'password.enter_new_password_here' =>                               'Enter new password here',
     'password.confirm' =>                                               'Confirm',
     'password.confirm_new_password' =>                                  'Confirm new password',
-    
+
     'privacy.privacy_settings' =>                                       'Privacy Settings',
     'privacy.private_account' =>                                        'Private Account',
     'privacy.when_your_account_is_private_only_people_you_etc' =>       'When your account is private, only people you approve can see your photos and videos on pixelfed. Your existing followers won\'t be affected.',
@@ -123,7 +124,7 @@ return [
     'privacy.allow_new_follow_requests' =>                              'Allow new follow requests',
     'privacy.block_notifications_from_accounts_i_dont_follow' =>        'Block notifications from accounts I don\'t follow',
     'privacy.an_error_occured_please_try_again' =>                      'An error occured. Please try again.',
-  
+
     'relationships' =>                                                          'Relationships',
     'relationships.followers' =>                                                'Followers',
     'relationships.following' =>                                                'Following',
@@ -142,7 +143,7 @@ return [
     'relationships.you_have_successfully_unfollowed_that_user' =>               'You have successfully unfollowed that user',
     'relationships.an_error_occured_when_attempting_to_unfollow_this_user' =>   'An error occured when attempting to unfollow this user',
     'relationships.you_have_successfully_unfollowed_that_hashtag' =>            'You have successfully unfollowed that hashtag',
-    
+
     'security.two_factor_authentication' =>                                     'Two-factor authentication',
     'security.enabled' =>                                                       'Enabled',
     'security.danger_zone' =>                                                   'Danger Zone',
@@ -173,23 +174,23 @@ return [
     'security.see_reblogs_from_accounts_you_follow_in_your_home_etc' =>         'See reblogs from accounts you follow in your home feed. (Home timeline only)',
     'security.photo_reblogs_only' =>                                            'Photo reblogs only',
     'security.only_see_reblogs_of_photos_or_photo_albums_home_etc' =>           'Only see reblogs of photos or photo albums. (Home timeline only)',
-    
+
     // incomplete
-    // the oauth panel is loaded from elsewhere 
+    // the oauth panel is loaded from elsewhere
     'developers.oauth_has_not_been_enabled_on_this_instance' =>                 'OAuth has not been enabled on this instance.',
-    
+
     // incomplete
     // import/ig.blade.php seems not in use anymore
     'import.import_from_instagram' =>                                           'Import from Instagram',
-    
+
     'export.data_export' =>                                                     'Data Export',
     'export.we_generate_data_exports_once_per_hour_and_they_may_etc' =>         'We generate data exports once per hour, and they may not contain the latest data if you\'ve requested them recently.',
     'export.statuses' =>                                                        'Statuses',
     'export.mute_block_lists' =>                                                'Mute/Block List',
-    
+
     // incomplete
     // some language outside the blades (in app/Http/Controllers/Settings/LabsSettings.php)
     'labs' =>                                                                   'Labs',
     'labs.experimental_features' =>                                             'Experimental features',
     'labs.use_dark_mode_theme' =>                                               'Use dark mode theme.',
-];
+];

+ 78 - 0
resources/lang/en/web.php

@@ -32,6 +32,8 @@ return [
 		'sensitive' => 'Sensitive',
 		'sensitiveContent' => 'Sensitive Content',
 		'sensitiveContentWarning' => 'This post may contain sensitive content',
+
+        'continue' => 'Continue',
 	],
 
 	'site' => [
@@ -262,4 +264,80 @@ return [
         'feed' => 'Feed',
     ],
 
+    'settings' => [
+        'filters' => [
+            'title' => 'Filters',
+            'manage_your_custom_filters' => 'Manage your custom filters.',
+            'customize_your_experience' => 'Customize your experience with powerful content filters that screen for specific words or phrases throughout your entire account - including home and public timelines, and hashtag feeds.',
+            'add_new_filter' => 'Add New Filter',
+            'limit_message' => 'You can add up to <strong>:filters_num filters</strong> that can have up to <strong>:keywords_num keywords</strong>.',
+            'learn_more_help_center' => 'Learn more in our <a href="/site/help">Help Center</a>.',
+            'no_filters' => 'You don\'t have any content filters yet',
+            'no_filters_message' => 'Filters help you hide content containing specific words or phrases from your timelines.',
+            'create_first_filter' => 'Create Your First Filter',
+            'no_matching_filters' => 'You don\'t have any content filters that match <strong>:searchQuery</strong>.',
+            'no_matching_filters_message' => 'Filters help you hide content containing specific words or phrases from your timelines.',
+            'create_new_filter' => 'Create new Filter',
+            'filter_title' => 'Filter Title',
+            'edit_filter' => 'Edit Filter',
+            'create_filter' => 'Create Filter',
+            'advance_mode' => 'Advanced Mode',
+            'simple_mode' => 'Simple Mode',
+            'keywords' => 'Keywords',
+            'legend' => 'Legend',
+            'whole_word' => 'Whole word',
+            'partial_word' => 'Partial word',
+            'duplicate_not_allowed' => 'Duplicate keywords are not allowed',
+            'filter_action' => 'Filter Action',
+            'hide_media_blur' => 'Hide media behind a blurbash',
+            'show_warning' => 'Show warning before displaying content',
+            'hide_content_completely' => 'Hide content completely',
+            'apply_filters_to' => 'Apply filters to',
+            'home_timeline' => 'Home Timeline',
+            'notifications' => 'Notifications',
+            'public_timeline' => 'Public Timeline',
+            'hashtags' => 'Hashtag',
+            'groups' => 'Groups',
+            'conversations' => 'Conversations',
+            'duration' => 'Duration',
+            'forever' => 'Forever',
+            '30_minutes' => '30 minutes',
+            '1_hour' => '1 hour',
+            '6_hours' => '6 hours',
+            '12_hours' => '12 hours',
+            '1_day' => '1 day',
+            '1_week' => '1 week',
+            'cutom' => 'Custom..',
+            'enter_duration_in_seconds' => 'Enter duration in seconds',
+            'save_changes' => 'Save Changes',
+            'create_filter' => 'Create Filter',
+            'name_your_filter' => 'Name your filter',
+            'give_your_filter_a_name' => 'Give your filter a name that will help you remember what content it filters.',
+            'my_filter_name' => 'My Filter Name',
+            'filter_duration' => 'Filter Duration',
+            'add_filter_keywords' => 'Add filter keywords',
+            'add_word_or_phrase' => 'Add words or phrases you want to filter.<br />Content containing these words will be filtered according to your settings.',
+            'whole_word_match' => 'Whole word match - filters exact matches only (e.g. "book" won\'t match "bookstore")',
+            'partial_word_match' => 'Partial word match - filters any content containing this text (e.g. "book" will match "bookstore")',
+            'add_another_keyword' => 'Add another keyword',
+            'please_remove_duplicate_keywords' => 'Please remove duplicate keywords before continuing',
+            'choose_filter_action' => 'Choose filter action',
+            'choose_filter_action_description' => 'How would you like to handle content that matches your filter?',
+            'hide_completely' => 'Completely hide content that matches',
+            'choose_where_to_apply' => 'Choose Where to Apply',
+            'choose_where_to_apply_description' => 'Select which sections of the application should use this filter.',
+            'review_your_filter' => 'Review your filter',
+            'review_your_filter_description' => 'Here\'s a summary of the filter you\'ve created.',
+            'no_keywords_specified' => 'No keywords specified',
+            'action' => 'Action',
+            'expires' => 'Expires',
+            'never_expires' => 'Never Expires',
+            'titleAdvance' => 'Title',
+            'context' => 'Context',
+            'review' => 'Review',
+            'add_keyword' => 'Add a keyword...',
+            'enter_filter_title' => 'Enter filter title',
+        ],
+
+    ]
 ];

+ 3 - 0
resources/lang/pt/settings.php

@@ -6,6 +6,7 @@ return [
     'email' =>                  'Email',
     'invites' =>                'Convites',
     'media' =>                  'Mídia',
+    'filters' =>                'Filtros',
     'notifications' =>          'Notificações',
     'password' =>               'Senha',
     'privacy' =>                'Privacidade',
@@ -185,4 +186,6 @@ return [
     'labs' =>                                                                   'Laboratórios',
     'labs.experimental_features' =>                                             'Recursos experimentais',
     'labs.use_dark_mode_theme' =>                                               'Usar tema de modo escuro.',
+
+    
 ];

+ 78 - 1
resources/lang/pt/web.php

@@ -32,6 +32,8 @@ return [
 		'sensitive' => 'Sensível',
 		'sensitiveContent' => 'Conteúdo sensível',
 		'sensitiveContentWarning' => 'Este post pode conter conteúdo sensível',
+
+        'continue' => 'Continuar',
 	],
 
 	'site' => [
@@ -253,6 +255,81 @@ return [
         'grid' => 'Grade',
         'masonry' => 'Mansory',
         'feed' => 'Feed'
-    ]
+    ],
 
+    'settings' => [
+        'filters' => [
+            'title' => 'Filtros',
+            'manage_your_custom_filters' => 'Gerencie seus filtros personalizados.',
+            'customize_your_experience' => 'Personalize sua experiência com filtros de conteúdo poderosos que verificam palavras ou frases específicas em toda a sua conta - incluindo linhas do tempo pessoais e públicas, e feeds de hashtags.',
+            'add_new_filter' => 'Adicionar Novo Filtro',
+            'limit_message' => 'Você pode adicionar até <strong>:filters_num filtros</strong> que podem ter até <strong>:keywords_num palavras-chave</strong>.',
+            'learn_more_help_center' => 'Saiba mais no nosso <a href="/site/help">Centro de Ajuda</a>.',
+            'no_filters' => 'Você ainda não tem nenhum filtro de conteúdo',
+            'no_filters_message' => 'Os filtros ajudam você a ocultar conteúdo que contém palavras ou frases específicas das suas linhas do tempo.',
+            'create_first_filter' => 'Crie Seu Primeiro Filtro',
+            'no_matching_filters' => 'Você não tem nenhum filtro de conteúdo que corresponda a <strong>:searchQuery</strong>.',
+            'no_matching_filters_message' => 'Os filtros ajudam você a ocultar conteúdo que contém palavras ou frases específicas das suas linhas do tempo.',
+            'create_new_filter' => 'Criar Novo Filtro',
+            'filter_title' => 'Título do Filtro',
+            'edit_filter' => 'Editar Filtro',
+            'create_filter' => 'Criar Filtro',
+            'advance_mode' => 'Modo Avançado',
+            'simple_mode' => 'Modo Simples',
+            'keywords' => 'Palavras-chave',
+            'legend' => 'Legenda',
+            'whole_word' => 'Palavra inteira',
+            'partial_word' => 'Palavra parcial',
+            'duplicate_not_allowed' => 'Palavras-chave duplicadas não são permitidas',
+            'filter_action' => 'Ação do Filtro',
+            'hide_media_blur' => 'Ocultar mídia atrás de um desfoque',
+            'show_warning' => 'Mostrar aviso antes de exibir o conteúdo',
+            'hide_content_completely' => 'Ocultar conteúdo completamente',
+            'apply_filters_to' => 'Aplicar filtros a',
+            'home_timeline' => 'Linha do Tempo Pessoal',
+            'notifications' => 'Notificações',
+            'public_timeline' => 'Linha do Tempo Pública',
+            'hashtags' => 'Hashtags',
+            'groups' => 'Grupos',
+            'conversations' => 'Conversas',
+            'duration' => 'Duração',
+            'forever' => 'Para Sempre',
+            '30_minutes' => '30 minutos',
+            '1_hour' => '1 hora',
+            '6_hours' => '6 horas',
+            '12_hours' => '12 horas',
+            '1_day' => '1 dia',
+            '1_week' => '1 semana',
+            'cutom' => 'Personalizado...',
+            'enter_duration_in_seconds' => 'Insira a duração em segundos',
+            'save_changes' => 'Salvar Alterações',
+            'create_filter' => 'Criar Filtro',
+            'name_your_filter' => 'Nomeie seu filtro',
+            'give_your_filter_a_name' => 'Dê ao seu filtro um nome que o ajude a lembrar o que ele filtra.',
+            'my_filter_name' => 'Nome do Meu Filtro',
+            'filter_duration' => 'Duração do Filtro',
+            'add_filter_keywords' => 'Adicionar palavras-chave ao filtro',
+            'add_word_or_phrase' => 'Adicione palavras ou frases que você deseja filtrar.<br />Conteúdo contendo essas palavras será filtrado de acordo com suas configurações.',
+            'whole_word_match' => 'Correspondência de palavra inteira - filtra apenas correspondências exatas (ex.: "livro" não corresponderá a "livraria")',
+            'partial_word_match' => 'Correspondência de palavra parcial - filtra qualquer conteúdo que contenha este texto (ex.: "livro" corresponderá a "livraria")',
+            'add_another_keyword' => 'Adicionar outra palavra-chave',
+            'please_remove_duplicate_keywords' => 'Por favor, remova palavras-chave duplicadas antes de continuar',
+            'choose_filter_action' => 'Escolha a ação do filtro',
+            'choose_filter_action_description' => 'Como você gostaria de lidar com o conteúdo que corresponde ao seu filtro?',
+            'hide_completely' => 'Ocultar completamente o conteúdo que corresponde',
+            'choose_where_to_apply' => 'Escolha Onde Aplicar',
+            'choose_where_to_apply_description' => 'Selecione quais seções do aplicativo devem usar este filtro.',
+            'review_your_filter' => 'Revise seu filtro',
+            'review_your_filter_description' => 'Aqui está um resumo do filtro que você criou.',
+            'no_keywords_specified' => 'Nenhuma palavra-chave especificada',
+            'action' => 'Ação',
+            'expires' => 'Expira',
+            'never_expires' => 'Nunca Expira',
+            'titleAdvance' => 'Título',
+            'context' => 'Contexto',
+            'review' => 'Revisão',
+            'add_keyword' => 'Adicionar uma palavra-chave...',
+            'enter_filter_title' => 'Insira o título do filtro',
+        ],
+    ]
 ];

+ 1 - 1
resources/views/settings/partial/sidebar.blade.php

@@ -18,7 +18,7 @@
                 <a class="nav-link font-weight-light text-muted" href="{{route('settings.media')}}">{{__('settings.media')}}</a>
             </li>
             <li class="nav-item pl-3 {{request()->is('settings/filters*')?'active':''}}">
-                <a class="nav-link font-weight-light text-muted" href="{{route('settings.filters')}}">Filters</a>
+                <a class="nav-link font-weight-light text-muted" href="{{route('settings.filters')}}">{{__('settings.filters')}}</a>
             </li>
             {{-- <li class="nav-item pl-3 {{request()->is('settings/notifications')?'active':''}}">
                 <a class="nav-link font-weight-light text-muted" href="{{route('settings.notifications')}}">{{__('settings.notifications')}}</a>

+ 2 - 6
resources/views/settings/template.blade.php

@@ -38,9 +38,5 @@
 
 @push('scripts')
 <script type="text/javascript" src="{{ mix('js/compose.js') }}"></script>
-<script type="text/javascript">
-  new Vue({
-    el: '#content'
-  });
-</script>
-@endpush
+<script type="text/javascript" src="{{ mix('js/settings.js') }}"></script>
+@endpush

+ 1 - 0
webpack.mix.js

@@ -45,6 +45,7 @@ mix.js('resources/assets/js/app.js', 'public/js')
 .js('resources/assets/js/group-status.js', 'public/js')
 .js('resources/assets/js/group-topic-feed.js', 'public/js')
 .js('resources/assets/js/custom_filters.js', 'public/js')
+.js('resources/assets/js/settings.js', 'public/js')
 .vue({ version: 2 });
 
 mix.extract();