diff options
| -rw-r--r-- | src/components/avatar_list/avatar_list.js | 6 | ||||
| -rw-r--r-- | src/components/avatar_list/avatar_list.vue | 4 | ||||
| -rw-r--r-- | src/components/basic_user_card/basic_user_card.vue | 6 | ||||
| -rw-r--r-- | src/components/mobile_nav/mobile_nav.js | 5 | ||||
| -rw-r--r-- | src/components/mobile_nav/mobile_nav.vue | 42 | ||||
| -rw-r--r-- | src/components/notification/notification.vue | 2 | ||||
| -rw-r--r-- | src/components/notifications/notifications.js | 4 | ||||
| -rw-r--r-- | src/components/status/status.js | 6 | ||||
| -rw-r--r-- | src/components/status/status.vue | 17 | ||||
| -rw-r--r-- | src/components/user_avatar/user_avatar.js | 2 | ||||
| -rw-r--r-- | src/components/user_avatar/user_avatar.vue | 4 | ||||
| -rw-r--r-- | src/components/user_card/user_card.vue | 2 | ||||
| -rw-r--r-- | src/i18n/es.json | 106 | ||||
| -rw-r--r-- | src/services/entity_normalizer/entity_normalizer.service.js | 3 |
14 files changed, 162 insertions, 47 deletions
diff --git a/src/components/avatar_list/avatar_list.js b/src/components/avatar_list/avatar_list.js index d65125c2..b9e11aaa 100644 --- a/src/components/avatar_list/avatar_list.js +++ b/src/components/avatar_list/avatar_list.js @@ -1,10 +1,10 @@ import UserAvatar from '../user_avatar/user_avatar.vue' const AvatarList = { - props: ['avatars'], + props: ['users'], computed: { - slicedAvatars () { - return this.avatars ? this.avatars.slice(0, 15) : [] + slicedUsers () { + return this.users ? this.users.slice(0, 15) : [] } }, components: { diff --git a/src/components/avatar_list/avatar_list.vue b/src/components/avatar_list/avatar_list.vue index b14474ba..4e0de2c9 100644 --- a/src/components/avatar_list/avatar_list.vue +++ b/src/components/avatar_list/avatar_list.vue @@ -1,7 +1,7 @@ <template> <div class="avatars"> - <div class="avatars-item" v-for="avatar in slicedAvatars"> - <UserAvatar :src="avatar.profile_image_url" class="avatar-small" /> + <div class="avatars-item" v-for="user in slicedUsers"> + <UserAvatar :user="user" class="avatar-small" /> </div> </div> </template> diff --git a/src/components/basic_user_card/basic_user_card.vue b/src/components/basic_user_card/basic_user_card.vue index 25f1fb2a..634d62b3 100644 --- a/src/components/basic_user_card/basic_user_card.vue +++ b/src/components/basic_user_card/basic_user_card.vue @@ -1,7 +1,11 @@ <template> <div class="basic-user-card"> <router-link :to="userProfileLink(user)"> - <UserAvatar class="avatar" @click.prevent.native="toggleUserExpanded" :src="user.profile_image_url"/> + <UserAvatar + class="avatar" + :user="user" + @click.prevent.native="toggleUserExpanded" + /> </router-link> <div class="basic-user-card-expanded-content" v-if="userExpanded"> <UserCard :user="user" :rounded="true" :bordered="true"/> diff --git a/src/components/mobile_nav/mobile_nav.js b/src/components/mobile_nav/mobile_nav.js index bc63d2ba..9b341a3b 100644 --- a/src/components/mobile_nav/mobile_nav.js +++ b/src/components/mobile_nav/mobile_nav.js @@ -63,6 +63,11 @@ const MobileNav = { }, markNotificationsAsSeen () { this.$refs.notifications.markAsSeen() + }, + onScroll ({ target: { scrollTop, clientHeight, scrollHeight } }) { + if (this.$store.state.config.autoLoad && scrollTop + clientHeight >= scrollHeight) { + this.$refs.notifications.fetchOlderNotifications() + } } }, watch: { diff --git a/src/components/mobile_nav/mobile_nav.vue b/src/components/mobile_nav/mobile_nav.vue index 5fa41638..90707ce7 100644 --- a/src/components/mobile_nav/mobile_nav.vue +++ b/src/components/mobile_nav/mobile_nav.vue @@ -1,25 +1,26 @@ <template> - <nav class='nav-bar container' id="nav"> - <div class='mobile-inner-nav' @click="scrollToTop()"> - <div class='item'> - <a href="#" class="mobile-nav-button" @click.stop.prevent="toggleMobileSidebar()"> - <i class="button-icon icon-menu"></i> - </a> - <router-link class="site-name" :to="{ name: 'root' }" active-class="home">{{sitename}}</router-link> - </div> - <div class='item right'> - <a class="mobile-nav-button" v-if="currentUser" href="#" @click.stop.prevent="openMobileNotifications()"> - <i class="button-icon icon-bell-alt"></i> - <div class="alert-dot" v-if="unseenNotificationsCount"></div> - </a> + <div> + <nav class='nav-bar container' id="nav"> + <div class='mobile-inner-nav' @click="scrollToTop()"> + <div class='item'> + <a href="#" class="mobile-nav-button" @click.stop.prevent="toggleMobileSidebar()"> + <i class="button-icon icon-menu"></i> + </a> + <router-link class="site-name" :to="{ name: 'root' }" active-class="home">{{sitename}}</router-link> + </div> + <div class='item right'> + <a class="mobile-nav-button" v-if="currentUser" href="#" @click.stop.prevent="openMobileNotifications()"> + <i class="button-icon icon-bell-alt"></i> + <div class="alert-dot" v-if="unseenNotificationsCount"></div> + </a> + </div> </div> - </div> - <SideDrawer ref="sideDrawer" :logout="logout"/> + </nav> <div v-if="currentUser" class="mobile-notifications-drawer" :class="{ 'closed': !notificationsOpen }" - @touchstart="notificationsTouchStart" - @touchmove="notificationsTouchMove" + @touchstart.stop="notificationsTouchStart" + @touchmove.stop="notificationsTouchMove" > <div class="mobile-notifications-header"> <span class="title">{{$t('notifications.notifications')}}</span> @@ -27,12 +28,13 @@ <i class="button-icon icon-cancel"/> </a> </div> - <div v-if="currentUser" class="mobile-notifications"> + <div class="mobile-notifications" @scroll="onScroll"> <Notifications ref="notifications" noHeading="true"/> </div> </div> + <SideDrawer ref="sideDrawer" :logout="logout"/> <MobilePostStatusModal /> - </nav> + </div> </template> <script src="./mobile_nav.js"></script> @@ -79,6 +81,8 @@ transition-property: transform; transition-duration: 0.25s; transform: translateX(0); + z-index: 1001; + -webkit-overflow-scrolling: touch; &.closed { transform: translateX(100%); diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue index ae11d692..3427b9c5 100644 --- a/src/components/notification/notification.vue +++ b/src/components/notification/notification.vue @@ -7,7 +7,7 @@ </status> <div class="non-mention" :class="[userClass, { highlighted: userStyle }]" :style="[ userStyle ]" v-else> <a class='avatar-container' :href="notification.from_profile.statusnet_profile_url" @click.stop.prevent.capture="toggleUserExpanded"> - <UserAvatar :compact="true" :betterShadow="betterShadow" :src="notification.from_profile.profile_image_url_original" /> + <UserAvatar :compact="true" :betterShadow="betterShadow" :user="notification.from_profile"/> </a> <div class='notification-right'> <UserCard :user="getUser(notification)" :rounded="true" :bordered="true" v-if="userExpanded" /> diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js index e341212e..5b13b98e 100644 --- a/src/components/notifications/notifications.js +++ b/src/components/notifications/notifications.js @@ -52,6 +52,10 @@ const Notifications = { this.$store.dispatch('markNotificationsAsSeen') }, fetchOlderNotifications () { + if (this.loading) { + return + } + const store = this.$store const credentials = store.state.users.currentUser.credentials store.commit('setNotificationsLoading', { value: true }) diff --git a/src/components/status/status.js b/src/components/status/status.js index f10eb2e4..ff8cbe18 100644 --- a/src/components/status/status.js +++ b/src/components/status/status.js @@ -263,13 +263,13 @@ const Status = { } return this.status.summary_html + '<br />' + this.status.statusnet_html }, - combinedFavsAndRepeatsAvatars () { + combinedFavsAndRepeatsUsers () { // Use the status from the global status repository since favs and repeats are saved in it - const combinedAvatars = [].concat( + const combinedUsers = [].concat( this.statusFromGlobalRepository.favoritedBy, this.statusFromGlobalRepository.rebloggedBy ) - return uniqBy(combinedAvatars, 'id') + return uniqBy(combinedUsers, 'id') } }, components: { diff --git a/src/components/status/status.vue b/src/components/status/status.vue index a5f7429c..43c3030e 100644 --- a/src/components/status/status.vue +++ b/src/components/status/status.vue @@ -13,7 +13,7 @@ </template> <template v-else> <div v-if="retweet && !noHeading && !inConversation" :class="[repeaterClass, { highlighted: repeaterStyle }]" :style="[repeaterStyle]" class="media container retweet-info"> - <UserAvatar class="media-left" v-if="retweet" :betterShadow="betterShadow" :src="statusoid.user.profile_image_url_original"/> + <UserAvatar class="media-left" v-if="retweet" :betterShadow="betterShadow" :user="statusoid.user"/> <div class="media-body faint"> <span class="user-name"> <router-link v-if="retweeterHtml" :to="retweeterProfileLink" v-html="retweeterHtml"/> @@ -27,7 +27,7 @@ <div :class="[userClass, { highlighted: userStyle, 'is-retweet': retweet && !inConversation }]" :style="[ userStyle ]" class="media status"> <div v-if="!noHeading" class="media-left"> <router-link :to="userProfileLink" @click.stop.prevent.capture.native="toggleUserExpanded"> - <UserAvatar :compact="compact" :betterShadow="betterShadow" :src="status.user.profile_image_url_original"/> + <UserAvatar :compact="compact" :betterShadow="betterShadow" :user="status.user"/> </router-link> </div> <div class="status-body"> @@ -91,8 +91,13 @@ </div> <div v-if="showPreview" class="status-preview-container"> - <status class="status-preview" v-if="preview" :isPreview="true" :statusoid="preview" :compact=true></status> - <div class="status-preview status-preview-loading" v-else> + <status class="status-preview" + v-if="preview" + :isPreview="true" + :statusoid="preview" + :compact=true + /> + <div v-else class="status-preview status-preview-loading"> <i class="icon-spin4 animate-spin"></i> </div> </div> @@ -134,7 +139,7 @@ </div> <transition name="fade"> - <div class="favs-repeated-users" v-if="combinedFavsAndRepeatsAvatars.length > 0 && isFocused"> + <div class="favs-repeated-users" v-if="combinedFavsAndRepeatsUsers.length > 0 && isFocused"> <div class="stats"> <div class="stat-count" v-if="statusFromGlobalRepository.rebloggedBy && statusFromGlobalRepository.rebloggedBy.length > 0"> <a class="stat-title">{{ $t('status.repeats') }}</a> @@ -145,7 +150,7 @@ <div class="stat-number">{{ statusFromGlobalRepository.favoritedBy.length }}</div> </div> <div class="avatar-row"> - <AvatarList :avatars='combinedFavsAndRepeatsAvatars'></AvatarList> + <AvatarList :users="combinedFavsAndRepeatsUsers"></AvatarList> </div> </div> </div> diff --git a/src/components/user_avatar/user_avatar.js b/src/components/user_avatar/user_avatar.js index e6fed3b5..a42b9c71 100644 --- a/src/components/user_avatar/user_avatar.js +++ b/src/components/user_avatar/user_avatar.js @@ -2,7 +2,7 @@ import StillImage from '../still-image/still-image.vue' const UserAvatar = { props: [ - 'src', + 'user', 'betterShadow', 'compact' ], diff --git a/src/components/user_avatar/user_avatar.vue b/src/components/user_avatar/user_avatar.vue index 6bf7123d..e5466fdf 100644 --- a/src/components/user_avatar/user_avatar.vue +++ b/src/components/user_avatar/user_avatar.vue @@ -1,8 +1,10 @@ <template> <StillImage class="avatar" + :alt="user.screen_name" + :title="user.screen_name" + :src="user.profile_image_url_original" :class="{ 'avatar-compact': compact, 'better-shadow': betterShadow }" - :src="imgSrc" :imageLoadError="imageLoadError" /> </template> diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue index e1d3ff57..e62b384d 100644 --- a/src/components/user_card/user_card.vue +++ b/src/components/user_card/user_card.vue @@ -4,7 +4,7 @@ <div class='user-info'> <div class='container'> <router-link :to="userProfileLink(user)"> - <UserAvatar :betterShadow="betterShadow" :src="user.profile_image_url_original"/> + <UserAvatar :betterShadow="betterShadow" :user="user"/> </router-link> <div class="name-and-screen-name"> <div class="top-line"> diff --git a/src/i18n/es.json b/src/i18n/es.json index a692eef9..6c8fd26a 100644 --- a/src/i18n/es.json +++ b/src/i18n/es.json @@ -2,6 +2,10 @@ "chat": { "title": "Chat" }, + "exporter": { + "export": "Exportar", + "processing": "Procesando. Pronto se te pedirá que descargues tu archivo" + }, "features_panel": { "chat": "Chat", "gopher": "Gopher", @@ -19,7 +23,22 @@ "apply": "Aplicar", "submit": "Enviar", "more": "Más", - "generic_error": "Ha ocurrido un error" + "generic_error": "Ha ocurrido un error", + "optional": "opcional", + "show_more": "Mostrar más", + "show_less": "Mostrar menos", + "cancel": "Cancelar" + }, + "image_cropper": { + "crop_picture": "Recortar la foto", + "save": "Guardar", + "save_without_cropping": "Guardar sin recortar", + "cancel": "Cancelar" + }, + "importer": { + "submit": "Enviar", + "success": "Importado con éxito", + "error": "Se ha producido un error al importar el archivo." }, "login": { "login": "Identificación", @@ -31,6 +50,10 @@ "username": "Usuario", "hint": "Inicia sesión para unirte a la discusión" }, + "media_modal": { + "previous": "Anterior", + "next": "Siguiente" + }, "nav": { "about": "Sobre", "back": "Volver", @@ -61,15 +84,19 @@ "account_not_locked_warning_link": "bloqueada", "attachments_sensitive": "Contenido sensible", "content_type": { - "text/plain": "Texto Plano" + "text/plain": "Texto Plano", + "text/html": "HTML", + "text/markdown": "Markdown", + "text/bbcode": "BBCode" }, "content_warning": "Tema (opcional)", "default": "Acabo de aterrizar en L.A.", - "direct_warning": "Esta entrada solo será visible para los usuarios mencionados.", + "direct_warning": "Esta publicación solo será visible para los usuarios mencionados.", + "direct_warning_to_first_only": "Esta publicación solo será visible para los usuarios mencionados al comienzo del mensaje.", "posting": "Publicando", "scope": { "direct": "Directo - Solo para los usuarios mencionados.", - "private": "Solo-Seguidores - Solo tus seguidores leeran la entrada", + "private": "Solo-Seguidores - Solo tus seguidores leeran la publicación", "public": "Público - Entradas visibles en las Líneas Temporales Públicas", "unlisted": "Sin Listar - Entradas no visibles en las Líneas Temporales Públicas" } @@ -83,6 +110,9 @@ "token": "Token de invitación", "captcha": "CAPTCHA", "new_captcha": "Click en la imagen para obtener un nuevo captca", + "username_placeholder": "p.ej. lain", + "fullname_placeholder": "p.ej. Lain Iwakura", + "bio_placeholder": "e.g.\nHola, soy un ejemplo.\nAquí puedes poner algo representativo tuyo... o no.", "validations": { "username_required": "no puede estar vacío", "fullname_required": "no puede estar vacío", @@ -92,7 +122,11 @@ "password_confirmation_match": "la contraseña no coincide" } }, + "selectable_list": { + "select_all": "Seleccionarlo todo" + }, "settings": { + "app_name": "Nombre de la aplicación", "attachmentRadius": "Adjuntos", "attachments": "Adjuntos", "autoload": "Activar carga automática al llegar al final de la página", @@ -101,6 +135,12 @@ "avatarRadius": "Avatares", "background": "Fondo", "bio": "Biografía", + "block_export": "Exportar usuarios bloqueados", + "block_export_button": "Exporta la lista de tus usarios bloqueados a un archivo csv", + "block_import": "Importar usuarios bloqueados", + "block_import_error": "Error importando la lista de usuarios bloqueados", + "blocks_imported": "¡Lista de usuarios bloqueados importada! El procesado puede tardar un poco.", + "blocks_tab": "Bloqueados", "btnRadius": "Botones", "cBlue": "Azul (Responder, seguir)", "cGreen": "Verde (Retweet)", @@ -127,7 +167,6 @@ "filtering_explanation": "Todos los estados que contengan estas palabras serán silenciados, una por línea", "follow_export": "Exportar personas que tú sigues", "follow_export_button": "Exporta tus seguidores a un archivo csv", - "follow_export_processing": "Procesando, en breve se te preguntará para guardar el archivo", "follow_import": "Importar personas que tú sigues", "follow_import_error": "Error al importal el archivo", "follows_imported": "¡Importado! Procesarlos llevará tiempo.", @@ -135,12 +174,15 @@ "general": "General", "hide_attachments_in_convo": "Ocultar adjuntos en las conversaciones", "hide_attachments_in_tl": "Ocultar adjuntos en la línea temporal", + "hide_muted_posts": "Ocultar las publicaciones de los usuarios silenciados", + "max_thumbnails": "Cantidad máxima de miniaturas por publicación", "hide_isp": "Ocultar el panel específico de la instancia", "preload_images": "Precargar las imágenes", "use_one_click_nsfw": "Abrir los adjuntos NSFW con un solo click.", "hide_post_stats": "Ocultar las estadísticas de las entradas (p.ej. el número de favoritos)", "hide_user_stats": "Ocultar las estadísticas del usuario (p.ej. el número de seguidores)", "hide_filtered_statuses": "Ocultar estados filtrados", + "import_blocks_from_a_csv_file": "Importar lista de usuarios bloqueados dese un archivo csv", "import_followers_from_a_csv_file": "Importar personas que tú sigues a partir de un archivo csv", "import_theme": "Importar tema", "inputRadius": "Campos de entrada", @@ -155,6 +197,7 @@ "lock_account_description": "Restringir el acceso a tu cuenta solo a seguidores admitidos", "loop_video": "Vídeos en bucle", "loop_video_silent_only": "Bucle solo en vídeos sin sonido (p.ej. \"gifs\" de Mastodon)", + "mutes_tab": "Silenciados", "play_videos_in_modal": "Reproducir los vídeos directamente en el visor de medios", "use_contain_fit": "No recortar los adjuntos en miniaturas", "name": "Nombre", @@ -166,6 +209,8 @@ "notification_visibility_mentions": "Menciones", "notification_visibility_repeats": "Repeticiones (Repeats)", "no_rich_text_description": "Eliminar el formato de texto enriquecido de todas las entradas", + "no_blocks": "No hay usuarios bloqueados", + "no_mutes": "No hay usuarios sinlenciados", "hide_follows_description": "No mostrar a quién sigo", "hide_followers_description": "No mostrar quién me sigue", "show_admin_badge": "Mostrar la placa de administrador en mi perfil", @@ -190,8 +235,11 @@ "reply_visibility_self": "Solo mostrar réplicas para mí", "saving_err": "Error al guardar los ajustes", "saving_ok": "Ajustes guardados", + "search_user_to_block": "Buscar usuarios a bloquear", + "search_user_to_mute": "Buscar usuarios a silenciar", "security_tab": "Seguridad", - "scope_copy": "Copiar la visibilidad cuando contestamos (En los mensajes directos (MDs) siempre se copia)", + "scope_copy": "Copiar la visibilidad de la publicación cuando contestamos (En los mensajes directos (MDs) siempre se copia)", + "minimal_scopes_mode": "Minimizar las opciones de publicación", "set_new_avatar": "Cambiar avatar", "set_new_profile_background": "Cambiar fondo del perfil", "set_new_profile_banner": "Cambiar cabecera del perfil", @@ -210,6 +258,7 @@ "theme_help_v2_1": "También puede invalidar los colores y la opacidad de ciertos componentes si activa la casilla de verificación, use el botón \"Borrar todo\" para deshacer los cambios.", "theme_help_v2_2": "Los iconos debajo de algunas entradas son indicadores de contraste de fondo/texto, desplace el ratón para obtener información detallada. Tenga en cuenta que cuando se utilizan indicadores de contraste de transparencia se muestra el peor caso posible.", "tooltipRadius": "Información/alertas", + "upload_a_photo": "Subir una foto", "user_settings": "Ajustes de Usuario", "values": { "false": "no", @@ -325,6 +374,11 @@ "checkbox": "He revisado los términos y condiciones", "link": "un bonito enlace" } + }, + "version": { + "title": "Versión", + "backend_version": "Versión del Backend", + "frontend_version": "Versión del Frontend" } }, "timeline": { @@ -336,7 +390,14 @@ "repeated": "repetida", "show_new": "Mostrar lo nuevo", "up_to_date": "Actualizado", - "no_more_statuses": "No hay más estados" + "no_more_statuses": "No hay más estados", + "no_statuses": "Sin estados" + }, + "status": { + "favorites": "Favoritos", + "repeats": "Repetidos", + "reply_to": "Responder a", + "replies_list": "Respuestas:" }, "user_card": { "approve": "Aprovar", @@ -359,10 +420,37 @@ "muted": "Silenciado", "per_day": "por día", "remote_follow": "Seguir", - "statuses": "Estados" + "statuses": "Estados", + "unblock": "Desbloquear", + "unblock_progress": "Desbloqueando...", + "block_progress": "Bloqueando...", + "unmute": "Desenmudecer", + "unmute_progress": "Sesenmudeciendo...", + "mute_progress": "Silenciando...", + "admin_menu": { + "moderation": "Moderación", + "grant_admin": "Conceder permisos de Administrador", + "revoke_admin": "Revocar permisos de Administrador", + "grant_moderator": "Conceder permisos de Moderador", + "revoke_moderator": "Revocar permisos de Moderador", + "activate_account": "Activar cuenta", + "deactivate_account": "Desactivar cuenta", + "delete_account": "Borrar cuenta", + "force_nsfw": "Marcar todas las publicaciones como NSFW (no es seguro/apropiado para el trabajo)", + "strip_media": "Eliminar archivos multimedia de las publicaciones", + "force_unlisted": "Forzar que se publique en el modo -Sin Listar-", + "sandbox": "Forzar que se publique solo para tus seguidores", + "disable_remote_subscription": "No permitir que usuarios de instancias remotas te siga.", + "disable_any_subscription": "No permitir que ningún usuario te siga", + "quarantine": "No permitir publicaciones de usuarios de instancias remotas", + "delete_user": "Borrar usuario", + "delete_user_confirmation": "¿Estás completamente seguro? Esta acción no se puede deshacer." + } }, "user_profile": { - "timeline_title": "Linea temporal del usuario" + "timeline_title": "Linea temporal del usuario", + "profile_does_not_exist": "Lo sentimos, este perfil no existe.", + "profile_loading_error": "Lo sentimos, hubo un error al cargar este perfil." }, "who_to_follow": { "more": "Más", diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js index e706e7d9..309aa1e8 100644 --- a/src/services/entity_normalizer/entity_normalizer.service.js +++ b/src/services/entity_normalizer/entity_normalizer.service.js @@ -275,6 +275,9 @@ export const parseStatus = (data) => { output.retweeted_status = parseStatus(retweetedStatus) } + output.favoritedBy = [] + output.rebloggedBy = [] + return output } |
