Persist UI settings, add missing localizations for German
This commit is contained in:
		
							parent
							
								
									23ebf60b95
								
							
						
					
					
						commit
						75f80bef10
					
				|  | @ -14,8 +14,6 @@ export const NOTIFICATIONS_EXPAND_REQUEST = 'NOTIFICATIONS_EXPAND_REQUEST'; | ||||||
| export const NOTIFICATIONS_EXPAND_SUCCESS = 'NOTIFICATIONS_EXPAND_SUCCESS'; | export const NOTIFICATIONS_EXPAND_SUCCESS = 'NOTIFICATIONS_EXPAND_SUCCESS'; | ||||||
| export const NOTIFICATIONS_EXPAND_FAIL    = 'NOTIFICATIONS_EXPAND_FAIL'; | export const NOTIFICATIONS_EXPAND_FAIL    = 'NOTIFICATIONS_EXPAND_FAIL'; | ||||||
| 
 | 
 | ||||||
| export const NOTIFICATIONS_SETTING_CHANGE = 'NOTIFICATIONS_SETTING_CHANGE'; |  | ||||||
| 
 |  | ||||||
| const fetchRelatedRelationships = (dispatch, notifications) => { | const fetchRelatedRelationships = (dispatch, notifications) => { | ||||||
|   const accountIds = notifications.filter(item => item.type === 'follow').map(item => item.account.id); |   const accountIds = notifications.filter(item => item.type === 'follow').map(item => item.account.id); | ||||||
| 
 | 
 | ||||||
|  | @ -133,11 +131,3 @@ export function expandNotificationsFail(error) { | ||||||
|     error |     error | ||||||
|   }; |   }; | ||||||
| }; | }; | ||||||
| 
 |  | ||||||
| export function changeNotificationsSetting(key, checked) { |  | ||||||
|   return { |  | ||||||
|     type: NOTIFICATIONS_SETTING_CHANGE, |  | ||||||
|     key, |  | ||||||
|     checked |  | ||||||
|   }; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
|  | @ -0,0 +1,17 @@ | ||||||
|  | import axios from 'axios'; | ||||||
|  | 
 | ||||||
|  | export const SETTING_CHANGE = 'SETTING_CHANGE'; | ||||||
|  | 
 | ||||||
|  | export function changeSetting(key, value) { | ||||||
|  |   return (dispatch, getState) => { | ||||||
|  |     dispatch({ | ||||||
|  |       type: SETTING_CHANGE, | ||||||
|  |       key, | ||||||
|  |       value | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     axios.put('/api/web/settings', { | ||||||
|  |       data: getState().get('settings').toJS() | ||||||
|  |     }); | ||||||
|  |   }; | ||||||
|  | }; | ||||||
|  | @ -1,15 +1,15 @@ | ||||||
| import { connect } from 'react-redux'; | import { connect } from 'react-redux'; | ||||||
| import ColumnSettings from '../components/column_settings'; | import ColumnSettings from '../components/column_settings'; | ||||||
| import { changeNotificationsSetting } from '../../../actions/notifications'; | import { changeSetting } from '../../../actions/settings'; | ||||||
| 
 | 
 | ||||||
| const mapStateToProps = state => ({ | const mapStateToProps = state => ({ | ||||||
|   settings: state.getIn(['notifications', 'settings']) |   settings: state.getIn(['settings', 'notifications']) | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| const mapDispatchToProps = dispatch => ({ | const mapDispatchToProps = dispatch => ({ | ||||||
| 
 | 
 | ||||||
|   onChange (key, checked) { |   onChange (key, checked) { | ||||||
|     dispatch(changeNotificationsSetting(key, checked)); |     dispatch(changeSetting(['notifications', ...key], checked)); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | @ -18,7 +18,7 @@ const messages = defineMessages({ | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| const getNotifications = createSelector([ | const getNotifications = createSelector([ | ||||||
|   state => Immutable.List(state.getIn(['notifications', 'settings', 'shows']).filter(item => !item).keys()), |   state => Immutable.List(state.getIn(['settings', 'notifications', 'shows']).filter(item => !item).keys()), | ||||||
|   state => state.getIn(['notifications', 'items']) |   state => state.getIn(['notifications', 'items']) | ||||||
| ], (excludedTypes, notifications) => notifications.filterNot(item => excludedTypes.includes(item.get('type')))); | ], (excludedTypes, notifications) => notifications.filterNot(item => excludedTypes.includes(item.get('type')))); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -8,6 +8,9 @@ const en = { | ||||||
|   "status.reblog": "Teilen", |   "status.reblog": "Teilen", | ||||||
|   "status.favourite": "Favorisieren", |   "status.favourite": "Favorisieren", | ||||||
|   "status.reblogged_by": "{name} teilte", |   "status.reblogged_by": "{name} teilte", | ||||||
|  |   "status.sensitive_warning": "Sensible Inhalte", | ||||||
|  |   "status.sensitive_toggle": "Klicken um zu zeigen", | ||||||
|  |   "status.open": "Öffnen", | ||||||
|   "video_player.toggle_sound": "Ton umschalten", |   "video_player.toggle_sound": "Ton umschalten", | ||||||
|   "account.mention": "Erwähnen", |   "account.mention": "Erwähnen", | ||||||
|   "account.edit_profile": "Profil bearbeiten", |   "account.edit_profile": "Profil bearbeiten", | ||||||
|  | @ -19,14 +22,17 @@ const en = { | ||||||
|   "account.follows": "Folgt", |   "account.follows": "Folgt", | ||||||
|   "account.followers": "Folger", |   "account.followers": "Folger", | ||||||
|   "account.follows_you": "Folgt dir", |   "account.follows_you": "Folgt dir", | ||||||
|  |   "account.requested": "Warte auf Erlaubnis", | ||||||
|   "getting_started.heading": "Erste Schritte", |   "getting_started.heading": "Erste Schritte", | ||||||
|   "getting_started.about_addressing": "Du kannst Leuten folgen, falls du ihren Nutzernamen und ihre Domain kennst, in dem du eine e-mail-artige Addresse in das Suchfeld oben an der Seite eingibst.", |   "getting_started.about_addressing": "Du kannst Leuten folgen, falls du ihren Nutzernamen und ihre Domain kennst, in dem du eine e-mail-artige Addresse in das Suchfeld oben an der Seite eingibst.", | ||||||
|   "getting_started.about_shortcuts": "Falls der Zielnutzer an derselben Domain ist wie du, funktioniert der Nutzername auch alleine. Das gilt auch für Erwähnungen in Beiträgen.", |   "getting_started.about_shortcuts": "Falls der Zielnutzer an derselben Domain ist wie du, funktioniert der Nutzername auch alleine. Das gilt auch für Erwähnungen in Beiträgen.", | ||||||
|   "getting_started.about_developer": "Der Entwickler des Projekts kann unter Gargron@mastodon.social gefunden werden", |   "getting_started.about_developer": "Der Entwickler des Projekts kann unter Gargron@mastodon.social gefunden werden", | ||||||
|  |   "getting_started.open_source_notice": "Mastodon ist quelloffene Software. Du kannst auf {github} dazu beitragen oder Probleme melden.", | ||||||
|   "column.home": "Home", |   "column.home": "Home", | ||||||
|   "column.mentions": "Erwähnungen", |   "column.mentions": "Erwähnungen", | ||||||
|   "column.public": "Gesamtes Bekanntes Netz", |   "column.public": "Gesamtes Bekanntes Netz", | ||||||
|   "column.notifications": "Mitteilungen", |   "column.notifications": "Mitteilungen", | ||||||
|  |   "column.follow_requests": "Folgeanfragen", | ||||||
|   "tabs_bar.compose": "Schreiben", |   "tabs_bar.compose": "Schreiben", | ||||||
|   "tabs_bar.home": "Home", |   "tabs_bar.home": "Home", | ||||||
|   "tabs_bar.mentions": "Erwähnungen", |   "tabs_bar.mentions": "Erwähnungen", | ||||||
|  | @ -36,10 +42,12 @@ const en = { | ||||||
|   "compose_form.publish": "Veröffentlichen", |   "compose_form.publish": "Veröffentlichen", | ||||||
|   "compose_form.sensitive": "Medien als sensitiv markieren", |   "compose_form.sensitive": "Medien als sensitiv markieren", | ||||||
|   "compose_form.unlisted": "Öffentlich nicht auflisten", |   "compose_form.unlisted": "Öffentlich nicht auflisten", | ||||||
|  |   "compose_form.private": "Als privat markieren", | ||||||
|   "navigation_bar.edit_profile": "Profil bearbeiten", |   "navigation_bar.edit_profile": "Profil bearbeiten", | ||||||
|   "navigation_bar.preferences": "Einstellungen", |   "navigation_bar.preferences": "Einstellungen", | ||||||
|   "navigation_bar.public_timeline": "Öffentlich", |   "navigation_bar.public_timeline": "Öffentlich", | ||||||
|   "navigation_bar.logout": "Abmelden", |   "navigation_bar.logout": "Abmelden", | ||||||
|  |   "navigation_bar.follow_requests": "Folgeanfragen", | ||||||
|   "reply_indicator.cancel": "Abbrechen", |   "reply_indicator.cancel": "Abbrechen", | ||||||
|   "search.placeholder": "Suche", |   "search.placeholder": "Suche", | ||||||
|   "search.account": "Konto", |   "search.account": "Konto", | ||||||
|  | @ -49,7 +57,15 @@ const en = { | ||||||
|   "notification.follow": "{name} folgt dir", |   "notification.follow": "{name} folgt dir", | ||||||
|   "notification.favourite": "{name} favorisierte deinen Status", |   "notification.favourite": "{name} favorisierte deinen Status", | ||||||
|   "notification.reblog": "{name} teilte deinen Status", |   "notification.reblog": "{name} teilte deinen Status", | ||||||
|   "notification.mention": "{name} erwähnte dich" |   "notification.mention": "{name} erwähnte dich", | ||||||
|  |   "notifications.column_settings.alert": "Desktop-Benachrichtigunen", | ||||||
|  |   "notifications.column_settings.show": "In der Spalte anzeigen", | ||||||
|  |   "notifications.column_settings.follow": "Neue Folger:", | ||||||
|  |   "notifications.column_settings.favourite": "Favorisierungen:", | ||||||
|  |   "notifications.column_settings.mention": "Erwähnungen:", | ||||||
|  |   "notifications.column_settings.reblog": "Geteilte Beiträge:", | ||||||
|  |   "follow_request.authorize": "Erlauben", | ||||||
|  |   "follow_request.reject": "Ablehnen" | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export default en; | export default en; | ||||||
|  |  | ||||||
|  | @ -17,7 +17,6 @@ const en = { | ||||||
|   "account.unfollow": "Unfollow", |   "account.unfollow": "Unfollow", | ||||||
|   "account.block": "Block", |   "account.block": "Block", | ||||||
|   "account.follow": "Follow", |   "account.follow": "Follow", | ||||||
|   "account.block": "Block", |  | ||||||
|   "account.posts": "Posts", |   "account.posts": "Posts", | ||||||
|   "account.follows": "Follows", |   "account.follows": "Follows", | ||||||
|   "account.followers": "Followers", |   "account.followers": "Followers", | ||||||
|  | @ -41,6 +40,7 @@ const en = { | ||||||
|   "compose_form.publish": "Toot", |   "compose_form.publish": "Toot", | ||||||
|   "compose_form.sensitive": "Mark media as sensitive", |   "compose_form.sensitive": "Mark media as sensitive", | ||||||
|   "compose_form.private": "Mark as private", |   "compose_form.private": "Mark as private", | ||||||
|  |   "compose_form.unlisted": "Do not display in public timeline", | ||||||
|   "navigation_bar.edit_profile": "Edit profile", |   "navigation_bar.edit_profile": "Edit profile", | ||||||
|   "navigation_bar.preferences": "Preferences", |   "navigation_bar.preferences": "Preferences", | ||||||
|   "navigation_bar.public_timeline": "Public timeline", |   "navigation_bar.public_timeline": "Public timeline", | ||||||
|  |  | ||||||
|  | @ -11,6 +11,7 @@ import statuses from './statuses'; | ||||||
| import relationships from './relationships'; | import relationships from './relationships'; | ||||||
| import search from './search'; | import search from './search'; | ||||||
| import notifications from './notifications'; | import notifications from './notifications'; | ||||||
|  | import settings from './settings'; | ||||||
| 
 | 
 | ||||||
| export default combineReducers({ | export default combineReducers({ | ||||||
|   timelines, |   timelines, | ||||||
|  | @ -24,5 +25,6 @@ export default combineReducers({ | ||||||
|   statuses, |   statuses, | ||||||
|   relationships, |   relationships, | ||||||
|   search, |   search, | ||||||
|   notifications |   notifications, | ||||||
|  |   settings | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ import { | ||||||
|   NOTIFICATIONS_UPDATE, |   NOTIFICATIONS_UPDATE, | ||||||
|   NOTIFICATIONS_REFRESH_SUCCESS, |   NOTIFICATIONS_REFRESH_SUCCESS, | ||||||
|   NOTIFICATIONS_EXPAND_SUCCESS, |   NOTIFICATIONS_EXPAND_SUCCESS, | ||||||
|   NOTIFICATIONS_SETTING_CHANGE |  | ||||||
| } from '../actions/notifications'; | } from '../actions/notifications'; | ||||||
| import { ACCOUNT_BLOCK_SUCCESS } from '../actions/accounts'; | import { ACCOUNT_BLOCK_SUCCESS } from '../actions/accounts'; | ||||||
| import Immutable from 'immutable'; | import Immutable from 'immutable'; | ||||||
|  | @ -10,23 +9,7 @@ import Immutable from 'immutable'; | ||||||
| const initialState = Immutable.Map({ | const initialState = Immutable.Map({ | ||||||
|   items: Immutable.List(), |   items: Immutable.List(), | ||||||
|   next: null, |   next: null, | ||||||
|   loaded: false, |   loaded: false | ||||||
| 
 |  | ||||||
|   settings: Immutable.Map({ |  | ||||||
|     alerts: Immutable.Map({ |  | ||||||
|       follow: true, |  | ||||||
|       favourite: true, |  | ||||||
|       reblog: true, |  | ||||||
|       mention: true |  | ||||||
|     }), |  | ||||||
| 
 |  | ||||||
|     shows: Immutable.Map({ |  | ||||||
|       follow: true, |  | ||||||
|       favourite: true, |  | ||||||
|       reblog: true, |  | ||||||
|       mention: true |  | ||||||
|     }) |  | ||||||
|   }) |  | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| const notificationToMap = notification => Immutable.Map({ | const notificationToMap = notification => Immutable.Map({ | ||||||
|  | @ -67,17 +50,15 @@ const filterNotifications = (state, relationship) => { | ||||||
| 
 | 
 | ||||||
| export default function notifications(state = initialState, action) { | export default function notifications(state = initialState, action) { | ||||||
|   switch(action.type) { |   switch(action.type) { | ||||||
|     case NOTIFICATIONS_UPDATE: |   case NOTIFICATIONS_UPDATE: | ||||||
|       return normalizeNotification(state, action.notification); |     return normalizeNotification(state, action.notification); | ||||||
|     case NOTIFICATIONS_REFRESH_SUCCESS: |   case NOTIFICATIONS_REFRESH_SUCCESS: | ||||||
|       return normalizeNotifications(state, action.notifications, action.next); |     return normalizeNotifications(state, action.notifications, action.next); | ||||||
|     case NOTIFICATIONS_EXPAND_SUCCESS: |   case NOTIFICATIONS_EXPAND_SUCCESS: | ||||||
|       return appendNormalizedNotifications(state, action.notifications, action.next); |     return appendNormalizedNotifications(state, action.notifications, action.next); | ||||||
|     case ACCOUNT_BLOCK_SUCCESS: |   case ACCOUNT_BLOCK_SUCCESS: | ||||||
|       return filterNotifications(state, action.relationship); |     return filterNotifications(state, action.relationship); | ||||||
|     case NOTIFICATIONS_SETTING_CHANGE: |   default: | ||||||
|       return state.setIn(['settings', ...action.key], action.checked); |     return state; | ||||||
|     default: |  | ||||||
|       return state; |  | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -0,0 +1,32 @@ | ||||||
|  | import { SETTING_CHANGE } from '../actions/settings'; | ||||||
|  | import { STORE_HYDRATE } from '../actions/store'; | ||||||
|  | import Immutable from 'immutable'; | ||||||
|  | 
 | ||||||
|  | const initialState = Immutable.Map({ | ||||||
|  |   notifications: Immutable.Map({ | ||||||
|  |     alerts: Immutable.Map({ | ||||||
|  |       follow: true, | ||||||
|  |       favourite: true, | ||||||
|  |       reblog: true, | ||||||
|  |       mention: true | ||||||
|  |     }), | ||||||
|  | 
 | ||||||
|  |     shows: Immutable.Map({ | ||||||
|  |       follow: true, | ||||||
|  |       favourite: true, | ||||||
|  |       reblog: true, | ||||||
|  |       mention: true | ||||||
|  |     }) | ||||||
|  |   }) | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | export default function settings(state = initialState, action) { | ||||||
|  |   switch(action.type) { | ||||||
|  |   case STORE_HYDRATE: | ||||||
|  |     return state.merge(action.state.get('settings')); | ||||||
|  |   case SETTING_CHANGE: | ||||||
|  |     return state.setIn(action.key, action.value); | ||||||
|  |   default: | ||||||
|  |     return state; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | @ -0,0 +1,15 @@ | ||||||
|  | # frozen_string_literal: true | ||||||
|  | 
 | ||||||
|  | class Api::Web::SettingsController < ApiController | ||||||
|  |   respond_to :json | ||||||
|  | 
 | ||||||
|  |   before_action :require_user! | ||||||
|  | 
 | ||||||
|  |   def update | ||||||
|  |     setting      = Web::Setting.where(user: current_user).first_or_initialize(user: current_user) | ||||||
|  |     setting.data = params[:data] | ||||||
|  |     setting.save! | ||||||
|  | 
 | ||||||
|  |     render_empty | ||||||
|  |   end | ||||||
|  | end | ||||||
|  | @ -6,6 +6,7 @@ class HomeController < ApplicationController | ||||||
|   def index |   def index | ||||||
|     @body_classes = 'app-body' |     @body_classes = 'app-body' | ||||||
|     @token        = find_or_create_access_token.token |     @token        = find_or_create_access_token.token | ||||||
|  |     @web_settings = Web::Setting.find_by(user: current_user)&.data || {} | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   private |   private | ||||||
|  |  | ||||||
|  | @ -104,7 +104,7 @@ class Account < ApplicationRecord | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def subscribed? |   def subscribed? | ||||||
|     subscription_expires_at |     !subscription_expires_at.blank? | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def favourited?(status) |   def favourited?(status) | ||||||
|  | @ -189,7 +189,7 @@ class Account < ApplicationRecord | ||||||
|     def requested_map(target_account_ids, account_id) |     def requested_map(target_account_ids, account_id) | ||||||
|       follow_mapping(FollowRequest.where(target_account_id: target_account_ids, account_id: account_id), :target_account_id) |       follow_mapping(FollowRequest.where(target_account_id: target_account_ids, account_id: account_id), :target_account_id) | ||||||
|     end |     end | ||||||
|      | 
 | ||||||
|     private |     private | ||||||
| 
 | 
 | ||||||
|     def follow_mapping(query, field) |     def follow_mapping(query, field) | ||||||
|  |  | ||||||
|  | @ -0,0 +1,5 @@ | ||||||
|  | module Web | ||||||
|  |   def self.table_name_prefix | ||||||
|  |     'web_' | ||||||
|  |   end | ||||||
|  | end | ||||||
|  | @ -0,0 +1,7 @@ | ||||||
|  | # frozen_string_literal: true | ||||||
|  | 
 | ||||||
|  | class Web::Setting < ApplicationRecord | ||||||
|  |   belongs_to :user | ||||||
|  | 
 | ||||||
|  |   validates :user, uniqueness: true | ||||||
|  | end | ||||||
|  | @ -1,21 +1,6 @@ | ||||||
| - content_for :header_tags do | - content_for :header_tags do | ||||||
|   :javascript |   :javascript | ||||||
|     window.INITIAL_STATE = { |     window.INITIAL_STATE = #{render(file: 'home/initial_state', formats: :json)} | ||||||
|       "meta": { |  | ||||||
|         "access_token": "#{@token}", |  | ||||||
|         "locale": "#{I18n.locale}", |  | ||||||
|         "me": #{current_account.id} |  | ||||||
|       }, |  | ||||||
| 
 |  | ||||||
|       "compose": { |  | ||||||
|         "me": #{current_account.id}, |  | ||||||
|         "private": #{current_account.locked?} |  | ||||||
|       }, |  | ||||||
| 
 |  | ||||||
|       "accounts": { |  | ||||||
|         #{current_account.id}: #{render(file: 'api/v1/accounts/show', locals: { account: current_user.account }, formats: :json)} |  | ||||||
|       } |  | ||||||
|     }; |  | ||||||
| 
 | 
 | ||||||
|   = javascript_include_tag 'application' |   = javascript_include_tag 'application' | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,24 @@ | ||||||
|  | object false | ||||||
|  | 
 | ||||||
|  | node(:meta) { | ||||||
|  |   { | ||||||
|  |     access_token: @token, | ||||||
|  |     locale: I18n.locale, | ||||||
|  |     me: current_account.id, | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | node(:compose) { | ||||||
|  |   { | ||||||
|  |     me: current_account.id, | ||||||
|  |     private: current_account.locked?, | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | node(:accounts) { | ||||||
|  |   { | ||||||
|  |     current_account.id => partial('api/v1/accounts/show', object: current_account), | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | node(:settings) { @web_settings } | ||||||
|  | @ -14,6 +14,7 @@ de: | ||||||
|     people_followed_by: Nutzer, denen %{name} folgt |     people_followed_by: Nutzer, denen %{name} folgt | ||||||
|     people_who_follow: Nutzer, die %{name} folgen |     people_who_follow: Nutzer, die %{name} folgen | ||||||
|     posts: Beiträge |     posts: Beiträge | ||||||
|  |     remote_follow: Folgen | ||||||
|     unfollow: Entfolgen |     unfollow: Entfolgen | ||||||
|   application_mailer: |   application_mailer: | ||||||
|     signature: Mastodon-Benachrichtigungen von %{instance} |     signature: Mastodon-Benachrichtigungen von %{instance} | ||||||
|  | @ -26,6 +27,25 @@ de: | ||||||
|     resend_confirmation: Bestätigung nochmal versenden |     resend_confirmation: Bestätigung nochmal versenden | ||||||
|     reset_password: Passwort zurücksetzen |     reset_password: Passwort zurücksetzen | ||||||
|     set_new_password: Neues Passwort setzen |     set_new_password: Neues Passwort setzen | ||||||
|  |   authorize_follow: | ||||||
|  |     error: Das entfernte Profil konnte nicht geladen werden | ||||||
|  |     follow: Folgen | ||||||
|  |     prompt_html: 'Du (<strong>%{self}</strong>) möchtest dieser Person folgen:' | ||||||
|  |     title: "%{acct} folgen" | ||||||
|  |   datetime: | ||||||
|  |     distance_in_words: | ||||||
|  |       about_x_hours: "%{count}h" | ||||||
|  |       about_x_months: "%{count}mo" | ||||||
|  |       about_x_years: "%{count}y" | ||||||
|  |       almost_x_years: "%{count}y" | ||||||
|  |       half_a_minute: Gerade eben | ||||||
|  |       less_than_x_minutes: "%{count}m" | ||||||
|  |       less_than_x_seconds: Gerade eben | ||||||
|  |       over_x_years: "%{count}y" | ||||||
|  |       x_days: "%{count}d" | ||||||
|  |       x_minutes: "%{count}m" | ||||||
|  |       x_months: "%{count}mo" | ||||||
|  |       x_seconds: "%{count}s" | ||||||
|   generic: |   generic: | ||||||
|     changes_saved_msg: Änderungen gespeichert! |     changes_saved_msg: Änderungen gespeichert! | ||||||
|     powered_by: angetrieben von %{link} |     powered_by: angetrieben von %{link} | ||||||
|  | @ -40,6 +60,9 @@ de: | ||||||
|     follow: |     follow: | ||||||
|       body: "%{name} folgt dir jetzt!" |       body: "%{name} folgt dir jetzt!" | ||||||
|       subject: "%{name} folgt dir nun" |       subject: "%{name} folgt dir nun" | ||||||
|  |     follow_request: | ||||||
|  |       body: "%{name} möchte dir folgen:" | ||||||
|  |       subject: "%{name} möchte dir folgen" | ||||||
|     mention: |     mention: | ||||||
|       body: "%{name} hat dich erwähnt:" |       body: "%{name} hat dich erwähnt:" | ||||||
|       subject: "%{name} hat dich erwähnt" |       subject: "%{name} hat dich erwähnt" | ||||||
|  | @ -49,13 +72,23 @@ de: | ||||||
|   pagination: |   pagination: | ||||||
|     next: Vorwärts |     next: Vorwärts | ||||||
|     prev: Zurück |     prev: Zurück | ||||||
|  |   remote_follow: | ||||||
|  |     acct: Dein Nutzername@Domain, von dem du dieser Person folgen möchtest | ||||||
|  |     missing_resource: Die erforderliche Weiterleitungs-URL konnte leider in deinem Profil nicht gefunden werden | ||||||
|  |     proceed: Weiter | ||||||
|  |     prompt: 'Du wirst dieser Person folgen:' | ||||||
|   settings: |   settings: | ||||||
|     edit_profile: Profil bearbeiten |     edit_profile: Profil bearbeiten | ||||||
|     preferences: Einstellungen |     preferences: Einstellungen | ||||||
|   stream_entries: |   stream_entries: | ||||||
|  |     click_to_show: Klicken um zu zeigen | ||||||
|     favourited: favorisierte einen Beitrag von |     favourited: favorisierte einen Beitrag von | ||||||
|     is_now_following: folgt nun |     is_now_following: folgt nun | ||||||
|     reblogged: teilte |     reblogged: teilte | ||||||
|  |     sensitive_content: Sensible Inhalte | ||||||
|  |   time: | ||||||
|  |     formats: | ||||||
|  |       default: "%d.%m.%Y %H:%M" | ||||||
|   users: |   users: | ||||||
|     invalid_email: Inkorrekte E-mail-Addresse |     invalid_email: Inkorrekte E-mail-Addresse | ||||||
|   will_paginate: |   will_paginate: | ||||||
|  |  | ||||||
|  | @ -1,6 +1,9 @@ | ||||||
| --- | --- | ||||||
| de: | de: | ||||||
|   simple_form: |   simple_form: | ||||||
|  |     hints: | ||||||
|  |       defaults: | ||||||
|  |         locked: Erlaubt dir, Folger zu überprüfen, bevor sie dir folgen können | ||||||
|     labels: |     labels: | ||||||
|       defaults: |       defaults: | ||||||
|         avatar: Avatar |         avatar: Avatar | ||||||
|  | @ -11,6 +14,7 @@ de: | ||||||
|         email: E-mail-Addresse |         email: E-mail-Addresse | ||||||
|         header: Kopfbild |         header: Kopfbild | ||||||
|         locale: Sprache |         locale: Sprache | ||||||
|  |         locked: Gesperrter Profil | ||||||
|         new_password: Neues Passwort |         new_password: Neues Passwort | ||||||
|         note: Über mich |         note: Über mich | ||||||
|         password: Passwort |         password: Passwort | ||||||
|  | @ -21,6 +25,7 @@ de: | ||||||
|       notification_emails: |       notification_emails: | ||||||
|         favourite: E-mail senden, wenn jemand meinen Beitrag favorisiert |         favourite: E-mail senden, wenn jemand meinen Beitrag favorisiert | ||||||
|         follow: E-mail senden, wenn mir jemand folgt |         follow: E-mail senden, wenn mir jemand folgt | ||||||
|  |         follow_request: E-mail senden, wenn mir jemand folgen möchte | ||||||
|         mention: E-mail senden, wenn mich jemand erwähnt |         mention: E-mail senden, wenn mich jemand erwähnt | ||||||
|         reblog: E-mail senden, wenn jemand meinen Beitrag teilt |         reblog: E-mail senden, wenn jemand meinen Beitrag teilt | ||||||
|     'no': Nein |     'no': Nein | ||||||
|  |  | ||||||
|  | @ -134,6 +134,10 @@ Rails.application.routes.draw do | ||||||
|         end |         end | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
|  | 
 | ||||||
|  |     namespace :web do | ||||||
|  |       resource :settings, only: [:update] | ||||||
|  |     end | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   get '/web/(*any)', to: 'home#index', as: :web |   get '/web/(*any)', to: 'home#index', as: :web | ||||||
|  |  | ||||||
|  | @ -0,0 +1,12 @@ | ||||||
|  | class CreateWebSettings < ActiveRecord::Migration[5.0] | ||||||
|  |   def change | ||||||
|  |     create_table :web_settings do |t| | ||||||
|  |       t.integer :user_id | ||||||
|  |       t.json :data | ||||||
|  | 
 | ||||||
|  |       t.timestamps | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     add_index :web_settings, :user_id, unique: true | ||||||
|  |   end | ||||||
|  | end | ||||||
							
								
								
									
										79
									
								
								db/schema.rb
								
								
								
								
							
							
						
						
									
										79
									
								
								db/schema.rb
								
								
								
								
							|  | @ -10,7 +10,7 @@ | ||||||
| # | # | ||||||
| # It's strongly recommended that you check this file into your version control system. | # It's strongly recommended that you check this file into your version control system. | ||||||
| 
 | 
 | ||||||
| ActiveRecord::Schema.define(version: 20170105224407) do | ActiveRecord::Schema.define(version: 20170109120109) do | ||||||
| 
 | 
 | ||||||
|   # These are extensions that must be enabled in order to support this database |   # These are extensions that must be enabled in order to support this database | ||||||
|   enable_extension "plpgsql" |   enable_extension "plpgsql" | ||||||
|  | @ -169,6 +169,74 @@ ActiveRecord::Schema.define(version: 20170105224407) do | ||||||
|     t.index ["topic", "callback"], name: "index_pubsubhubbub_subscriptions_on_topic_and_callback", unique: true, using: :btree |     t.index ["topic", "callback"], name: "index_pubsubhubbub_subscriptions_on_topic_and_callback", unique: true, using: :btree | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  |   create_table "push_devices", force: :cascade do |t| | ||||||
|  |     t.string   "service",    default: "", null: false | ||||||
|  |     t.string   "token",      default: "", null: false | ||||||
|  |     t.integer  "account",                 null: false | ||||||
|  |     t.datetime "created_at",              null: false | ||||||
|  |     t.datetime "updated_at",              null: false | ||||||
|  |     t.index ["service", "token"], name: "index_push_devices_on_service_and_token", unique: true, using: :btree | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   create_table "rpush_apps", force: :cascade do |t| | ||||||
|  |     t.string   "name",                                null: false | ||||||
|  |     t.string   "environment" | ||||||
|  |     t.text     "certificate" | ||||||
|  |     t.string   "password" | ||||||
|  |     t.integer  "connections",             default: 1, null: false | ||||||
|  |     t.datetime "created_at",                          null: false | ||||||
|  |     t.datetime "updated_at",                          null: false | ||||||
|  |     t.string   "type",                                null: false | ||||||
|  |     t.string   "auth_key" | ||||||
|  |     t.string   "client_id" | ||||||
|  |     t.string   "client_secret" | ||||||
|  |     t.string   "access_token" | ||||||
|  |     t.datetime "access_token_expiration" | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   create_table "rpush_feedback", force: :cascade do |t| | ||||||
|  |     t.string   "device_token", limit: 64, null: false | ||||||
|  |     t.datetime "failed_at",               null: false | ||||||
|  |     t.datetime "created_at",              null: false | ||||||
|  |     t.datetime "updated_at",              null: false | ||||||
|  |     t.integer  "app_id" | ||||||
|  |     t.index ["device_token"], name: "index_rpush_feedback_on_device_token", using: :btree | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   create_table "rpush_notifications", force: :cascade do |t| | ||||||
|  |     t.integer  "badge" | ||||||
|  |     t.string   "device_token",      limit: 64 | ||||||
|  |     t.string   "sound",                        default: "default" | ||||||
|  |     t.text     "alert" | ||||||
|  |     t.text     "data" | ||||||
|  |     t.integer  "expiry",                       default: 86400 | ||||||
|  |     t.boolean  "delivered",                    default: false,     null: false | ||||||
|  |     t.datetime "delivered_at" | ||||||
|  |     t.boolean  "failed",                       default: false,     null: false | ||||||
|  |     t.datetime "failed_at" | ||||||
|  |     t.integer  "error_code" | ||||||
|  |     t.text     "error_description" | ||||||
|  |     t.datetime "deliver_after" | ||||||
|  |     t.datetime "created_at",                                       null: false | ||||||
|  |     t.datetime "updated_at",                                       null: false | ||||||
|  |     t.boolean  "alert_is_json",                default: false | ||||||
|  |     t.string   "type",                                             null: false | ||||||
|  |     t.string   "collapse_key" | ||||||
|  |     t.boolean  "delay_while_idle",             default: false,     null: false | ||||||
|  |     t.text     "registration_ids" | ||||||
|  |     t.integer  "app_id",                                           null: false | ||||||
|  |     t.integer  "retries",                      default: 0 | ||||||
|  |     t.string   "uri" | ||||||
|  |     t.datetime "fail_after" | ||||||
|  |     t.boolean  "processing",                   default: false,     null: false | ||||||
|  |     t.integer  "priority" | ||||||
|  |     t.text     "url_args" | ||||||
|  |     t.string   "category" | ||||||
|  |     t.boolean  "content_available",            default: false | ||||||
|  |     t.text     "notification" | ||||||
|  |     t.index ["delivered", "failed"], name: "index_rpush_notifications_multi", where: "((NOT delivered) AND (NOT failed))", using: :btree | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|   create_table "settings", force: :cascade do |t| |   create_table "settings", force: :cascade do |t| | ||||||
|     t.string   "var",         null: false |     t.string   "var",         null: false | ||||||
|     t.text     "value" |     t.text     "value" | ||||||
|  | @ -191,7 +259,6 @@ ActiveRecord::Schema.define(version: 20170105224407) do | ||||||
|     t.boolean  "sensitive",              default: false |     t.boolean  "sensitive",              default: false | ||||||
|     t.integer  "visibility",             default: 0,     null: false |     t.integer  "visibility",             default: 0,     null: false | ||||||
|     t.integer  "in_reply_to_account_id" |     t.integer  "in_reply_to_account_id" | ||||||
|     t.string   "conversation_uri" |  | ||||||
|     t.index ["account_id"], name: "index_statuses_on_account_id", using: :btree |     t.index ["account_id"], name: "index_statuses_on_account_id", using: :btree | ||||||
|     t.index ["in_reply_to_id"], name: "index_statuses_on_in_reply_to_id", using: :btree |     t.index ["in_reply_to_id"], name: "index_statuses_on_in_reply_to_id", using: :btree | ||||||
|     t.index ["reblog_of_id"], name: "index_statuses_on_reblog_of_id", using: :btree |     t.index ["reblog_of_id"], name: "index_statuses_on_reblog_of_id", using: :btree | ||||||
|  | @ -260,4 +327,12 @@ ActiveRecord::Schema.define(version: 20170105224407) do | ||||||
|     t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree |     t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  |   create_table "web_settings", force: :cascade do |t| | ||||||
|  |     t.integer  "user_id" | ||||||
|  |     t.json     "data" | ||||||
|  |     t.datetime "created_at", null: false | ||||||
|  |     t.datetime "updated_at", null: false | ||||||
|  |     t.index ["user_id"], name: "index_web_settings_on_user_id", unique: true, using: :btree | ||||||
|  |   end | ||||||
|  | 
 | ||||||
| end | end | ||||||
|  |  | ||||||
|  | @ -1,2 +1,3 @@ | ||||||
| Fabricator(:media_attachment) do | Fabricator(:media_attachment) do | ||||||
|  | 
 | ||||||
| end | end | ||||||
|  |  | ||||||
|  | @ -0,0 +1,3 @@ | ||||||
|  | Fabricator('Web::Setting') do | ||||||
|  | 
 | ||||||
|  | end | ||||||
|  | @ -154,6 +154,31 @@ RSpec.describe Account, type: :model do | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  |   describe '.following_map' do | ||||||
|  |     it 'returns an hash' do | ||||||
|  |       expect(Account.following_map([], 1)).to be_a Hash | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   describe '.followed_by_map' do | ||||||
|  |     it 'returns an hash' do | ||||||
|  |       expect(Account.followed_by_map([], 1)).to be_a Hash | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   describe '.blocking_map' do | ||||||
|  |     it 'returns an hash' do | ||||||
|  |       expect(Account.blocking_map([], 1)).to be_a Hash | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   describe '.requested_map' do | ||||||
|  |     it 'returns an hash' do | ||||||
|  |       expect(Account.requested_map([], 1)).to be_a Hash | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|   describe 'MENTION_RE' do |   describe 'MENTION_RE' do | ||||||
|     subject { Account::MENTION_RE } |     subject { Account::MENTION_RE } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,5 @@ | ||||||
|  | require 'rails_helper' | ||||||
|  | 
 | ||||||
|  | RSpec.describe Web::Setting, type: :model do | ||||||
|  | 
 | ||||||
|  | end | ||||||
		Loading…
	
		Reference in New Issue