From 21d1a59e7b6644b2e7e1248d68c56c2236a2ed4b Mon Sep 17 00:00:00 2001 From: Natalia Ossipova Date: Mon, 13 Feb 2023 13:36:04 +0100 Subject: [PATCH 01/87] Show post visibility indicator --- Mastodon.xcodeproj/project.pbxproj | 4 - .../Compose/View/ComposeToolbarView.swift | 384 ------------------ .../ComposeContentViewController.swift | 1 - .../View/Content/StatusAuthorView.swift | 77 ++-- .../View/Content/StatusView+ViewModel.swift | 15 + 5 files changed, 67 insertions(+), 414 deletions(-) delete mode 100644 Mastodon/Scene/Compose/View/ComposeToolbarView.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index df71d94d6..b0162ba6e 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -390,7 +390,6 @@ DB9F58EC26EF435000E7BBE9 /* AccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9F58EB26EF435000E7BBE9 /* AccountViewController.swift */; }; DB9F58EF26EF491E00E7BBE9 /* AccountListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9F58EE26EF491E00E7BBE9 /* AccountListViewModel.swift */; }; DB9F58F126EF512300E7BBE9 /* AccountListTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9F58F026EF512300E7BBE9 /* AccountListTableViewCell.swift */; }; - DBA0A11325FB3FC10079C110 /* ComposeToolbarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA0A11225FB3FC10079C110 /* ComposeToolbarView.swift */; }; DBA4B0F626C269880077136E /* Intents.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = DBA4B0F926C269880077136E /* Intents.stringsdict */; }; DBA4B0F726C269880077136E /* Intents.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = DBA4B0F926C269880077136E /* Intents.stringsdict */; }; DBA5A53126F08EF000CACBAA /* DragIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA5A53026F08EF000CACBAA /* DragIndicatorView.swift */; }; @@ -1087,7 +1086,6 @@ DB9F58EB26EF435000E7BBE9 /* AccountViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountViewController.swift; sourceTree = ""; }; DB9F58EE26EF491E00E7BBE9 /* AccountListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountListViewModel.swift; sourceTree = ""; }; DB9F58F026EF512300E7BBE9 /* AccountListTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountListTableViewCell.swift; sourceTree = ""; }; - DBA0A11225FB3FC10079C110 /* ComposeToolbarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeToolbarView.swift; sourceTree = ""; }; DBA4B0D326BD10AC0077136E /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Intents.strings"; sourceTree = ""; }; DBA4B0D626BD10AD0077136E /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; DBA4B0D726BD10F40077136E /* ca */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ca; path = ca.lproj/Intents.strings; sourceTree = ""; }; @@ -2164,7 +2162,6 @@ DB55D32225FB4D320002F825 /* View */ = { isa = PBXGroup; children = ( - DBA0A11225FB3FC10079C110 /* ComposeToolbarView.swift */, DB8190C52601FF0400020C08 /* AttachmentContainerView.swift */, DB9A486B26032AC1008B817C /* AttachmentContainerView+EmptyStateView.swift */, DBC7A671260C897100E57475 /* StatusContentWarningEditorView.swift */, @@ -3839,7 +3836,6 @@ DB45FAB625CA5485005A8AC7 /* UIAlertController.swift in Sources */, DBE0821525CD382600FD6BBD /* MastodonRegisterViewController.swift in Sources */, DBEFCD74282A130400C0ABEA /* ReportReasonViewModel.swift in Sources */, - DBA0A11325FB3FC10079C110 /* ComposeToolbarView.swift in Sources */, DBFEEC96279BDC67004F81DD /* ProfileAboutViewController.swift in Sources */, DB63F74F2799405600455B82 /* SearchHistoryViewModel+Diffable.swift in Sources */, DB0EF72B26FDB1D200347686 /* SidebarListCollectionViewCell.swift in Sources */, diff --git a/Mastodon/Scene/Compose/View/ComposeToolbarView.swift b/Mastodon/Scene/Compose/View/ComposeToolbarView.swift deleted file mode 100644 index a993da228..000000000 --- a/Mastodon/Scene/Compose/View/ComposeToolbarView.swift +++ /dev/null @@ -1,384 +0,0 @@ -// -// ComposeToolbarView.swift -// Mastodon -// -// Created by MainasuK Cirno on 2021-3-12. -// - -import os.log -import UIKit -import Combine -import MastodonSDK -import MastodonAsset -import MastodonCore -import MastodonUI -import MastodonLocalization - -protocol ComposeToolbarViewDelegate: AnyObject { - func composeToolbarView(_ composeToolbarView: ComposeToolbarView, mediaButtonDidPressed sender: Any, mediaSelectionType type: ComposeToolbarView.MediaSelectionType) - func composeToolbarView(_ composeToolbarView: ComposeToolbarView, pollButtonDidPressed sender: Any) - func composeToolbarView(_ composeToolbarView: ComposeToolbarView, emojiButtonDidPressed sender: Any) - func composeToolbarView(_ composeToolbarView: ComposeToolbarView, contentWarningButtonDidPressed sender: Any) - func composeToolbarView(_ composeToolbarView: ComposeToolbarView, visibilityButtonDidPressed sender: Any, visibilitySelectionType type: ComposeToolbarView.VisibilitySelectionType) -} - -final class ComposeToolbarView: UIView { - - var disposeBag = Set() - - static let toolbarButtonSize: CGSize = CGSize(width: 44, height: 44) - static let toolbarHeight: CGFloat = 44 - - weak var delegate: ComposeToolbarViewDelegate? - - // barButtonItem - private(set) lazy var mediaBarButtonItem: UIBarButtonItem = { - let barButtonItem = UIBarButtonItem() - barButtonItem.image = UIImage(systemName: "photo") - barButtonItem.accessibilityLabel = L10n.Scene.Compose.Accessibility.appendAttachment - return barButtonItem - }() - - let pollBarButtonItem: UIBarButtonItem = { - let barButtonItem = UIBarButtonItem() - barButtonItem.image = UIImage(systemName: "list.bullet") - barButtonItem.accessibilityLabel = L10n.Scene.Compose.Accessibility.appendPoll - return barButtonItem - }() - - let contentWarningBarButtonItem: UIBarButtonItem = { - let barButtonItem = UIBarButtonItem() - barButtonItem.image = UIImage(systemName: "exclamationmark.shield") - barButtonItem.accessibilityLabel = L10n.Scene.Compose.Accessibility.enableContentWarning - return barButtonItem - }() - - let visibilityBarButtonItem: UIBarButtonItem = { - let barButtonItem = UIBarButtonItem() - barButtonItem.image = UIImage(systemName: "person.3") - barButtonItem.accessibilityLabel = L10n.Scene.Compose.Accessibility.postVisibilityMenu - return barButtonItem - }() - - // button - - let mediaButton: UIButton = { - let button = HighlightDimmableButton() - ComposeToolbarView.configureToolbarButtonAppearance(button: button) - button.setImage(UIImage(systemName: "photo", withConfiguration: UIImage.SymbolConfiguration(pointSize: 20, weight: .regular)), for: .normal) - button.accessibilityLabel = L10n.Scene.Compose.Accessibility.appendAttachment - return button - }() - - let pollButton: UIButton = { - let button = HighlightDimmableButton(type: .custom) - ComposeToolbarView.configureToolbarButtonAppearance(button: button) - button.setImage(UIImage(systemName: "list.bullet", withConfiguration: UIImage.SymbolConfiguration(pointSize: 20, weight: .medium)), for: .normal) - button.accessibilityLabel = L10n.Scene.Compose.Accessibility.appendPoll - return button - }() - - let emojiButton: UIButton = { - let button = HighlightDimmableButton() - ComposeToolbarView.configureToolbarButtonAppearance(button: button) - let image = Asset.Human.faceSmilingAdaptive.image - .af.imageScaled(to: CGSize(width: 20, height: 20)) - .withRenderingMode(.alwaysTemplate) - button.setImage(image, for: .normal) - button.accessibilityLabel = L10n.Scene.Compose.Accessibility.customEmojiPicker - return button - }() - - let contentWarningButton: UIButton = { - let button = HighlightDimmableButton() - ComposeToolbarView.configureToolbarButtonAppearance(button: button) - button.setImage(UIImage(systemName: "exclamationmark.shield", withConfiguration: UIImage.SymbolConfiguration(pointSize: 20, weight: .regular)), for: .normal) - button.accessibilityLabel = L10n.Scene.Compose.Accessibility.enableContentWarning - return button - }() - - let visibilityButton: UIButton = { - let button = HighlightDimmableButton() - ComposeToolbarView.configureToolbarButtonAppearance(button: button) - button.setImage(UIImage(systemName: "person.3", withConfiguration: UIImage.SymbolConfiguration(pointSize: 15, weight: .medium)), for: .normal) - button.accessibilityLabel = L10n.Scene.Compose.Accessibility.postVisibilityMenu - return button - }() - - let characterCountLabel: UILabel = { - let label = UILabel() - label.font = .systemFont(ofSize: 15, weight: .regular) - label.text = "500" - label.textColor = Asset.Colors.Label.secondary.color - label.accessibilityLabel = L10n.A11y.Plural.Count.inputLimitRemains(500) - return label - }() - - let activeVisibilityType = CurrentValueSubject(.public) - - override init(frame: CGRect) { - super.init(frame: frame) - _init() - } - - required init?(coder: NSCoder) { - super.init(coder: coder) - _init() - } - -} - -extension ComposeToolbarView { - - private func _init() { - setupBackgroundColor(theme: ThemeService.shared.currentTheme.value) - ThemeService.shared.currentTheme - .receive(on: DispatchQueue.main) - .sink { [weak self] theme in - guard let self = self else { return } - self.setupBackgroundColor(theme: theme) - } - .store(in: &disposeBag) - - let stackView = UIStackView() - stackView.axis = .horizontal - stackView.spacing = 0 - stackView.distribution = .fillEqually - stackView.translatesAutoresizingMaskIntoConstraints = false - addSubview(stackView) - NSLayoutConstraint.activate([ - stackView.centerYAnchor.constraint(equalTo: centerYAnchor), - layoutMarginsGuide.leadingAnchor.constraint(equalTo: stackView.leadingAnchor, constant: 8), // tweak button margin offset - ]) - - let buttons = [ - mediaButton, - pollButton, - emojiButton, - contentWarningButton, - visibilityButton, - ] - buttons.forEach { button in - button.translatesAutoresizingMaskIntoConstraints = false - stackView.addArrangedSubview(button) - NSLayoutConstraint.activate([ - button.widthAnchor.constraint(equalToConstant: 44), - button.heightAnchor.constraint(equalToConstant: 44), - ]) - } - - characterCountLabel.translatesAutoresizingMaskIntoConstraints = false - addSubview(characterCountLabel) - NSLayoutConstraint.activate([ - characterCountLabel.topAnchor.constraint(equalTo: topAnchor), - characterCountLabel.leadingAnchor.constraint(greaterThanOrEqualTo: stackView.trailingAnchor, constant: 8), - characterCountLabel.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor), - characterCountLabel.bottomAnchor.constraint(equalTo: bottomAnchor), - ]) - characterCountLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal) - - mediaBarButtonItem.menu = createMediaContextMenu() - mediaButton.menu = createMediaContextMenu() - mediaButton.showsMenuAsPrimaryAction = true - pollBarButtonItem.target = self - pollBarButtonItem.action = #selector(ComposeToolbarView.pollButtonDidPressed(_:)) - pollButton.addTarget(self, action: #selector(ComposeToolbarView.pollButtonDidPressed(_:)), for: .touchUpInside) - emojiButton.addTarget(self, action: #selector(ComposeToolbarView.emojiButtonDidPressed(_:)), for: .touchUpInside) - contentWarningBarButtonItem.target = self - contentWarningBarButtonItem.action = #selector(ComposeToolbarView.contentWarningButtonDidPressed(_:)) - contentWarningButton.addTarget(self, action: #selector(ComposeToolbarView.contentWarningButtonDidPressed(_:)), for: .touchUpInside) - visibilityBarButtonItem.menu = createVisibilityContextMenu(interfaceStyle: traitCollection.userInterfaceStyle) - visibilityButton.menu = createVisibilityContextMenu(interfaceStyle: traitCollection.userInterfaceStyle) - visibilityButton.showsMenuAsPrimaryAction = true - - updateToolbarButtonUserInterfaceStyle() - - // update menu when selected visibility type changed - activeVisibilityType - .receive(on: RunLoop.main) - .sink { [weak self] type in - guard let self = self else { return } - self.visibilityBarButtonItem.menu = self.createVisibilityContextMenu(interfaceStyle: self.traitCollection.userInterfaceStyle) - self.visibilityButton.menu = self.createVisibilityContextMenu(interfaceStyle: self.traitCollection.userInterfaceStyle) - } - .store(in: &disposeBag) - } - - override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { - super.traitCollectionDidChange(previousTraitCollection) - - updateToolbarButtonUserInterfaceStyle() - } - -} - -extension ComposeToolbarView { - enum MediaSelectionType: String { - case camera - case photoLibrary - case browse - } - - enum VisibilitySelectionType: String, CaseIterable { - case `public` - // TODO: remove unlisted option from codebase - // case unlisted - case `private` - case direct - - var title: String { - switch self { - case .public: return L10n.Scene.Compose.Visibility.public - // case .unlisted: return L10n.Scene.Compose.Visibility.unlisted - case .private: return L10n.Scene.Compose.Visibility.private - case .direct: return L10n.Scene.Compose.Visibility.direct - } - } - - func image(interfaceStyle: UIUserInterfaceStyle) -> UIImage { - switch self { - case .public: return UIImage(systemName: "globe", withConfiguration: UIImage.SymbolConfiguration(pointSize: 19, weight: .medium))! - // case .unlisted: return UIImage(systemName: "eye.slash", withConfiguration: UIImage.SymbolConfiguration(pointSize: 18, weight: .regular))! - case .private: - switch interfaceStyle { - case .light: return UIImage(systemName: "person.3", withConfiguration: UIImage.SymbolConfiguration(pointSize: 15, weight: .medium))! - default: return UIImage(systemName: "person.3.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: 15, weight: .medium))! - } - case .direct: return UIImage(systemName: "at", withConfiguration: UIImage.SymbolConfiguration(pointSize: 19, weight: .regular))! - } - } - - var visibility: Mastodon.Entity.Status.Visibility { - switch self { - case .public: return .public - // case .unlisted: return .unlisted - case .private: return .private - case .direct: return .direct - } - } - } -} - -extension ComposeToolbarView { - - private func setupBackgroundColor(theme: Theme) { - backgroundColor = theme.composeToolbarBackgroundColor - } - - private static func configureToolbarButtonAppearance(button: UIButton) { - button.tintColor = ThemeService.tintColor - button.setBackgroundImage(.placeholder(size: ComposeToolbarView.toolbarButtonSize, color: .systemFill), for: .highlighted) - button.layer.masksToBounds = true - button.layer.cornerRadius = 5 - button.layer.cornerCurve = .continuous - } - - private func updateToolbarButtonUserInterfaceStyle() { - // reset emoji - let emojiButtonImage = Asset.Human.faceSmilingAdaptive.image - .af.imageScaled(to: CGSize(width: 20, height: 20)) - .withRenderingMode(.alwaysTemplate) - emojiButton.setImage(emojiButtonImage, for: .normal) - - switch traitCollection.userInterfaceStyle { - case .light: - mediaBarButtonItem.image = UIImage(systemName: "photo") - mediaButton.setImage(UIImage(systemName: "photo", withConfiguration: UIImage.SymbolConfiguration(pointSize: 20, weight: .regular))!, for: .normal) - contentWarningBarButtonItem.image = UIImage(systemName: "exclamationmark.shield") - contentWarningButton.setImage(UIImage(systemName: "exclamationmark.shield", withConfiguration: UIImage.SymbolConfiguration(pointSize: 20, weight: .regular))!, for: .normal) - - case .dark: - mediaBarButtonItem.image = UIImage(systemName: "photo.fill") - mediaButton.setImage(UIImage(systemName: "photo.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: 20, weight: .regular))!, for: .normal) - contentWarningBarButtonItem.image = UIImage(systemName: "exclamationmark.shield.fill") - contentWarningButton.setImage(UIImage(systemName: "exclamationmark.shield.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: 20, weight: .regular))!, for: .normal) - - default: - assertionFailure() - } - - visibilityBarButtonItem.menu = createVisibilityContextMenu(interfaceStyle: traitCollection.userInterfaceStyle) - visibilityButton.menu = createVisibilityContextMenu(interfaceStyle: traitCollection.userInterfaceStyle) - } - - private func createMediaContextMenu() -> UIMenu { - var children: [UIMenuElement] = [] - let photoLibraryAction = UIAction(title: L10n.Scene.Compose.MediaSelection.photoLibrary, image: UIImage(systemName: "rectangle.on.rectangle"), identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off) { [weak self] _ in - guard let self = self else { return } - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: mediaSelectionType: .photoLibrary", ((#file as NSString).lastPathComponent), #line, #function) - self.delegate?.composeToolbarView(self, mediaButtonDidPressed: self.mediaButton, mediaSelectionType: .photoLibrary) - } - children.append(photoLibraryAction) - if UIImagePickerController.isSourceTypeAvailable(.camera) { - let cameraAction = UIAction(title: L10n.Scene.Compose.MediaSelection.camera, image: UIImage(systemName: "camera"), identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off, handler: { [weak self] _ in - guard let self = self else { return } - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: mediaSelectionType: .camera", ((#file as NSString).lastPathComponent), #line, #function) - self.delegate?.composeToolbarView(self, mediaButtonDidPressed: self.mediaButton, mediaSelectionType: .camera) - }) - children.append(cameraAction) - } - let browseAction = UIAction(title: L10n.Scene.Compose.MediaSelection.browse, image: UIImage(systemName: "ellipsis"), identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off) { [weak self] _ in - guard let self = self else { return } - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: mediaSelectionType: .browse", ((#file as NSString).lastPathComponent), #line, #function) - self.delegate?.composeToolbarView(self, mediaButtonDidPressed: self.mediaButton, mediaSelectionType: .browse) - } - children.append(browseAction) - - return UIMenu(title: "", image: nil, identifier: nil, options: .displayInline, children: children) - } - - private func createVisibilityContextMenu(interfaceStyle: UIUserInterfaceStyle) -> UIMenu { - let children: [UIMenuElement] = VisibilitySelectionType.allCases.map { type in - let state: UIMenuElement.State = activeVisibilityType.value == type ? .on : .off - return UIAction(title: type.title, image: type.image(interfaceStyle: interfaceStyle), identifier: nil, discoverabilityTitle: nil, attributes: [], state: state) { [weak self] action in - guard let self = self else { return } - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: visibilitySelectionType: %s", ((#file as NSString).lastPathComponent), #line, #function, type.rawValue) - self.delegate?.composeToolbarView(self, visibilityButtonDidPressed: self.visibilityButton, visibilitySelectionType: type) - } - } - return UIMenu(title: "", image: nil, identifier: nil, options: .displayInline, children: children) - } - -} - -extension ComposeToolbarView { - - @objc private func pollButtonDidPressed(_ sender: Any) { - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) - delegate?.composeToolbarView(self, pollButtonDidPressed: sender) - } - - @objc private func emojiButtonDidPressed(_ sender: Any) { - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) - delegate?.composeToolbarView(self, emojiButtonDidPressed: sender) - } - - @objc private func contentWarningButtonDidPressed(_ sender: Any) { - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) - delegate?.composeToolbarView(self, contentWarningButtonDidPressed: sender) - } - -} - -#if canImport(SwiftUI) && DEBUG -import SwiftUI - -struct ComposeToolbarView_Previews: PreviewProvider { - - static var previews: some View { - UIViewPreview(width: 375) { - let toolbarView = ComposeToolbarView() - toolbarView.translatesAutoresizingMaskIntoConstraints = false - NSLayoutConstraint.activate([ - toolbarView.widthAnchor.constraint(equalToConstant: 375).priority(.defaultHigh), - toolbarView.heightAnchor.constraint(equalToConstant: 64).priority(.defaultHigh), - ]) - return toolbarView - } - .previewLayout(.fixed(width: 375, height: 100)) - } - -} - -#endif - diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewController.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewController.swift index f3efb9957..326c84cfd 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewController.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewController.swift @@ -131,7 +131,6 @@ extension ComposeContentViewController { toolbarHostingView.view.heightAnchor.constraint(equalToConstant: ComposeContentToolbarView.toolbarHeight), ]) toolbarHostingView.view.preservesSuperviewLayoutMargins = true - //composeToolbarView.delegate = self composeContentToolbarBackgroundView.translatesAutoresizingMaskIntoConstraints = false view.insertSubview(composeContentToolbarBackgroundView, belowSubview: toolbarHostingView.view) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift index ef40ab7fc..1d4814db1 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift @@ -41,9 +41,23 @@ public class StatusAuthorView: UIStackView { // timestamp public let dateLabel = MetaLabel(style: .statusUsername) + public let dateTrailingDotLabel: MetaLabel = { + let label = MetaLabel(style: .statusUsername) + label.configure(content: PlaintextMetaContent(string: "·")) + return label + }() + + let visibilityIconImageView: UIImageView = { + let imageView = UIImageView() + imageView.tintColor = Asset.Colors.Label.secondary.color + imageView.contentMode = .scaleAspectFit + imageView.image = Asset.Scene.Compose.earth.image.withRenderingMode(.alwaysTemplate) + return imageView + }() + public let menuButton: UIButton = { let button = HitTestExpandedButton(type: .system) - button.expandEdgeInsets = UIEdgeInsets(top: -20, left: -10, bottom: -5, right: -10) + button.expandEdgeInsets = UIEdgeInsets(top: -20, left: -10, bottom: -10, right: -10) button.tintColor = Asset.Colors.Label.secondary.color let image = UIImage(systemName: "ellipsis", withConfiguration: UIImage.SymbolConfiguration(font: .systemFont(ofSize: 15))) button.setImage(image, for: .normal) @@ -53,11 +67,10 @@ public class StatusAuthorView: UIStackView { public let contentSensitiveeToggleButton: UIButton = { let button = HitTestExpandedButton(type: .system) - button.expandEdgeInsets = UIEdgeInsets(top: -5, left: -10, bottom: -20, right: -10) + button.expandEdgeInsets = UIEdgeInsets(top: -20, left: -10, bottom: -10, right: -10) button.tintColor = Asset.Colors.Label.secondary.color - button.imageView?.contentMode = .scaleAspectFill - button.imageView?.clipsToBounds = false - let image = UIImage(systemName: "eye.slash.fill", withConfiguration: UIImage.SymbolConfiguration(font: .systemFont(ofSize: 15))) + button.imageView?.contentMode = .scaleAspectFit + let image = UIImage(systemName: "eye.slash.fill") button.setImage(image, for: .normal) return button }() @@ -137,6 +150,8 @@ extension StatusAuthorView { // dateLabel dateLabel.isUserInteractionEnabled = false + + visibilityIconImageView.isUserInteractionEnabled = false } } @@ -245,47 +260,59 @@ extension StatusAuthorView { // authorPrimaryMetaContainer: H - [ authorNameLabel | (padding) | menuButton ] let authorPrimaryMetaContainer = UIStackView() authorPrimaryMetaContainer.axis = .horizontal - authorPrimaryMetaContainer.spacing = 10 + authorPrimaryMetaContainer.alignment = .center + authorPrimaryMetaContainer.spacing = 8 authorMetaContainer.addArrangedSubview(authorPrimaryMetaContainer) // authorNameLabel authorPrimaryMetaContainer.addArrangedSubview(authorNameLabel) - authorNameLabel.setContentHuggingPriority(.required - 10, for: .horizontal) - authorNameLabel.setContentCompressionResistancePriority(.required - 10, for: .horizontal) + authorNameLabel.setContentHuggingPriority(.required - 1, for: .vertical) + authorNameLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal) + authorPrimaryMetaContainer.addArrangedSubview(UIView()) + + authorPrimaryMetaContainer.addArrangedSubview(contentSensitiveeToggleButton) + NSLayoutConstraint.activate([ + contentSensitiveeToggleButton.heightAnchor.constraint(equalToConstant: 18), + ]) + + authorPrimaryMetaContainer.setCustomSpacing(16, after: contentSensitiveeToggleButton) + // menuButton authorPrimaryMetaContainer.addArrangedSubview(menuButton) - menuButton.setContentHuggingPriority(.required - 2, for: .horizontal) - menuButton.setContentCompressionResistancePriority(.required - 2, for: .horizontal) + menuButton.setContentHuggingPriority(.required - 1, for: .horizontal) + menuButton.setContentCompressionResistancePriority(.required - 1, for: .horizontal) // authorSecondaryMetaContainer: H - [ authorUsername | usernameTrialingDotLabel | dateLabel | (padding) | contentSensitiveeToggleButton ] let authorSecondaryMetaContainer = UIStackView() authorSecondaryMetaContainer.axis = .horizontal + authorSecondaryMetaContainer.alignment = .center authorSecondaryMetaContainer.spacing = 4 authorMetaContainer.addArrangedSubview(authorSecondaryMetaContainer) authorSecondaryMetaContainer.addArrangedSubview(authorUsernameLabel) - authorUsernameLabel.setContentHuggingPriority(.required - 8, for: .horizontal) - authorUsernameLabel.setContentCompressionResistancePriority(.required - 8, for: .horizontal) + authorUsernameLabel.setContentHuggingPriority(.required - 1, for: .vertical) + authorUsernameLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal) + authorSecondaryMetaContainer.addArrangedSubview(usernameTrialingDotLabel) - usernameTrialingDotLabel.setContentHuggingPriority(.required - 2, for: .horizontal) - usernameTrialingDotLabel.setContentCompressionResistancePriority(.required - 2, for: .horizontal) + usernameTrialingDotLabel.setContentCompressionResistancePriority(.required, for: .horizontal) + authorSecondaryMetaContainer.addArrangedSubview(dateLabel) dateLabel.setContentHuggingPriority(.required - 1, for: .horizontal) dateLabel.setContentCompressionResistancePriority(.required - 1, for: .horizontal) - authorSecondaryMetaContainer.addArrangedSubview(UIView()) - contentSensitiveeToggleButton.translatesAutoresizingMaskIntoConstraints = false - authorSecondaryMetaContainer.addArrangedSubview(contentSensitiveeToggleButton) + + authorSecondaryMetaContainer.addArrangedSubview(dateTrailingDotLabel) + dateTrailingDotLabel.setContentCompressionResistancePriority(.required, for: .horizontal) + + authorSecondaryMetaContainer.addArrangedSubview(visibilityIconImageView) NSLayoutConstraint.activate([ - contentSensitiveeToggleButton.heightAnchor.constraint(equalTo: authorUsernameLabel.heightAnchor, multiplier: 1.0).priority(.required - 1), - contentSensitiveeToggleButton.widthAnchor.constraint(equalTo: contentSensitiveeToggleButton.heightAnchor, multiplier: 1.0).priority(.required - 1), + visibilityIconImageView.heightAnchor.constraint(equalTo: authorUsernameLabel.heightAnchor), + visibilityIconImageView.widthAnchor.constraint(equalTo: visibilityIconImageView.heightAnchor), ]) - authorUsernameLabel.setContentHuggingPriority(.required - 1, for: .vertical) - authorUsernameLabel.setContentCompressionResistancePriority(.required - 1, for: .vertical) - contentSensitiveeToggleButton.setContentHuggingPriority(.defaultLow, for: .vertical) - contentSensitiveeToggleButton.setContentHuggingPriority(.defaultLow, for: .horizontal) - contentSensitiveeToggleButton.setContentCompressionResistancePriority(.defaultLow, for: .horizontal) - contentSensitiveeToggleButton.setContentCompressionResistancePriority(.defaultLow, for: .vertical) + + authorSecondaryMetaContainer.setCustomSpacing(0, after: visibilityIconImageView) + + authorSecondaryMetaContainer.addArrangedSubview(UIView()) } func layoutReport() { diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index 4c2c0943e..8a199f8bd 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -283,6 +283,21 @@ extension StatusView.ViewModel { authorView.dateLabel.configure(content: PlaintextMetaContent(string: text)) } .store(in: &disposeBag) + + $visibility + .map { + switch $0 { + case .public: return Asset.Scene.Compose.earth + case .unlisted: return Asset.Scene.Compose.people + case .private: return Asset.Scene.Compose.peopleAdd + case .direct: return Asset.Scene.Compose.mention + case ._other: return Asset.Scene.Compose.more + } + } + .sink { + authorView.visibilityIconImageView.image = $0.image.withRenderingMode(.alwaysTemplate) + } + .store(in: &disposeBag) } private func bindContent(statusView: StatusView) { From 2b3660086da27f71643d4605287e3f4c7641ca83 Mon Sep 17 00:00:00 2001 From: Natalia Ossipova Date: Thu, 16 Feb 2023 16:23:02 +0100 Subject: [PATCH 02/87] Add icon for 'other' visibility --- .../questionmark.circle.imageset/Contents.json | 15 +++++++++++++++ .../questionmark.circle.pdf | Bin 0 -> 1495 bytes .../Sources/MastodonAsset/Generated/Assets.swift | 1 + .../View/Content/StatusView+ViewModel.swift | 2 +- 4 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Scene/Compose/questionmark.circle.imageset/Contents.json create mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Scene/Compose/questionmark.circle.imageset/questionmark.circle.pdf diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Scene/Compose/questionmark.circle.imageset/Contents.json b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Scene/Compose/questionmark.circle.imageset/Contents.json new file mode 100644 index 000000000..e09f6367e --- /dev/null +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Scene/Compose/questionmark.circle.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "questionmark.circle.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Scene/Compose/questionmark.circle.imageset/questionmark.circle.pdf b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Scene/Compose/questionmark.circle.imageset/questionmark.circle.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8a9014fd0aab72f4f749296e5d01171310f134ac GIT binary patch literal 1495 zcmY!laBlN;pir)tP^=efvE2DP%fbDR_0X0aNd7UaId zA<)EnCTX30s(R*L^^Z~dZ;SqDhR;quRD9S%ZTyyUGc|X#yRf3Rm%E4w=6DJymj&|lfEBSmKWYv z>}UB^)p_R1mWYRUB&X}B#F(>bWhsQRZ|yrVGi#k$Ux0A=>M0N2PYts1a^LzX>h+x3 zD|rztSG2qo%>q3)UHq`{(8j{=k!ybjoKcU|{kw(V+kBER-=nNY(cw$4nJj47YQs>t zSY_)2lcIttHMefHvr9_(d8{m-Vf*+*W=p30ze}7KtUFm}iZR&e+)OEo+q}ud@RZmM z&&@2?nOS6gIeq7G`bNBtU7{=9RT3}bzFL)mpYPsLk*O;+Zizh3;F|vIerU|YJe8E9 zNDb$WCxs0p&Rux$_fg#qb(fQcd55mf`{8!5dEv&QX^&@5&h6S~{mSK%|AiG-ZNDAS zyk3yDZfQiR`lrUAY;o|IfH-#pOP()VvgE z^a5F+gaJwoAR3q+Ow24m@*tiuJlTK~ifcuQdvFObkto>MfCPX*KhXflQP6jGR4`P~ zPfi4qz@!6|0FpoiHOCBYj)HzjWkITfzJF3ya7ixMRA_oMho?tB1w*ieTV_#liGm4~ zjX#ar_S$kEG7xC{{;#XNaBDoDs8jp402!8*d5;8MDaKBkuq5gK-klzMUe0U({%&nR zij%_r+_nkvPr5fa&t&A8HpRV@DOe=EN^jF;`8&;80at%3`%m7s?1(a3_1YSXQj0(N z?yJL@6(wfW*IraB<-O+hl;``o=u7GqyMq?lEn%zDH}*|FzA5+d|IRsaZ+-Ym-|+n6 z-X3Dwh#AfxUqZv#(9{SPJ{ClTkD(z_02w0%kf9k-A>`X{%gtoS0}i3jd<%WGw7Pb@ zP|{P%dlhi5NbG6VmeLRRtHbRl)v}|L9&H}#k*PPz^cG`Q> zgR`Dk=Ul#%l)7uP&ekgye?7iue!1{+e$l?j*(rf*p3nNyVdB5*l8uxQf5)l!+4(c4 zdOmyix+mSRApbJ|UWPvlT@Pc1A~-By!Ds Date: Thu, 16 Feb 2023 16:34:02 +0100 Subject: [PATCH 03/87] Move visibility switch to extension --- .../Extension/MastodonVisibility+Image.swift | 20 +++++++++++++++++++ .../View/Content/StatusView+ViewModel.swift | 13 ++---------- 2 files changed, 22 insertions(+), 11 deletions(-) create mode 100644 MastodonSDK/Sources/MastodonUI/Extension/MastodonVisibility+Image.swift diff --git a/MastodonSDK/Sources/MastodonUI/Extension/MastodonVisibility+Image.swift b/MastodonSDK/Sources/MastodonUI/Extension/MastodonVisibility+Image.swift new file mode 100644 index 000000000..05dcd5e18 --- /dev/null +++ b/MastodonSDK/Sources/MastodonUI/Extension/MastodonVisibility+Image.swift @@ -0,0 +1,20 @@ +// Copyright © 2023 Mastodon gGmbH. All rights reserved. + +import UIKit +import CoreDataStack +import MastodonAsset + +extension MastodonVisibility { + + public var image: UIImage { + let asset: ImageAsset + switch self { + case .public: asset = Asset.Scene.Compose.earth + case .unlisted: asset = Asset.Scene.Compose.people + case .private: asset = Asset.Scene.Compose.peopleAdd + case .direct: asset = Asset.Scene.Compose.mention + case ._other: asset = Asset.Scene.Compose.questionmarkCircle + } + return asset.image.withRenderingMode(.alwaysTemplate) + } +} diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index 36b3795cd..94b9a206e 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -285,17 +285,8 @@ extension StatusView.ViewModel { .store(in: &disposeBag) $visibility - .map { - switch $0 { - case .public: return Asset.Scene.Compose.earth - case .unlisted: return Asset.Scene.Compose.people - case .private: return Asset.Scene.Compose.peopleAdd - case .direct: return Asset.Scene.Compose.mention - case ._other: return Asset.Scene.Compose.questionmarkCircle - } - } - .sink { - authorView.visibilityIconImageView.image = $0.image.withRenderingMode(.alwaysTemplate) + .sink { visibility in + authorView.visibilityIconImageView.image = visibility.image } .store(in: &disposeBag) } From e39719177312a6dbf66ea179e9f54578f7e204f6 Mon Sep 17 00:00:00 2001 From: Natalia Ossipova Date: Wed, 17 May 2023 14:07:43 +0200 Subject: [PATCH 04/87] Show visibility icon also in notification view --- .../Content/NotificationView+ViewModel.swift | 8 ++++ .../View/Content/NotificationView.swift | 38 +++++++++++++++++-- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift index ed038f47f..099af1d99 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift @@ -42,6 +42,8 @@ extension NotificationView { @Published public var timestamp: Date? + @Published public var visibility: MastodonVisibility = .public + @Published public var followRequestState = MastodonFollowRequestState(state: .none) @Published public var transientFollowRequestState = MastodonFollowRequestState(state: .none) @@ -121,6 +123,12 @@ extension NotificationView.ViewModel { } .store(in: &disposeBag) + $visibility + .sink { visibility in + notificationView.visibilityIconImageView.image = visibility.image + } + .store(in: &disposeBag) + // notification type indicator $notificationIndicatorText .sink { text in diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift index 6bd0062e3..4bd2278d5 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift @@ -91,6 +91,20 @@ public final class NotificationView: UIView { // timestamp public let dateLabel = MetaLabel(style: .statusUsername) + public let dateTrailingDotLabel: MetaLabel = { + let label = MetaLabel(style: .statusUsername) + label.configure(content: PlaintextMetaContent(string: "·")) + return label + }() + + let visibilityIconImageView: UIImageView = { + let imageView = UIImageView() + imageView.tintColor = Asset.Colors.Label.secondary.color + imageView.contentMode = .scaleAspectFit + imageView.image = Asset.Scene.Compose.earth.image.withRenderingMode(.alwaysTemplate) + return imageView + }() + public let menuButton: UIButton = { let button = HitTestExpandedButton(type: .system) button.tintColor = Asset.Colors.Label.secondary.color @@ -272,16 +286,32 @@ extension NotificationView { authrMetaContainer.setCustomSpacing(4, after: authorSecondaryMetaContainer) authorSecondaryMetaContainer.addArrangedSubview(authorUsernameLabel) - authorUsernameLabel.setContentHuggingPriority(.required - 8, for: .horizontal) - authorUsernameLabel.setContentCompressionResistancePriority(.required - 8, for: .horizontal) + authorUsernameLabel.setContentHuggingPriority(.required - 1, for: .vertical) + authorUsernameLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal) + authorSecondaryMetaContainer.addArrangedSubview(usernameTrialingDotLabel) - usernameTrialingDotLabel.setContentHuggingPriority(.required - 2, for: .horizontal) - usernameTrialingDotLabel.setContentCompressionResistancePriority(.required - 2, for: .horizontal) + usernameTrialingDotLabel.setContentCompressionResistancePriority(.required, for: .horizontal) + authorSecondaryMetaContainer.addArrangedSubview(dateLabel) dateLabel.setContentHuggingPriority(.required - 1, for: .horizontal) dateLabel.setContentCompressionResistancePriority(.required - 1, for: .horizontal) + + authorSecondaryMetaContainer.addArrangedSubview(dateTrailingDotLabel) + dateTrailingDotLabel.setContentCompressionResistancePriority(.required, for: .horizontal) + + authorSecondaryMetaContainer.addArrangedSubview(dateTrailingDotLabel) + dateTrailingDotLabel.setContentCompressionResistancePriority(.required, for: .horizontal) + + authorSecondaryMetaContainer.addArrangedSubview(visibilityIconImageView) + NSLayoutConstraint.activate([ + visibilityIconImageView.heightAnchor.constraint(equalTo: authorUsernameLabel.heightAnchor), + visibilityIconImageView.widthAnchor.constraint(equalTo: visibilityIconImageView.heightAnchor), + ]) + authorSecondaryMetaContainer.addArrangedSubview(UIView()) + authorSecondaryMetaContainer.setCustomSpacing(0, after: visibilityIconImageView) + // authorContainerViewBottomPaddingView authorContainerViewBottomPaddingView.translatesAutoresizingMaskIntoConstraints = false containerStackView.addArrangedSubview(authorContainerViewBottomPaddingView) From 846fa44369738d9656f3807aa03281ec0b4f5879 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Fri, 2 Jun 2023 11:55:35 +0200 Subject: [PATCH 05/87] Refactor action-menu to better support sections (IOS-103) --- .../Scene/Profile/ProfileViewController.swift | 2 +- .../View/Content/NotificationView.swift | 13 +++++++---- .../View/Content/StatusAuthorView.swift | 15 +++++++----- .../MastodonUI/View/Menu/MastodonMenu.swift | 23 +++++++++---------- 4 files changed, 29 insertions(+), 24 deletions(-) diff --git a/Mastodon/Scene/Profile/ProfileViewController.swift b/Mastodon/Scene/Profile/ProfileViewController.swift index 238f076f0..9dce85225 100644 --- a/Mastodon/Scene/Profile/ProfileViewController.swift +++ b/Mastodon/Scene/Profile/ProfileViewController.swift @@ -428,7 +428,7 @@ extension ProfileViewController { } let menu = MastodonMenu.setupMenu( - actions: menuActions, + actions: [menuActions], delegate: self ) return menu diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift index 6bd0062e3..88956d9be 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift @@ -460,9 +460,10 @@ extension NotificationView { public typealias AuthorMenuContext = StatusAuthorView.AuthorMenuContext public func setupAuthorMenu(menuContext: AuthorMenuContext) -> (UIMenu, [UIAccessibilityCustomAction]) { - var actions: [MastodonMenu.Action] = [] - - actions = [ + var actions: [[MastodonMenu.Action]] = [] + var upperActions: [MastodonMenu.Action] = [] + + upperActions = [ .muteUser(.init( name: menuContext.name, isMuting: menuContext.isMuting @@ -473,11 +474,13 @@ extension NotificationView { )), .reportUser( .init(name: menuContext.name) - ), + ) ] + + actions.append(upperActions) if menuContext.isMyself { - actions.append(.deleteStatus) + actions.append([.deleteStatus]) } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift index 7569b640a..a70fcfddd 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift @@ -157,20 +157,21 @@ extension StatusAuthorView { } public func setupAuthorMenu(menuContext: AuthorMenuContext) -> (UIMenu, [UIAccessibilityCustomAction]) { - var actions = [MastodonMenu.Action]() + var actions: [[MastodonMenu.Action]] = [] + var upperActions: [MastodonMenu.Action] = [] if menuContext.isMyself { - actions.append(.editStatus) + upperActions.append(.editStatus) } if !menuContext.isMyself { if let statusLanguage = menuContext.statusLanguage, menuContext.isTranslationEnabled, !menuContext.isTranslated { - actions.append( + upperActions.append( .translateStatus(.init(language: statusLanguage)) ) } - actions.append(contentsOf: [ + upperActions.append(contentsOf: [ .muteUser(.init( name: menuContext.name, isMuting: menuContext.isMuting @@ -185,15 +186,17 @@ extension StatusAuthorView { ]) } - actions.append(contentsOf: [ + upperActions.append(contentsOf: [ .bookmarkStatus( .init(isBookmarking: menuContext.isBookmarking) ), .shareStatus ]) + actions.append(upperActions) + if menuContext.isMyself { - actions.append(.deleteStatus) + actions.append([.deleteStatus]) } diff --git a/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift b/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift index e67d11450..24c976780 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift @@ -14,31 +14,30 @@ public protocol MastodonMenuDelegate: AnyObject { public enum MastodonMenu { public static func setupMenu( - actions: [Action], + actions: [[Action]], delegate: MastodonMenuDelegate ) -> UIMenu { var children: [UIMenuElement] = [] - for action in actions { - let element: UIMenuElement - - if case let .deleteStatus = action { - let deleteAction = action.build(delegate: delegate).menuElement - element = UIMenu(options: .displayInline, children: [deleteAction]) - } else { - element = action.build(delegate: delegate).menuElement + for actionGroup in actions { + var submenuChildren: [UIMenuElement] = [] + for action in actionGroup { + let element = action.build(delegate: delegate).menuElement + submenuChildren.append(element) } - children.append(element) + let submenu = UIMenu(options: .displayInline, children: submenuChildren) + children.append(submenu) } + return UIMenu(children: children) } public static func setupAccessibilityActions( - actions: [Action], + actions: [[Action]], delegate: MastodonMenuDelegate ) -> [UIAccessibilityCustomAction] { var accessibilityActions: [UIAccessibilityCustomAction] = [] - for action in actions { + for action in actions.flatMap({ $0 }) { let element = action.build(delegate: delegate) accessibilityActions.append(element.accessibilityCustomAction) } From 6b2fe9111224b36958535d860c6d53b930735847 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Fri, 2 Jun 2023 16:08:48 +0200 Subject: [PATCH 06/87] Put existing actions into their section (IOS-103) --- .../View/Content/StatusAuthorView.swift | 59 +++++++++---------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift index a70fcfddd..638890cfa 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift @@ -158,48 +158,45 @@ extension StatusAuthorView { public func setupAuthorMenu(menuContext: AuthorMenuContext) -> (UIMenu, [UIAccessibilityCustomAction]) { var actions: [[MastodonMenu.Action]] = [] - var upperActions: [MastodonMenu.Action] = [] + var postActions: [MastodonMenu.Action] = [] + var userActions: [MastodonMenu.Action] = [] if menuContext.isMyself { - upperActions.append(.editStatus) + postActions.append(.editStatus) } - if !menuContext.isMyself { - if let statusLanguage = menuContext.statusLanguage, menuContext.isTranslationEnabled, !menuContext.isTranslated { - upperActions.append( - .translateStatus(.init(language: statusLanguage)) - ) - } - - upperActions.append(contentsOf: [ - .muteUser(.init( - name: menuContext.name, - isMuting: menuContext.isMuting - )), - .blockUser(.init( - name: menuContext.name, - isBlocking: menuContext.isBlocking - )), - .reportUser( - .init(name: menuContext.name) - ) - ]) + if let statusLanguage = menuContext.statusLanguage, menuContext.isTranslationEnabled, !menuContext.isTranslated { + postActions.append( + .translateStatus(.init(language: statusLanguage)) + ) } - - upperActions.append(contentsOf: [ - .bookmarkStatus( - .init(isBookmarking: menuContext.isBookmarking) - ), - .shareStatus - ]) - actions.append(upperActions) + postActions.append(.bookmarkStatus(.init(isBookmarking: menuContext.isBookmarking))) + postActions.append(.shareStatus) + + if menuContext.isMyself == false { + userActions.append(.muteUser(.init( + name: menuContext.name, + isMuting: menuContext.isMuting + ))) + + userActions.append(.blockUser(.init( + name: menuContext.name, + isBlocking: menuContext.isBlocking + ))) + + userActions.append(.reportUser( + .init(name: menuContext.name) + )) + } + + actions.append(postActions) + actions.append(userActions) if menuContext.isMyself { actions.append([.deleteStatus]) } - let menu = MastodonMenu.setupMenu( actions: actions, delegate: self.statusView! From 9b422a95ac2259e3a0ba613c7d2b5785a9cce714 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Fri, 2 Jun 2023 16:31:20 +0200 Subject: [PATCH 07/87] Sprinkle in some localization (IOS-103) --- Localization/app.json | 5 +++-- .../Sources/MastodonLocalization/Generated/Strings.swift | 4 ++++ .../Resources/Base.lproj/Localizable.strings | 2 ++ .../Sources/MastodonUI/View/Content/StatusAuthorView.swift | 4 ++-- MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift | 6 +++--- 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Localization/app.json b/Localization/app.json index 52f0db07b..b5d25f48b 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -101,8 +101,9 @@ "title": "Translate from %s", "unknown_language": "Unknown" }, - "edit_post": "Edit" - + "edit_post": "Edit", + "bookmark": "Bookmark" + "remove_bookmark": "Remove Bookmark", }, "tabs": { "home": "Home", diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index 259af8fb9..bbda9cad2 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -112,6 +112,8 @@ public enum L10n { public static func blockDomain(_ p1: Any) -> String { return L10n.tr("Localizable", "Common.Controls.Actions.BlockDomain", String(describing: p1), fallback: "Block %@") } + /// Bookmark + public static let bookmark = L10n.tr("Localizable", "Common.Controls.Actions.Bookmark", fallback: "Bookmark") /// Cancel public static let cancel = L10n.tr("Localizable", "Common.Controls.Actions.Cancel", fallback: "Cancel") /// Compose @@ -154,6 +156,8 @@ public enum L10n { public static let previous = L10n.tr("Localizable", "Common.Controls.Actions.Previous", fallback: "Previous") /// Remove public static let remove = L10n.tr("Localizable", "Common.Controls.Actions.Remove", fallback: "Remove") + /// Remove Bookmark + public static let removeBookmark = L10n.tr("Localizable", "Common.Controls.Actions.RemoveBookmark", fallback: "Remove Bookmark") /// Reply public static let reply = L10n.tr("Localizable", "Common.Controls.Actions.Reply", fallback: "Reply") /// Report %@ diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 55cf7ec74..ca51a011d 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -40,6 +40,8 @@ Please check your internet connection."; "Common.Controls.Actions.Discard" = "Discard"; "Common.Controls.Actions.Done" = "Done"; "Common.Controls.Actions.Edit" = "Edit"; +"Common.Controls.Actions.Bookmark" = "Bookmark"; +"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; "Common.Controls.Actions.EditPost" = "Edit"; "Common.Controls.Actions.FindPeople" = "Find people to follow"; "Common.Controls.Actions.ManuallySearch" = "Manually search instead"; diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift index 638890cfa..81bd6f5a6 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift @@ -214,14 +214,14 @@ extension StatusAuthorView { extension StatusAuthorView { @objc private func authorAvatarButtonDidPressed(_ sender: UIButton) { - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") guard let statusView = statusView else { return } + statusView.delegate?.statusView(statusView, authorAvatarButtonDidPressed: avatarButton) } @objc private func contentSensitiveeToggleButtonDidPressed(_ sender: UIButton) { - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") guard let statusView = statusView else { return } + statusView.delegate?.statusView(statusView, contentSensitiveeToggleButtonDidPressed: sender) } } diff --git a/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift b/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift index 24c976780..3d06ffa23 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift @@ -120,10 +120,10 @@ extension MastodonMenu { let title: String let image: UIImage? if context.isBookmarking { - title = "Remove Bookmark" // TODO: i18n + title = L10n.Common.Controls.Actions.removeBookmark image = UIImage(systemName: "bookmark.slash.fill") } else { - title = "Bookmark" // TODO: i18n + title = L10n.Common.Controls.Actions.bookmark image = UIImage(systemName: "bookmark") } let action = LabeledAction(title: title, image: image) { [weak delegate] in @@ -133,7 +133,7 @@ extension MastodonMenu { return action case .shareStatus: let action = LabeledAction( - title: "Share", // TODO: i18n + title: L10n.Common.Controls.Actions.sharePost, image: UIImage(systemName: "square.and.arrow.up") ) { [weak delegate] in guard let delegate = delegate else { return } From d455da85d27004cbfa5d1cf73d072dd380995d82 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Fri, 2 Jun 2023 18:18:11 +0200 Subject: [PATCH 08/87] Add follow/unfollow-option to user-section (IOS-103) --- Localization/app.json | 4 ++- .../Provider/DataSourceFacade+Status.swift | 7 +++++ .../NotificationView+Configuration.swift | 16 +++++++++++ .../Generated/Strings.swift | 8 ++++++ .../Resources/Base.lproj/Localizable.strings | 2 ++ .../Content/NotificationView+ViewModel.swift | 11 +++++--- .../View/Content/StatusAuthorView.swift | 7 +++++ .../Content/StatusView+Configuration.swift | 13 +++++++++ .../View/Content/StatusView+ViewModel.swift | 9 ++++-- .../MastodonUI/View/Content/StatusView.swift | 1 - .../MastodonUI/View/Menu/MastodonMenu.swift | 28 +++++++++++++++++++ 11 files changed, 97 insertions(+), 9 deletions(-) diff --git a/Localization/app.json b/Localization/app.json index b5d25f48b..0aa701147 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -102,8 +102,10 @@ "unknown_language": "Unknown" }, "edit_post": "Edit", - "bookmark": "Bookmark" + "bookmark": "Bookmark", "remove_bookmark": "Remove Bookmark", + "follow" = "Follow %s", + "unfollow" = "Unfollow %s" }, "tabs": { "home": "Home", diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift index dacec8381..044e9b7a4 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift @@ -384,6 +384,13 @@ extension DataSourceFacade { composeContext: .editStatus(status: status, statusSource: statusSource), destination: .topLevel) _ = dependency.coordinator.present(scene: .editStatus(viewModel: editStatusViewModel), transition: .modal(animated: true)) + + case .followUser(_): + + guard let author = menuContext.author else { return } + + try await DataSourceFacade.responseToUserFollowAction(dependency: dependency, + user: author) } } // end func } diff --git a/Mastodon/Scene/Share/View/Content/NotificationView+Configuration.swift b/Mastodon/Scene/Share/View/Content/NotificationView+Configuration.swift index 018628473..011435fff 100644 --- a/Mastodon/Scene/Share/View/Content/NotificationView+Configuration.swift +++ b/Mastodon/Scene/Share/View/Content/NotificationView+Configuration.swift @@ -187,6 +187,7 @@ extension NotificationView { } .assign(to: \.isBlocking, on: viewModel) .store(in: &disposeBag) + // isMyself Publishers.CombineLatest( author.publisher(for: \.domain), @@ -199,12 +200,27 @@ extension NotificationView { } .assign(to: \.isMyself, on: viewModel) .store(in: &disposeBag) + // follow request state notification.publisher(for: \.followRequestState) .assign(to: \.followRequestState, on: viewModel) .store(in: &disposeBag) + notification.publisher(for: \.transientFollowRequestState) .assign(to: \.transientFollowRequestState, on: viewModel) .store(in: &disposeBag) + + // Following + author.publisher(for: \.followingBy) + .map { [weak viewModel] followingBy in + guard let viewModel = viewModel else { return false } + guard let authContext = viewModel.authContext else { return false } + return followingBy.contains(where: { + $0.id == authContext.mastodonAuthenticationBox.userID && $0.domain == authContext.mastodonAuthenticationBox.domain + }) + } + .assign(to: \.isFollowed, on: viewModel) + .store(in: &disposeBag) + } } diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index bbda9cad2..65bb3abbe 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -138,6 +138,10 @@ public enum L10n { public static let editPost = L10n.tr("Localizable", "Common.Controls.Actions.EditPost", fallback: "Edit") /// Find people to follow public static let findPeople = L10n.tr("Localizable", "Common.Controls.Actions.FindPeople", fallback: "Find people to follow") + /// Follow %@ + public static func follow(_ p1: Any) -> String { + return L10n.tr("Localizable", "Common.Controls.Actions.Follow", String(describing: p1), fallback: "Follow %@") + } /// Manually search instead public static let manuallySearch = L10n.tr("Localizable", "Common.Controls.Actions.ManuallySearch", fallback: "Manually search instead") /// Next @@ -192,6 +196,10 @@ public enum L10n { public static func unblockDomain(_ p1: Any) -> String { return L10n.tr("Localizable", "Common.Controls.Actions.UnblockDomain", String(describing: p1), fallback: "Unblock %@") } + /// Unfollow %@ + public static func unfollow(_ p1: Any) -> String { + return L10n.tr("Localizable", "Common.Controls.Actions.Unfollow", String(describing: p1), fallback: "Unfollow %@") + } public enum TranslatePost { /// Translate from %@ public static func title(_ p1: Any) -> String { diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index ca51a011d..971de9623 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -69,6 +69,8 @@ Please check your internet connection."; "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; "Common.Controls.Actions.TryAgain" = "Try Again"; "Common.Controls.Actions.UnblockDomain" = "Unblock %@"; +"Common.Controls.Actions.Follow" = "Follow %@"; +"Common.Controls.Actions.Unfollow" = "Unfollow %@"; "Common.Controls.Friendship.Block" = "Block"; "Common.Controls.Friendship.BlockDomain" = "Block %@"; "Common.Controls.Friendship.BlockUser" = "Block %@"; diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift index ed038f47f..68b13fed5 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView+ViewModel.swift @@ -39,6 +39,7 @@ extension NotificationView { @Published public var isMuting = false @Published public var isBlocking = false @Published public var isTranslated = false + @Published public var isFollowed = false @Published public var timestamp: Date? @@ -208,18 +209,19 @@ extension NotificationView.ViewModel { $authorName, $isMuting, $isBlocking, - Publishers.CombineLatest( + Publishers.CombineLatest3( $isMyself, - $isTranslated + $isTranslated, + $isFollowed ) ) - .sink { [weak self] authorName, isMuting, isBlocking, isMyselfIsTranslated in + .sink { [weak self] authorName, isMuting, isBlocking, isMyselfIsTranslatedIsFollowed in guard let name = authorName?.string else { notificationView.menuButton.menu = nil return } - let (isMyself, isTranslated) = isMyselfIsTranslated + let (isMyself, isTranslated, isFollowed) = isMyselfIsTranslatedIsFollowed lazy var instanceConfigurationV2: Mastodon.Entity.V2.Instance.Configuration? = { guard @@ -243,6 +245,7 @@ extension NotificationView.ViewModel { isBlocking: isBlocking, isMyself: isMyself, isBookmarking: false, // no bookmark action display for notification item + isFollowed: isFollowed, isTranslationEnabled: instanceConfigurationV2?.translation?.enabled == true, isTranslated: isTranslated, statusLanguage: "" diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift index 81bd6f5a6..f1972a5e8 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift @@ -150,6 +150,7 @@ extension StatusAuthorView { public let isBlocking: Bool public let isMyself: Bool public let isBookmarking: Bool + public let isFollowed: Bool public let isTranslationEnabled: Bool public let isTranslated: Bool @@ -175,6 +176,12 @@ extension StatusAuthorView { postActions.append(.shareStatus) if menuContext.isMyself == false { + + userActions.append(.followUser(.init( + name: menuContext.name, + isFollowing: menuContext.isFollowed + ))) + userActions.append(.muteUser(.init( name: menuContext.name, isMuting: menuContext.isMuting diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift index 03eff8c27..5ccc88e83 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift @@ -258,6 +258,18 @@ extension StatusView { } .assign(to: \.isMyself, on: viewModel) .store(in: &disposeBag) + + // Following + author.publisher(for: \.followingBy) + .map { [weak viewModel] followingBy in + guard let viewModel = viewModel else { return false } + guard let authContext = viewModel.authContext else { return false } + return followingBy.contains(where: { + $0.id == authContext.mastodonAuthenticationBox.userID && $0.domain == authContext.mastodonAuthenticationBox.domain + }) + } + .assign(to: \.isFollowed, on: viewModel) + .store(in: &disposeBag) } private func configureTimestamp(timestamp: AnyPublisher) { @@ -280,6 +292,7 @@ extension StatusView { func revertTranslation() { guard let originalStatus = viewModel.originalStatus else { return } + viewModel.translatedFromLanguage = nil viewModel.translatedUsingProvider = nil originalStatus.reblog?.update(translatedContent: nil) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index f466fd819..f52728da1 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -45,6 +45,7 @@ extension StatusView { @Published public var isMyself = false @Published public var isMuting = false @Published public var isBlocking = false + @Published public var isFollowed = false // Translation @Published public var isCurrentlyTranslating = false @@ -656,10 +657,11 @@ extension StatusView.ViewModel { $authorName, $isMyself ) - let publishersTwo = Publishers.CombineLatest3( + let publishersTwo = Publishers.CombineLatest4( $isMuting, $isBlocking, - $isBookmark + $isBookmark, + $isFollowed ) let publishersThree = Publishers.CombineLatest( $translatedFromLanguage, @@ -673,7 +675,7 @@ extension StatusView.ViewModel { ).eraseToAnyPublisher() .sink { tupleOne, tupleTwo, tupleThree in let (authorName, isMyself) = tupleOne - let (isMuting, isBlocking, isBookmark) = tupleTwo + let (isMuting, isBlocking, isBookmark, isFollowed) = tupleTwo let (translatedFromLanguage, language) = tupleThree guard let name = authorName?.string else { @@ -704,6 +706,7 @@ extension StatusView.ViewModel { isBlocking: isBlocking, isMyself: isMyself, isBookmarking: isBookmark, + isFollowed: isFollowed, isTranslationEnabled: instanceConfigurationV2?.translation?.enabled == true, isTranslated: translatedFromLanguage != nil, statusLanguage: language diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift index 652c8c545..ed1d5ed8c 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift @@ -792,7 +792,6 @@ extension StatusView: StatusMetricViewDelegate { // MARK: - MastodonMenuDelegate extension StatusView: MastodonMenuDelegate { public func menuAction(_ action: MastodonMenu.Action) { - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") delegate?.statusView(self, menuButton: authorView.menuButton, didSelectAction: action) } } diff --git a/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift b/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift index 3d06ffa23..faef873d1 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift @@ -57,6 +57,7 @@ extension MastodonMenu { case shareStatus case deleteStatus case editStatus + case followUser(FollowUserActionContext) func build(delegate: MastodonMenuDelegate) -> LabeledAction { switch self { @@ -171,6 +172,22 @@ extension MastodonMenu { } return editStatusAction + case .followUser(let context): + let title: String + let image: UIImage? + if context.isFollowing { + title = L10n.Common.Controls.Actions.unfollow(context.name) + image = UIImage(systemName: "person.fill.badge.minus") + } else { + title = L10n.Common.Controls.Actions.follow(context.name) + image = UIImage(systemName: "person.fill.badge.plus") + } + let action = LabeledAction(title: title, image: image) { [weak delegate] in + guard let delegate = delegate else { return } + delegate.menuAction(self) + } + return action + } // end switch } // end func build } // end enum Action @@ -236,4 +253,15 @@ extension MastodonMenu { self.language = language } } + + public struct FollowUserActionContext { + + public let name: String + public let isFollowing: Bool + + init(name: String, isFollowing: Bool) { + self.name = name + self.isFollowing = isFollowing + } + } } From 7b0840303505d39dd03648c9570a01d188575665 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Fri, 2 Jun 2023 18:31:00 +0200 Subject: [PATCH 09/87] Add menu-action to untranslate a translated status (IOS-103) --- .../Protocol/Provider/DataSourceFacade+Status.swift | 3 +++ ...taSourceProvider+StatusTableViewCellDelegate.swift | 8 ++++++++ .../MastodonUI/View/Content/StatusAuthorView.swift | 10 ++++++---- .../View/Content/StatusView+Configuration.swift | 2 +- .../Sources/MastodonUI/View/Menu/MastodonMenu.swift | 11 +++++++++++ 5 files changed, 29 insertions(+), 5 deletions(-) diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift index 044e9b7a4..da5e97820 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Status.swift @@ -385,6 +385,9 @@ extension DataSourceFacade { destination: .topLevel) _ = dependency.coordinator.present(scene: .editStatus(viewModel: editStatusViewModel), transition: .modal(animated: true)) + case .showOriginal: + // do nothing, as the translation is reverted in `StatusTableViewCellDelegate` in `DataSourceProvider+StatusTableViewCellDelegate.swift`. + break case .followUser(_): guard let author = menuContext.author else { return } diff --git a/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift b/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift index 230608e58..dc6a9fda5 100644 --- a/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift +++ b/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift @@ -496,6 +496,14 @@ extension StatusTableViewCellDelegate where Self: DataSourceProvider & AuthConte cell.invalidateIntrinsicContentSize() } } + + if case .showOriginal = action { + DispatchQueue.main.async { + if let cell = cell as? StatusTableViewCell { + cell.statusView.revertTranslation() + } + } + } try await DataSourceFacade.responseToMenuAction( dependency: self, diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift index f1972a5e8..a5cb3e808 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusAuthorView.swift @@ -166,10 +166,12 @@ extension StatusAuthorView { postActions.append(.editStatus) } - if let statusLanguage = menuContext.statusLanguage, menuContext.isTranslationEnabled, !menuContext.isTranslated { - postActions.append( - .translateStatus(.init(language: statusLanguage)) - ) + if let statusLanguage = menuContext.statusLanguage, menuContext.isTranslationEnabled { + if menuContext.isTranslated == false { + postActions.append(.translateStatus(.init(language: statusLanguage))) + } else { + postActions.append(.showOriginal) + } } postActions.append(.bookmarkStatus(.init(isBookmarking: menuContext.isBookmarking))) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift index 5ccc88e83..653854bf4 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift @@ -290,7 +290,7 @@ extension StatusView { viewModel.applicationName = applicationName } - func revertTranslation() { + public func revertTranslation() { guard let originalStatus = viewModel.originalStatus else { return } viewModel.translatedFromLanguage = nil diff --git a/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift b/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift index faef873d1..65231c51d 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Menu/MastodonMenu.swift @@ -48,6 +48,7 @@ public enum MastodonMenu { extension MastodonMenu { public enum Action { case translateStatus(TranslateStatusActionContext) + case showOriginal case muteUser(MuteUserActionContext) case blockUser(BlockUserActionContext) case reportUser(ReportUserActionContext) @@ -161,6 +162,16 @@ extension MastodonMenu { delegate.menuAction(self) } return translateAction + case .showOriginal: + let action = LabeledAction( + title: L10n.Common.Controls.Status.Translation.showOriginal, + image: UIImage(systemName: "character.book.closed") + ) { [weak delegate] in + guard let delegate = delegate else { return } + delegate.menuAction(self) + } + + return action case .editStatus: let editStatusAction = LabeledAction( title: L10n.Common.Controls.Actions.editPost, From a4a78a2c099b9734a96b69adc542067a002ccf82 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Tue, 13 Jun 2023 15:30:23 +0200 Subject: [PATCH 10/87] Fix JSON (IOS-103) --- Localization/app.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Localization/app.json b/Localization/app.json index 0aa701147..fc0e84c8b 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -104,8 +104,8 @@ "edit_post": "Edit", "bookmark": "Bookmark", "remove_bookmark": "Remove Bookmark", - "follow" = "Follow %s", - "unfollow" = "Unfollow %s" + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Home", From 5cf681e2d77d5477848f8c35eeafd8122df79611 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Mon, 26 Jun 2023 05:08:18 -0400 Subject: [PATCH 11/87] =?UTF-8?q?Set=20a=20solid=20background=20on=20the?= =?UTF-8?q?=20blurhash=20view=20in=20case=20it=20doesn=E2=80=99t=20load=20?= =?UTF-8?q?(#1069)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift index 6155b0da5..693c43d54 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/MediaView.swift @@ -30,6 +30,8 @@ public final class MediaView: UIView { imageView.contentMode = .scaleAspectFill imageView.isUserInteractionEnabled = false imageView.layer.masksToBounds = true // clip overflow + imageView.backgroundColor = .gray + imageView.isOpaque = true return imageView }() From 21275217be4e71d893484ae3b8f27146dbff59fe Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 28 Jun 2023 10:50:00 +0200 Subject: [PATCH 12/87] New Crowdin updates (#1052) --- .../Intents/input/el.lproj/Intents.strings | 6 +- .../StringsConvertor/input/an.lproj/app.json | 10 +- .../StringsConvertor/input/ar.lproj/app.json | 10 +- .../StringsConvertor/input/be.lproj/app.json | 10 +- .../StringsConvertor/input/ca.lproj/app.json | 10 +- .../StringsConvertor/input/ckb.lproj/app.json | 10 +- .../StringsConvertor/input/cs.lproj/app.json | 10 +- .../StringsConvertor/input/cy.lproj/app.json | 10 +- .../StringsConvertor/input/da.lproj/app.json | 18 ++-- .../StringsConvertor/input/de.lproj/app.json | 10 +- .../StringsConvertor/input/el.lproj/app.json | 98 ++++++++++--------- .../input/en-US.lproj/app.json | 10 +- .../StringsConvertor/input/en.lproj/app.json | 10 +- .../input/es-AR.lproj/app.json | 10 +- .../StringsConvertor/input/es.lproj/app.json | 10 +- .../StringsConvertor/input/eu.lproj/app.json | 10 +- .../StringsConvertor/input/fi.lproj/app.json | 30 +++--- .../StringsConvertor/input/fr.lproj/app.json | 10 +- .../StringsConvertor/input/gd.lproj/app.json | 10 +- .../StringsConvertor/input/gl.lproj/app.json | 10 +- .../StringsConvertor/input/he.lproj/app.json | 10 +- .../StringsConvertor/input/hi.lproj/app.json | 10 +- .../StringsConvertor/input/id.lproj/app.json | 10 +- .../StringsConvertor/input/is.lproj/app.json | 10 +- .../StringsConvertor/input/it.lproj/app.json | 18 ++-- .../StringsConvertor/input/ja.lproj/app.json | 12 ++- .../StringsConvertor/input/kab.lproj/app.json | 10 +- .../StringsConvertor/input/kmr.lproj/app.json | 10 +- .../StringsConvertor/input/ko.lproj/app.json | 10 +- .../StringsConvertor/input/lv.lproj/app.json | 10 +- .../StringsConvertor/input/my.lproj/app.json | 10 +- .../StringsConvertor/input/nl.lproj/app.json | 10 +- .../StringsConvertor/input/pl.lproj/app.json | 10 +- .../input/pt-BR.lproj/app.json | 10 +- .../StringsConvertor/input/pt.lproj/app.json | 10 +- .../StringsConvertor/input/ro.lproj/app.json | 10 +- .../StringsConvertor/input/ru.lproj/app.json | 10 +- .../StringsConvertor/input/si.lproj/app.json | 10 +- .../StringsConvertor/input/sl.lproj/app.json | 10 +- .../StringsConvertor/input/sv.lproj/app.json | 80 ++++++++------- .../StringsConvertor/input/th.lproj/app.json | 14 ++- .../StringsConvertor/input/tr.lproj/app.json | 10 +- .../StringsConvertor/input/uk.lproj/app.json | 10 +- .../StringsConvertor/input/vi.lproj/app.json | 10 +- .../zh-Hans.lproj/Localizable.stringsdict | 2 +- .../input/zh-Hans.lproj/app.json | 14 ++- .../input/zh-Hant.lproj/app.json | 12 ++- 47 files changed, 422 insertions(+), 242 deletions(-) diff --git a/Localization/StringsConvertor/Intents/input/el.lproj/Intents.strings b/Localization/StringsConvertor/Intents/input/el.lproj/Intents.strings index 6877490ba..484cc94b2 100644 --- a/Localization/StringsConvertor/Intents/input/el.lproj/Intents.strings +++ b/Localization/StringsConvertor/Intents/input/el.lproj/Intents.strings @@ -1,8 +1,8 @@ -"16wxgf" = "Post on Mastodon"; +"16wxgf" = "Ανάρτηση στο Mastodon"; -"751xkl" = "Text Content"; +"751xkl" = "Περιεχόμενο Κειμένου"; -"CsR7G2" = "Post on Mastodon"; +"CsR7G2" = "Ανάρτηση στο Mastodon"; "HZSGTr" = "What content to post?"; diff --git a/Localization/StringsConvertor/input/an.lproj/app.json b/Localization/StringsConvertor/input/an.lproj/app.json index cada279ea..8b04b3e3e 100644 --- a/Localization/StringsConvertor/input/an.lproj/app.json +++ b/Localization/StringsConvertor/input/an.lproj/app.json @@ -101,7 +101,11 @@ "title": "Translate from %s", "unknown_language": "Unknown" }, - "edit_post": "Edit" + "edit_post": "Edit", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Inicio", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Troba Chent a la quala Seguir", - "follow_explain": "Quan sigas a belún veyerás las suyas publicacions en a tuya pachina d'inicio." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/ar.lproj/app.json b/Localization/StringsConvertor/input/ar.lproj/app.json index 87fd1036a..1f6dd9504 100644 --- a/Localization/StringsConvertor/input/ar.lproj/app.json +++ b/Localization/StringsConvertor/input/ar.lproj/app.json @@ -101,7 +101,11 @@ "title": "الترجَمَة مِن %s", "unknown_language": "غير مَعرُوفة" }, - "edit_post": "Edit" + "edit_post": "Edit", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "الرَّئِيسَة", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "ابحث عن أشخاص لمتابعتهم", - "follow_explain": "عِندَ مُتابَعَتِكَ لأحدِهِم، سَوف تَرى مَنشوراته في تغذيَتِكَ الرئيسة." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/be.lproj/app.json b/Localization/StringsConvertor/input/be.lproj/app.json index 051730605..ec33e07c4 100644 --- a/Localization/StringsConvertor/input/be.lproj/app.json +++ b/Localization/StringsConvertor/input/be.lproj/app.json @@ -101,7 +101,11 @@ "title": "Перакласці з %s", "unknown_language": "Невядомая" }, - "edit_post": "Рэдагаваць" + "edit_post": "Рэдагаваць", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Галоўная", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Знайсці людзей, каб падпісацца", - "follow_explain": "Калі вы падпішацеся на кагосьці, вы ўбачыце яго допісы ў сваёй хатняй стужцы." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/ca.lproj/app.json b/Localization/StringsConvertor/input/ca.lproj/app.json index 9d4d3080c..d151bacfb 100644 --- a/Localization/StringsConvertor/input/ca.lproj/app.json +++ b/Localization/StringsConvertor/input/ca.lproj/app.json @@ -101,7 +101,11 @@ "title": "Traduït del %s", "unknown_language": "Desconegut" }, - "edit_post": "Edita" + "edit_post": "Edita", + "bookmark": "Marcador", + "remove_bookmark": "Suprimeix el marcador", + "follow": "Segueix a %s", + "unfollow": "Deixa de seguir %s" }, "tabs": { "home": "Inici", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Cerca Persones a Seguir", - "follow_explain": "Quan segueixes algú, veuràs els seus tuts a Inici." + "title": "Popular a Mastodon", + "follow_all": "Seguir a tothom" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/ckb.lproj/app.json b/Localization/StringsConvertor/input/ckb.lproj/app.json index 56ff08b7a..ae2f8bfae 100644 --- a/Localization/StringsConvertor/input/ckb.lproj/app.json +++ b/Localization/StringsConvertor/input/ckb.lproj/app.json @@ -101,7 +101,11 @@ "title": "Translate from %s", "unknown_language": "Unknown" }, - "edit_post": "Edit" + "edit_post": "Edit", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "ماڵەوە", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "خەڵک بدۆزەوە", - "follow_explain": "کاتێک شوێنی یەکێک دەکەویت، پۆستەکانی دێتە بەردەمت." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/cs.lproj/app.json b/Localization/StringsConvertor/input/cs.lproj/app.json index d53994c1b..e42a741e4 100644 --- a/Localization/StringsConvertor/input/cs.lproj/app.json +++ b/Localization/StringsConvertor/input/cs.lproj/app.json @@ -101,7 +101,11 @@ "title": "Přeložit z %s", "unknown_language": "Neznámý" }, - "edit_post": "Upravit" + "edit_post": "Upravit", + "bookmark": "Záložka", + "remove_bookmark": "Odstranit záložku", + "follow": "Sledovat %s", + "unfollow": "Přestat sledovat %s" }, "tabs": { "home": "Domů", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Najít lidi pro sledování", - "follow_explain": "Když někoho sledujete, uvidíte jejich příspěvky ve vašem domovském kanálu." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json index b5671b410..c39f7e60e 100644 --- a/Localization/StringsConvertor/input/cy.lproj/app.json +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -101,7 +101,11 @@ "title": "Cyfieithu o %s", "unknown_language": "Anhysbys" }, - "edit_post": "Golygu" + "edit_post": "Golygu", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Hafan", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Chwilio a Dilyn Pobl", - "follow_explain": "Ar ôl ichi ddilyn rhywun, byddwch yn gweld eu postiadau yn eich ffrwd hafan." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/da.lproj/app.json b/Localization/StringsConvertor/input/da.lproj/app.json index 96eaddfe1..51ba05829 100644 --- a/Localization/StringsConvertor/input/da.lproj/app.json +++ b/Localization/StringsConvertor/input/da.lproj/app.json @@ -2,14 +2,14 @@ "common": { "alerts": { "common": { - "please_try_again": "Please try again.", - "please_try_again_later": "Please try again later." + "please_try_again": "Prøv venligst igen.", + "please_try_again_later": "Prøv venligst igen senere." }, "sign_up_failure": { - "title": "Sign Up Failure" + "title": "Tilmeldingsfejl" }, "server_error": { - "title": "Server Error" + "title": "Serverfejl" }, "vote_failure": { "title": "Vote Failure", @@ -101,7 +101,11 @@ "title": "Translate from %s", "unknown_language": "Unknown" }, - "edit_post": "Edit" + "edit_post": "Edit", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Home", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Find People to Follow", - "follow_explain": "When you follow someone, you’ll see their posts in your home feed." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/de.lproj/app.json b/Localization/StringsConvertor/input/de.lproj/app.json index 020eea89d..bc4452e8d 100644 --- a/Localization/StringsConvertor/input/de.lproj/app.json +++ b/Localization/StringsConvertor/input/de.lproj/app.json @@ -101,7 +101,11 @@ "title": "Von %s übersetzen", "unknown_language": "Unbekannt" }, - "edit_post": "Bearbeiten" + "edit_post": "Bearbeiten", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Startseite", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Finde Personen zum Folgen", - "follow_explain": "Sobald du anderen folgst, siehst du deren Beiträge in deinem Home-Feed." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/el.lproj/app.json b/Localization/StringsConvertor/input/el.lproj/app.json index adf4d7f56..33038b39e 100644 --- a/Localization/StringsConvertor/input/el.lproj/app.json +++ b/Localization/StringsConvertor/input/el.lproj/app.json @@ -101,7 +101,11 @@ "title": "Μετάφραση από %s", "unknown_language": "Άγνωστο" }, - "edit_post": "Επεξεργασία" + "edit_post": "Επεξεργασία", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Αρχική", @@ -125,55 +129,55 @@ "next_status": "Επόμενη Ανάρτηση", "open_status": "Άνοιγμα Ανάρτησης", "open_author_profile": "Άνοιγμα Προφίλ Συντάκτη", - "open_reblogger_profile": "Open Reblogger's Profile", - "reply_status": "Reply to Post", - "toggle_reblog": "Toggle Reblog on Post", + "open_reblogger_profile": "Άνοιγμα Προφίλ Του Reblogger", + "reply_status": "Απάντηση στην Ανάρτηση", + "toggle_reblog": "Εναλλαγή Αναδημοσίευσης στην Ανάρτηση", "toggle_favorite": "Toggle Favorite on Post", "toggle_content_warning": "Toggle Content Warning", - "preview_image": "Preview Image" + "preview_image": "Προεπισκόπηση Εικόνας" }, "segmented_control": { - "previous_section": "Previous Section", - "next_section": "Next Section" + "previous_section": "Προηγούμενη Ενότητα", + "next_section": "Επόμενη Ενότητα" } }, "status": { - "user_reblogged": "%s reblogged", - "user_replied_to": "Replied to %s", - "show_post": "Show Post", - "show_user_profile": "Show user profile", - "content_warning": "Content Warning", - "sensitive_content": "Sensitive Content", - "media_content_warning": "Tap anywhere to reveal", - "tap_to_reveal": "Tap to reveal", - "load_embed": "Load Embed", - "link_via_user": "%s via %s", + "user_reblogged": "%s αναδημοσίευσε", + "user_replied_to": "Απάντησε στον χρήστη %s", + "show_post": "Εμφάνιση Ανάρτησης", + "show_user_profile": "Εμφάνιση προφίλ χρήστη", + "content_warning": "Προειδοποίηση Περιεχομένου", + "sensitive_content": "Ευαίσθητο Περιεχόμενο", + "media_content_warning": "Πάτα οπουδήποτε για εμφάνιση", + "tap_to_reveal": "Πάτα για εμφάνιση", + "load_embed": "Φόρτωση Ενσωμάτωσης", + "link_via_user": "%s μέσω %s", "poll": { - "vote": "Vote", - "closed": "Closed" + "vote": "Ψήφισε", + "closed": "Κλειστή" }, "meta_entity": { - "url": "Link: %s", - "hashtag": "Hashtag: %s", - "mention": "Show Profile: %s", - "email": "Email address: %s" + "url": "Σύνδεσμος: %s", + "hashtag": "Ετικέτα: %s", + "mention": "Εμφάνιση Προφίλ: %s", + "email": "Διεύθυνση email: %s" }, "actions": { - "reply": "Reply", - "reblog": "Reblog", - "unreblog": "Undo reblog", - "favorite": "Favorite", - "unfavorite": "Unfavorite", - "menu": "Menu", - "hide": "Hide", - "show_image": "Show image", - "show_gif": "Show GIF", - "show_video_player": "Show video player", - "share_link_in_post": "Share Link in Post", - "tap_then_hold_to_show_menu": "Tap then hold to show menu", + "reply": "Απάντηση", + "reblog": "Αναδημοσίευση", + "unreblog": "Αναίρεση αναδημοσίευσης", + "favorite": "Αγαπημένο", + "unfavorite": "Αφαίρεση από αγαπημένα", + "menu": "Μενού", + "hide": "Απόκρυψη", + "show_image": "Εμφάνιση εικόνας", + "show_gif": "Εμφάνιση GIF", + "show_video_player": "Εμφάνιση προγράμματος αναπαραγωγής βίντεο", + "share_link_in_post": "Κοινοποίηση Συνδέσμου στην Ανάρτηση", + "tap_then_hold_to_show_menu": "Πάτα παρατεταμένα για εμφάνιση μενού", "a11y_labels": { - "reblog": "Re-blog", - "unreblog": "Undo re-blog" + "reblog": "Αναδημοσίευση", + "unreblog": "Αναίρεση αναδημοσίευσης" } }, "tag": { @@ -185,16 +189,16 @@ "emoji": "Emoji" }, "visibility": { - "unlisted": "Everyone can see this post but not display in the public timeline.", - "private": "Only their followers can see this post.", - "private_from_me": "Only my followers can see this post.", - "direct": "Only mentioned user can see this post." + "unlisted": "Όλοι μπορούν να δουν αυτή την ανάρτηση, αλλά δεν εμφανίζεται στη δημόσια ροή.", + "private": "Μόνο οι ακόλουθοί τους μπορούν να δουν αυτή την ανάρτηση.", + "private_from_me": "Μόνο οι ακόλουθοί μου μπορούν να δουν αυτή την ανάρτηση.", + "direct": "Μόνο ο αναφερόμενος χρήστης μπορεί να δει αυτή την ανάρτηση." }, "translation": { - "translated_from": "Translated from %s using %s", - "unknown_language": "Unknown", - "unknown_provider": "Unknown", - "show_original": "Show Original" + "translated_from": "Μεταφράστηκε από %s χρησιμοποιώντας το %s", + "unknown_language": "Άγνωστο", + "unknown_provider": "Άγνωστο", + "show_original": "Εμφάνιση Αρχικού" }, "media": { "accessibility_label": "%s, attachment %d of %d", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Find People to Follow", - "follow_explain": "When you follow someone, you’ll see their posts in your home feed." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/en-US.lproj/app.json b/Localization/StringsConvertor/input/en-US.lproj/app.json index 96eaddfe1..5c798e695 100644 --- a/Localization/StringsConvertor/input/en-US.lproj/app.json +++ b/Localization/StringsConvertor/input/en-US.lproj/app.json @@ -101,7 +101,11 @@ "title": "Translate from %s", "unknown_language": "Unknown" }, - "edit_post": "Edit" + "edit_post": "Edit", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Home", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Find People to Follow", - "follow_explain": "When you follow someone, you’ll see their posts in your home feed." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/en.lproj/app.json b/Localization/StringsConvertor/input/en.lproj/app.json index 96eaddfe1..5c798e695 100644 --- a/Localization/StringsConvertor/input/en.lproj/app.json +++ b/Localization/StringsConvertor/input/en.lproj/app.json @@ -101,7 +101,11 @@ "title": "Translate from %s", "unknown_language": "Unknown" }, - "edit_post": "Edit" + "edit_post": "Edit", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Home", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Find People to Follow", - "follow_explain": "When you follow someone, you’ll see their posts in your home feed." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/es-AR.lproj/app.json b/Localization/StringsConvertor/input/es-AR.lproj/app.json index 6136b31ef..5d1526dba 100644 --- a/Localization/StringsConvertor/input/es-AR.lproj/app.json +++ b/Localization/StringsConvertor/input/es-AR.lproj/app.json @@ -101,7 +101,11 @@ "title": "Traducido desde el %s", "unknown_language": "Desconocido" }, - "edit_post": "Editar" + "edit_post": "Editar", + "bookmark": "Marcar", + "remove_bookmark": "Quitar marcador", + "follow": "Seguir a %s", + "unfollow": "Dejar de seguir a %s" }, "tabs": { "home": "Principal", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Encontrá cuentas para seguir", - "follow_explain": "Cuando sigás una cuenta, verás sus mensajes en tu línea temporal principal." + "title": "Popular en Mastodon", + "follow_all": "Seguir a todos" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/es.lproj/app.json b/Localization/StringsConvertor/input/es.lproj/app.json index 0cdbe6f75..c5be64866 100644 --- a/Localization/StringsConvertor/input/es.lproj/app.json +++ b/Localization/StringsConvertor/input/es.lproj/app.json @@ -101,7 +101,11 @@ "title": "Traducir desde %s", "unknown_language": "Desconocido" }, - "edit_post": "Edit" + "edit_post": "Edit", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Inicio", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Encuentra Gente a la que Seguir", - "follow_explain": "Cuando sigas a alguien verás sus publicaciones en tu página de inicio." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/eu.lproj/app.json b/Localization/StringsConvertor/input/eu.lproj/app.json index bf646bddc..971204abc 100644 --- a/Localization/StringsConvertor/input/eu.lproj/app.json +++ b/Localization/StringsConvertor/input/eu.lproj/app.json @@ -101,7 +101,11 @@ "title": "Translate from %s", "unknown_language": "Unknown" }, - "edit_post": "Edit" + "edit_post": "Edit", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Hasiera", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Bilatu jarraitzeko jendea", - "follow_explain": "Norbait jarraitzen duzunean, bere bidalketak zure hasierako denbora-lerroan agertuko zaizkizu." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/fi.lproj/app.json b/Localization/StringsConvertor/input/fi.lproj/app.json index f3fd52013..b4961b466 100644 --- a/Localization/StringsConvertor/input/fi.lproj/app.json +++ b/Localization/StringsConvertor/input/fi.lproj/app.json @@ -101,7 +101,11 @@ "title": "Käännetty kielestä %s", "unknown_language": "Tuntematon" }, - "edit_post": "Muokkaa" + "edit_post": "Muokkaa", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Koti", @@ -257,8 +261,8 @@ } }, "user_list": { - "no_verified_link": "No verified link", - "followers_count": "%@ followers" + "no_verified_link": "Ei todennettua linkkiä", + "followers_count": "%@ seuraajaa" } }, "scene": { @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Löydä tilejä seurattavaksi", - "follow_explain": "Kun seuraat jotakuta, näet hänen julkaisunsa kotisyötteessäsi." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { @@ -875,18 +879,18 @@ }, "hashtag": { "configuration": { - "display_name": "Hashtag", - "description": "Shows a recent post with the selected hashtag." + "display_name": "Aihetunniste", + "description": "Näyttää hiljattaisen julkaisun valitusta aihetunnisteesta." }, "not_found": { - "account_name": "John Mastodon", - "account": "@johnMastodon@no-such.account", - "content": "Sorry, we couldn’t find any posts with the hashtag #%@. Please try a #DifferentHashtag or check the widget settings." + "account_name": "Mikko Mastodon", + "account": "@mikkoMastodon@ei-sellaista.tiliä", + "content": "Valitettavasti emme löytäneet yhtään julkaisua aihetunnisteella #%@. Kokeile #DifferentHashtag tai tarkista widgetin asetukset." }, "placeholder": { - "account_name": "John Mastodon", - "account": "@johnMastodon@no-such.account", - "content": "This is how a post with a #hashtag would look. Pick whichever #hashtag you want in the widget settings." + "account_name": "Mikko Mastodon", + "account": "@mikkoMastodon@ei-sellaista.tiliä", + "content": "Tältä aihetunnisteen #aihetunniste julkaisu näyttäisi. Valitse mikä tahansa #aihetunniste widgetin asetuksista." } } } diff --git a/Localization/StringsConvertor/input/fr.lproj/app.json b/Localization/StringsConvertor/input/fr.lproj/app.json index e11e920f9..f42e7cbc2 100644 --- a/Localization/StringsConvertor/input/fr.lproj/app.json +++ b/Localization/StringsConvertor/input/fr.lproj/app.json @@ -101,7 +101,11 @@ "title": "Traduit depuis %s", "unknown_language": "Inconnu" }, - "edit_post": "Éditer" + "edit_post": "Éditer", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Accueil", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Trouver des personnes à suivre", - "follow_explain": "Quand vous suivez quelqu'un, vous verrez leurs messages dans votre flux d’accueil." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/gd.lproj/app.json b/Localization/StringsConvertor/input/gd.lproj/app.json index b182f7e1f..ec503a5a1 100644 --- a/Localization/StringsConvertor/input/gd.lproj/app.json +++ b/Localization/StringsConvertor/input/gd.lproj/app.json @@ -101,7 +101,11 @@ "title": "Eadar-theangaich o: %s", "unknown_language": "Chan eil fhios" }, - "edit_post": "Deasaich" + "edit_post": "Deasaich", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Dachaigh", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Lorg daoine a leanas tu", - "follow_explain": "Nuair a leanas tu cuideigin, chì thu na puist aca air inbhir na dachaigh agad." + "title": "Fèillmhor air Mastodon", + "follow_all": "Lean na h-uile" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/gl.lproj/app.json b/Localization/StringsConvertor/input/gl.lproj/app.json index d5f702c42..b731358ac 100644 --- a/Localization/StringsConvertor/input/gl.lproj/app.json +++ b/Localization/StringsConvertor/input/gl.lproj/app.json @@ -101,7 +101,11 @@ "title": "Traducido do %s", "unknown_language": "Descoñecido" }, - "edit_post": "Editar" + "edit_post": "Editar", + "bookmark": "Marcar", + "remove_bookmark": "Eliminar Marcador", + "follow": "Segue a %s", + "unfollow": "Deixa de seguir a %s" }, "tabs": { "home": "Inicio", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Atopar persoas para seguir", - "follow_explain": "Cando sigas a alguén verás as súas publicacións na cronoloxía de inicio." + "title": "Popular en Mastodon", + "follow_all": "Seguir a todas" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/he.lproj/app.json b/Localization/StringsConvertor/input/he.lproj/app.json index 15c0f1e35..12afb59f2 100644 --- a/Localization/StringsConvertor/input/he.lproj/app.json +++ b/Localization/StringsConvertor/input/he.lproj/app.json @@ -101,7 +101,11 @@ "title": "Translate from %s", "unknown_language": "Unknown" }, - "edit_post": "Edit" + "edit_post": "Edit", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Home", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Find People to Follow", - "follow_explain": "When you follow someone, you’ll see their posts in your home feed." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/hi.lproj/app.json b/Localization/StringsConvertor/input/hi.lproj/app.json index 5ff31187b..fa65fb89a 100644 --- a/Localization/StringsConvertor/input/hi.lproj/app.json +++ b/Localization/StringsConvertor/input/hi.lproj/app.json @@ -101,7 +101,11 @@ "title": "Translate from %s", "unknown_language": "Unknown" }, - "edit_post": "Edit" + "edit_post": "Edit", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Home", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Find People to Follow", - "follow_explain": "When you follow someone, you’ll see their posts in your home feed." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/id.lproj/app.json b/Localization/StringsConvertor/input/id.lproj/app.json index 0af26e99b..878e8743c 100644 --- a/Localization/StringsConvertor/input/id.lproj/app.json +++ b/Localization/StringsConvertor/input/id.lproj/app.json @@ -101,7 +101,11 @@ "title": "Terjemahkan dari %s", "unknown_language": "Unknown" }, - "edit_post": "Edit" + "edit_post": "Edit", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Beranda", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Temukan Orang untuk Diikuti", - "follow_explain": "Ketika Anda mengikuti seseorang, Anda akan melihat postingan mereka di beranda Anda." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/is.lproj/app.json b/Localization/StringsConvertor/input/is.lproj/app.json index 1eed941e7..4a58e3e6d 100644 --- a/Localization/StringsConvertor/input/is.lproj/app.json +++ b/Localization/StringsConvertor/input/is.lproj/app.json @@ -101,7 +101,11 @@ "title": "Þýða úr %s", "unknown_language": "Óþekkt" }, - "edit_post": "Breyta" + "edit_post": "Breyta", + "bookmark": "Bókamerki", + "remove_bookmark": "Fjarlægja bókamerki", + "follow": "Fylgjast með %s", + "unfollow": "Hætta að fylgjast með %s" }, "tabs": { "home": "Heim", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Finndu fólk til að fylgjast með", - "follow_explain": "Þegar þú fylgist með einhverjum, muntu sjá færslur frá viðkomandi á streyminu þínu." + "title": "Vinsælt á Mastodon", + "follow_all": "Fylgjast með öllum" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/it.lproj/app.json b/Localization/StringsConvertor/input/it.lproj/app.json index ff5a19e92..6a2077672 100644 --- a/Localization/StringsConvertor/input/it.lproj/app.json +++ b/Localization/StringsConvertor/input/it.lproj/app.json @@ -101,7 +101,11 @@ "title": "Traduci da %s", "unknown_language": "Sconosciuto" }, - "edit_post": "Modifica" + "edit_post": "Modifica", + "bookmark": "Segnalibro", + "remove_bookmark": "Rimuovi il segnalibro", + "follow": "Segui %s", + "unfollow": "Smetti di seguire %s" }, "tabs": { "home": "Inizio", @@ -146,7 +150,7 @@ "sensitive_content": "Contenuto sensibile", "media_content_warning": "Tocca ovunque per rivelare", "tap_to_reveal": "Tocca per rivelare", - "load_embed": "Carica Incorpora", + "load_embed": "Carica l'incorporato", "link_via_user": "%s tramite %s", "poll": { "vote": "Vota", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Trova alcune persone da seguire", - "follow_explain": "Quando segui qualcuno, vedrai i loro post nella tua home feed." + "title": "Popolare su Mastodon", + "follow_all": "Segui tutti" }, "compose": { "title": { @@ -613,7 +617,7 @@ } }, "follower": { - "title": "seguace", + "title": "seguaci", "footer": "I seguaci da altri server non vengono visualizzati." }, "following": { @@ -625,7 +629,7 @@ "followed_by_names": "Seguito da %s" }, "favorited_by": { - "title": "Preferito Da" + "title": "Preferito da" }, "reblogged_by": { "title": "Condiviso Da" @@ -831,7 +835,7 @@ "title": "Segnalibri" }, "followed_tags": { - "title": "Etichette seguite", + "title": "Hashtag seguiti", "header": { "posts": "post", "participants": "partecipanti", diff --git a/Localization/StringsConvertor/input/ja.lproj/app.json b/Localization/StringsConvertor/input/ja.lproj/app.json index 0254a81e4..5fa24cf06 100644 --- a/Localization/StringsConvertor/input/ja.lproj/app.json +++ b/Localization/StringsConvertor/input/ja.lproj/app.json @@ -101,7 +101,11 @@ "title": "%sから翻訳", "unknown_language": "不明" }, - "edit_post": "編集" + "edit_post": "編集", + "bookmark": "ブックマーク", + "remove_bookmark": "ブックマークから削除", + "follow": "%sをフォロー", + "unfollow": "%sをフォロー解除" }, "tabs": { "home": "ホーム", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "フォローする人を探す", - "follow_explain": "誰かをフォローすると、その人の投稿がタイムラインに表示されるようになります。" + "title": "人気のアカウント", + "follow_all": "すべてフォロー" }, "compose": { "title": { @@ -886,7 +890,7 @@ "placeholder": { "account_name": "John Mastodon", "account": "@johnMastodon@no-such.account", - "content": "This is how a post with a #hashtag would look. Pick whichever #hashtag you want in the widget settings." + "content": "#ハッシュタグ 投稿のサンプルです。検索する #ハッシュタグ はウィジェットの設定で指定できます。" } } } diff --git a/Localization/StringsConvertor/input/kab.lproj/app.json b/Localization/StringsConvertor/input/kab.lproj/app.json index d5596d6f2..d7715c685 100644 --- a/Localization/StringsConvertor/input/kab.lproj/app.json +++ b/Localization/StringsConvertor/input/kab.lproj/app.json @@ -101,7 +101,11 @@ "title": "Translate from %s", "unknown_language": "Unknown" }, - "edit_post": "Edit" + "edit_post": "Edit", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Agejdan", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Af imdanen ara tḍefreḍ", - "follow_explain": "Mi ara teṭṭafareḍ albaɛḍ, ad twaliḍ tisuffaɣ-is deg usuddem-inek agejdan." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/kmr.lproj/app.json b/Localization/StringsConvertor/input/kmr.lproj/app.json index 947e67800..ff504a3bb 100644 --- a/Localization/StringsConvertor/input/kmr.lproj/app.json +++ b/Localization/StringsConvertor/input/kmr.lproj/app.json @@ -101,7 +101,11 @@ "title": "Ji %s wergerîne", "unknown_language": "Nenas" }, - "edit_post": "Serrast bike" + "edit_post": "Serrast bike", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Serrûpel", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Kesên bo ku bişopînî bibîne", - "follow_explain": "Gava tu kesekî dişopînî, tu yê şandiyê wan di serrûpelê de bibîne." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/ko.lproj/app.json b/Localization/StringsConvertor/input/ko.lproj/app.json index 141b32946..2e543a3d6 100644 --- a/Localization/StringsConvertor/input/ko.lproj/app.json +++ b/Localization/StringsConvertor/input/ko.lproj/app.json @@ -101,7 +101,11 @@ "title": "%s에서 번역됨", "unknown_language": "알 수 없음" }, - "edit_post": "수정" + "edit_post": "수정", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "홈", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Find People to Follow", - "follow_explain": "When you follow someone, you’ll see their posts in your home feed." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/lv.lproj/app.json b/Localization/StringsConvertor/input/lv.lproj/app.json index 08c3e0a29..94c7ee93f 100644 --- a/Localization/StringsConvertor/input/lv.lproj/app.json +++ b/Localization/StringsConvertor/input/lv.lproj/app.json @@ -101,7 +101,11 @@ "title": "Tulkot no %s", "unknown_language": "Nezināms" }, - "edit_post": "Edit" + "edit_post": "Edit", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Sākums", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Atrodi Cilvēkus kam Sekot", - "follow_explain": "Kad seko kādam, tu redzēsi viņu ziņas savā mājas plūsmā." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/my.lproj/app.json b/Localization/StringsConvertor/input/my.lproj/app.json index f0de2d92d..055a99a38 100644 --- a/Localization/StringsConvertor/input/my.lproj/app.json +++ b/Localization/StringsConvertor/input/my.lproj/app.json @@ -101,7 +101,11 @@ "title": "Translate from %s", "unknown_language": "Unknown" }, - "edit_post": "Edit" + "edit_post": "Edit", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "အိမ်", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Find People to Follow", - "follow_explain": "When you follow someone, you’ll see their posts in your home feed." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/nl.lproj/app.json b/Localization/StringsConvertor/input/nl.lproj/app.json index ce728d863..dd0f1762d 100644 --- a/Localization/StringsConvertor/input/nl.lproj/app.json +++ b/Localization/StringsConvertor/input/nl.lproj/app.json @@ -101,7 +101,11 @@ "title": "Vertaald uit het %s", "unknown_language": "Onbekend" }, - "edit_post": "Bewerken" + "edit_post": "Bewerken", + "bookmark": "Bladwijzer toevoegen", + "remove_bookmark": "Bladwijzer verwijderen", + "follow": "Volg %s", + "unfollow": "Ontvolg %s" }, "tabs": { "home": "Start", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Zoek mensen om te volgen", - "follow_explain": "Wanneer je iemand volgt, zie je hun berichten op jouw starttijdlijn." + "title": "Populair op Mastodon", + "follow_all": "Iedereen volgen" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/pl.lproj/app.json b/Localization/StringsConvertor/input/pl.lproj/app.json index da4364c6b..affd918b0 100644 --- a/Localization/StringsConvertor/input/pl.lproj/app.json +++ b/Localization/StringsConvertor/input/pl.lproj/app.json @@ -101,7 +101,11 @@ "title": "Przetłumacz z %s", "unknown_language": "Nieznany" }, - "edit_post": "Edytuj" + "edit_post": "Edytuj", + "bookmark": "Zakładka", + "remove_bookmark": "Usuń zakładkę", + "follow": "Obserwuj %s", + "unfollow": "Przestań obserwować %s" }, "tabs": { "home": "Strona główna", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Find People to Follow", - "follow_explain": "When you follow someone, you’ll see their posts in your home feed." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/pt-BR.lproj/app.json b/Localization/StringsConvertor/input/pt-BR.lproj/app.json index bf90976a4..68f154151 100644 --- a/Localization/StringsConvertor/input/pt-BR.lproj/app.json +++ b/Localization/StringsConvertor/input/pt-BR.lproj/app.json @@ -101,7 +101,11 @@ "title": "Translate from %s", "unknown_language": "Unknown" }, - "edit_post": "Edit" + "edit_post": "Edit", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Início", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Encontre pessoas para seguir", - "follow_explain": "Ao seguir alguém, você verá as publicações dessa pessoa na sua página inicial." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/pt.lproj/app.json b/Localization/StringsConvertor/input/pt.lproj/app.json index a26551b7a..806a1e779 100644 --- a/Localization/StringsConvertor/input/pt.lproj/app.json +++ b/Localization/StringsConvertor/input/pt.lproj/app.json @@ -101,7 +101,11 @@ "title": "Translate from %s", "unknown_language": "Unknown" }, - "edit_post": "Edit" + "edit_post": "Edit", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Home", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Find People to Follow", - "follow_explain": "When you follow someone, you’ll see their posts in your home feed." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/ro.lproj/app.json b/Localization/StringsConvertor/input/ro.lproj/app.json index f297ddd21..93a073f40 100644 --- a/Localization/StringsConvertor/input/ro.lproj/app.json +++ b/Localization/StringsConvertor/input/ro.lproj/app.json @@ -101,7 +101,11 @@ "title": "Traduceți din %s", "unknown_language": "Necunoscut" }, - "edit_post": "Edit" + "edit_post": "Edit", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Acasă", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Find People to Follow", - "follow_explain": "When you follow someone, you’ll see their posts in your home feed." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/ru.lproj/app.json b/Localization/StringsConvertor/input/ru.lproj/app.json index e8aaf2f77..cb58da5c6 100644 --- a/Localization/StringsConvertor/input/ru.lproj/app.json +++ b/Localization/StringsConvertor/input/ru.lproj/app.json @@ -101,7 +101,11 @@ "title": "Translate from %s", "unknown_language": "Unknown" }, - "edit_post": "Edit" + "edit_post": "Edit", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Главная", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Подпишитесь на людей", - "follow_explain": "Посты людей, на которых вы подписались, будут видны на главной странице." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/si.lproj/app.json b/Localization/StringsConvertor/input/si.lproj/app.json index 52d34af59..6735c4f8c 100644 --- a/Localization/StringsConvertor/input/si.lproj/app.json +++ b/Localization/StringsConvertor/input/si.lproj/app.json @@ -101,7 +101,11 @@ "title": "Translate from %s", "unknown_language": "Unknown" }, - "edit_post": "Edit" + "edit_post": "Edit", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Home", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Find People to Follow", - "follow_explain": "When you follow someone, you’ll see their posts in your home feed." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/sl.lproj/app.json b/Localization/StringsConvertor/input/sl.lproj/app.json index 9ad9bbe59..5a3e7813b 100644 --- a/Localization/StringsConvertor/input/sl.lproj/app.json +++ b/Localization/StringsConvertor/input/sl.lproj/app.json @@ -101,7 +101,11 @@ "title": "Prevedi iz: %s", "unknown_language": "Neznano" }, - "edit_post": "Uredi" + "edit_post": "Uredi", + "bookmark": "Zaznamek", + "remove_bookmark": "Odstrani zaznamek", + "follow": "Sledi %s", + "unfollow": "Prenehaj slediti %s" }, "tabs": { "home": "Domov", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Poiščite osebe, ki jim želite slediti", - "follow_explain": "Ko nekomu sledite, vidite njihove objave v svojem domačem viru." + "title": "Priljubljeno na Mastodonu", + "follow_all": "Sledi vsem" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/sv.lproj/app.json b/Localization/StringsConvertor/input/sv.lproj/app.json index 24b0b3158..fc9012a94 100644 --- a/Localization/StringsConvertor/input/sv.lproj/app.json +++ b/Localization/StringsConvertor/input/sv.lproj/app.json @@ -101,7 +101,11 @@ "title": "Översätt från %s", "unknown_language": "Okänt" }, - "edit_post": "Redigera" + "edit_post": "Redigera", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Hem", @@ -109,8 +113,8 @@ "notifications": "Notiser", "profile": "Profil", "a11y": { - "search": "Search", - "explore": "Explore" + "search": "Sök", + "explore": "Utforska" } }, "keyboard": { @@ -209,7 +213,7 @@ "edit_history_title": "Edit History", "edit_history_detail": "Last edit %s" }, - "edited_at_timestamp_prefix": "Edited %s", + "edited_at_timestamp_prefix": "Ändrad %s", "edit_history": { "title": "Edit History", "original_post": "Original Post · %s" @@ -257,7 +261,7 @@ } }, "user_list": { - "no_verified_link": "No verified link", + "no_verified_link": "Ingen verifierad länk", "followers_count": "%@ följare" } }, @@ -265,36 +269,36 @@ "welcome": { "log_in": "Logga in", "learn_more": "Läs mer", - "join_default_server": "Join mastodon.social", - "pick_server": "Pick another server", + "join_default_server": "Gå med i mastodon.social", + "pick_server": "Hitta en annan server", "separator": { - "or": "or" + "or": "eller" }, "education": { "mastodon": { - "title": "Welcome to Mastodon", - "description": "Mastodon is a decentralized social network, meaning no single company controls it. It’s made up of many independently-run servers, all connected together." + "title": "Välkommen till Mastodon", + "description": "Mastodon är ett decentraliserat socialt nätverk, vilket innebär att inget enskilt företag kontrollerar det. Det består av många oberoende servrar, alla sammankopplade." }, "servers": { - "title": "What are servers?", - "description": "Every Mastodon account is hosted on a server — each with its own values, rules, & admins. No matter which one you pick, you can follow and interact with people on any server." + "title": "Vad är servrar?", + "description": "Varje Mastodon-konto finns på en server — var och en med sina värderingar, regler och administratörer. Oavsett vilken du väljer kan du följa och interagera med människor på vilken server som helst." }, "a11y": { "what_is_mastodon": { - "title": "What is Mastodon?" + "title": "Vad är Mastodon?" } } } }, "login": { - "title": "Welcome back", + "title": "Välkommen tillbaka", "subtitle": "Logga in på servern där du skapade ditt konto.", "server_search_field": { "placeholder": "Ange URL eller sök efter din server" } }, "server_picker": { - "title": "Pick Server", + "title": "Välj server", "button": { "language": "Språk", "signup_speed": "Sign-up Speed", @@ -333,25 +337,25 @@ "signup_speed": { "all": "All", "instant": "Instant Sign-up", - "manually_reviewed": "Manual Review" + "manually_reviewed": "Manuell granskning" }, "language": { "all": "All" }, "search": { - "placeholder": "Search name or URL" + "placeholder": "Sök namn eller URL" }, - "no_server_selected_hint": "We’ll pick a server based on your language if you continue without making a selection." + "no_server_selected_hint": "Vi kommer att välja en server baserat på ditt språk om du fortsätter utan att göra ett val." }, "privacy": { "title": "Privacy", - "description": "Although the Mastodon app does not collect any data, the server you sign up through may have a different policy. Take a minute to review and agree to the Mastodon app privacy policy and your server’s privacy policy.", + "description": "Även om Mastodon-appen inte samlar in någon data kan servern du registrerar dig genom ha en annan policy. Ta en stund till att granska och godkänna Mastodon-appens sekretesspolicy och din servers sekretesspolicy.", "policy": { "ios": "Integritetspolicy - Mastodon för iOS", "server": "Integritetspolicy - %s" }, "button": { - "confirm": "I Agree" + "confirm": "Jag godkänner" } }, "register": { @@ -373,7 +377,7 @@ }, "password": { "placeholder": "lösenord", - "confirmation_placeholder": "Confirm Password", + "confirmation_placeholder": "Bekräfta lösenord", "require": "Ditt lösenord behöver minst:", "character_limit": "8 tecken", "accessibility": { @@ -398,7 +402,7 @@ "reason": { "blocked": "%s innehåller en icke tillåten e-postleverantör", "unreachable": "%s verkar inte existera", - "taken": "%s is already taken. How about:", + "taken": "%s är redan tagen. Vad sägs om:", "reserved": "%s är ett reserverat nyckelord", "accepted": "%s måste godkännas", "blank": "%s krävs", @@ -422,12 +426,12 @@ "terms_of_service": "användarvillkor", "privacy_policy": "integritetspolicy", "button": { - "confirm": "I Agree" + "confirm": "Jag godkänner" } }, "confirm_email": { - "title": "Check Your Inbox", - "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we sent you to verify %@. We’ll wait right here.", + "title": "Kolla din inkorg", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "Klicka på länken som vi har skickat till dig för att bekräfta %@. Vi väntar här.", "button": { "resend": "Skicka igen" }, @@ -443,8 +447,8 @@ "open_email_client": "Öppna e-postklient" }, "didnt_get_link": { - "prefix": "Didn’t get a link?", - "resend_in": "Resend (%@)", + "prefix": "Fick du ingen länk?", + "resend_in": "Skicka igen (%@)", "resend_now": "Resend now." } }, @@ -462,14 +466,14 @@ } }, "suggestion_account": { - "title": "Hitta personer att följa", - "follow_explain": "När du följer någon, kommer du att se deras inlägg i ditt hemflöde." + "title": "Populärt på Mastodon", + "follow_all": "Följ alla" }, "compose": { "title": { "new_post": "Nytt inlägg", "new_reply": "Nytt svar", - "edit_post": "Edit Post" + "edit_post": "Redigera inlägg" }, "media_selection": { "camera": "Ta foto", @@ -506,8 +510,8 @@ "the_poll_has_empty_option": "Undersökningen har ett tomt alternativ", "add_option": "Add Option", "remove_option": "Remove Option", - "move_up": "Move Up", - "move_down": "Move Down" + "move_up": "Flytta upp", + "move_down": "Flytta ned" }, "content_warning": { "placeholder": "Skriv en noggrann varning här..." @@ -543,8 +547,8 @@ "language": { "title": "Post Language", "suggested": "Suggested", - "recent": "Recent", - "other": "Other Language…" + "recent": "Senaste", + "other": "Andra språk…" } }, "profile": { @@ -845,7 +849,7 @@ }, "extension": { "open_in": { - "invalid_link_error": "This doesn't seem to be a valid Mastodon link." + "invalid_link_error": "Detta verkar inte vara en giltig Mastodon-länk." } }, "widget": { @@ -854,10 +858,10 @@ "user_not_logged_in": "Please open Mastodon to log in to an Account." }, "followers_count": { - "configuration_display_name": "Followers", + "configuration_display_name": "Följare", "configuration_description": "Show number of followers.", - "title": "FOLLOWERS", - "followers_today": "%s followers today" + "title": "FÖLJARE", + "followers_today": "%s följare idag" }, "multiple_followers": { "configuration_display_name": "Multiple followers", diff --git a/Localization/StringsConvertor/input/th.lproj/app.json b/Localization/StringsConvertor/input/th.lproj/app.json index 0343d6005..c7d6136b9 100644 --- a/Localization/StringsConvertor/input/th.lproj/app.json +++ b/Localization/StringsConvertor/input/th.lproj/app.json @@ -101,7 +101,11 @@ "title": "แปลจาก %s", "unknown_language": "ไม่รู้จัก" }, - "edit_post": "แก้ไข" + "edit_post": "แก้ไข", + "bookmark": "เพิ่มที่คั่นหน้า", + "remove_bookmark": "เอาที่คั่นหน้าออก", + "follow": "ติดตาม %s", + "unfollow": "เลิกติดตาม %s" }, "tabs": { "home": "หน้าแรก", @@ -341,7 +345,7 @@ "search": { "placeholder": "ค้นหาชื่อหรือ URL" }, - "no_server_selected_hint": "เราจะเลือกเซิร์ฟเวอร์ตามภาษาของคุณหากคุณดำเนินการต่อโดยไม่ได้ทำการเลือก" + "no_server_selected_hint": "เราจะเลือกเซิร์ฟเวอร์โดยอิงตามภาษาของคุณหากคุณดำเนินการต่อโดยไม่ได้ทำการเลือก" }, "privacy": { "title": "ความเป็นส่วนตัว", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "ค้นหาผู้คนที่จะติดตาม", - "follow_explain": "เมื่อคุณติดตามใครสักคน คุณจะเห็นโพสต์ของเขาในฟีดหน้าแรกของคุณ" + "title": "เป็นที่นิยมใน Mastodon", + "follow_all": "ติดตามทั้งหมด" }, "compose": { "title": { @@ -671,7 +675,7 @@ "community": "ชุมชน", "for_you": "สำหรับคุณ" }, - "intro": "นี่คือโพสต์ที่กำลังได้รับความสนใจในมุมของ Mastodon ของคุณ" + "intro": "นี่คือโพสต์ที่ได้รับความสนใจในมุมของ Mastodon ของคุณ" }, "favorite": { "title": "รายการโปรด" diff --git a/Localization/StringsConvertor/input/tr.lproj/app.json b/Localization/StringsConvertor/input/tr.lproj/app.json index 504f987fd..e4ba16c29 100644 --- a/Localization/StringsConvertor/input/tr.lproj/app.json +++ b/Localization/StringsConvertor/input/tr.lproj/app.json @@ -101,7 +101,11 @@ "title": "Translate from %s", "unknown_language": "Unknown" }, - "edit_post": "Edit" + "edit_post": "Edit", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Ana Sayfa", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Takip Edecek İnsanlar Bul", - "follow_explain": "Birisini takip ettiğinizde, ana sayfanızda o kişinin gönderilerini görürsünüz." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/uk.lproj/app.json b/Localization/StringsConvertor/input/uk.lproj/app.json index 43020e5f0..17156ab8f 100644 --- a/Localization/StringsConvertor/input/uk.lproj/app.json +++ b/Localization/StringsConvertor/input/uk.lproj/app.json @@ -101,7 +101,11 @@ "title": "Translate from %s", "unknown_language": "Unknown" }, - "edit_post": "Edit" + "edit_post": "Edit", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Головна", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Знайти людей, аби підписатися", - "follow_explain": "Коли ви підпишетесь на когось, ви побачите його дописи у своїй домашній стрічці." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/vi.lproj/app.json b/Localization/StringsConvertor/input/vi.lproj/app.json index 74fda5ce0..b44485561 100644 --- a/Localization/StringsConvertor/input/vi.lproj/app.json +++ b/Localization/StringsConvertor/input/vi.lproj/app.json @@ -101,7 +101,11 @@ "title": "Dịch từ %s", "unknown_language": "Chưa xác định" }, - "edit_post": "Sửa" + "edit_post": "Sửa", + "bookmark": "Lưu", + "remove_bookmark": "Bỏ lưu", + "follow": "Theo dõi %s", + "unfollow": "Bỏ theo dõi %s" }, "tabs": { "home": "Bảng tin", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "Đề xuất theo dõi", - "follow_explain": "Khi theo dõi ai đó, bạn sẽ thấy tút của họ trong bảng tin." + "title": "Thịnh hành trên Mastodon", + "follow_all": "Theo dõi tất cả" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/zh-Hans.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/zh-Hans.lproj/Localizable.stringsdict index c7a332a38..f6e2ef97a 100644 --- a/Localization/StringsConvertor/input/zh-Hans.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/zh-Hans.lproj/Localizable.stringsdict @@ -162,7 +162,7 @@ NSStringFormatValueTypeKey ld other - %ld re-blogs + %ld 次转发 plural.count.reply diff --git a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json index abb177f66..638adc19e 100644 --- a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json @@ -101,7 +101,11 @@ "title": "翻译自 %s", "unknown_language": "未知的" }, - "edit_post": "编辑" + "edit_post": "编辑", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "主页", @@ -257,8 +261,8 @@ } }, "user_list": { - "no_verified_link": "No verified link", - "followers_count": "%@ followers" + "no_verified_link": "未验证链接", + "followers_count": "%@ 名关注者" } }, "scene": { @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "查看推荐关注的用户", - "follow_explain": "当你关注某个人时,你将会在主页看到他们的帖子。" + "title": "Mastodon上流行的", + "follow_all": "一键关注" }, "compose": { "title": { diff --git a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json index 78687cc55..4b0672be8 100644 --- a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json @@ -101,7 +101,11 @@ "title": "翻譯自 %s", "unknown_language": "未知" }, - "edit_post": "編輯" + "edit_post": "編輯", + "bookmark": "書籤", + "remove_bookmark": "移除書籤", + "follow": "跟隨 %s", + "unfollow": "取消跟隨 %s" }, "tabs": { "home": "首頁", @@ -462,8 +466,8 @@ } }, "suggestion_account": { - "title": "尋找一些人來跟隨", - "follow_explain": "當您跟隨這些人時,將會看到他們的嘟文出現在您的首頁時間軸上。" + "title": "Mastodon 上之流行內容", + "follow_all": "跟隨所有" }, "compose": { "title": { @@ -487,7 +491,7 @@ "description_video": "為視障人士提供影片說明...", "load_failed": "讀取失敗", "upload_failed": "上傳失敗", - "can_not_recognize_this_media_attachment": "無法識別此媒體附加檔案", + "can_not_recognize_this_media_attachment": "無法識別此多媒體附加檔案", "attachment_too_large": "附加檔案大小過大", "compressing_state": "正在壓縮...", "server_processing_state": "伺服器處理中..." From 38434bde50c1a3529ecd79da2a593cae11cbf582 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 28 Jun 2023 13:46:26 +0200 Subject: [PATCH 13/87] Update strings --- .../input/Base.lproj/app.json | 11 ++- MastodonIntent/el.lproj/Intents.strings | 6 +- .../Generated/Strings.swift | 4 +- .../Resources/Base.lproj/Localizable.strings | 10 +- .../Resources/ar.lproj/Localizable.strings | 8 +- .../Resources/ca.lproj/Localizable.strings | 8 +- .../Resources/ckb.lproj/Localizable.strings | 8 +- .../Resources/cs.lproj/Localizable.strings | 8 +- .../Resources/de.lproj/Localizable.strings | 8 +- .../Resources/el.lproj/Localizable.strings | 96 ++++++++++--------- .../Resources/en.lproj/Localizable.strings | 8 +- .../Resources/es.lproj/Localizable.strings | 8 +- .../Resources/eu.lproj/Localizable.strings | 8 +- .../Resources/fi.lproj/Localizable.strings | 28 +++--- .../Resources/fr.lproj/Localizable.strings | 8 +- .../Resources/gd.lproj/Localizable.strings | 8 +- .../Resources/gl.lproj/Localizable.strings | 8 +- .../Resources/it.lproj/Localizable.strings | 16 ++-- .../Resources/ja.lproj/Localizable.strings | 10 +- .../Resources/kab.lproj/Localizable.strings | 8 +- .../Resources/ku.lproj/Localizable.strings | 8 +- .../Resources/nl.lproj/Localizable.strings | 8 +- .../Resources/ru.lproj/Localizable.strings | 8 +- .../Resources/sl.lproj/Localizable.strings | 8 +- .../Resources/sv.lproj/Localizable.strings | 78 ++++++++------- .../Resources/th.lproj/Localizable.strings | 12 ++- .../Resources/tr.lproj/Localizable.strings | 8 +- .../Resources/vi.lproj/Localizable.strings | 8 +- .../zh-Hans.lproj/Localizable.strings | 12 ++- .../zh-Hans.lproj/Localizable.stringsdict | 2 +- .../zh-Hant.lproj/Localizable.strings | 10 +- Podfile.lock | 2 +- 32 files changed, 274 insertions(+), 167 deletions(-) diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index fdac63c88..fc0e84c8b 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -101,8 +101,11 @@ "title": "Translate from %s", "unknown_language": "Unknown" }, - "edit_post": "Edit" - + "edit_post": "Edit", + "bookmark": "Bookmark", + "remove_bookmark": "Remove Bookmark", + "follow": "Follow %s", + "unfollow": "Unfollow %s" }, "tabs": { "home": "Home", @@ -464,8 +467,8 @@ } }, "suggestion_account": { - "title": "Find People to Follow", - "follow_explain": "When you follow someone, you’ll see their posts in your home feed." + "title": "Popular on Mastodon", + "follow_all": "Follow all" }, "compose": { "title": { diff --git a/MastodonIntent/el.lproj/Intents.strings b/MastodonIntent/el.lproj/Intents.strings index 6877490ba..484cc94b2 100644 --- a/MastodonIntent/el.lproj/Intents.strings +++ b/MastodonIntent/el.lproj/Intents.strings @@ -1,8 +1,8 @@ -"16wxgf" = "Post on Mastodon"; +"16wxgf" = "Ανάρτηση στο Mastodon"; -"751xkl" = "Text Content"; +"751xkl" = "Περιεχόμενο Κειμένου"; -"CsR7G2" = "Post on Mastodon"; +"CsR7G2" = "Ανάρτηση στο Mastodon"; "HZSGTr" = "What content to post?"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index 65bb3abbe..a140c1f4e 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -1496,8 +1496,8 @@ public enum L10n { } } public enum SuggestionAccount { - /// Follow All - public static let followAll = L10n.tr("Localizable", "Scene.SuggestionAccount.FollowAll", fallback: "Follow All") + /// Follow all + public static let followAll = L10n.tr("Localizable", "Scene.SuggestionAccount.FollowAll", fallback: "Follow all") /// Popular on Mastodon public static let title = L10n.tr("Localizable", "Scene.SuggestionAccount.Title", fallback: "Popular on Mastodon") } diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 971de9623..970175d5c 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -30,6 +30,7 @@ Please check your internet connection."; "Common.Controls.Actions.Add" = "Add"; "Common.Controls.Actions.Back" = "Back"; "Common.Controls.Actions.BlockDomain" = "Block %@"; +"Common.Controls.Actions.Bookmark" = "Bookmark"; "Common.Controls.Actions.Cancel" = "Cancel"; "Common.Controls.Actions.Compose" = "Compose"; "Common.Controls.Actions.Confirm" = "Confirm"; @@ -40,10 +41,9 @@ Please check your internet connection."; "Common.Controls.Actions.Discard" = "Discard"; "Common.Controls.Actions.Done" = "Done"; "Common.Controls.Actions.Edit" = "Edit"; -"Common.Controls.Actions.Bookmark" = "Bookmark"; -"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; "Common.Controls.Actions.EditPost" = "Edit"; "Common.Controls.Actions.FindPeople" = "Find people to follow"; +"Common.Controls.Actions.Follow" = "Follow %@"; "Common.Controls.Actions.ManuallySearch" = "Manually search instead"; "Common.Controls.Actions.Next" = "Next"; "Common.Controls.Actions.Ok" = "OK"; @@ -53,6 +53,7 @@ Please check your internet connection."; "Common.Controls.Actions.Preview" = "Preview"; "Common.Controls.Actions.Previous" = "Previous"; "Common.Controls.Actions.Remove" = "Remove"; +"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; "Common.Controls.Actions.Reply" = "Reply"; "Common.Controls.Actions.ReportUser" = "Report %@"; "Common.Controls.Actions.Save" = "Save"; @@ -69,7 +70,6 @@ Please check your internet connection."; "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; "Common.Controls.Actions.TryAgain" = "Try Again"; "Common.Controls.Actions.UnblockDomain" = "Unblock %@"; -"Common.Controls.Actions.Follow" = "Follow %@"; "Common.Controls.Actions.Unfollow" = "Unfollow %@"; "Common.Controls.Friendship.Block" = "Block"; "Common.Controls.Friendship.BlockDomain" = "Block %@"; @@ -521,8 +521,8 @@ uploaded to Mastodon."; "Scene.Settings.Section.SpicyZone.Signout" = "Sign Out"; "Scene.Settings.Section.SpicyZone.Title" = "The Spicy Zone"; "Scene.Settings.Title" = "Settings"; +"Scene.SuggestionAccount.FollowAll" = "Follow all"; "Scene.SuggestionAccount.Title" = "Popular on Mastodon"; -"Scene.SuggestionAccount.FollowAll" = "Follow All"; "Scene.Thread.BackTitle" = "Post"; "Scene.Thread.Title" = "Post from %@"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "What is Mastodon?"; @@ -556,4 +556,4 @@ uploaded to Mastodon."; "Widget.MultipleFollowers.ConfigurationDescription" = "Show number of followers for multiple accounts."; "Widget.MultipleFollowers.ConfigurationDisplayName" = "Multiple followers"; "Widget.MultipleFollowers.MockUser.AccountName" = "another@follower.social"; -"Widget.MultipleFollowers.MockUser.DisplayName" = "Another follower"; +"Widget.MultipleFollowers.MockUser.DisplayName" = "Another follower"; \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.strings index 5a8af847a..f904471e4 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.strings @@ -30,6 +30,7 @@ "Common.Controls.Actions.Add" = "إضافة"; "Common.Controls.Actions.Back" = "العودة"; "Common.Controls.Actions.BlockDomain" = "حظر %@"; +"Common.Controls.Actions.Bookmark" = "Bookmark"; "Common.Controls.Actions.Cancel" = "إلغاء"; "Common.Controls.Actions.Compose" = "تأليف"; "Common.Controls.Actions.Confirm" = "تأكيد"; @@ -42,6 +43,7 @@ "Common.Controls.Actions.Edit" = "تَحرير"; "Common.Controls.Actions.EditPost" = "Edit"; "Common.Controls.Actions.FindPeople" = "ابحث عن أشخاص لِمُتابعتهم"; +"Common.Controls.Actions.Follow" = "Follow %@"; "Common.Controls.Actions.ManuallySearch" = "البحث يدويًا بدلًا من ذلك"; "Common.Controls.Actions.Next" = "التالي"; "Common.Controls.Actions.Ok" = "حسنًا"; @@ -51,6 +53,7 @@ "Common.Controls.Actions.Preview" = "مُعاينة"; "Common.Controls.Actions.Previous" = "السابق"; "Common.Controls.Actions.Remove" = "حذف"; +"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; "Common.Controls.Actions.Reply" = "الرَّد"; "Common.Controls.Actions.ReportUser" = "الإبلاغُ عَن %@"; "Common.Controls.Actions.Save" = "حفظ"; @@ -67,6 +70,7 @@ "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "غير مَعرُوفة"; "Common.Controls.Actions.TryAgain" = "المُحاولة مرة أُخرى"; "Common.Controls.Actions.UnblockDomain" = "رفع الحظر عن %@"; +"Common.Controls.Actions.Unfollow" = "Unfollow %@"; "Common.Controls.Friendship.Block" = "حظر"; "Common.Controls.Friendship.BlockDomain" = "حظر %@"; "Common.Controls.Friendship.BlockUser" = "حَظرُ %@"; @@ -517,8 +521,8 @@ "Scene.Settings.Section.SpicyZone.Signout" = "تَسجيلُ الخُروج"; "Scene.Settings.Section.SpicyZone.Title" = "المنطِقَةُ اللَّاذِعَة"; "Scene.Settings.Title" = "الإعدادات"; -"Scene.SuggestionAccount.FollowExplain" = "عِندَ مُتابَعَتِكَ لأحدِهِم، سَوف تَرى مَنشوراته في تغذيَتِكَ الرئيسة."; -"Scene.SuggestionAccount.Title" = "ابحث عن أشخاص لمتابعتهم"; +"Scene.SuggestionAccount.FollowAll" = "Follow all"; +"Scene.SuggestionAccount.Title" = "Popular on Mastodon"; "Scene.Thread.BackTitle" = "منشور"; "Scene.Thread.Title" = "مَنشور مِن %@"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "What is Mastodon?"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.strings index a7b7af620..d3ca97d91 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.strings @@ -30,6 +30,7 @@ Comprova la connexió a Internet."; "Common.Controls.Actions.Add" = "Afegeix"; "Common.Controls.Actions.Back" = "Enrere"; "Common.Controls.Actions.BlockDomain" = "Bloqueja %@"; +"Common.Controls.Actions.Bookmark" = "Marcador"; "Common.Controls.Actions.Cancel" = "Cancel·la"; "Common.Controls.Actions.Compose" = "Redacta"; "Common.Controls.Actions.Confirm" = "Confirma"; @@ -42,6 +43,7 @@ Comprova la connexió a Internet."; "Common.Controls.Actions.Edit" = "Edita"; "Common.Controls.Actions.EditPost" = "Edita"; "Common.Controls.Actions.FindPeople" = "Busca persones a seguir"; +"Common.Controls.Actions.Follow" = "Segueix a %@"; "Common.Controls.Actions.ManuallySearch" = "Cerca manualment a canvi"; "Common.Controls.Actions.Next" = "Següent"; "Common.Controls.Actions.Ok" = "D'acord"; @@ -51,6 +53,7 @@ Comprova la connexió a Internet."; "Common.Controls.Actions.Preview" = "Vista prèvia"; "Common.Controls.Actions.Previous" = "Anterior"; "Common.Controls.Actions.Remove" = "Elimina"; +"Common.Controls.Actions.RemoveBookmark" = "Suprimeix el marcador"; "Common.Controls.Actions.Reply" = "Respon"; "Common.Controls.Actions.ReportUser" = "Informa sobre %@"; "Common.Controls.Actions.Save" = "Desa"; @@ -67,6 +70,7 @@ Comprova la connexió a Internet."; "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Desconegut"; "Common.Controls.Actions.TryAgain" = "Torna a provar"; "Common.Controls.Actions.UnblockDomain" = "Desbloca %@"; +"Common.Controls.Actions.Unfollow" = "Deixa de seguir %@"; "Common.Controls.Friendship.Block" = "Bloca"; "Common.Controls.Friendship.BlockDomain" = "Bloca %@"; "Common.Controls.Friendship.BlockUser" = "Bloca %@"; @@ -518,8 +522,8 @@ Elegiremos un servidor basado en su idioma si continúa sin hacer una selección "Scene.Settings.Section.SpicyZone.Signout" = "Tancar Sessió"; "Scene.Settings.Section.SpicyZone.Title" = "La Zona Picant"; "Scene.Settings.Title" = "Configuració"; -"Scene.SuggestionAccount.FollowExplain" = "Quan segueixes algú, veuràs els seus tuts a Inici."; -"Scene.SuggestionAccount.Title" = "Cerca Persones a Seguir"; +"Scene.SuggestionAccount.FollowAll" = "Seguir a tothom"; +"Scene.SuggestionAccount.Title" = "Popular a Mastodon"; "Scene.Thread.BackTitle" = "Tut"; "Scene.Thread.Title" = "Tut de %@"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "Què és Mastodon?"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings index bf51fc737..6aa5a0591 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings @@ -30,6 +30,7 @@ "Common.Controls.Actions.Add" = "زیادی بکە"; "Common.Controls.Actions.Back" = "بگەڕێوە"; "Common.Controls.Actions.BlockDomain" = "%@ ئاستەنگ بکە"; +"Common.Controls.Actions.Bookmark" = "Bookmark"; "Common.Controls.Actions.Cancel" = "هەڵوەشاندنەوه"; "Common.Controls.Actions.Compose" = "پۆست بکە"; "Common.Controls.Actions.Confirm" = "پشتڕاستی بکەوە"; @@ -42,6 +43,7 @@ "Common.Controls.Actions.Edit" = "دەستکاری"; "Common.Controls.Actions.EditPost" = "Edit"; "Common.Controls.Actions.FindPeople" = "خەڵک بدۆزەوە"; +"Common.Controls.Actions.Follow" = "Follow %@"; "Common.Controls.Actions.ManuallySearch" = "خۆت بگەڕێ"; "Common.Controls.Actions.Next" = "دواتر"; "Common.Controls.Actions.Ok" = "باشە"; @@ -51,6 +53,7 @@ "Common.Controls.Actions.Preview" = "پێشبینین"; "Common.Controls.Actions.Previous" = "پێشتر"; "Common.Controls.Actions.Remove" = "لایبە"; +"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; "Common.Controls.Actions.Reply" = "وەڵامی بدەوە"; "Common.Controls.Actions.ReportUser" = "سکاڵا لە %@ بکە"; "Common.Controls.Actions.Save" = "هەڵی بگرە"; @@ -67,6 +70,7 @@ "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; "Common.Controls.Actions.TryAgain" = "هەوڵ بدەوە"; "Common.Controls.Actions.UnblockDomain" = "%@ ئاستەنگ مەکە"; +"Common.Controls.Actions.Unfollow" = "Unfollow %@"; "Common.Controls.Friendship.Block" = "ئاستەنگی بکە"; "Common.Controls.Friendship.BlockDomain" = "%@ ئاستەنگ بکە"; "Common.Controls.Friendship.BlockUser" = "%@ ئاستەنگ بکە"; @@ -516,8 +520,8 @@ "Scene.Settings.Section.SpicyZone.Signout" = "دەربچۆ"; "Scene.Settings.Section.SpicyZone.Title" = "ناوچەی گەرم"; "Scene.Settings.Title" = "رێکخستنەکان"; -"Scene.SuggestionAccount.FollowExplain" = "کاتێک شوێنی یەکێک دەکەویت، پۆستەکانی دێتە بەردەمت."; -"Scene.SuggestionAccount.Title" = "خەڵک بدۆزەوە"; +"Scene.SuggestionAccount.FollowAll" = "Follow all"; +"Scene.SuggestionAccount.Title" = "Popular on Mastodon"; "Scene.Thread.BackTitle" = "پۆستەکە"; "Scene.Thread.Title" = "پۆستی %@"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "What is Mastodon?"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/cs.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/cs.lproj/Localizable.strings index ea23c0f46..159a02330 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/cs.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/cs.lproj/Localizable.strings @@ -30,6 +30,7 @@ Zkontrolujte prosím připojení k internetu."; "Common.Controls.Actions.Add" = "Přidat"; "Common.Controls.Actions.Back" = "Zpět"; "Common.Controls.Actions.BlockDomain" = "Blokovat %@"; +"Common.Controls.Actions.Bookmark" = "Záložka"; "Common.Controls.Actions.Cancel" = "Zrušit"; "Common.Controls.Actions.Compose" = "Napsat"; "Common.Controls.Actions.Confirm" = "Potvrdit"; @@ -42,6 +43,7 @@ Zkontrolujte prosím připojení k internetu."; "Common.Controls.Actions.Edit" = "Upravit"; "Common.Controls.Actions.EditPost" = "Upravit"; "Common.Controls.Actions.FindPeople" = "Najít lidi ke sledování"; +"Common.Controls.Actions.Follow" = "Sledovat %@"; "Common.Controls.Actions.ManuallySearch" = "Místo toho ručně vyhledat"; "Common.Controls.Actions.Next" = "Další"; "Common.Controls.Actions.Ok" = "OK"; @@ -51,6 +53,7 @@ Zkontrolujte prosím připojení k internetu."; "Common.Controls.Actions.Preview" = "Náhled"; "Common.Controls.Actions.Previous" = "Předchozí"; "Common.Controls.Actions.Remove" = "Odstranit"; +"Common.Controls.Actions.RemoveBookmark" = "Odstranit záložku"; "Common.Controls.Actions.Reply" = "Odpovědět"; "Common.Controls.Actions.ReportUser" = "Nahlásit %@"; "Common.Controls.Actions.Save" = "Uložit"; @@ -67,6 +70,7 @@ Zkontrolujte prosím připojení k internetu."; "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Neznámý"; "Common.Controls.Actions.TryAgain" = "Zkusit znovu"; "Common.Controls.Actions.UnblockDomain" = "Odblokovat %@"; +"Common.Controls.Actions.Unfollow" = "Přestat sledovat %@"; "Common.Controls.Friendship.Block" = "Blokovat"; "Common.Controls.Friendship.BlockDomain" = "Blokovat %@"; "Common.Controls.Friendship.BlockUser" = "Blokovat %@"; @@ -513,8 +517,8 @@ nahrán do Mastodonu."; "Scene.Settings.Section.SpicyZone.Signout" = "Odhlásit se"; "Scene.Settings.Section.SpicyZone.Title" = "Ostrá část"; "Scene.Settings.Title" = "Nastavení"; -"Scene.SuggestionAccount.FollowExplain" = "Když někoho sledujete, uvidíte jejich příspěvky ve vašem domovském kanálu."; -"Scene.SuggestionAccount.Title" = "Najít lidi pro sledování"; +"Scene.SuggestionAccount.FollowAll" = "Follow all"; +"Scene.SuggestionAccount.Title" = "Popular on Mastodon"; "Scene.Thread.BackTitle" = "Příspěvek"; "Scene.Thread.Title" = "Příspěvek od %@"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "What is Mastodon?"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.strings index 3d2683ae5..1f16d7455 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.strings @@ -30,6 +30,7 @@ Bitte überprüfe deine Internetverbindung."; "Common.Controls.Actions.Add" = "Hinzufügen"; "Common.Controls.Actions.Back" = "Zurück"; "Common.Controls.Actions.BlockDomain" = "%@ blockieren"; +"Common.Controls.Actions.Bookmark" = "Bookmark"; "Common.Controls.Actions.Cancel" = "Abbrechen"; "Common.Controls.Actions.Compose" = "Neue Nachricht"; "Common.Controls.Actions.Confirm" = "Bestätigen"; @@ -42,6 +43,7 @@ Bitte überprüfe deine Internetverbindung."; "Common.Controls.Actions.Edit" = "Bearbeiten"; "Common.Controls.Actions.EditPost" = "Bearbeiten"; "Common.Controls.Actions.FindPeople" = "Finde Personen zum Folgen"; +"Common.Controls.Actions.Follow" = "Follow %@"; "Common.Controls.Actions.ManuallySearch" = "Stattdessen manuell suchen"; "Common.Controls.Actions.Next" = "Weiter"; "Common.Controls.Actions.Ok" = "OK"; @@ -51,6 +53,7 @@ Bitte überprüfe deine Internetverbindung."; "Common.Controls.Actions.Preview" = "Vorschau"; "Common.Controls.Actions.Previous" = "Vorheriges"; "Common.Controls.Actions.Remove" = "Entfernen"; +"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; "Common.Controls.Actions.Reply" = "Antworten"; "Common.Controls.Actions.ReportUser" = "%@ melden"; "Common.Controls.Actions.Save" = "Speichern"; @@ -67,6 +70,7 @@ Bitte überprüfe deine Internetverbindung."; "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unbekannt"; "Common.Controls.Actions.TryAgain" = "Nochmals versuchen"; "Common.Controls.Actions.UnblockDomain" = "Blockierung von %@ aufheben"; +"Common.Controls.Actions.Unfollow" = "Unfollow %@"; "Common.Controls.Friendship.Block" = "Blockieren"; "Common.Controls.Friendship.BlockDomain" = "%@ blockieren"; "Common.Controls.Friendship.BlockUser" = "%@ blockieren"; @@ -517,8 +521,8 @@ kann nicht auf Mastodon hochgeladen werden."; "Scene.Settings.Section.SpicyZone.Signout" = "Abmelden"; "Scene.Settings.Section.SpicyZone.Title" = "Der Gefährliche Bereich"; "Scene.Settings.Title" = "Einstellungen"; -"Scene.SuggestionAccount.FollowExplain" = "Sobald du anderen folgst, siehst du deren Beiträge in deinem Home-Feed."; -"Scene.SuggestionAccount.Title" = "Finde Personen zum Folgen"; +"Scene.SuggestionAccount.FollowAll" = "Follow all"; +"Scene.SuggestionAccount.Title" = "Popular on Mastodon"; "Scene.Thread.BackTitle" = "Beitrag"; "Scene.Thread.Title" = "Beitrag von %@"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "Was ist Mastodon?"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/el.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/el.lproj/Localizable.strings index 385d042bd..02c30c293 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/el.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/el.lproj/Localizable.strings @@ -30,6 +30,7 @@ "Common.Controls.Actions.Add" = "Προσθήκη"; "Common.Controls.Actions.Back" = "Πίσω"; "Common.Controls.Actions.BlockDomain" = "Αποκλεισμός %@"; +"Common.Controls.Actions.Bookmark" = "Bookmark"; "Common.Controls.Actions.Cancel" = "Άκυρο"; "Common.Controls.Actions.Compose" = "Σύνταξη"; "Common.Controls.Actions.Confirm" = "Επιβεβαίωση"; @@ -42,6 +43,7 @@ "Common.Controls.Actions.Edit" = "Επεξεργασία"; "Common.Controls.Actions.EditPost" = "Επεξεργασία"; "Common.Controls.Actions.FindPeople" = "Βρες άτομα για να ακολουθήσεις"; +"Common.Controls.Actions.Follow" = "Follow %@"; "Common.Controls.Actions.ManuallySearch" = "Μη αυτόματη αναζήτηση"; "Common.Controls.Actions.Next" = "Επόμενο"; "Common.Controls.Actions.Ok" = "ΟΚ"; @@ -51,6 +53,7 @@ "Common.Controls.Actions.Preview" = "Προεπισκόπηση"; "Common.Controls.Actions.Previous" = "Προηγούμενο"; "Common.Controls.Actions.Remove" = "Αφαίρεση"; +"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; "Common.Controls.Actions.Reply" = "Απάντηση"; "Common.Controls.Actions.ReportUser" = "Αναφορά %@"; "Common.Controls.Actions.Save" = "Αποθήκευση"; @@ -67,6 +70,7 @@ "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Άγνωστο"; "Common.Controls.Actions.TryAgain" = "Προσπάθησε ξανά"; "Common.Controls.Actions.UnblockDomain" = "Άρση αποκλεισμού %@"; +"Common.Controls.Actions.Unfollow" = "Unfollow %@"; "Common.Controls.Friendship.Block" = "Block"; "Common.Controls.Friendship.BlockDomain" = "Block %@"; "Common.Controls.Friendship.BlockUser" = "Block %@"; @@ -89,74 +93,74 @@ "Common.Controls.Keyboard.Common.OpenSettings" = "Άνοιγμα Ρυθμίσεων"; "Common.Controls.Keyboard.Common.ShowFavorites" = "Εμφάνιση Αγαπημένων"; "Common.Controls.Keyboard.Common.SwitchToTab" = "Εναλλαγή σε %@"; -"Common.Controls.Keyboard.SegmentedControl.NextSection" = "Next Section"; -"Common.Controls.Keyboard.SegmentedControl.PreviousSection" = "Previous Section"; +"Common.Controls.Keyboard.SegmentedControl.NextSection" = "Επόμενη Ενότητα"; +"Common.Controls.Keyboard.SegmentedControl.PreviousSection" = "Προηγούμενη Ενότητα"; "Common.Controls.Keyboard.Timeline.NextStatus" = "Επόμενη Ανάρτηση"; "Common.Controls.Keyboard.Timeline.OpenAuthorProfile" = "Άνοιγμα Προφίλ Συντάκτη"; -"Common.Controls.Keyboard.Timeline.OpenRebloggerProfile" = "Open Reblogger's Profile"; +"Common.Controls.Keyboard.Timeline.OpenRebloggerProfile" = "Άνοιγμα Προφίλ Του Reblogger"; "Common.Controls.Keyboard.Timeline.OpenStatus" = "Άνοιγμα Ανάρτησης"; -"Common.Controls.Keyboard.Timeline.PreviewImage" = "Preview Image"; +"Common.Controls.Keyboard.Timeline.PreviewImage" = "Προεπισκόπηση Εικόνας"; "Common.Controls.Keyboard.Timeline.PreviousStatus" = "Προηγούμενη Ανάρτηση"; -"Common.Controls.Keyboard.Timeline.ReplyStatus" = "Reply to Post"; +"Common.Controls.Keyboard.Timeline.ReplyStatus" = "Απάντηση στην Ανάρτηση"; "Common.Controls.Keyboard.Timeline.ToggleContentWarning" = "Toggle Content Warning"; "Common.Controls.Keyboard.Timeline.ToggleFavorite" = "Toggle Favorite on Post"; -"Common.Controls.Keyboard.Timeline.ToggleReblog" = "Toggle Reblog on Post"; -"Common.Controls.Status.Actions.A11YLabels.Reblog" = "Re-blog"; -"Common.Controls.Status.Actions.A11YLabels.Unreblog" = "Undo re-blog"; -"Common.Controls.Status.Actions.Favorite" = "Favorite"; -"Common.Controls.Status.Actions.Hide" = "Hide"; -"Common.Controls.Status.Actions.Menu" = "Menu"; -"Common.Controls.Status.Actions.Reblog" = "Reblog"; -"Common.Controls.Status.Actions.Reply" = "Reply"; -"Common.Controls.Status.Actions.ShareLinkInPost" = "Share Link in Post"; -"Common.Controls.Status.Actions.ShowGif" = "Show GIF"; -"Common.Controls.Status.Actions.ShowImage" = "Show image"; -"Common.Controls.Status.Actions.ShowVideoPlayer" = "Show video player"; -"Common.Controls.Status.Actions.TapThenHoldToShowMenu" = "Tap then hold to show menu"; -"Common.Controls.Status.Actions.Unfavorite" = "Unfavorite"; -"Common.Controls.Status.Actions.Unreblog" = "Undo reblog"; +"Common.Controls.Keyboard.Timeline.ToggleReblog" = "Εναλλαγή Αναδημοσίευσης στην Ανάρτηση"; +"Common.Controls.Status.Actions.A11YLabels.Reblog" = "Αναδημοσίευση"; +"Common.Controls.Status.Actions.A11YLabels.Unreblog" = "Αναίρεση αναδημοσίευσης"; +"Common.Controls.Status.Actions.Favorite" = "Αγαπημένο"; +"Common.Controls.Status.Actions.Hide" = "Απόκρυψη"; +"Common.Controls.Status.Actions.Menu" = "Μενού"; +"Common.Controls.Status.Actions.Reblog" = "Αναδημοσίευση"; +"Common.Controls.Status.Actions.Reply" = "Απάντηση"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Κοινοποίηση Συνδέσμου στην Ανάρτηση"; +"Common.Controls.Status.Actions.ShowGif" = "Εμφάνιση GIF"; +"Common.Controls.Status.Actions.ShowImage" = "Εμφάνιση εικόνας"; +"Common.Controls.Status.Actions.ShowVideoPlayer" = "Εμφάνιση προγράμματος αναπαραγωγής βίντεο"; +"Common.Controls.Status.Actions.TapThenHoldToShowMenu" = "Πάτα παρατεταμένα για εμφάνιση μενού"; +"Common.Controls.Status.Actions.Unfavorite" = "Αφαίρεση από αγαπημένα"; +"Common.Controls.Status.Actions.Unreblog" = "Αναίρεση αναδημοσίευσης"; "Common.Controls.Status.Buttons.EditHistoryDetail" = "Last edit %@"; "Common.Controls.Status.Buttons.EditHistoryTitle" = "Edit History"; "Common.Controls.Status.Buttons.FavoritesTitle" = "Favorites"; "Common.Controls.Status.Buttons.ReblogsTitle" = "Reblogs"; -"Common.Controls.Status.ContentWarning" = "Content Warning"; +"Common.Controls.Status.ContentWarning" = "Προειδοποίηση Περιεχομένου"; "Common.Controls.Status.EditHistory.OriginalPost" = "Original Post · %@"; "Common.Controls.Status.EditHistory.Title" = "Edit History"; "Common.Controls.Status.EditedAtTimestampPrefix" = "Edited %@"; -"Common.Controls.Status.LinkViaUser" = "%@ via %@"; -"Common.Controls.Status.LoadEmbed" = "Load Embed"; +"Common.Controls.Status.LinkViaUser" = "%@ μέσω %@"; +"Common.Controls.Status.LoadEmbed" = "Φόρτωση Ενσωμάτωσης"; "Common.Controls.Status.Media.AccessibilityLabel" = "%@, attachment %d of %d"; "Common.Controls.Status.Media.ExpandGifHint" = "Expands the GIF. Double-tap and hold to show actions"; "Common.Controls.Status.Media.ExpandImageHint" = "Expands the image. Double-tap and hold to show actions"; "Common.Controls.Status.Media.ExpandVideoHint" = "Shows the video player. Double-tap and hold to show actions"; -"Common.Controls.Status.MediaContentWarning" = "Tap anywhere to reveal"; -"Common.Controls.Status.MetaEntity.Email" = "Email address: %@"; -"Common.Controls.Status.MetaEntity.Hashtag" = "Hashtag: %@"; -"Common.Controls.Status.MetaEntity.Mention" = "Show Profile: %@"; -"Common.Controls.Status.MetaEntity.Url" = "Link: %@"; -"Common.Controls.Status.Poll.Closed" = "Closed"; -"Common.Controls.Status.Poll.Vote" = "Vote"; +"Common.Controls.Status.MediaContentWarning" = "Πάτα οπουδήποτε για εμφάνιση"; +"Common.Controls.Status.MetaEntity.Email" = "Διεύθυνση email: %@"; +"Common.Controls.Status.MetaEntity.Hashtag" = "Ετικέτα: %@"; +"Common.Controls.Status.MetaEntity.Mention" = "Εμφάνιση Προφίλ: %@"; +"Common.Controls.Status.MetaEntity.Url" = "Σύνδεσμος: %@"; +"Common.Controls.Status.Poll.Closed" = "Κλειστή"; +"Common.Controls.Status.Poll.Vote" = "Ψήφισε"; "Common.Controls.Status.PostedViaApplication" = "%@ via %@"; -"Common.Controls.Status.SensitiveContent" = "Sensitive Content"; -"Common.Controls.Status.ShowPost" = "Show Post"; -"Common.Controls.Status.ShowUserProfile" = "Show user profile"; +"Common.Controls.Status.SensitiveContent" = "Ευαίσθητο Περιεχόμενο"; +"Common.Controls.Status.ShowPost" = "Εμφάνιση Ανάρτησης"; +"Common.Controls.Status.ShowUserProfile" = "Εμφάνιση προφίλ χρήστη"; "Common.Controls.Status.Tag.Email" = "Email"; "Common.Controls.Status.Tag.Emoji" = "Emoji"; "Common.Controls.Status.Tag.Hashtag" = "Ετικέτα"; "Common.Controls.Status.Tag.Link" = "Σύνδεσμος"; "Common.Controls.Status.Tag.Mention" = "Επισήμανση"; "Common.Controls.Status.Tag.Url" = "URL"; -"Common.Controls.Status.TapToReveal" = "Tap to reveal"; -"Common.Controls.Status.Translation.ShowOriginal" = "Show Original"; -"Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; -"Common.Controls.Status.Translation.UnknownLanguage" = "Unknown"; -"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; -"Common.Controls.Status.UserReblogged" = "%@ reblogged"; -"Common.Controls.Status.UserRepliedTo" = "Replied to %@"; -"Common.Controls.Status.Visibility.Direct" = "Only mentioned user can see this post."; -"Common.Controls.Status.Visibility.Private" = "Only their followers can see this post."; -"Common.Controls.Status.Visibility.PrivateFromMe" = "Only my followers can see this post."; -"Common.Controls.Status.Visibility.Unlisted" = "Everyone can see this post but not display in the public timeline."; +"Common.Controls.Status.TapToReveal" = "Πάτα για εμφάνιση"; +"Common.Controls.Status.Translation.ShowOriginal" = "Εμφάνιση Αρχικού"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Μεταφράστηκε από %@ χρησιμοποιώντας το %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Άγνωστο"; +"Common.Controls.Status.Translation.UnknownProvider" = "Άγνωστο"; +"Common.Controls.Status.UserReblogged" = "%@ αναδημοσίευσε"; +"Common.Controls.Status.UserRepliedTo" = "Απάντησε στον χρήστη %@"; +"Common.Controls.Status.Visibility.Direct" = "Μόνο ο αναφερόμενος χρήστης μπορεί να δει αυτή την ανάρτηση."; +"Common.Controls.Status.Visibility.Private" = "Μόνο οι ακόλουθοί τους μπορούν να δουν αυτή την ανάρτηση."; +"Common.Controls.Status.Visibility.PrivateFromMe" = "Μόνο οι ακόλουθοί μου μπορούν να δουν αυτή την ανάρτηση."; +"Common.Controls.Status.Visibility.Unlisted" = "Όλοι μπορούν να δουν αυτή την ανάρτηση, αλλά δεν εμφανίζεται στη δημόσια ροή."; "Common.Controls.Tabs.A11Y.Explore" = "Εξερεύνηση"; "Common.Controls.Tabs.A11Y.Search" = "Αναζήτηση"; "Common.Controls.Tabs.Home" = "Αρχική"; @@ -517,8 +521,8 @@ uploaded to Mastodon."; "Scene.Settings.Section.SpicyZone.Signout" = "Sign Out"; "Scene.Settings.Section.SpicyZone.Title" = "The Spicy Zone"; "Scene.Settings.Title" = "Settings"; -"Scene.SuggestionAccount.FollowExplain" = "When you follow someone, you’ll see their posts in your home feed."; -"Scene.SuggestionAccount.Title" = "Find People to Follow"; +"Scene.SuggestionAccount.FollowAll" = "Follow all"; +"Scene.SuggestionAccount.Title" = "Popular on Mastodon"; "Scene.Thread.BackTitle" = "Post"; "Scene.Thread.Title" = "Post from %@"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "What is Mastodon?"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings index 55cf7ec74..970175d5c 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings @@ -30,6 +30,7 @@ Please check your internet connection."; "Common.Controls.Actions.Add" = "Add"; "Common.Controls.Actions.Back" = "Back"; "Common.Controls.Actions.BlockDomain" = "Block %@"; +"Common.Controls.Actions.Bookmark" = "Bookmark"; "Common.Controls.Actions.Cancel" = "Cancel"; "Common.Controls.Actions.Compose" = "Compose"; "Common.Controls.Actions.Confirm" = "Confirm"; @@ -42,6 +43,7 @@ Please check your internet connection."; "Common.Controls.Actions.Edit" = "Edit"; "Common.Controls.Actions.EditPost" = "Edit"; "Common.Controls.Actions.FindPeople" = "Find people to follow"; +"Common.Controls.Actions.Follow" = "Follow %@"; "Common.Controls.Actions.ManuallySearch" = "Manually search instead"; "Common.Controls.Actions.Next" = "Next"; "Common.Controls.Actions.Ok" = "OK"; @@ -51,6 +53,7 @@ Please check your internet connection."; "Common.Controls.Actions.Preview" = "Preview"; "Common.Controls.Actions.Previous" = "Previous"; "Common.Controls.Actions.Remove" = "Remove"; +"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; "Common.Controls.Actions.Reply" = "Reply"; "Common.Controls.Actions.ReportUser" = "Report %@"; "Common.Controls.Actions.Save" = "Save"; @@ -67,6 +70,7 @@ Please check your internet connection."; "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; "Common.Controls.Actions.TryAgain" = "Try Again"; "Common.Controls.Actions.UnblockDomain" = "Unblock %@"; +"Common.Controls.Actions.Unfollow" = "Unfollow %@"; "Common.Controls.Friendship.Block" = "Block"; "Common.Controls.Friendship.BlockDomain" = "Block %@"; "Common.Controls.Friendship.BlockUser" = "Block %@"; @@ -517,8 +521,8 @@ uploaded to Mastodon."; "Scene.Settings.Section.SpicyZone.Signout" = "Sign Out"; "Scene.Settings.Section.SpicyZone.Title" = "The Spicy Zone"; "Scene.Settings.Title" = "Settings"; +"Scene.SuggestionAccount.FollowAll" = "Follow all"; "Scene.SuggestionAccount.Title" = "Popular on Mastodon"; -"Scene.SuggestionAccount.FollowAll" = "Follow All"; "Scene.Thread.BackTitle" = "Post"; "Scene.Thread.Title" = "Post from %@"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "What is Mastodon?"; @@ -552,4 +556,4 @@ uploaded to Mastodon."; "Widget.MultipleFollowers.ConfigurationDescription" = "Show number of followers for multiple accounts."; "Widget.MultipleFollowers.ConfigurationDisplayName" = "Multiple followers"; "Widget.MultipleFollowers.MockUser.AccountName" = "another@follower.social"; -"Widget.MultipleFollowers.MockUser.DisplayName" = "Another follower"; +"Widget.MultipleFollowers.MockUser.DisplayName" = "Another follower"; \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.strings index dae5d8b31..d77be43a2 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.strings @@ -30,6 +30,7 @@ Por favor, revise su conexión a internet."; "Common.Controls.Actions.Add" = "Añadir"; "Common.Controls.Actions.Back" = "Atrás"; "Common.Controls.Actions.BlockDomain" = "Bloquear %@"; +"Common.Controls.Actions.Bookmark" = "Bookmark"; "Common.Controls.Actions.Cancel" = "Cancelar"; "Common.Controls.Actions.Compose" = "Redactar"; "Common.Controls.Actions.Confirm" = "Confirmar"; @@ -42,6 +43,7 @@ Por favor, revise su conexión a internet."; "Common.Controls.Actions.Edit" = "Editar"; "Common.Controls.Actions.EditPost" = "Edit"; "Common.Controls.Actions.FindPeople" = "Encuentra gente a la que seguir"; +"Common.Controls.Actions.Follow" = "Follow %@"; "Common.Controls.Actions.ManuallySearch" = "Mejor hacer una búsqueda manual"; "Common.Controls.Actions.Next" = "Siguiente"; "Common.Controls.Actions.Ok" = "Aceptar"; @@ -51,6 +53,7 @@ Por favor, revise su conexión a internet."; "Common.Controls.Actions.Preview" = "Vista previa"; "Common.Controls.Actions.Previous" = "Anterior"; "Common.Controls.Actions.Remove" = "Eliminar"; +"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; "Common.Controls.Actions.Reply" = "Responder"; "Common.Controls.Actions.ReportUser" = "Reportar a %@"; "Common.Controls.Actions.Save" = "Guardar"; @@ -67,6 +70,7 @@ Por favor, revise su conexión a internet."; "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Desconocido"; "Common.Controls.Actions.TryAgain" = "Inténtalo de nuevo"; "Common.Controls.Actions.UnblockDomain" = "Desbloquear %@"; +"Common.Controls.Actions.Unfollow" = "Unfollow %@"; "Common.Controls.Friendship.Block" = "Bloquear"; "Common.Controls.Friendship.BlockDomain" = "Bloquear a %@"; "Common.Controls.Friendship.BlockUser" = "Bloquear a %@"; @@ -517,8 +521,8 @@ subirse a Mastodon."; "Scene.Settings.Section.SpicyZone.Signout" = "Cerrar Sesión"; "Scene.Settings.Section.SpicyZone.Title" = "La Zona Picante"; "Scene.Settings.Title" = "Configuración"; -"Scene.SuggestionAccount.FollowExplain" = "Cuando sigas a alguien verás sus publicaciones en tu página de inicio."; -"Scene.SuggestionAccount.Title" = "Encuentra Gente a la que Seguir"; +"Scene.SuggestionAccount.FollowAll" = "Follow all"; +"Scene.SuggestionAccount.Title" = "Popular on Mastodon"; "Scene.Thread.BackTitle" = "Publicación"; "Scene.Thread.Title" = "Publicación de %@"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "What is Mastodon?"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings index 42d6c4225..1950a0c95 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings @@ -30,6 +30,7 @@ Egiaztatu Interneteko konexioa."; "Common.Controls.Actions.Add" = "Gehitu"; "Common.Controls.Actions.Back" = "Atzera"; "Common.Controls.Actions.BlockDomain" = "Blokeatu %@"; +"Common.Controls.Actions.Bookmark" = "Bookmark"; "Common.Controls.Actions.Cancel" = "Utzi"; "Common.Controls.Actions.Compose" = "Idatzi"; "Common.Controls.Actions.Confirm" = "Berretsi"; @@ -42,6 +43,7 @@ Egiaztatu Interneteko konexioa."; "Common.Controls.Actions.Edit" = "Editatu"; "Common.Controls.Actions.EditPost" = "Edit"; "Common.Controls.Actions.FindPeople" = "Bilatu jarraitzeko jendea"; +"Common.Controls.Actions.Follow" = "Follow %@"; "Common.Controls.Actions.ManuallySearch" = "Eskuz bilatu"; "Common.Controls.Actions.Next" = "Hurrengoa"; "Common.Controls.Actions.Ok" = "Ados"; @@ -51,6 +53,7 @@ Egiaztatu Interneteko konexioa."; "Common.Controls.Actions.Preview" = "Aurrebista"; "Common.Controls.Actions.Previous" = "Aurrekoa"; "Common.Controls.Actions.Remove" = "Kendu"; +"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; "Common.Controls.Actions.Reply" = "Erantzun"; "Common.Controls.Actions.ReportUser" = "Salatu %@"; "Common.Controls.Actions.Save" = "Gorde"; @@ -67,6 +70,7 @@ Egiaztatu Interneteko konexioa."; "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; "Common.Controls.Actions.TryAgain" = "Saiatu berriro"; "Common.Controls.Actions.UnblockDomain" = "Desblokeatu %@"; +"Common.Controls.Actions.Unfollow" = "Unfollow %@"; "Common.Controls.Friendship.Block" = "Blokeatu"; "Common.Controls.Friendship.BlockDomain" = "Blokeatu %@"; "Common.Controls.Friendship.BlockUser" = "Blokeatu %@"; @@ -517,8 +521,8 @@ Mastodonera igo."; "Scene.Settings.Section.SpicyZone.Signout" = "Amaitu saioa"; "Scene.Settings.Section.SpicyZone.Title" = "Eremu beroa"; "Scene.Settings.Title" = "Ezarpenak"; -"Scene.SuggestionAccount.FollowExplain" = "Norbait jarraitzen duzunean, bere bidalketak zure hasierako denbora-lerroan agertuko zaizkizu."; -"Scene.SuggestionAccount.Title" = "Bilatu jarraitzeko jendea"; +"Scene.SuggestionAccount.FollowAll" = "Follow all"; +"Scene.SuggestionAccount.Title" = "Popular on Mastodon"; "Scene.Thread.BackTitle" = "Bidalketa"; "Scene.Thread.Title" = "%@(e)n bidalketa"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "What is Mastodon?"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings index e4555a0d2..e1cf921d6 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings @@ -30,6 +30,7 @@ Tarkista internet-yhteytesi."; "Common.Controls.Actions.Add" = "Lisää"; "Common.Controls.Actions.Back" = "Takaisin"; "Common.Controls.Actions.BlockDomain" = "Estä %@"; +"Common.Controls.Actions.Bookmark" = "Bookmark"; "Common.Controls.Actions.Cancel" = "Kumoa"; "Common.Controls.Actions.Compose" = "Koosta"; "Common.Controls.Actions.Confirm" = "Vahvista"; @@ -42,6 +43,7 @@ Tarkista internet-yhteytesi."; "Common.Controls.Actions.Edit" = "Muokkaa"; "Common.Controls.Actions.EditPost" = "Muokkaa"; "Common.Controls.Actions.FindPeople" = "Löydä tilejä seurattavaksi"; +"Common.Controls.Actions.Follow" = "Follow %@"; "Common.Controls.Actions.ManuallySearch" = "Etsi sen sijaan manuaalisesti"; "Common.Controls.Actions.Next" = "Seuraava"; "Common.Controls.Actions.Ok" = "OK"; @@ -51,6 +53,7 @@ Tarkista internet-yhteytesi."; "Common.Controls.Actions.Preview" = "Esikatselu"; "Common.Controls.Actions.Previous" = "Edellinen"; "Common.Controls.Actions.Remove" = "Poista"; +"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; "Common.Controls.Actions.Reply" = "Vastaa"; "Common.Controls.Actions.ReportUser" = "Ilmianna %@"; "Common.Controls.Actions.Save" = "Tallenna"; @@ -67,6 +70,7 @@ Tarkista internet-yhteytesi."; "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Tuntematon"; "Common.Controls.Actions.TryAgain" = "Yritä uudelleen"; "Common.Controls.Actions.UnblockDomain" = "Poista esto %@"; +"Common.Controls.Actions.Unfollow" = "Unfollow %@"; "Common.Controls.Friendship.Block" = "Estä"; "Common.Controls.Friendship.BlockDomain" = "Estä %@"; "Common.Controls.Friendship.BlockUser" = "Estä %@"; @@ -181,8 +185,8 @@ Profiilisi näyttää tältä hänelle."; "Common.Controls.Timeline.Loader.LoadingMissingPosts" = "Ladataan puuttuvia julkaisuja..."; "Common.Controls.Timeline.Loader.ShowMoreReplies" = "Näytä lisää vastauksia"; "Common.Controls.Timeline.Timestamp.Now" = "Nyt"; -"Common.UserList.FollowersCount" = "%@ followers"; -"Common.UserList.NoVerifiedLink" = "No verified link"; +"Common.UserList.FollowersCount" = "%@ seuraajaa"; +"Common.UserList.NoVerifiedLink" = "Ei todennettua linkkiä"; "Extension.OpenIn.InvalidLinkError" = "Tämä ei näytä olevan kelvollinen Mastodon-linkki."; "Scene.AccountList.AddAccount" = "Lisää tili"; "Scene.AccountList.DismissAccountSwitcher" = "Sulje tilin vaihtaja"; @@ -517,8 +521,8 @@ uploaded to Mastodon."; "Scene.Settings.Section.SpicyZone.Signout" = "Kirjaudu ulos"; "Scene.Settings.Section.SpicyZone.Title" = "Varovainen alue"; "Scene.Settings.Title" = "Asetukset"; -"Scene.SuggestionAccount.FollowExplain" = "Kun seuraat jotakuta, näet hänen julkaisunsa kotisyötteessäsi."; -"Scene.SuggestionAccount.Title" = "Löydä tilejä seurattavaksi"; +"Scene.SuggestionAccount.FollowAll" = "Follow all"; +"Scene.SuggestionAccount.Title" = "Popular on Mastodon"; "Scene.Thread.BackTitle" = "Julkaisu"; "Scene.Thread.Title" = "Julkaisu tililtä %@"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "Mikä Mastodon on?"; @@ -537,14 +541,14 @@ uploaded to Mastodon."; "Widget.FollowersCount.ConfigurationDisplayName" = "Seuraajat"; "Widget.FollowersCount.FollowersToday" = "%@ seuraajaa tänään"; "Widget.FollowersCount.Title" = "SEURAAJAT"; -"Widget.Hashtag.Configuration.Description" = "Shows a recent post with the selected hashtag."; -"Widget.Hashtag.Configuration.DisplayName" = "Hashtag"; -"Widget.Hashtag.NotFound.Account" = "@johnMastodon@no-such.account"; -"Widget.Hashtag.NotFound.AccountName" = "John Mastodon"; -"Widget.Hashtag.NotFound.Content" = "Sorry, we couldn’t find any posts with the hashtag #%@. Please try a #DifferentHashtag or check the widget settings."; -"Widget.Hashtag.Placeholder.Account" = "@johnMastodon@no-such.account"; -"Widget.Hashtag.Placeholder.AccountName" = "John Mastodon"; -"Widget.Hashtag.Placeholder.Content" = "This is how a post with a #hashtag would look. Pick whichever #hashtag you want in the widget settings."; +"Widget.Hashtag.Configuration.Description" = "Näyttää hiljattaisen julkaisun valitusta aihetunnisteesta."; +"Widget.Hashtag.Configuration.DisplayName" = "Aihetunniste"; +"Widget.Hashtag.NotFound.Account" = "@mikkoMastodon@ei-sellaista.tiliä"; +"Widget.Hashtag.NotFound.AccountName" = "Mikko Mastodon"; +"Widget.Hashtag.NotFound.Content" = "Valitettavasti emme löytäneet yhtään julkaisua aihetunnisteella #%@. Kokeile #DifferentHashtag tai tarkista widgetin asetukset."; +"Widget.Hashtag.Placeholder.Account" = "@mikkoMastodon@ei-sellaista.tiliä"; +"Widget.Hashtag.Placeholder.AccountName" = "Mikko Mastodon"; +"Widget.Hashtag.Placeholder.Content" = "Tältä aihetunnisteen #aihetunniste julkaisu näyttäisi. Valitse mikä tahansa #aihetunniste widgetin asetuksista."; "Widget.LatestFollowers.ConfigurationDescription" = "Näyyä uusimmat seuraajat."; "Widget.LatestFollowers.ConfigurationDisplayName" = "Uusimmat seuraajat"; "Widget.LatestFollowers.LastUpdate" = "Päivitettiin viimeksi %@"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.strings index c7ed81880..e0c2b6b54 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.strings @@ -30,6 +30,7 @@ Veuillez vérifier votre accès à Internet."; "Common.Controls.Actions.Add" = "Ajouter"; "Common.Controls.Actions.Back" = "Retour"; "Common.Controls.Actions.BlockDomain" = "Bloquer %@"; +"Common.Controls.Actions.Bookmark" = "Bookmark"; "Common.Controls.Actions.Cancel" = "Annuler"; "Common.Controls.Actions.Compose" = "Rédiger"; "Common.Controls.Actions.Confirm" = "Confirmer"; @@ -42,6 +43,7 @@ Veuillez vérifier votre accès à Internet."; "Common.Controls.Actions.Edit" = "Éditer"; "Common.Controls.Actions.EditPost" = "Éditer"; "Common.Controls.Actions.FindPeople" = "Trouver des personnes à suivre"; +"Common.Controls.Actions.Follow" = "Follow %@"; "Common.Controls.Actions.ManuallySearch" = "Rechercher manuellement à la place"; "Common.Controls.Actions.Next" = "Suivant"; "Common.Controls.Actions.Ok" = "OK"; @@ -51,6 +53,7 @@ Veuillez vérifier votre accès à Internet."; "Common.Controls.Actions.Preview" = "Aperçu"; "Common.Controls.Actions.Previous" = "Précédent"; "Common.Controls.Actions.Remove" = "Supprimer"; +"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; "Common.Controls.Actions.Reply" = "Répondre"; "Common.Controls.Actions.ReportUser" = "Signaler %@"; "Common.Controls.Actions.Save" = "Enregistrer"; @@ -67,6 +70,7 @@ Veuillez vérifier votre accès à Internet."; "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Inconnu"; "Common.Controls.Actions.TryAgain" = "Réessayer"; "Common.Controls.Actions.UnblockDomain" = "Débloquer %@"; +"Common.Controls.Actions.Unfollow" = "Unfollow %@"; "Common.Controls.Friendship.Block" = "Bloquer"; "Common.Controls.Friendship.BlockDomain" = "Bloquer %@"; "Common.Controls.Friendship.BlockUser" = "Bloquer %@"; @@ -517,8 +521,8 @@ téléversé sur Mastodon."; "Scene.Settings.Section.SpicyZone.Signout" = "Se déconnecter"; "Scene.Settings.Section.SpicyZone.Title" = "La Zone Épicée"; "Scene.Settings.Title" = "Paramètres"; -"Scene.SuggestionAccount.FollowExplain" = "Quand vous suivez quelqu'un, vous verrez leurs messages dans votre flux d’accueil."; -"Scene.SuggestionAccount.Title" = "Trouver des personnes à suivre"; +"Scene.SuggestionAccount.FollowAll" = "Follow all"; +"Scene.SuggestionAccount.Title" = "Popular on Mastodon"; "Scene.Thread.BackTitle" = "Publication"; "Scene.Thread.Title" = "Publication de %@"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "Qu’est-ce que Mastodon ?"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/gd.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/gd.lproj/Localizable.strings index a0acbf3cd..ea79cf5bc 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/gd.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/gd.lproj/Localizable.strings @@ -30,6 +30,7 @@ Thoir sùil air a’ cheangal agad ris an eadar-lìon."; "Common.Controls.Actions.Add" = "Cuir ris"; "Common.Controls.Actions.Back" = "Air ais"; "Common.Controls.Actions.BlockDomain" = "Bac %@"; +"Common.Controls.Actions.Bookmark" = "Bookmark"; "Common.Controls.Actions.Cancel" = "Sguir dheth"; "Common.Controls.Actions.Compose" = "Sgrìobh"; "Common.Controls.Actions.Confirm" = "Dearbh"; @@ -42,6 +43,7 @@ Thoir sùil air a’ cheangal agad ris an eadar-lìon."; "Common.Controls.Actions.Edit" = "Deasaich"; "Common.Controls.Actions.EditPost" = "Deasaich"; "Common.Controls.Actions.FindPeople" = "Lorg daoine a leanas tu"; +"Common.Controls.Actions.Follow" = "Follow %@"; "Common.Controls.Actions.ManuallySearch" = "Lorg a làimh ’na àite"; "Common.Controls.Actions.Next" = "Air adhart"; "Common.Controls.Actions.Ok" = "Ceart ma-thà"; @@ -51,6 +53,7 @@ Thoir sùil air a’ cheangal agad ris an eadar-lìon."; "Common.Controls.Actions.Preview" = "Ro-sheall"; "Common.Controls.Actions.Previous" = "Air ais"; "Common.Controls.Actions.Remove" = "Thoir air falbh"; +"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; "Common.Controls.Actions.Reply" = "Freagair"; "Common.Controls.Actions.ReportUser" = "Dèan gearan mu %@"; "Common.Controls.Actions.Save" = "Sàbhail"; @@ -67,6 +70,7 @@ Thoir sùil air a’ cheangal agad ris an eadar-lìon."; "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Chan eil fhios"; "Common.Controls.Actions.TryAgain" = "Feuch ris a-rithist"; "Common.Controls.Actions.UnblockDomain" = "Dì-bhac %@"; +"Common.Controls.Actions.Unfollow" = "Unfollow %@"; "Common.Controls.Friendship.Block" = "Bac"; "Common.Controls.Friendship.BlockDomain" = "Bac %@"; "Common.Controls.Friendship.BlockUser" = "Bac %@"; @@ -517,8 +521,8 @@ a luchdadh suas gu Mastodon."; "Scene.Settings.Section.SpicyZone.Signout" = "Clàraich a-mach"; "Scene.Settings.Section.SpicyZone.Title" = "Gnìomhan"; "Scene.Settings.Title" = "Roghainnean"; -"Scene.SuggestionAccount.FollowExplain" = "Nuair a leanas tu cuideigin, chì thu na puist aca air inbhir na dachaigh agad."; -"Scene.SuggestionAccount.Title" = "Lorg daoine a leanas tu"; +"Scene.SuggestionAccount.FollowAll" = "Lean na h-uile"; +"Scene.SuggestionAccount.Title" = "Fèillmhor air Mastodon"; "Scene.Thread.BackTitle" = "Post"; "Scene.Thread.Title" = "Post le %@"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "Dè th’ ann am Mastodon?"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.strings index 611c5cc8a..a041a4612 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.strings @@ -30,6 +30,7 @@ Comproba a conexión a internet."; "Common.Controls.Actions.Add" = "Engadir"; "Common.Controls.Actions.Back" = "Volver"; "Common.Controls.Actions.BlockDomain" = "Bloquear a %@"; +"Common.Controls.Actions.Bookmark" = "Marcar"; "Common.Controls.Actions.Cancel" = "Cancelar"; "Common.Controls.Actions.Compose" = "Escribir"; "Common.Controls.Actions.Confirm" = "Confirmar"; @@ -42,6 +43,7 @@ Comproba a conexión a internet."; "Common.Controls.Actions.Edit" = "Editar"; "Common.Controls.Actions.EditPost" = "Editar"; "Common.Controls.Actions.FindPeople" = "Atopar persoas para seguir"; +"Common.Controls.Actions.Follow" = "Segue a %@"; "Common.Controls.Actions.ManuallySearch" = "Buscar de xeito manual"; "Common.Controls.Actions.Next" = "Seguinte"; "Common.Controls.Actions.Ok" = "OK"; @@ -51,6 +53,7 @@ Comproba a conexión a internet."; "Common.Controls.Actions.Preview" = "Vista previa"; "Common.Controls.Actions.Previous" = "Anterior"; "Common.Controls.Actions.Remove" = "Eliminar"; +"Common.Controls.Actions.RemoveBookmark" = "Eliminar Marcador"; "Common.Controls.Actions.Reply" = "Responder"; "Common.Controls.Actions.ReportUser" = "Denunciar a %@"; "Common.Controls.Actions.Save" = "Gardar"; @@ -67,6 +70,7 @@ Comproba a conexión a internet."; "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Descoñecido"; "Common.Controls.Actions.TryAgain" = "Intentar de novo"; "Common.Controls.Actions.UnblockDomain" = "Desbloquear a %@"; +"Common.Controls.Actions.Unfollow" = "Deixa de seguir a %@"; "Common.Controls.Friendship.Block" = "Bloquear"; "Common.Controls.Friendship.BlockDomain" = "Bloquear a %@"; "Common.Controls.Friendship.BlockUser" = "Bloquear a %@"; @@ -517,8 +521,8 @@ ser subido a Mastodon."; "Scene.Settings.Section.SpicyZone.Signout" = "Pechar sesión"; "Scene.Settings.Section.SpicyZone.Title" = "A zona picante"; "Scene.Settings.Title" = "Axustes"; -"Scene.SuggestionAccount.FollowExplain" = "Cando sigas a alguén verás as súas publicacións na cronoloxía de inicio."; -"Scene.SuggestionAccount.Title" = "Atopar persoas para seguir"; +"Scene.SuggestionAccount.FollowAll" = "Seguir a todas"; +"Scene.SuggestionAccount.Title" = "Popular en Mastodon"; "Scene.Thread.BackTitle" = "Publicación"; "Scene.Thread.Title" = "Publicación de %@"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "Que é Mastodon?"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.strings index af8678239..765de5d03 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.strings @@ -30,6 +30,7 @@ Per favore verifica la tua connessione internet."; "Common.Controls.Actions.Add" = "Aggiungi"; "Common.Controls.Actions.Back" = "Indietro"; "Common.Controls.Actions.BlockDomain" = "Blocca %@"; +"Common.Controls.Actions.Bookmark" = "Segnalibro"; "Common.Controls.Actions.Cancel" = "Annulla"; "Common.Controls.Actions.Compose" = "Scrivi"; "Common.Controls.Actions.Confirm" = "Conferma"; @@ -42,6 +43,7 @@ Per favore verifica la tua connessione internet."; "Common.Controls.Actions.Edit" = "Modifica"; "Common.Controls.Actions.EditPost" = "Modifica"; "Common.Controls.Actions.FindPeople" = "Trova persone da seguire"; +"Common.Controls.Actions.Follow" = "Segui %@"; "Common.Controls.Actions.ManuallySearch" = "Cerca manualmente invece"; "Common.Controls.Actions.Next" = "Avanti"; "Common.Controls.Actions.Ok" = "OK"; @@ -51,6 +53,7 @@ Per favore verifica la tua connessione internet."; "Common.Controls.Actions.Preview" = "Anteprima"; "Common.Controls.Actions.Previous" = "Precedente"; "Common.Controls.Actions.Remove" = "Rimuovi"; +"Common.Controls.Actions.RemoveBookmark" = "Rimuovi il segnalibro"; "Common.Controls.Actions.Reply" = "Rispondi"; "Common.Controls.Actions.ReportUser" = "Segnala %@"; "Common.Controls.Actions.Save" = "Salva"; @@ -67,6 +70,7 @@ Per favore verifica la tua connessione internet."; "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Sconosciuto"; "Common.Controls.Actions.TryAgain" = "Riprova"; "Common.Controls.Actions.UnblockDomain" = "Sblocca %@"; +"Common.Controls.Actions.Unfollow" = "Smetti di seguire %@"; "Common.Controls.Friendship.Block" = "Blocca"; "Common.Controls.Friendship.BlockDomain" = "Blocca %@"; "Common.Controls.Friendship.BlockUser" = "Blocca %@"; @@ -124,7 +128,7 @@ Per favore verifica la tua connessione internet."; "Common.Controls.Status.EditHistory.Title" = "Modifica la cronologia"; "Common.Controls.Status.EditedAtTimestampPrefix" = "Modificato %@"; "Common.Controls.Status.LinkViaUser" = "%@ tramite %@"; -"Common.Controls.Status.LoadEmbed" = "Carica Incorpora"; +"Common.Controls.Status.LoadEmbed" = "Carica l'incorporato"; "Common.Controls.Status.Media.AccessibilityLabel" = "%@, allegato %d di %d"; "Common.Controls.Status.Media.ExpandGifHint" = "Espande la GIF. Tocca due volte e tieni premuto per mostrare le azioni"; "Common.Controls.Status.Media.ExpandImageHint" = "Espande l'immagine. Tocca due volte e tieni premuto per mostrare le azioni"; @@ -271,15 +275,15 @@ caricato su Mastodon."; "Scene.Familiarfollowers.FollowedByNames" = "Seguito da %@"; "Scene.Familiarfollowers.Title" = "Seguaci che conosci"; "Scene.Favorite.Title" = "Preferiti"; -"Scene.FavoritedBy.Title" = "Preferito Da"; +"Scene.FavoritedBy.Title" = "Preferito da"; "Scene.FollowedTags.Actions.Follow" = "Segui"; "Scene.FollowedTags.Actions.Unfollow" = "Smetti di seguire"; "Scene.FollowedTags.Header.Participants" = "partecipanti"; "Scene.FollowedTags.Header.Posts" = "post"; "Scene.FollowedTags.Header.PostsToday" = "post di oggi"; -"Scene.FollowedTags.Title" = "Etichette seguite"; +"Scene.FollowedTags.Title" = "Hashtag seguiti"; "Scene.Follower.Footer" = "I seguaci da altri server non vengono visualizzati."; -"Scene.Follower.Title" = "seguace"; +"Scene.Follower.Title" = "seguaci"; "Scene.Following.Footer" = "I follow da altri server non vengono visualizzati."; "Scene.Following.Title" = "seguendo"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tocca per scorrere verso l'alto e tocca di nuovo verso la posizione precedente"; @@ -517,8 +521,8 @@ caricato su Mastodon."; "Scene.Settings.Section.SpicyZone.Signout" = "Esci"; "Scene.Settings.Section.SpicyZone.Title" = "La zona piccante"; "Scene.Settings.Title" = "Impostazioni"; -"Scene.SuggestionAccount.FollowExplain" = "Quando segui qualcuno, vedrai i loro post nella tua home feed."; -"Scene.SuggestionAccount.Title" = "Trova alcune persone da seguire"; +"Scene.SuggestionAccount.FollowAll" = "Segui tutti"; +"Scene.SuggestionAccount.Title" = "Popolare su Mastodon"; "Scene.Thread.BackTitle" = "Post"; "Scene.Thread.Title" = "Post da %@"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "Cosa è Mastodon?"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.strings index 40a397917..1f717141d 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.strings @@ -30,6 +30,7 @@ "Common.Controls.Actions.Add" = "追加"; "Common.Controls.Actions.Back" = "戻る"; "Common.Controls.Actions.BlockDomain" = "%@をブロック"; +"Common.Controls.Actions.Bookmark" = "ブックマーク"; "Common.Controls.Actions.Cancel" = "キャンセル"; "Common.Controls.Actions.Compose" = "新規作成"; "Common.Controls.Actions.Confirm" = "確認"; @@ -42,6 +43,7 @@ "Common.Controls.Actions.Edit" = "編集"; "Common.Controls.Actions.EditPost" = "編集"; "Common.Controls.Actions.FindPeople" = "フォローする人を見つける"; +"Common.Controls.Actions.Follow" = "%@をフォロー"; "Common.Controls.Actions.ManuallySearch" = "手動で検索する"; "Common.Controls.Actions.Next" = "次へ"; "Common.Controls.Actions.Ok" = "OK"; @@ -51,6 +53,7 @@ "Common.Controls.Actions.Preview" = "プレビュー"; "Common.Controls.Actions.Previous" = "前"; "Common.Controls.Actions.Remove" = "消去"; +"Common.Controls.Actions.RemoveBookmark" = "ブックマークから削除"; "Common.Controls.Actions.Reply" = "返信"; "Common.Controls.Actions.ReportUser" = "%@を通報"; "Common.Controls.Actions.Save" = "保存"; @@ -67,6 +70,7 @@ "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "不明"; "Common.Controls.Actions.TryAgain" = "再実行"; "Common.Controls.Actions.UnblockDomain" = "%@のブロックを解除"; +"Common.Controls.Actions.Unfollow" = "%@をフォロー解除"; "Common.Controls.Friendship.Block" = "ブロック"; "Common.Controls.Friendship.BlockDomain" = "%@をブロック"; "Common.Controls.Friendship.BlockUser" = "%@をブロック"; @@ -512,8 +516,8 @@ "Scene.Settings.Section.SpicyZone.Signout" = "サインアウト"; "Scene.Settings.Section.SpicyZone.Title" = "取り扱い注意項目"; "Scene.Settings.Title" = "設定"; -"Scene.SuggestionAccount.FollowExplain" = "誰かをフォローすると、その人の投稿がタイムラインに表示されるようになります。"; -"Scene.SuggestionAccount.Title" = "フォローする人を探す"; +"Scene.SuggestionAccount.FollowAll" = "すべてフォロー"; +"Scene.SuggestionAccount.Title" = "人気のアカウント"; "Scene.Thread.BackTitle" = "投稿"; "Scene.Thread.Title" = "%@の投稿"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "Mastodonとは?"; @@ -539,7 +543,7 @@ "Widget.Hashtag.NotFound.Content" = "#%@ の投稿が見つかりませんでした。 #ほかのハッシュタグ を指定するか、ウィジェットの設定を変更してみてください。"; "Widget.Hashtag.Placeholder.Account" = "@johnMastodon@no-such.account"; "Widget.Hashtag.Placeholder.AccountName" = "John Mastodon"; -"Widget.Hashtag.Placeholder.Content" = "This is how a post with a #hashtag would look. Pick whichever #hashtag you want in the widget settings."; +"Widget.Hashtag.Placeholder.Content" = "#ハッシュタグ 投稿のサンプルです。検索する #ハッシュタグ はウィジェットの設定で指定できます。"; "Widget.LatestFollowers.ConfigurationDescription" = "最新のフォロワーを表示します。"; "Widget.LatestFollowers.ConfigurationDisplayName" = "最新のフォロワー"; "Widget.LatestFollowers.LastUpdate" = "最終更新: %@"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.strings index aaf7bad2e..fb92ce3bb 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.strings @@ -30,6 +30,7 @@ Ma ulac aɣilif, senqed tuqqna-inek internet."; "Common.Controls.Actions.Add" = "Rnu"; "Common.Controls.Actions.Back" = "Tuɣalin"; "Common.Controls.Actions.BlockDomain" = "Sewḥel %@"; +"Common.Controls.Actions.Bookmark" = "Bookmark"; "Common.Controls.Actions.Cancel" = "Sefsex"; "Common.Controls.Actions.Compose" = "Sudes"; "Common.Controls.Actions.Confirm" = "Sentem"; @@ -42,6 +43,7 @@ Ma ulac aɣilif, senqed tuqqna-inek internet."; "Common.Controls.Actions.Edit" = "Ẓreg"; "Common.Controls.Actions.EditPost" = "Edit"; "Common.Controls.Actions.FindPeople" = "Af imdanen ara tḍefreḍ"; +"Common.Controls.Actions.Follow" = "Follow %@"; "Common.Controls.Actions.ManuallySearch" = "Anadi s ufus deg wadeg-is"; "Common.Controls.Actions.Next" = "Uḍfir"; "Common.Controls.Actions.Ok" = "IH"; @@ -51,6 +53,7 @@ Ma ulac aɣilif, senqed tuqqna-inek internet."; "Common.Controls.Actions.Preview" = "Taskant"; "Common.Controls.Actions.Previous" = "Uzwir"; "Common.Controls.Actions.Remove" = "Kkes"; +"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; "Common.Controls.Actions.Reply" = "Err"; "Common.Controls.Actions.ReportUser" = "Cetki ɣef %@"; "Common.Controls.Actions.Save" = "Sekles"; @@ -67,6 +70,7 @@ Ma ulac aɣilif, senqed tuqqna-inek internet."; "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; "Common.Controls.Actions.TryAgain" = "Ɛreḍ tikkelt-nniḍen"; "Common.Controls.Actions.UnblockDomain" = "Serreḥ i %@"; +"Common.Controls.Actions.Unfollow" = "Unfollow %@"; "Common.Controls.Friendship.Block" = "Sewḥel"; "Common.Controls.Friendship.BlockDomain" = "Sewḥel %@"; "Common.Controls.Friendship.BlockUser" = "Sewḥel %@"; @@ -517,8 +521,8 @@ Ad d-yettwasali ɣef Mastodon."; "Scene.Settings.Section.SpicyZone.Signout" = "Senser"; "Scene.Settings.Section.SpicyZone.Title" = "Tamnaḍt tamihawt"; "Scene.Settings.Title" = "Iɣewwaṛen"; -"Scene.SuggestionAccount.FollowExplain" = "Mi ara teṭṭafareḍ albaɛḍ, ad twaliḍ tisuffaɣ-is deg usuddem-inek agejdan."; -"Scene.SuggestionAccount.Title" = "Af imdanen ara tḍefreḍ"; +"Scene.SuggestionAccount.FollowAll" = "Follow all"; +"Scene.SuggestionAccount.Title" = "Popular on Mastodon"; "Scene.Thread.BackTitle" = "Amagrad"; "Scene.Thread.Title" = "Tasuffeɣt sɣur %@"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "What is Mastodon?"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.strings index 62207f94b..83e0f2546 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.strings @@ -30,6 +30,7 @@ Jkx girêdana înternetê xwe kontrol bike."; "Common.Controls.Actions.Add" = "Tevlî bike"; "Common.Controls.Actions.Back" = "Vegere"; "Common.Controls.Actions.BlockDomain" = "%@ asteng bike"; +"Common.Controls.Actions.Bookmark" = "Bookmark"; "Common.Controls.Actions.Cancel" = "Dev jê berde"; "Common.Controls.Actions.Compose" = "Binivîsîne"; "Common.Controls.Actions.Confirm" = "Bipejirîne"; @@ -42,6 +43,7 @@ Jkx girêdana înternetê xwe kontrol bike."; "Common.Controls.Actions.Edit" = "Serrast bike"; "Common.Controls.Actions.EditPost" = "Serrast bike"; "Common.Controls.Actions.FindPeople" = "Mirovan bo şopandinê bibîne"; +"Common.Controls.Actions.Follow" = "Follow %@"; "Common.Controls.Actions.ManuallySearch" = "Ji devlê bi destan lêgerînê bike"; "Common.Controls.Actions.Next" = "Pêş"; "Common.Controls.Actions.Ok" = "BAŞ E"; @@ -51,6 +53,7 @@ Jkx girêdana înternetê xwe kontrol bike."; "Common.Controls.Actions.Preview" = "Pêşdîtin"; "Common.Controls.Actions.Previous" = "Paş"; "Common.Controls.Actions.Remove" = "Rake"; +"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; "Common.Controls.Actions.Reply" = "Bersivê bide"; "Common.Controls.Actions.ReportUser" = "%@ ragihîne"; "Common.Controls.Actions.Save" = "Tomar bike"; @@ -67,6 +70,7 @@ Jkx girêdana înternetê xwe kontrol bike."; "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Nenas"; "Common.Controls.Actions.TryAgain" = "Dîsa biceribîne"; "Common.Controls.Actions.UnblockDomain" = "%@ asteng neke"; +"Common.Controls.Actions.Unfollow" = "Unfollow %@"; "Common.Controls.Friendship.Block" = "Asteng bike"; "Common.Controls.Friendship.BlockDomain" = "%@ asteng bike"; "Common.Controls.Friendship.BlockUser" = "%@ asteng bike"; @@ -517,8 +521,8 @@ Profîla te ji wan ra wiha xuya dike."; "Scene.Settings.Section.SpicyZone.Signout" = "Derkeve"; "Scene.Settings.Section.SpicyZone.Title" = "Devera germ"; "Scene.Settings.Title" = "Sazkarî"; -"Scene.SuggestionAccount.FollowExplain" = "Gava tu kesekî dişopînî, tu yê şandiyê wan di serrûpelê de bibîne."; -"Scene.SuggestionAccount.Title" = "Kesên bo ku bişopînî bibîne"; +"Scene.SuggestionAccount.FollowAll" = "Follow all"; +"Scene.SuggestionAccount.Title" = "Popular on Mastodon"; "Scene.Thread.BackTitle" = "Şandî"; "Scene.Thread.Title" = "Şandî ji %@"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "Mastodon çi ye?"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings index 313da8b79..4cb922844 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings @@ -29,6 +29,7 @@ "Common.Controls.Actions.Add" = "Voeg toe"; "Common.Controls.Actions.Back" = "Terug"; "Common.Controls.Actions.BlockDomain" = "%@ blokkeren"; +"Common.Controls.Actions.Bookmark" = "Bladwijzer toevoegen"; "Common.Controls.Actions.Cancel" = "Annuleren"; "Common.Controls.Actions.Compose" = "Bericht schrijven"; "Common.Controls.Actions.Confirm" = "Bevestigen"; @@ -41,6 +42,7 @@ "Common.Controls.Actions.Edit" = "Bewerk"; "Common.Controls.Actions.EditPost" = "Bewerken"; "Common.Controls.Actions.FindPeople" = "Zoek mensen om te volgen"; +"Common.Controls.Actions.Follow" = "Volg %@"; "Common.Controls.Actions.ManuallySearch" = "Handmatig zoeken"; "Common.Controls.Actions.Next" = "Volgende"; "Common.Controls.Actions.Ok" = "Ok"; @@ -50,6 +52,7 @@ "Common.Controls.Actions.Preview" = "Voorvertoning"; "Common.Controls.Actions.Previous" = "Vorige"; "Common.Controls.Actions.Remove" = "Verwijder"; +"Common.Controls.Actions.RemoveBookmark" = "Bladwijzer verwijderen"; "Common.Controls.Actions.Reply" = "Reageer"; "Common.Controls.Actions.ReportUser" = "%@ rapporteren"; "Common.Controls.Actions.Save" = "Bewaar"; @@ -66,6 +69,7 @@ "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Onbekend"; "Common.Controls.Actions.TryAgain" = "Opnieuw proberen"; "Common.Controls.Actions.UnblockDomain" = "%@ deblokkeren"; +"Common.Controls.Actions.Unfollow" = "Ontvolg %@"; "Common.Controls.Friendship.Block" = "Blokkeren"; "Common.Controls.Friendship.BlockDomain" = "%@ blokkeren"; "Common.Controls.Friendship.BlockUser" = "%@ blokkeren"; @@ -511,8 +515,8 @@ Jouw profiel ziet er zo uit voor hen."; "Scene.Settings.Section.SpicyZone.Signout" = "Uitloggen"; "Scene.Settings.Section.SpicyZone.Title" = "De gevaarlijke zone"; "Scene.Settings.Title" = "Instellingen"; -"Scene.SuggestionAccount.FollowExplain" = "Wanneer je iemand volgt, zie je hun berichten op jouw starttijdlijn."; -"Scene.SuggestionAccount.Title" = "Zoek mensen om te volgen"; +"Scene.SuggestionAccount.FollowAll" = "Iedereen volgen"; +"Scene.SuggestionAccount.Title" = "Populair op Mastodon"; "Scene.Thread.BackTitle" = "Bericht"; "Scene.Thread.Title" = "Bericht van %@"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "Wat is Mastodon?"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings index a88924899..c5d95aeb4 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings @@ -30,6 +30,7 @@ "Common.Controls.Actions.Add" = "Добавить"; "Common.Controls.Actions.Back" = "Назад"; "Common.Controls.Actions.BlockDomain" = "Заблокировать %@"; +"Common.Controls.Actions.Bookmark" = "Bookmark"; "Common.Controls.Actions.Cancel" = "Отмена"; "Common.Controls.Actions.Compose" = "Написать"; "Common.Controls.Actions.Confirm" = "Подтвердить"; @@ -42,6 +43,7 @@ "Common.Controls.Actions.Edit" = "Изменить"; "Common.Controls.Actions.EditPost" = "Edit"; "Common.Controls.Actions.FindPeople" = "Подпишитесь на людей"; +"Common.Controls.Actions.Follow" = "Follow %@"; "Common.Controls.Actions.ManuallySearch" = "Найти вручную"; "Common.Controls.Actions.Next" = "Далее"; "Common.Controls.Actions.Ok" = "ОК"; @@ -51,6 +53,7 @@ "Common.Controls.Actions.Preview" = "Предпросмотр"; "Common.Controls.Actions.Previous" = "Прошлые"; "Common.Controls.Actions.Remove" = "Убрать"; +"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; "Common.Controls.Actions.Reply" = "Ответить"; "Common.Controls.Actions.ReportUser" = "Пожаловаться на %@"; "Common.Controls.Actions.Save" = "Сохранить"; @@ -67,6 +70,7 @@ "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; "Common.Controls.Actions.TryAgain" = "Попробовать снова"; "Common.Controls.Actions.UnblockDomain" = "Разблокировать %@"; +"Common.Controls.Actions.Unfollow" = "Unfollow %@"; "Common.Controls.Friendship.Block" = "Заблокировать"; "Common.Controls.Friendship.BlockDomain" = "Заблокировать %@"; "Common.Controls.Friendship.BlockUser" = "Заблокировать %@"; @@ -525,8 +529,8 @@ "Scene.Settings.Section.SpicyZone.Signout" = "Выйти из учётной записи"; "Scene.Settings.Section.SpicyZone.Title" = "Пикантная зона"; "Scene.Settings.Title" = "Настройки"; -"Scene.SuggestionAccount.FollowExplain" = "Посты людей, на которых вы подписались, будут видны на главной странице."; -"Scene.SuggestionAccount.Title" = "Подпишитесь на людей"; +"Scene.SuggestionAccount.FollowAll" = "Follow all"; +"Scene.SuggestionAccount.Title" = "Popular on Mastodon"; "Scene.Thread.BackTitle" = "Пост"; "Scene.Thread.Title" = "Пост %@"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "What is Mastodon?"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/sl.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/sl.lproj/Localizable.strings index ee5b069f6..3285e976e 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/sl.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/sl.lproj/Localizable.strings @@ -30,6 +30,7 @@ Preverite svojo internetno povezavo."; "Common.Controls.Actions.Add" = "Dodaj"; "Common.Controls.Actions.Back" = "Nazaj"; "Common.Controls.Actions.BlockDomain" = "Blokiraj %@"; +"Common.Controls.Actions.Bookmark" = "Zaznamek"; "Common.Controls.Actions.Cancel" = "Prekliči"; "Common.Controls.Actions.Compose" = "Sestavi"; "Common.Controls.Actions.Confirm" = "Potrdi"; @@ -42,6 +43,7 @@ Preverite svojo internetno povezavo."; "Common.Controls.Actions.Edit" = "Uredi"; "Common.Controls.Actions.EditPost" = "Uredi"; "Common.Controls.Actions.FindPeople" = "Poiščite osebe, ki jim želite slediti"; +"Common.Controls.Actions.Follow" = "Sledi %@"; "Common.Controls.Actions.ManuallySearch" = "Raje išči ročno"; "Common.Controls.Actions.Next" = "Naslednji"; "Common.Controls.Actions.Ok" = "V redu"; @@ -51,6 +53,7 @@ Preverite svojo internetno povezavo."; "Common.Controls.Actions.Preview" = "Predogled"; "Common.Controls.Actions.Previous" = "Prejšnji"; "Common.Controls.Actions.Remove" = "Odstrani"; +"Common.Controls.Actions.RemoveBookmark" = "Odstrani zaznamek"; "Common.Controls.Actions.Reply" = "Odgovori"; "Common.Controls.Actions.ReportUser" = "Prijavi %@"; "Common.Controls.Actions.Save" = "Shrani"; @@ -67,6 +70,7 @@ Preverite svojo internetno povezavo."; "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Neznano"; "Common.Controls.Actions.TryAgain" = "Poskusi ponovno"; "Common.Controls.Actions.UnblockDomain" = "Odblokiraj %@"; +"Common.Controls.Actions.Unfollow" = "Prenehaj slediti %@"; "Common.Controls.Friendship.Block" = "Blokiraj"; "Common.Controls.Friendship.BlockDomain" = "Blokiraj %@"; "Common.Controls.Friendship.BlockUser" = "Blokiraj %@"; @@ -517,8 +521,8 @@ možno naložiti v Mastodon."; "Scene.Settings.Section.SpicyZone.Signout" = "Odjava"; "Scene.Settings.Section.SpicyZone.Title" = "Pikantna cona"; "Scene.Settings.Title" = "Nastavitve"; -"Scene.SuggestionAccount.FollowExplain" = "Ko nekomu sledite, vidite njihove objave v svojem domačem viru."; -"Scene.SuggestionAccount.Title" = "Poiščite osebe, ki jim želite slediti"; +"Scene.SuggestionAccount.FollowAll" = "Sledi vsem"; +"Scene.SuggestionAccount.Title" = "Priljubljeno na Mastodonu"; "Scene.Thread.BackTitle" = "Objavi"; "Scene.Thread.Title" = "Objavil/a"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "Kaj je Mastodon?"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.strings index 71ea0901e..28c89370f 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.strings @@ -30,6 +30,7 @@ Kontrollera din internetanslutning."; "Common.Controls.Actions.Add" = "Lägg till"; "Common.Controls.Actions.Back" = "Tillbaka"; "Common.Controls.Actions.BlockDomain" = "Blockera %@"; +"Common.Controls.Actions.Bookmark" = "Bookmark"; "Common.Controls.Actions.Cancel" = "Avbryt"; "Common.Controls.Actions.Compose" = "Skriv"; "Common.Controls.Actions.Confirm" = "Bekräfta"; @@ -42,6 +43,7 @@ Kontrollera din internetanslutning."; "Common.Controls.Actions.Edit" = "Redigera"; "Common.Controls.Actions.EditPost" = "Redigera"; "Common.Controls.Actions.FindPeople" = "Hitta personer att följa"; +"Common.Controls.Actions.Follow" = "Follow %@"; "Common.Controls.Actions.ManuallySearch" = "Sök manuellt istället"; "Common.Controls.Actions.Next" = "Nästa"; "Common.Controls.Actions.Ok" = "OK"; @@ -51,6 +53,7 @@ Kontrollera din internetanslutning."; "Common.Controls.Actions.Preview" = "Förhandsvisa"; "Common.Controls.Actions.Previous" = "Föregående"; "Common.Controls.Actions.Remove" = "Radera"; +"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; "Common.Controls.Actions.Reply" = "Svara"; "Common.Controls.Actions.ReportUser" = "Rapportera %@"; "Common.Controls.Actions.Save" = "Spara"; @@ -67,6 +70,7 @@ Kontrollera din internetanslutning."; "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Okänt"; "Common.Controls.Actions.TryAgain" = "Försök igen"; "Common.Controls.Actions.UnblockDomain" = "Avblockera %@"; +"Common.Controls.Actions.Unfollow" = "Unfollow %@"; "Common.Controls.Friendship.Block" = "Blockera"; "Common.Controls.Friendship.BlockDomain" = "Blockera %@"; "Common.Controls.Friendship.BlockUser" = "Blockera %@"; @@ -122,7 +126,7 @@ Kontrollera din internetanslutning."; "Common.Controls.Status.ContentWarning" = "Innehållsvarning"; "Common.Controls.Status.EditHistory.OriginalPost" = "Original Post · %@"; "Common.Controls.Status.EditHistory.Title" = "Edit History"; -"Common.Controls.Status.EditedAtTimestampPrefix" = "Edited %@"; +"Common.Controls.Status.EditedAtTimestampPrefix" = "Ändrad %@"; "Common.Controls.Status.LinkViaUser" = "%@ via %@"; "Common.Controls.Status.LoadEmbed" = "Ladda inbäddning"; "Common.Controls.Status.Media.AccessibilityLabel" = "%@, bilaga %d av %d"; @@ -157,8 +161,8 @@ Kontrollera din internetanslutning."; "Common.Controls.Status.Visibility.Private" = "Endast deras följare kan se detta inlägg."; "Common.Controls.Status.Visibility.PrivateFromMe" = "Bara mina följare kan se det här inlägget."; "Common.Controls.Status.Visibility.Unlisted" = "Alla kan se detta inlägg men det visas inte i den offentliga tidslinjen."; -"Common.Controls.Tabs.A11Y.Explore" = "Explore"; -"Common.Controls.Tabs.A11Y.Search" = "Search"; +"Common.Controls.Tabs.A11Y.Explore" = "Utforska"; +"Common.Controls.Tabs.A11Y.Search" = "Sök"; "Common.Controls.Tabs.Home" = "Hem"; "Common.Controls.Tabs.Notifications" = "Notiser"; "Common.Controls.Tabs.Profile" = "Profil"; @@ -182,8 +186,8 @@ Din profil ser ut så här för dem."; "Common.Controls.Timeline.Loader.ShowMoreReplies" = "Visa fler svar"; "Common.Controls.Timeline.Timestamp.Now" = "Nu"; "Common.UserList.FollowersCount" = "%@ följare"; -"Common.UserList.NoVerifiedLink" = "No verified link"; -"Extension.OpenIn.InvalidLinkError" = "This doesn't seem to be a valid Mastodon link."; +"Common.UserList.NoVerifiedLink" = "Ingen verifierad länk"; +"Extension.OpenIn.InvalidLinkError" = "Detta verkar inte vara en giltig Mastodon-länk."; "Scene.AccountList.AddAccount" = "Lägg till konto"; "Scene.AccountList.DismissAccountSwitcher" = "Stäng kontoväxlare"; "Scene.AccountList.TabBarHint" = "Nuvarande vald profil: %@. Dubbeltryck och håll för att visa kontoväxlare"; @@ -219,8 +223,8 @@ laddas upp till Mastodon."; "Scene.Compose.Keyboard.SelectVisibilityEntry" = "Välj synlighet - %@"; "Scene.Compose.Keyboard.ToggleContentWarning" = "Växla innehållsvarning"; "Scene.Compose.Keyboard.TogglePoll" = "Växla omröstning"; -"Scene.Compose.Language.Other" = "Other Language…"; -"Scene.Compose.Language.Recent" = "Recent"; +"Scene.Compose.Language.Other" = "Andra språk…"; +"Scene.Compose.Language.Recent" = "Senaste"; "Scene.Compose.Language.Suggested" = "Suggested"; "Scene.Compose.Language.Title" = "Post Language"; "Scene.Compose.MediaSelection.Browse" = "Bläddra"; @@ -228,8 +232,8 @@ laddas upp till Mastodon."; "Scene.Compose.MediaSelection.PhotoLibrary" = "Fotobibliotek"; "Scene.Compose.Poll.AddOption" = "Add Option"; "Scene.Compose.Poll.DurationTime" = "Längd: %@"; -"Scene.Compose.Poll.MoveDown" = "Move Down"; -"Scene.Compose.Poll.MoveUp" = "Move Up"; +"Scene.Compose.Poll.MoveDown" = "Flytta ned"; +"Scene.Compose.Poll.MoveUp" = "Flytta upp"; "Scene.Compose.Poll.OneDay" = "1 dag"; "Scene.Compose.Poll.OneHour" = "1 timme"; "Scene.Compose.Poll.OptionNumber" = "Alternativ %ld"; @@ -242,7 +246,7 @@ laddas upp till Mastodon."; "Scene.Compose.Poll.ThreeDays" = "3 dagar"; "Scene.Compose.Poll.Title" = "Poll"; "Scene.Compose.ReplyingToUser" = "svarar %@"; -"Scene.Compose.Title.EditPost" = "Edit Post"; +"Scene.Compose.Title.EditPost" = "Redigera inlägg"; "Scene.Compose.Title.NewPost" = "Nytt inlägg"; "Scene.Compose.Title.NewReply" = "Nytt svar"; "Scene.Compose.Visibility.Direct" = "Bara personer jag nämner"; @@ -250,8 +254,8 @@ laddas upp till Mastodon."; "Scene.Compose.Visibility.Public" = "Offentlig"; "Scene.Compose.Visibility.Unlisted" = "Olistad"; "Scene.ConfirmEmail.Button.Resend" = "Skicka igen"; -"Scene.ConfirmEmail.DidntGetLink.Prefix" = "Didn’t get a link?"; -"Scene.ConfirmEmail.DidntGetLink.ResendIn" = "Resend (%@)"; +"Scene.ConfirmEmail.DidntGetLink.Prefix" = "Fick du ingen länk?"; +"Scene.ConfirmEmail.DidntGetLink.ResendIn" = "Skicka igen (%@)"; "Scene.ConfirmEmail.DidntGetLink.ResendNow" = "Resend now."; "Scene.ConfirmEmail.DontReceiveEmail.Description" = "Kontrollera om din e-postadress är korrekt samt din skräppostmapp om du inte har gjort det."; "Scene.ConfirmEmail.DontReceiveEmail.ResendEmail" = "Skicka e-postmeddelande igen"; @@ -260,8 +264,8 @@ laddas upp till Mastodon."; "Scene.ConfirmEmail.OpenEmailApp.Mail" = "E-post"; "Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "Öppna e-postklient"; "Scene.ConfirmEmail.OpenEmailApp.Title" = "Check your Inbox."; -"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Tap the link we sent you to verify %@. We’ll wait right here."; -"Scene.ConfirmEmail.Title" = "Check Your Inbox"; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Klicka på länken som vi har skickat till dig för att bekräfta %@. Vi väntar här."; +"Scene.ConfirmEmail.Title" = "Kolla din inkorg"; "Scene.Discovery.Intro" = "Detta är de inlägg som engagerar i ditt hörn av Mastodon."; "Scene.Discovery.Tabs.Community" = "Server"; "Scene.Discovery.Tabs.ForYou" = "För dig"; @@ -291,7 +295,7 @@ laddas upp till Mastodon."; "Scene.HomeTimeline.Title" = "Hem"; "Scene.Login.ServerSearchField.Placeholder" = "Ange URL eller sök efter din server"; "Scene.Login.Subtitle" = "Logga in på servern där du skapade ditt konto."; -"Scene.Login.Title" = "Welcome back"; +"Scene.Login.Title" = "Välkommen tillbaka"; "Scene.Notification.FollowRequest.Accept" = "Godkänn"; "Scene.Notification.FollowRequest.Accepted" = "Godkänd"; "Scene.Notification.FollowRequest.Reject" = "avvisa"; @@ -309,8 +313,8 @@ laddas upp till Mastodon."; "Scene.Preview.Keyboard.ClosePreview" = "Stäng förhandsvisning"; "Scene.Preview.Keyboard.ShowNext" = "Visa nästa"; "Scene.Preview.Keyboard.ShowPrevious" = "Visa föregående"; -"Scene.Privacy.Button.Confirm" = "I Agree"; -"Scene.Privacy.Description" = "Although the Mastodon app does not collect any data, the server you sign up through may have a different policy. Take a minute to review and agree to the Mastodon app privacy policy and your server’s privacy policy."; +"Scene.Privacy.Button.Confirm" = "Jag godkänner"; +"Scene.Privacy.Description" = "Även om Mastodon-appen inte samlar in någon data kan servern du registrerar dig genom ha en annan policy. Ta en stund till att granska och godkänna Mastodon-appens sekretesspolicy och din servers sekretesspolicy."; "Scene.Privacy.Policy.Ios" = "Integritetspolicy - Mastodon för iOS"; "Scene.Privacy.Policy.Server" = "Integritetspolicy - %@"; "Scene.Privacy.Title" = "Privacy"; @@ -362,7 +366,7 @@ laddas upp till Mastodon."; "Scene.Register.Error.Reason.Inclusion" = "%@ är inte ett värde som stöds"; "Scene.Register.Error.Reason.Invalid" = "%@ är ogiltig"; "Scene.Register.Error.Reason.Reserved" = "%@ är ett reserverat nyckelord"; -"Scene.Register.Error.Reason.Taken" = "%@ is already taken. How about:"; +"Scene.Register.Error.Reason.Taken" = "%@ är redan tagen. Vad sägs om:"; "Scene.Register.Error.Reason.TooLong" = "%@ är för långt"; "Scene.Register.Error.Reason.TooShort" = "%@ är för kort"; "Scene.Register.Error.Reason.Unreachable" = "%@ verkar inte existera"; @@ -377,7 +381,7 @@ laddas upp till Mastodon."; "Scene.Register.Input.Password.Accessibility.Checked" = "markerad"; "Scene.Register.Input.Password.Accessibility.Unchecked" = "avmarkerad"; "Scene.Register.Input.Password.CharacterLimit" = "8 tecken"; -"Scene.Register.Input.Password.ConfirmationPlaceholder" = "Confirm Password"; +"Scene.Register.Input.Password.ConfirmationPlaceholder" = "Bekräfta lösenord"; "Scene.Register.Input.Password.Hint" = "Ditt lösenord måste bestå av minst 8 tecken"; "Scene.Register.Input.Password.Placeholder" = "lösenord"; "Scene.Register.Input.Password.Require" = "Ditt lösenord behöver minst:"; @@ -471,13 +475,13 @@ laddas upp till Mastodon."; "Scene.ServerPicker.Label.Language" = "SPRÅK"; "Scene.ServerPicker.Label.Users" = "ANVÄNDARE"; "Scene.ServerPicker.Language.All" = "All"; -"Scene.ServerPicker.NoServerSelectedHint" = "We’ll pick a server based on your language if you continue without making a selection."; -"Scene.ServerPicker.Search.Placeholder" = "Search name or URL"; +"Scene.ServerPicker.NoServerSelectedHint" = "Vi kommer att välja en server baserat på ditt språk om du fortsätter utan att göra ett val."; +"Scene.ServerPicker.Search.Placeholder" = "Sök namn eller URL"; "Scene.ServerPicker.SignupSpeed.All" = "All"; "Scene.ServerPicker.SignupSpeed.Instant" = "Instant Sign-up"; -"Scene.ServerPicker.SignupSpeed.ManuallyReviewed" = "Manual Review"; -"Scene.ServerPicker.Title" = "Pick Server"; -"Scene.ServerRules.Button.Confirm" = "I Agree"; +"Scene.ServerPicker.SignupSpeed.ManuallyReviewed" = "Manuell granskning"; +"Scene.ServerPicker.Title" = "Välj server"; +"Scene.ServerRules.Button.Confirm" = "Jag godkänner"; "Scene.ServerRules.PrivacyPolicy" = "integritetspolicy"; "Scene.ServerRules.Prompt" = "Genom att fortsätta omfattas du av villkoren för tjänsten och sekretesspolicyn för %@."; "Scene.ServerRules.Subtitle" = "Dessa sätts och verkställs av moderatorerna på %@."; @@ -517,26 +521,26 @@ laddas upp till Mastodon."; "Scene.Settings.Section.SpicyZone.Signout" = "Logga ut"; "Scene.Settings.Section.SpicyZone.Title" = "Den spännande zonen"; "Scene.Settings.Title" = "Inställningar"; -"Scene.SuggestionAccount.FollowExplain" = "När du följer någon, kommer du att se deras inlägg i ditt hemflöde."; -"Scene.SuggestionAccount.Title" = "Hitta personer att följa"; +"Scene.SuggestionAccount.FollowAll" = "Följ alla"; +"Scene.SuggestionAccount.Title" = "Populärt på Mastodon"; "Scene.Thread.BackTitle" = "Inlägg"; "Scene.Thread.Title" = "Inlägg från %@"; -"Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "What is Mastodon?"; -"Scene.Welcome.Education.Mastodon.Description" = "Mastodon is a decentralized social network, meaning no single company controls it. It’s made up of many independently-run servers, all connected together."; -"Scene.Welcome.Education.Mastodon.Title" = "Welcome to Mastodon"; -"Scene.Welcome.Education.Servers.Description" = "Every Mastodon account is hosted on a server — each with its own values, rules, & admins. No matter which one you pick, you can follow and interact with people on any server."; -"Scene.Welcome.Education.Servers.Title" = "What are servers?"; -"Scene.Welcome.JoinDefaultServer" = "Join mastodon.social"; +"Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "Vad är Mastodon?"; +"Scene.Welcome.Education.Mastodon.Description" = "Mastodon är ett decentraliserat socialt nätverk, vilket innebär att inget enskilt företag kontrollerar det. Det består av många oberoende servrar, alla sammankopplade."; +"Scene.Welcome.Education.Mastodon.Title" = "Välkommen till Mastodon"; +"Scene.Welcome.Education.Servers.Description" = "Varje Mastodon-konto finns på en server — var och en med sina värderingar, regler och administratörer. Oavsett vilken du väljer kan du följa och interagera med människor på vilken server som helst."; +"Scene.Welcome.Education.Servers.Title" = "Vad är servrar?"; +"Scene.Welcome.JoinDefaultServer" = "Gå med i mastodon.social"; "Scene.Welcome.LearnMore" = "Läs mer"; "Scene.Welcome.LogIn" = "Logga in"; -"Scene.Welcome.PickServer" = "Pick another server"; -"Scene.Welcome.Separator.Or" = "or"; +"Scene.Welcome.PickServer" = "Hitta en annan server"; +"Scene.Welcome.Separator.Or" = "eller"; "Widget.Common.UnsupportedWidgetFamily" = "Sorry but this Widget family is unsupported."; "Widget.Common.UserNotLoggedIn" = "Please open Mastodon to log in to an Account."; "Widget.FollowersCount.ConfigurationDescription" = "Show number of followers."; -"Widget.FollowersCount.ConfigurationDisplayName" = "Followers"; -"Widget.FollowersCount.FollowersToday" = "%@ followers today"; -"Widget.FollowersCount.Title" = "FOLLOWERS"; +"Widget.FollowersCount.ConfigurationDisplayName" = "Följare"; +"Widget.FollowersCount.FollowersToday" = "%@ följare idag"; +"Widget.FollowersCount.Title" = "FÖLJARE"; "Widget.Hashtag.Configuration.Description" = "Shows a recent post with the selected hashtag."; "Widget.Hashtag.Configuration.DisplayName" = "Hashtag"; "Widget.Hashtag.NotFound.Account" = "@johnMastodon@no-such.account"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.strings index f97a8e066..d00093bb0 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.strings @@ -30,6 +30,7 @@ "Common.Controls.Actions.Add" = "เพิ่ม"; "Common.Controls.Actions.Back" = "ย้อนกลับ"; "Common.Controls.Actions.BlockDomain" = "ปิดกั้น %@"; +"Common.Controls.Actions.Bookmark" = "เพิ่มที่คั่นหน้า"; "Common.Controls.Actions.Cancel" = "ยกเลิก"; "Common.Controls.Actions.Compose" = "เขียน"; "Common.Controls.Actions.Confirm" = "ยืนยัน"; @@ -42,6 +43,7 @@ "Common.Controls.Actions.Edit" = "แก้ไข"; "Common.Controls.Actions.EditPost" = "แก้ไข"; "Common.Controls.Actions.FindPeople" = "ค้นหาผู้คนที่จะติดตาม"; +"Common.Controls.Actions.Follow" = "ติดตาม %@"; "Common.Controls.Actions.ManuallySearch" = "ค้นหาด้วยตนเองแทน"; "Common.Controls.Actions.Next" = "ถัดไป"; "Common.Controls.Actions.Ok" = "ตกลง"; @@ -51,6 +53,7 @@ "Common.Controls.Actions.Preview" = "แสดงตัวอย่าง"; "Common.Controls.Actions.Previous" = "ก่อนหน้า"; "Common.Controls.Actions.Remove" = "เอาออก"; +"Common.Controls.Actions.RemoveBookmark" = "เอาที่คั่นหน้าออก"; "Common.Controls.Actions.Reply" = "ตอบกลับ"; "Common.Controls.Actions.ReportUser" = "รายงาน %@"; "Common.Controls.Actions.Save" = "บันทึก"; @@ -67,6 +70,7 @@ "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "ไม่รู้จัก"; "Common.Controls.Actions.TryAgain" = "ลองอีกครั้ง"; "Common.Controls.Actions.UnblockDomain" = "เลิกปิดกั้น %@"; +"Common.Controls.Actions.Unfollow" = "เลิกติดตาม %@"; "Common.Controls.Friendship.Block" = "ปิดกั้น"; "Common.Controls.Friendship.BlockDomain" = "ปิดกั้น %@"; "Common.Controls.Friendship.BlockUser" = "ปิดกั้น %@"; @@ -262,7 +266,7 @@ "Scene.ConfirmEmail.OpenEmailApp.Title" = "ตรวจสอบกล่องขาเข้าของคุณ"; "Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "แตะลิงก์ที่เราส่งถึงคุณเพื่อยืนยัน %@ เราจะรออยู่ตรงนี้"; "Scene.ConfirmEmail.Title" = "ตรวจสอบกล่องขาเข้าของคุณ"; -"Scene.Discovery.Intro" = "นี่คือโพสต์ที่กำลังได้รับความสนใจในมุมของ Mastodon ของคุณ"; +"Scene.Discovery.Intro" = "นี่คือโพสต์ที่ได้รับความสนใจในมุมของ Mastodon ของคุณ"; "Scene.Discovery.Tabs.Community" = "ชุมชน"; "Scene.Discovery.Tabs.ForYou" = "สำหรับคุณ"; "Scene.Discovery.Tabs.Hashtags" = "แฮชแท็ก"; @@ -471,7 +475,7 @@ "Scene.ServerPicker.Label.Language" = "ภาษา"; "Scene.ServerPicker.Label.Users" = "ผู้ใช้"; "Scene.ServerPicker.Language.All" = "ทั้งหมด"; -"Scene.ServerPicker.NoServerSelectedHint" = "เราจะเลือกเซิร์ฟเวอร์ตามภาษาของคุณหากคุณดำเนินการต่อโดยไม่ได้ทำการเลือก"; +"Scene.ServerPicker.NoServerSelectedHint" = "เราจะเลือกเซิร์ฟเวอร์โดยอิงตามภาษาของคุณหากคุณดำเนินการต่อโดยไม่ได้ทำการเลือก"; "Scene.ServerPicker.Search.Placeholder" = "ค้นหาชื่อหรือ URL"; "Scene.ServerPicker.SignupSpeed.All" = "ทั้งหมด"; "Scene.ServerPicker.SignupSpeed.Instant" = "การลงทะเบียนทันที"; @@ -517,8 +521,8 @@ "Scene.Settings.Section.SpicyZone.Signout" = "ลงชื่อออก"; "Scene.Settings.Section.SpicyZone.Title" = "โซนเผ็ดร้อน"; "Scene.Settings.Title" = "การตั้งค่า"; -"Scene.SuggestionAccount.FollowExplain" = "เมื่อคุณติดตามใครสักคน คุณจะเห็นโพสต์ของเขาในฟีดหน้าแรกของคุณ"; -"Scene.SuggestionAccount.Title" = "ค้นหาผู้คนที่จะติดตาม"; +"Scene.SuggestionAccount.FollowAll" = "ติดตามทั้งหมด"; +"Scene.SuggestionAccount.Title" = "เป็นที่นิยมใน Mastodon"; "Scene.Thread.BackTitle" = "โพสต์"; "Scene.Thread.Title" = "โพสต์จาก %@"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "Mastodon คืออะไร?"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.strings index c066d820d..ab697aa37 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.strings @@ -29,6 +29,7 @@ "Common.Controls.Actions.Add" = "Ekle"; "Common.Controls.Actions.Back" = "Geri"; "Common.Controls.Actions.BlockDomain" = "%@ kişisini engelle"; +"Common.Controls.Actions.Bookmark" = "Bookmark"; "Common.Controls.Actions.Cancel" = "İptal et"; "Common.Controls.Actions.Compose" = "Yaz"; "Common.Controls.Actions.Confirm" = "Onayla"; @@ -41,6 +42,7 @@ "Common.Controls.Actions.Edit" = "Düzenle"; "Common.Controls.Actions.EditPost" = "Edit"; "Common.Controls.Actions.FindPeople" = "Takip etmek için birkaç kişi bul"; +"Common.Controls.Actions.Follow" = "Follow %@"; "Common.Controls.Actions.ManuallySearch" = "Onun yerine manuel olarak ara"; "Common.Controls.Actions.Next" = "İleri"; "Common.Controls.Actions.Ok" = "Tamam"; @@ -50,6 +52,7 @@ "Common.Controls.Actions.Preview" = "Önizleme"; "Common.Controls.Actions.Previous" = "Önceki"; "Common.Controls.Actions.Remove" = "Kaldır"; +"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; "Common.Controls.Actions.Reply" = "Yanıtla"; "Common.Controls.Actions.ReportUser" = "%@ kişisini bildir"; "Common.Controls.Actions.Save" = "Kaydet"; @@ -66,6 +69,7 @@ "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; "Common.Controls.Actions.TryAgain" = "Tekrar Deneyin"; "Common.Controls.Actions.UnblockDomain" = "%@ kişisinin engelini kaldır"; +"Common.Controls.Actions.Unfollow" = "Unfollow %@"; "Common.Controls.Friendship.Block" = "Engelle"; "Common.Controls.Friendship.BlockDomain" = "%@ kişisini engelle"; "Common.Controls.Friendship.BlockUser" = "%@ kişisini engelle"; @@ -516,8 +520,8 @@ yüklenemiyor."; "Scene.Settings.Section.SpicyZone.Signout" = "Oturumu Kapat"; "Scene.Settings.Section.SpicyZone.Title" = "Tehlikeli bölge"; "Scene.Settings.Title" = "Ayarlar"; -"Scene.SuggestionAccount.FollowExplain" = "Birisini takip ettiğinizde, ana sayfanızda o kişinin gönderilerini görürsünüz."; -"Scene.SuggestionAccount.Title" = "Takip Edecek İnsanlar Bul"; +"Scene.SuggestionAccount.FollowAll" = "Follow all"; +"Scene.SuggestionAccount.Title" = "Popular on Mastodon"; "Scene.Thread.BackTitle" = "Gönderi"; "Scene.Thread.Title" = "%@ kullanıcının gönderisi"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "What is Mastodon?"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.strings index f74bff828..750cdc4b7 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.strings @@ -30,6 +30,7 @@ Vui lòng kiểm tra kết nối mạng."; "Common.Controls.Actions.Add" = "Thêm"; "Common.Controls.Actions.Back" = "Quay lại"; "Common.Controls.Actions.BlockDomain" = "Chặn %@"; +"Common.Controls.Actions.Bookmark" = "Lưu"; "Common.Controls.Actions.Cancel" = "Hủy bỏ"; "Common.Controls.Actions.Compose" = "Viết tút"; "Common.Controls.Actions.Confirm" = "Xác nhận"; @@ -42,6 +43,7 @@ Vui lòng kiểm tra kết nối mạng."; "Common.Controls.Actions.Edit" = "Sửa"; "Common.Controls.Actions.EditPost" = "Sửa"; "Common.Controls.Actions.FindPeople" = "Đề xuất theo dõi"; +"Common.Controls.Actions.Follow" = "Theo dõi %@"; "Common.Controls.Actions.ManuallySearch" = "Tự tìm kiếm thủ công"; "Common.Controls.Actions.Next" = "Kế tiếp"; "Common.Controls.Actions.Ok" = "OK"; @@ -51,6 +53,7 @@ Vui lòng kiểm tra kết nối mạng."; "Common.Controls.Actions.Preview" = "Xem trước"; "Common.Controls.Actions.Previous" = "Trước đó"; "Common.Controls.Actions.Remove" = "Xóa"; +"Common.Controls.Actions.RemoveBookmark" = "Bỏ lưu"; "Common.Controls.Actions.Reply" = "Trả lời"; "Common.Controls.Actions.ReportUser" = "Báo cáo %@"; "Common.Controls.Actions.Save" = "Lưu"; @@ -67,6 +70,7 @@ Vui lòng kiểm tra kết nối mạng."; "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Chưa xác định"; "Common.Controls.Actions.TryAgain" = "Thử lại"; "Common.Controls.Actions.UnblockDomain" = "Bỏ chặn %@"; +"Common.Controls.Actions.Unfollow" = "Bỏ theo dõi %@"; "Common.Controls.Friendship.Block" = "Chặn"; "Common.Controls.Friendship.BlockDomain" = "Chặn %@"; "Common.Controls.Friendship.BlockUser" = "Chặn %@"; @@ -517,8 +521,8 @@ tải lên Mastodon."; "Scene.Settings.Section.SpicyZone.Signout" = "Đăng xuất"; "Scene.Settings.Section.SpicyZone.Title" = "Thú vị"; "Scene.Settings.Title" = "Cài đặt"; -"Scene.SuggestionAccount.FollowExplain" = "Khi theo dõi ai đó, bạn sẽ thấy tút của họ trong bảng tin."; -"Scene.SuggestionAccount.Title" = "Đề xuất theo dõi"; +"Scene.SuggestionAccount.FollowAll" = "Theo dõi tất cả"; +"Scene.SuggestionAccount.Title" = "Thịnh hành trên Mastodon"; "Scene.Thread.BackTitle" = "Tút"; "Scene.Thread.Title" = "Tút của %@"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "Mastodon là gì?"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.strings index 63d308741..5b4f2bd60 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.strings @@ -30,6 +30,7 @@ "Common.Controls.Actions.Add" = "添加"; "Common.Controls.Actions.Back" = "返回"; "Common.Controls.Actions.BlockDomain" = "屏蔽 %@"; +"Common.Controls.Actions.Bookmark" = "Bookmark"; "Common.Controls.Actions.Cancel" = "取消"; "Common.Controls.Actions.Compose" = "撰写"; "Common.Controls.Actions.Confirm" = "确认"; @@ -42,6 +43,7 @@ "Common.Controls.Actions.Edit" = "编辑"; "Common.Controls.Actions.EditPost" = "编辑"; "Common.Controls.Actions.FindPeople" = "查看推荐关注的用户"; +"Common.Controls.Actions.Follow" = "Follow %@"; "Common.Controls.Actions.ManuallySearch" = "手动搜索用户"; "Common.Controls.Actions.Next" = "下一个"; "Common.Controls.Actions.Ok" = "好的"; @@ -51,6 +53,7 @@ "Common.Controls.Actions.Preview" = "预览"; "Common.Controls.Actions.Previous" = "上一个"; "Common.Controls.Actions.Remove" = "删除"; +"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; "Common.Controls.Actions.Reply" = "回复"; "Common.Controls.Actions.ReportUser" = "举报 %@"; "Common.Controls.Actions.Save" = "保存"; @@ -67,6 +70,7 @@ "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "未知的"; "Common.Controls.Actions.TryAgain" = "再试一次"; "Common.Controls.Actions.UnblockDomain" = "解除屏蔽 %@"; +"Common.Controls.Actions.Unfollow" = "Unfollow %@"; "Common.Controls.Friendship.Block" = "屏蔽"; "Common.Controls.Friendship.BlockDomain" = "屏蔽 %@"; "Common.Controls.Friendship.BlockUser" = "屏蔽 %@"; @@ -181,8 +185,8 @@ "Common.Controls.Timeline.Loader.LoadingMissingPosts" = "正在加载帖子..."; "Common.Controls.Timeline.Loader.ShowMoreReplies" = "显示更多回复"; "Common.Controls.Timeline.Timestamp.Now" = "现在"; -"Common.UserList.FollowersCount" = "%@ followers"; -"Common.UserList.NoVerifiedLink" = "No verified link"; +"Common.UserList.FollowersCount" = "%@ 名关注者"; +"Common.UserList.NoVerifiedLink" = "未验证链接"; "Extension.OpenIn.InvalidLinkError" = "这似乎不是一个有效的 Mastodon 链接。"; "Scene.AccountList.AddAccount" = "添加账户"; "Scene.AccountList.DismissAccountSwitcher" = "关闭账户切换页面"; @@ -517,8 +521,8 @@ "Scene.Settings.Section.SpicyZone.Signout" = "退出"; "Scene.Settings.Section.SpicyZone.Title" = "The Spicy Zone"; "Scene.Settings.Title" = "设置"; -"Scene.SuggestionAccount.FollowExplain" = "当你关注某个人时,你将会在主页看到他们的帖子。"; -"Scene.SuggestionAccount.Title" = "查看推荐关注的用户"; +"Scene.SuggestionAccount.FollowAll" = "一键关注"; +"Scene.SuggestionAccount.Title" = "Mastodon上流行的"; "Scene.Thread.BackTitle" = "帖子"; "Scene.Thread.Title" = "来自 %@ 的帖子"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "Mastodon 是什么?"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.stringsdict index c7a332a38..f6e2ef97a 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.stringsdict @@ -162,7 +162,7 @@ NSStringFormatValueTypeKey ld other - %ld re-blogs + %ld 次转发 plural.count.reply diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.strings index 82656704e..3c7340620 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.strings @@ -30,6 +30,7 @@ "Common.Controls.Actions.Add" = "新增"; "Common.Controls.Actions.Back" = "上一頁"; "Common.Controls.Actions.BlockDomain" = "封鎖 %@"; +"Common.Controls.Actions.Bookmark" = "書籤"; "Common.Controls.Actions.Cancel" = "取消"; "Common.Controls.Actions.Compose" = "撰寫"; "Common.Controls.Actions.Confirm" = "確認"; @@ -42,6 +43,7 @@ "Common.Controls.Actions.Edit" = "編輯"; "Common.Controls.Actions.EditPost" = "編輯"; "Common.Controls.Actions.FindPeople" = "尋找一些人來跟隨"; +"Common.Controls.Actions.Follow" = "跟隨 %@"; "Common.Controls.Actions.ManuallySearch" = "手動搜尋"; "Common.Controls.Actions.Next" = "下一頁"; "Common.Controls.Actions.Ok" = "OK"; @@ -51,6 +53,7 @@ "Common.Controls.Actions.Preview" = "預覽"; "Common.Controls.Actions.Previous" = "上一步"; "Common.Controls.Actions.Remove" = "刪除"; +"Common.Controls.Actions.RemoveBookmark" = "移除書籤"; "Common.Controls.Actions.Reply" = "回覆"; "Common.Controls.Actions.ReportUser" = "檢舉 %@"; "Common.Controls.Actions.Save" = "儲存"; @@ -67,6 +70,7 @@ "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "未知"; "Common.Controls.Actions.TryAgain" = "再試一次"; "Common.Controls.Actions.UnblockDomain" = "解除封鎖 %@"; +"Common.Controls.Actions.Unfollow" = "取消跟隨 %@"; "Common.Controls.Friendship.Block" = "封鎖"; "Common.Controls.Friendship.BlockDomain" = "封鎖 %@"; "Common.Controls.Friendship.BlockUser" = "封鎖 %@"; @@ -195,7 +199,7 @@ "Scene.Compose.Accessibility.RemovePoll" = "移除投票"; "Scene.Compose.Attachment.AttachmentBroken" = "此 %@ 已損毀,並無法被上傳至 Mastodon。"; "Scene.Compose.Attachment.AttachmentTooLarge" = "附加檔案大小過大"; -"Scene.Compose.Attachment.CanNotRecognizeThisMediaAttachment" = "無法識別此媒體附加檔案"; +"Scene.Compose.Attachment.CanNotRecognizeThisMediaAttachment" = "無法識別此多媒體附加檔案"; "Scene.Compose.Attachment.CompressingState" = "正在壓縮..."; "Scene.Compose.Attachment.DescriptionPhoto" = "為視障人士提供圖片說明..."; "Scene.Compose.Attachment.DescriptionVideo" = "為視障人士提供影片說明..."; @@ -512,8 +516,8 @@ "Scene.Settings.Section.SpicyZone.Signout" = "登出"; "Scene.Settings.Section.SpicyZone.Title" = "危險地帶"; "Scene.Settings.Title" = "設定"; -"Scene.SuggestionAccount.FollowExplain" = "當您跟隨這些人時,將會看到他們的嘟文出現在您的首頁時間軸上。"; -"Scene.SuggestionAccount.Title" = "尋找一些人來跟隨"; +"Scene.SuggestionAccount.FollowAll" = "跟隨所有"; +"Scene.SuggestionAccount.Title" = "Mastodon 上之流行內容"; "Scene.Thread.BackTitle" = "嘟文"; "Scene.Thread.Title" = "來自 %@ 的嘟文"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "什麼是 Mastodon?"; diff --git a/Podfile.lock b/Podfile.lock index 354d465a6..b83291363 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -31,4 +31,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 219ef7456c1c3111c3f61653632501ce09918bf0 -COCOAPODS: 1.11.3 +COCOAPODS: 1.12.1 From a6a25426eee168abf55e0d5a72068a28049d395d Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 28 Jun 2023 18:47:58 +0200 Subject: [PATCH 14/87] Bump version --- Mastodon.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 7d3c4f611..78682c7d7 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -4571,7 +4571,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2023.10; + MARKETING_VERSION = 2023.11; PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -4603,7 +4603,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2023.10; + MARKETING_VERSION = 2023.11; PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -4790,7 +4790,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2023.10; + MARKETING_VERSION = 2023.11; PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -5081,7 +5081,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2023.10; + MARKETING_VERSION = 2023.11; PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; From bd1339e9f2d5b8d965cbbb92fa09a5bb4f255aaf Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Thu, 29 Jun 2023 02:54:10 -0400 Subject: [PATCH 15/87] Hide the entire top toolbar for videos & audio (#1070) --- Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift index ca7572bbe..f68bd1b70 100644 --- a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift +++ b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift @@ -113,12 +113,11 @@ extension MediaPreviewViewController { guard let self = self else { return } switch self.viewModel.item { case .attachment(let previewContext): - let needsHideCloseButton: Bool = { + self.topToolbar.isHidden = { guard index < previewContext.attachments.count else { return false } let attachment = previewContext.attachments[index] - return attachment.kind == .video // not hide buttno for audio + return attachment.kind == .video || attachment.kind == .audio }() - self.closeButton.isHidden = needsHideCloseButton default: break } From c7455a20b5d2ad1862c01f2e0adb36dbccd4f0e1 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Fri, 30 Jun 2023 17:17:55 -0400 Subject: [PATCH 16/87] Remove unused `DiscardPostContent` strings --- Localization/StringsConvertor/input/Base.lproj/app.json | 4 ---- Localization/app.json | 4 ---- .../Sources/MastodonLocalization/Generated/Strings.swift | 6 ------ .../Resources/Base.lproj/Localizable.strings | 2 -- 4 files changed, 16 deletions(-) diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index fc0e84c8b..08a3c8327 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -15,10 +15,6 @@ "title": "Vote Failure", "poll_ended": "The poll has ended" }, - "discard_post_content": { - "title": "Discard Draft", - "message": "Confirm to discard composed post content." - }, "publish_post_failure": { "title": "Publish Failure", "message": "Failed to publish the post.\nPlease check your internet connection.", diff --git a/Localization/app.json b/Localization/app.json index fc0e84c8b..08a3c8327 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -15,10 +15,6 @@ "title": "Vote Failure", "poll_ended": "The poll has ended" }, - "discard_post_content": { - "title": "Discard Draft", - "message": "Confirm to discard composed post content." - }, "publish_post_failure": { "title": "Publish Failure", "message": "Failed to publish the post.\nPlease check your internet connection.", diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index a140c1f4e..c87f9688a 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -40,12 +40,6 @@ public enum L10n { /// Delete Post public static let title = L10n.tr("Localizable", "Common.Alerts.DeletePost.Title", fallback: "Delete Post") } - public enum DiscardPostContent { - /// Confirm to discard composed post content. - public static let message = L10n.tr("Localizable", "Common.Alerts.DiscardPostContent.Message", fallback: "Confirm to discard composed post content.") - /// Discard Draft - public static let title = L10n.tr("Localizable", "Common.Alerts.DiscardPostContent.Title", fallback: "Discard Draft") - } public enum EditProfileFailure { /// Cannot edit profile. Please try again. public static let message = L10n.tr("Localizable", "Common.Alerts.EditProfileFailure.Message", fallback: "Cannot edit profile. Please try again.") diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 970175d5c..c568e4613 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "Please try again later."; "Common.Alerts.DeletePost.Message" = "Are you sure you want to delete this post?"; "Common.Alerts.DeletePost.Title" = "Delete Post"; -"Common.Alerts.DiscardPostContent.Message" = "Confirm to discard composed post content."; -"Common.Alerts.DiscardPostContent.Title" = "Discard Draft"; "Common.Alerts.EditProfileFailure.Message" = "Cannot edit profile. Please try again."; "Common.Alerts.EditProfileFailure.Title" = "Edit Profile Error"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "Cannot attach more than one video."; From dd953d69eaf140b942456cce852db1a73e60a631 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Fri, 30 Jun 2023 17:38:00 -0400 Subject: [PATCH 17/87] Fix comparison of current content with initial content --- .../Scene/ComposeContent/ComposeContentViewModel.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift index 4e5c217ba..12b45204f 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift @@ -479,7 +479,9 @@ extension ComposeContentViewModel { return true } // if the trimmed content equal to initial content - return content.trimmingCharacters(in: .whitespacesAndNewlines) == self.initialContent + let trimmedContent = content.trimmingCharacters(in: .whitespacesAndNewlines) + let initialContent = self.initialContent.trimmingCharacters(in: .whitespacesAndNewlines) + return trimmedContent == initialContent } .assign(to: &$shouldDismiss) From f8617ac8f2b2d9bc429499513f5fa3da18adde68 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Fri, 30 Jun 2023 17:44:44 -0400 Subject: [PATCH 18/87] =?UTF-8?q?Don=E2=80=99t=20insta-discard=20if=20ther?= =?UTF-8?q?e=20is=20a=20CW/poll/attachment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ComposeContentViewModel.swift | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift index 12b45204f..c2e13fb40 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift @@ -472,18 +472,27 @@ extension ComposeContentViewModel { .assign(to: &$isPublishBarButtonItemEnabled) // bind modal dismiss state - $content - .receive(on: DispatchQueue.main) - .map { content in - if content.isEmpty { - return true - } - // if the trimmed content equal to initial content - let trimmedContent = content.trimmingCharacters(in: .whitespacesAndNewlines) - let initialContent = self.initialContent.trimmingCharacters(in: .whitespacesAndNewlines) - return trimmedContent == initialContent - } - .assign(to: &$shouldDismiss) + Publishers.CombineLatest4( + $contentWarning, + $content, + $isPollActive, + $attachmentViewModels + ) + .receive(on: DispatchQueue.main) + .map { contentWarning, content, hasPoll, attachments in + let canDiscardContentWarning = contentWarning.isEmpty + + let trimmedContent = content.trimmingCharacters(in: .whitespacesAndNewlines) + let initialContent = self.initialContent.trimmingCharacters(in: .whitespacesAndNewlines) + let canDiscardContent = trimmedContent.isEmpty || trimmedContent == initialContent + + let canDiscardPoll = !hasPoll + + let canDiscardAttachments = attachments.isEmpty + + return canDiscardContent && canDiscardPoll && canDiscardAttachments + } + .assign(to: &$shouldDismiss) // languages context.settingService.currentSetting From 18895a373b1991c866a3304042318bbf8d69c52c Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sun, 2 Jul 2023 12:39:27 +0200 Subject: [PATCH 19/87] Download default servers (IOS-171) --- .../API/Mastodon+API+Onboarding.swift | 25 +++++++++++++++++++ .../MastodonSDK/API/Mastodon+API.swift | 10 ++++---- .../Mastodon+Entity+DefaultServer.swift | 10 ++++++++ 3 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+DefaultServer.swift diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Onboarding.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Onboarding.swift index 0c816b142..dcbd6e9b9 100644 --- a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Onboarding.swift +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Onboarding.swift @@ -13,6 +13,7 @@ extension Mastodon.API.Onboarding { static let serversEndpointURL = Mastodon.API.joinMastodonEndpointURL.appendingPathComponent("servers") static let categoriesEndpointURL = Mastodon.API.joinMastodonEndpointURL.appendingPathComponent("categories") static let languagesEndpointURL = Mastodon.API.joinMastodonEndpointURL.appendingPathComponent("languages") + static let defaultServersEndpointURL = Mastodon.API.joinMastodonEndpointURL.appendingPathComponent("default-servers") /// Fetch server list /// @@ -96,6 +97,30 @@ extension Mastodon.API.Onboarding { } .eraseToAnyPublisher() } + + /// Fetch default servers + /// + /// Using this endpoint to fetch default servers + /// + /// # Last Update + /// 2023/07/02 + /// # Reference + /// undocumented + /// - Parameters: + /// - session: `URLSession` + /// - Returns: `AnyPublisher` contains `Language` nested in the response + public static func defaultServers( + session: URLSession + ) -> AnyPublisher, Error> { + let request = Mastodon.API.get(url: defaultServersEndpointURL) + return session.dataTaskPublisher(for: request) + .tryMap { data, response in + let value = try Mastodon.API.decode(type: [Mastodon.Entity.DefaultServer].self, from: data, response: response) + return Mastodon.Response.Content(value: value, response: response) + } + .eraseToAnyPublisher() + } + } extension Mastodon.API.Onboarding { diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift index d0c9d39af..76bebe5a0 100644 --- a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift @@ -134,7 +134,7 @@ extension Mastodon.API { static func get( url: URL, query: GetQuery? = nil, - authorization: OAuth.Authorization? + authorization: OAuth.Authorization? = nil ) -> URLRequest { return buildRequest(url: url, method: .GET, query: query, authorization: authorization) } @@ -142,7 +142,7 @@ extension Mastodon.API { static func post( url: URL, query: PostQuery?, - authorization: OAuth.Authorization? + authorization: OAuth.Authorization? = nil ) -> URLRequest { return buildRequest(url: url, method: .POST, query: query, authorization: authorization) } @@ -150,7 +150,7 @@ extension Mastodon.API { static func patch( url: URL, query: PatchQuery?, - authorization: OAuth.Authorization? + authorization: OAuth.Authorization? = nil ) -> URLRequest { return buildRequest(url: url, method: .PATCH, query: query, authorization: authorization) } @@ -158,7 +158,7 @@ extension Mastodon.API { static func put( url: URL, query: PutQuery? = nil, - authorization: OAuth.Authorization? + authorization: OAuth.Authorization? = nil ) -> URLRequest { return buildRequest(url: url, method: .PUT, query: query, authorization: authorization) } @@ -166,7 +166,7 @@ extension Mastodon.API { static func delete( url: URL, query: DeleteQuery?, - authorization: OAuth.Authorization? + authorization: OAuth.Authorization? = nil ) -> URLRequest { return buildRequest(url: url, method: .DELETE, query: query, authorization: authorization) } diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+DefaultServer.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+DefaultServer.swift new file mode 100644 index 000000000..960afad86 --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+DefaultServer.swift @@ -0,0 +1,10 @@ +// Copyright © 2023 Mastodon gGmbH. All rights reserved. + +import Foundation + +extension Mastodon.Entity { + public struct DefaultServer: Codable { + let domain: String + let weight: Int + } +} From fcb5275dc8fb785b5da943d257f0a2dd6838872d Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sun, 2 Jul 2023 14:26:21 +0200 Subject: [PATCH 20/87] Use download of default servers (IOS-171) --- .../MastodonCore/Service/API/APIService+Onboarding.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Onboarding.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Onboarding.swift index 3af6a030e..d554e9d62 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Onboarding.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Onboarding.swift @@ -33,4 +33,8 @@ extension APIService { public func languages() -> AnyPublisher, Error> { return Mastodon.API.Onboarding.languages(session: session) } + + public func defaultServers() -> AnyPublisher, Error> { + return Mastodon.API.Onboarding.defaultServers(session: session) + } } From 4b5151bb396add473519bf2c14917a98a08f68b3 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sun, 2 Jul 2023 14:43:49 +0200 Subject: [PATCH 21/87] Get servers and choose one randomly for signup (IOS-171) Server list from backend has a weight which plays a role in which server gets selected. mastodon.social is the fallback in case something goes wrong --- Localization/app.json | 2 +- .../Welcome/WelcomeViewController.swift | 54 +++++++++++++------ .../Onboarding/Welcome/WelcomeViewModel.swift | 42 ++++++++++++++- .../Generated/Strings.swift | 6 ++- .../Resources/Base.lproj/Localizable.strings | 4 +- .../Resources/en.lproj/Localizable.strings | 4 +- .../Mastodon+Entity+DefaultServer.swift | 9 +++- 7 files changed, 93 insertions(+), 28 deletions(-) diff --git a/Localization/app.json b/Localization/app.json index fc0e84c8b..ff84b8853 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -270,7 +270,7 @@ "welcome": { "log_in": "Log In", "learn_more": "Learn more", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift b/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift index 9ebbc43e1..dcf7c295c 100644 --- a/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift +++ b/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift @@ -47,10 +47,6 @@ final class WelcomeViewController: UIViewController, NeedsDependency { private(set) lazy var joinDefaultServerButton: UIButton = { var buttonConfiguration = UIButton.Configuration.filled() - buttonConfiguration.attributedTitle = AttributedString( - L10n.Scene.Welcome.joinDefaultServer, - attributes: .init([.font: UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 17, weight: .semibold))]) - ) buttonConfiguration.baseForegroundColor = .white buttonConfiguration.background.backgroundColor = Asset.Colors.Brand.blurple.color buttonConfiguration.background.cornerRadius = 14 @@ -217,6 +213,23 @@ extension WelcomeViewController { .store(in: &disposeBag) setupIllustrationLayout() + + joinDefaultServerButton.configuration?.showsActivityIndicator = true + joinDefaultServerButton.isEnabled = false + joinDefaultServerButton.configuration?.title = nil + + viewModel.downloadDefaultServer { [weak self] in + guard let selectedDefaultServer = self?.viewModel.randomDefaultServer else { return } + + DispatchQueue.main.async { + self?.joinDefaultServerButton.configuration?.showsActivityIndicator = false + self?.joinDefaultServerButton.isEnabled = true + self?.joinDefaultServerButton.configuration?.attributedTitle = AttributedString( + L10n.Scene.Welcome.joinDefaultServer(selectedDefaultServer.domain), + attributes: .init([.font: UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 17, weight: .semibold))]) + ) + } + } } override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { @@ -262,12 +275,12 @@ extension WelcomeViewController { //MARK: - Actions @objc private func joinDefaultServer(_ sender: UIButton) { + + guard let server = viewModel.randomDefaultServer else { return } sender.configuration?.title = nil sender.isEnabled = false sender.configuration?.showsActivityIndicator = true - let server = Mastodon.Entity.Server.mastodonDotSocial - authenticationViewModel.isAuthenticating.send(true) context.apiService.instance(domain: server.domain) @@ -320,19 +333,26 @@ extension WelcomeViewController { self.authenticationViewModel.isAuthenticating.send(false) switch completion { - case .failure(let error): - //TODO: show an alert or something - break - case .finished: - break + case .failure(let error ): + guard let randomServer = self.viewModel.pickRandomDefaultServer() else { return } + + viewModel.randomDefaultServer = randomServer + + sender.isEnabled = true + sender.configuration?.showsActivityIndicator = false + sender.configuration?.attributedTitle = AttributedString( + L10n.Scene.Welcome.joinDefaultServer(randomServer.domain), + attributes: .init([.font: UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 17, weight: .semibold))]) + ) + case .finished: + sender.isEnabled = true + sender.configuration?.showsActivityIndicator = false + sender.configuration?.attributedTitle = AttributedString( + L10n.Scene.Welcome.joinDefaultServer(server.domain), + attributes: .init([.font: UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 17, weight: .semibold))]) + ) } - sender.isEnabled = true - sender.configuration?.showsActivityIndicator = false - sender.configuration?.attributedTitle = AttributedString( - L10n.Scene.Welcome.joinDefaultServer, - attributes: .init([.font: UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 17, weight: .semibold))]) - ) } receiveValue: { [weak self] response in guard let self = self else { return } if let rules = response.instance.value.rules, !rules.isEmpty { diff --git a/Mastodon/Scene/Onboarding/Welcome/WelcomeViewModel.swift b/Mastodon/Scene/Onboarding/Welcome/WelcomeViewModel.swift index e835027f3..dde2464f9 100644 --- a/Mastodon/Scene/Onboarding/Welcome/WelcomeViewModel.swift +++ b/Mastodon/Scene/Onboarding/Welcome/WelcomeViewModel.swift @@ -8,11 +8,14 @@ import Foundation import Combine import MastodonCore +import MastodonSDK final class WelcomeViewModel { var disposeBag = Set() - + private(set) var defaultServers: [Mastodon.Entity.DefaultServer]? + var randomDefaultServer: Mastodon.Entity.Server? + // input let context: AppContext @@ -26,5 +29,40 @@ final class WelcomeViewModel { .map { !$0.isEmpty } .assign(to: &$needsShowDismissEntry) } - + + func downloadDefaultServer(completion: (() -> Void)? = nil) { + context.apiService.defaultServers() + .timeout(.milliseconds(500) , scheduler: DispatchQueue.main) + .sink { [weak self] result in + + switch result { + case .finished: + if let defaultServers = self?.defaultServers, defaultServers.isEmpty == false { + self?.randomDefaultServer = self?.pickRandomDefaultServer() + } else { + self?.randomDefaultServer = Mastodon.Entity.Server.mastodonDotSocial + } + case .failure(_): + self?.randomDefaultServer = Mastodon.Entity.Server.mastodonDotSocial + } + + completion?() + } receiveValue: { [weak self] servers in + self?.defaultServers = servers.value + } + .store(in: &disposeBag) + } + + func pickRandomDefaultServer() -> Mastodon.Entity.Server? { + guard let defaultServers else { return nil } + + let weightedServers = defaultServers + .compactMap { [Mastodon.Entity.DefaultServer](repeating: $0, count: $0.weight) } + .reduce([], +) + + let randomServer = weightedServers.randomElement() + .map { Mastodon.Entity.Server(domain: $0.domain, instance: Mastodon.Entity.Instance(domain: $0.domain)) } + + return randomServer + } } diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index a140c1f4e..05bf74a7a 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -1510,8 +1510,10 @@ public enum L10n { } } public enum Welcome { - /// Join mastodon.social - public static let joinDefaultServer = L10n.tr("Localizable", "Scene.Welcome.JoinDefaultServer", fallback: "Join mastodon.social") + /// Join %@ + public static func joinDefaultServer(_ p1: Any) -> String { + return L10n.tr("Localizable", "Scene.Welcome.JoinDefaultServer", String(describing: p1), fallback: "Join %@") + } /// Learn more public static let learnMore = L10n.tr("Localizable", "Scene.Welcome.LearnMore", fallback: "Learn more") /// Log In diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 970175d5c..8f277893c 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -530,7 +530,7 @@ uploaded to Mastodon."; "Scene.Welcome.Education.Mastodon.Title" = "Welcome to Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Every Mastodon account is hosted on a server — each with its own values, rules, & admins. No matter which one you pick, you can follow and interact with people on any server."; "Scene.Welcome.Education.Servers.Title" = "What are servers?"; -"Scene.Welcome.JoinDefaultServer" = "Join mastodon.social"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "Learn more"; "Scene.Welcome.LogIn" = "Log In"; "Scene.Welcome.PickServer" = "Pick another server"; @@ -556,4 +556,4 @@ uploaded to Mastodon."; "Widget.MultipleFollowers.ConfigurationDescription" = "Show number of followers for multiple accounts."; "Widget.MultipleFollowers.ConfigurationDisplayName" = "Multiple followers"; "Widget.MultipleFollowers.MockUser.AccountName" = "another@follower.social"; -"Widget.MultipleFollowers.MockUser.DisplayName" = "Another follower"; \ No newline at end of file +"Widget.MultipleFollowers.MockUser.DisplayName" = "Another follower"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings index 970175d5c..8f277893c 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings @@ -530,7 +530,7 @@ uploaded to Mastodon."; "Scene.Welcome.Education.Mastodon.Title" = "Welcome to Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Every Mastodon account is hosted on a server — each with its own values, rules, & admins. No matter which one you pick, you can follow and interact with people on any server."; "Scene.Welcome.Education.Servers.Title" = "What are servers?"; -"Scene.Welcome.JoinDefaultServer" = "Join mastodon.social"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "Learn more"; "Scene.Welcome.LogIn" = "Log In"; "Scene.Welcome.PickServer" = "Pick another server"; @@ -556,4 +556,4 @@ uploaded to Mastodon."; "Widget.MultipleFollowers.ConfigurationDescription" = "Show number of followers for multiple accounts."; "Widget.MultipleFollowers.ConfigurationDisplayName" = "Multiple followers"; "Widget.MultipleFollowers.MockUser.AccountName" = "another@follower.social"; -"Widget.MultipleFollowers.MockUser.DisplayName" = "Another follower"; \ No newline at end of file +"Widget.MultipleFollowers.MockUser.DisplayName" = "Another follower"; diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+DefaultServer.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+DefaultServer.swift index 960afad86..75d56dde2 100644 --- a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+DefaultServer.swift +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+DefaultServer.swift @@ -4,7 +4,12 @@ import Foundation extension Mastodon.Entity { public struct DefaultServer: Codable { - let domain: String - let weight: Int + public let domain: String + public let weight: Int + + public init(domain: String, weight: Int) { + self.domain = domain + self.weight = weight + } } } From 06e9e3c99048e1d9ddef3ea846534c16b6c8a53d Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sun, 2 Jul 2023 14:52:34 +0200 Subject: [PATCH 22/87] Fix build :facepalm: (IOS-171) --- Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift b/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift index dcf7c295c..506487504 100644 --- a/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift +++ b/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift @@ -336,7 +336,7 @@ extension WelcomeViewController { case .failure(let error ): guard let randomServer = self.viewModel.pickRandomDefaultServer() else { return } - viewModel.randomDefaultServer = randomServer + self.viewModel.randomDefaultServer = randomServer sender.isEnabled = true sender.configuration?.showsActivityIndicator = false From 2711af501157461fffc05a9360620e7c6e3a66ef Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 2 Jul 2023 16:55:13 +0200 Subject: [PATCH 23/87] New Crowdin updates (#1075) --- .../StringsConvertor/input/an.lproj/app.json | 2 +- .../StringsConvertor/input/ar.lproj/app.json | 2 +- .../StringsConvertor/input/be.lproj/app.json | 2 +- .../StringsConvertor/input/ca.lproj/app.json | 2 +- .../StringsConvertor/input/ckb.lproj/app.json | 2 +- .../StringsConvertor/input/cs.lproj/app.json | 2 +- .../StringsConvertor/input/cy.lproj/app.json | 2 +- .../StringsConvertor/input/da.lproj/app.json | 2 +- .../StringsConvertor/input/de.lproj/app.json | 2 +- .../StringsConvertor/input/el.lproj/app.json | 88 +++++++++---------- .../input/en-US.lproj/app.json | 2 +- .../StringsConvertor/input/en.lproj/app.json | 2 +- .../input/es-AR.lproj/app.json | 2 +- .../StringsConvertor/input/es.lproj/app.json | 2 +- .../StringsConvertor/input/eu.lproj/app.json | 2 +- .../StringsConvertor/input/fi.lproj/app.json | 2 +- .../StringsConvertor/input/fr.lproj/app.json | 2 +- .../StringsConvertor/input/gd.lproj/app.json | 2 +- .../StringsConvertor/input/gl.lproj/app.json | 2 +- .../StringsConvertor/input/he.lproj/app.json | 2 +- .../StringsConvertor/input/hi.lproj/app.json | 2 +- .../StringsConvertor/input/id.lproj/app.json | 2 +- .../StringsConvertor/input/is.lproj/app.json | 2 +- .../StringsConvertor/input/it.lproj/app.json | 2 +- .../StringsConvertor/input/ja.lproj/app.json | 2 +- .../StringsConvertor/input/kab.lproj/app.json | 2 +- .../StringsConvertor/input/kmr.lproj/app.json | 2 +- .../StringsConvertor/input/ko.lproj/app.json | 2 +- .../StringsConvertor/input/lv.lproj/app.json | 2 +- .../StringsConvertor/input/my.lproj/app.json | 2 +- .../StringsConvertor/input/nl.lproj/app.json | 2 +- .../StringsConvertor/input/pl.lproj/app.json | 2 +- .../input/pt-BR.lproj/app.json | 2 +- .../StringsConvertor/input/pt.lproj/app.json | 2 +- .../StringsConvertor/input/ro.lproj/app.json | 2 +- .../StringsConvertor/input/ru.lproj/app.json | 2 +- .../StringsConvertor/input/si.lproj/app.json | 2 +- .../StringsConvertor/input/sl.lproj/app.json | 2 +- .../StringsConvertor/input/sv.lproj/app.json | 2 +- .../StringsConvertor/input/th.lproj/app.json | 2 +- .../StringsConvertor/input/tr.lproj/app.json | 2 +- .../StringsConvertor/input/uk.lproj/app.json | 2 +- .../StringsConvertor/input/vi.lproj/app.json | 2 +- .../input/zh-Hans.lproj/app.json | 2 +- .../input/zh-Hant.lproj/app.json | 2 +- 45 files changed, 88 insertions(+), 88 deletions(-) diff --git a/Localization/StringsConvertor/input/an.lproj/app.json b/Localization/StringsConvertor/input/an.lproj/app.json index 8b04b3e3e..398e163d8 100644 --- a/Localization/StringsConvertor/input/an.lproj/app.json +++ b/Localization/StringsConvertor/input/an.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Iniciar sesión", "learn_more": "Learn more", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/ar.lproj/app.json b/Localization/StringsConvertor/input/ar.lproj/app.json index 1f6dd9504..24d446a3e 100644 --- a/Localization/StringsConvertor/input/ar.lproj/app.json +++ b/Localization/StringsConvertor/input/ar.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "تسجيلُ الدخول", "learn_more": "Learn more", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/be.lproj/app.json b/Localization/StringsConvertor/input/be.lproj/app.json index ec33e07c4..819c56e63 100644 --- a/Localization/StringsConvertor/input/be.lproj/app.json +++ b/Localization/StringsConvertor/input/be.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Увайсці", "learn_more": "Даведацца больш", - "join_default_server": "Далучайцеся да mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "або" diff --git a/Localization/StringsConvertor/input/ca.lproj/app.json b/Localization/StringsConvertor/input/ca.lproj/app.json index d151bacfb..b44017705 100644 --- a/Localization/StringsConvertor/input/ca.lproj/app.json +++ b/Localization/StringsConvertor/input/ca.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Inicia sessió", "learn_more": "Més informació", - "join_default_server": "Uneix-te a mastodon.social", + "join_default_server": "Join %@", "pick_server": "Tria un altre servidor", "separator": { "or": "o" diff --git a/Localization/StringsConvertor/input/ckb.lproj/app.json b/Localization/StringsConvertor/input/ckb.lproj/app.json index ae2f8bfae..80af30fc1 100644 --- a/Localization/StringsConvertor/input/ckb.lproj/app.json +++ b/Localization/StringsConvertor/input/ckb.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "بچۆ ژوورەوە", "learn_more": "Learn more", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/cs.lproj/app.json b/Localization/StringsConvertor/input/cs.lproj/app.json index e42a741e4..96cd1fbb2 100644 --- a/Localization/StringsConvertor/input/cs.lproj/app.json +++ b/Localization/StringsConvertor/input/cs.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Přihlásit se", "learn_more": "Zjistit více", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json index c39f7e60e..7eddc6e8a 100644 --- a/Localization/StringsConvertor/input/cy.lproj/app.json +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Mewngofnodi", "learn_more": "Dysgu mwy", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/da.lproj/app.json b/Localization/StringsConvertor/input/da.lproj/app.json index 51ba05829..8b2e51f11 100644 --- a/Localization/StringsConvertor/input/da.lproj/app.json +++ b/Localization/StringsConvertor/input/da.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Log In", "learn_more": "Learn more", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/de.lproj/app.json b/Localization/StringsConvertor/input/de.lproj/app.json index bc4452e8d..5b8ca6ec3 100644 --- a/Localization/StringsConvertor/input/de.lproj/app.json +++ b/Localization/StringsConvertor/input/de.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Anmelden", "learn_more": "Mehr erfahren", - "join_default_server": "mastodon.social beitreten", + "join_default_server": "Join %@", "pick_server": "Einen anderen Server auswählen", "separator": { "or": "oder" diff --git a/Localization/StringsConvertor/input/el.lproj/app.json b/Localization/StringsConvertor/input/el.lproj/app.json index 33038b39e..f570e8534 100644 --- a/Localization/StringsConvertor/input/el.lproj/app.json +++ b/Localization/StringsConvertor/input/el.lproj/app.json @@ -102,10 +102,10 @@ "unknown_language": "Άγνωστο" }, "edit_post": "Επεξεργασία", - "bookmark": "Bookmark", - "remove_bookmark": "Remove Bookmark", - "follow": "Follow %s", - "unfollow": "Unfollow %s" + "bookmark": "Σελιδοδείκτης", + "remove_bookmark": "Αφαίρεση σελιδοδείκτη", + "follow": "Ακολούθησε %s", + "unfollow": "Κατάργηση ακολούθησης του %s" }, "tabs": { "home": "Αρχική", @@ -132,8 +132,8 @@ "open_reblogger_profile": "Άνοιγμα Προφίλ Του Reblogger", "reply_status": "Απάντηση στην Ανάρτηση", "toggle_reblog": "Εναλλαγή Αναδημοσίευσης στην Ανάρτηση", - "toggle_favorite": "Toggle Favorite on Post", - "toggle_content_warning": "Toggle Content Warning", + "toggle_favorite": "Εναλλαγή Αγαπημένου στην Ανάρτηση", + "toggle_content_warning": "Εναλλαγή Προειδοποίησης Περιεχομένου", "preview_image": "Προεπισκόπηση Εικόνας" }, "segmented_control": { @@ -201,57 +201,57 @@ "show_original": "Εμφάνιση Αρχικού" }, "media": { - "accessibility_label": "%s, attachment %d of %d", - "expand_image_hint": "Expands the image. Double-tap and hold to show actions", - "expand_gif_hint": "Expands the GIF. Double-tap and hold to show actions", - "expand_video_hint": "Shows the video player. Double-tap and hold to show actions" + "accessibility_label": "%s, συνημμένο %d από %d", + "expand_image_hint": "Επεκτείνει την εικόνα. Πάτα δύο φορές και κράτα πατημένο για εμφάνιση ενεργειών", + "expand_gif_hint": "Επεκτείνει το GIF. Πάτα δύο φορές και κράτα πατημένο για να εμφανίσεις τις ενέργειες", + "expand_video_hint": "Εμφανίζει το πρόγραμμα αναπαραγωγής βίντεο. Πάτα δύο φορές και κράτα πατημένο για να δείς τις ενέργειες" }, - "posted_via_application": "%s via %s", + "posted_via_application": "%s μέσω %s", "buttons": { - "reblogs_title": "Reblogs", - "favorites_title": "Favorites", - "edit_history_title": "Edit History", - "edit_history_detail": "Last edit %s" + "reblogs_title": "Αναδημοσιεύσεις", + "favorites_title": "Αγαπημένα", + "edit_history_title": "Επεξεργασία Ιστορικού", + "edit_history_detail": "Τελευταία επεξεργασία %s" }, - "edited_at_timestamp_prefix": "Edited %s", + "edited_at_timestamp_prefix": "Επεξεργάστηκε στις %s", "edit_history": { - "title": "Edit History", - "original_post": "Original Post · %s" + "title": "Επεξεργασία Ιστορικού", + "original_post": "Αρχική Ανάρτηση · %s" } }, "friendship": { - "follow": "Follow", - "following": "Following", - "request": "Request", - "pending": "Pending", - "block": "Block", - "block_user": "Block %s", - "block_domain": "Block %s", - "unblock": "Unblock", - "unblock_user": "Unblock %s", - "blocked": "Blocked", - "mute": "Mute", - "mute_user": "Mute %s", - "unmute": "Unmute", - "unmute_user": "Unmute %s", - "muted": "Muted", - "edit_info": "Edit Info", - "show_reblogs": "Show Reblogs", - "hide_reblogs": "Hide Reblogs" + "follow": "Ακολούθησε", + "following": "Ακολουθείς", + "request": "Αίτημα", + "pending": "Εκκρεμεί", + "block": "Αποκλεισμός", + "block_user": "Αποκλεισμός %s", + "block_domain": "Αποκλεισμός %s", + "unblock": "Άρση αποκλεισμού", + "unblock_user": "Άρση αποκλεισμού %s", + "blocked": "Αποκλείστηκε", + "mute": "Σίγαση", + "mute_user": "Σίγαση %s", + "unmute": "Κατάργηση σίγασης", + "unmute_user": "Κατάργηση σίγασης %s", + "muted": "Σε Σίγαση", + "edit_info": "Επεξεργασία Πληροφοριών", + "show_reblogs": "Εμφάνιση Αναδημοσιεύσεων", + "hide_reblogs": "Απόκρυψη Αναδημοσιεύσεων" }, "timeline": { - "filtered": "Filtered", + "filtered": "Φιλτραρισμένα", "timestamp": { - "now": "Now" + "now": "Τώρα" }, "loader": { - "load_missing_posts": "Load missing posts", - "loading_missing_posts": "Loading missing posts...", - "show_more_replies": "Show more replies" + "load_missing_posts": "Φόρτωση αναρτήσεων που λείπουν", + "loading_missing_posts": "Φόρτωση αναρτήσεων που λείπουν...", + "show_more_replies": "Εμφάνιση περισσότερων απαντήσεων" }, "header": { - "no_status_found": "No Post Found", - "blocking_warning": "You can’t view this user's profile\nuntil you unblock them.\nYour profile looks like this to them.", + "no_status_found": "Δεν Βρέθηκε Ανάρτηση", + "blocking_warning": "Δεν μπορείς να δεις το προφίλ αυτού του χρήστη\nμέχρι να τον ξεμπλοκάρεις.\nΤο προφίλ σου μοιάζει έτσι και σε αυτόν.", "user_blocking_warning": "You can’t view %s’s profile\nuntil you unblock them.\nYour profile looks like this to them.", "blocked_warning": "You can’t view this user’s profile\nuntil they unblock you.", "user_blocked_warning": "You can’t view %s’s profile\nuntil they unblock you.", @@ -269,7 +269,7 @@ "welcome": { "log_in": "Log In", "learn_more": "Learn more", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/en-US.lproj/app.json b/Localization/StringsConvertor/input/en-US.lproj/app.json index 5c798e695..76d932356 100644 --- a/Localization/StringsConvertor/input/en-US.lproj/app.json +++ b/Localization/StringsConvertor/input/en-US.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Log In", "learn_more": "Learn more", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/en.lproj/app.json b/Localization/StringsConvertor/input/en.lproj/app.json index 5c798e695..76d932356 100644 --- a/Localization/StringsConvertor/input/en.lproj/app.json +++ b/Localization/StringsConvertor/input/en.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Log In", "learn_more": "Learn more", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/es-AR.lproj/app.json b/Localization/StringsConvertor/input/es-AR.lproj/app.json index 5d1526dba..4b2be65bd 100644 --- a/Localization/StringsConvertor/input/es-AR.lproj/app.json +++ b/Localization/StringsConvertor/input/es-AR.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Iniciar sesión", "learn_more": "Aprendé más", - "join_default_server": "Unite a mastodon.social", + "join_default_server": "Join %@", "pick_server": "Elegí otro servidor", "separator": { "or": "o" diff --git a/Localization/StringsConvertor/input/es.lproj/app.json b/Localization/StringsConvertor/input/es.lproj/app.json index c5be64866..2298eda97 100644 --- a/Localization/StringsConvertor/input/es.lproj/app.json +++ b/Localization/StringsConvertor/input/es.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Iniciar sesión", "learn_more": "Learn more", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/eu.lproj/app.json b/Localization/StringsConvertor/input/eu.lproj/app.json index 971204abc..ec716e2b7 100644 --- a/Localization/StringsConvertor/input/eu.lproj/app.json +++ b/Localization/StringsConvertor/input/eu.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Hasi saioa", "learn_more": "Learn more", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/fi.lproj/app.json b/Localization/StringsConvertor/input/fi.lproj/app.json index b4961b466..c091d7e3e 100644 --- a/Localization/StringsConvertor/input/fi.lproj/app.json +++ b/Localization/StringsConvertor/input/fi.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Kirjaudu sisään", "learn_more": "Lue lisää", - "join_default_server": "Liity mastodon.social-palvelimelle", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "tai" diff --git a/Localization/StringsConvertor/input/fr.lproj/app.json b/Localization/StringsConvertor/input/fr.lproj/app.json index f42e7cbc2..ec296540c 100644 --- a/Localization/StringsConvertor/input/fr.lproj/app.json +++ b/Localization/StringsConvertor/input/fr.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Se connecter", "learn_more": "En savoir plus", - "join_default_server": "Rejoindre mastodon.social", + "join_default_server": "Join %@", "pick_server": "Trouver un autre serveur", "separator": { "or": "ou" diff --git a/Localization/StringsConvertor/input/gd.lproj/app.json b/Localization/StringsConvertor/input/gd.lproj/app.json index ec503a5a1..ffa67fbbc 100644 --- a/Localization/StringsConvertor/input/gd.lproj/app.json +++ b/Localization/StringsConvertor/input/gd.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Clàraich a-steach", "learn_more": "Barrachd fiosrachaidh", - "join_default_server": "Faigh ballrachd air mastodon.social", + "join_default_server": "Join %@", "pick_server": "Tagh frithealaiche eile", "separator": { "or": "no" diff --git a/Localization/StringsConvertor/input/gl.lproj/app.json b/Localization/StringsConvertor/input/gl.lproj/app.json index b731358ac..ba529ab2f 100644 --- a/Localization/StringsConvertor/input/gl.lproj/app.json +++ b/Localization/StringsConvertor/input/gl.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Acceder", "learn_more": "Saber máis", - "join_default_server": "Únete a mastodon.social", + "join_default_server": "Join %@", "pick_server": "Elixe outro servidor", "separator": { "or": "ou" diff --git a/Localization/StringsConvertor/input/he.lproj/app.json b/Localization/StringsConvertor/input/he.lproj/app.json index 12afb59f2..44c3608ed 100644 --- a/Localization/StringsConvertor/input/he.lproj/app.json +++ b/Localization/StringsConvertor/input/he.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Log In", "learn_more": "Learn more", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/hi.lproj/app.json b/Localization/StringsConvertor/input/hi.lproj/app.json index fa65fb89a..df2c9c5a9 100644 --- a/Localization/StringsConvertor/input/hi.lproj/app.json +++ b/Localization/StringsConvertor/input/hi.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Log In", "learn_more": "Learn more", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/id.lproj/app.json b/Localization/StringsConvertor/input/id.lproj/app.json index 878e8743c..d32eb4d1b 100644 --- a/Localization/StringsConvertor/input/id.lproj/app.json +++ b/Localization/StringsConvertor/input/id.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Login", "learn_more": "Learn more", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/is.lproj/app.json b/Localization/StringsConvertor/input/is.lproj/app.json index 4a58e3e6d..0cc337bda 100644 --- a/Localization/StringsConvertor/input/is.lproj/app.json +++ b/Localization/StringsConvertor/input/is.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Skrá inn", "learn_more": "Kanna nánar", - "join_default_server": "Taka þátt á mastodon.social", + "join_default_server": "Join %@", "pick_server": "Veldu annan netþjón", "separator": { "or": "eða" diff --git a/Localization/StringsConvertor/input/it.lproj/app.json b/Localization/StringsConvertor/input/it.lproj/app.json index 6a2077672..fc4162c50 100644 --- a/Localization/StringsConvertor/input/it.lproj/app.json +++ b/Localization/StringsConvertor/input/it.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Accedi", "learn_more": "Scopri di più", - "join_default_server": "Unisciti a mastodon.social", + "join_default_server": "Join %@", "pick_server": "Scegli un altro server", "separator": { "or": "o" diff --git a/Localization/StringsConvertor/input/ja.lproj/app.json b/Localization/StringsConvertor/input/ja.lproj/app.json index 5fa24cf06..d0190b313 100644 --- a/Localization/StringsConvertor/input/ja.lproj/app.json +++ b/Localization/StringsConvertor/input/ja.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "ログイン", "learn_more": "詳しく学ぶ", - "join_default_server": "mastodon.social に登録", + "join_default_server": "Join %@", "pick_server": "ほかのサーバーをさがす", "separator": { "or": "または" diff --git a/Localization/StringsConvertor/input/kab.lproj/app.json b/Localization/StringsConvertor/input/kab.lproj/app.json index d7715c685..2f933def1 100644 --- a/Localization/StringsConvertor/input/kab.lproj/app.json +++ b/Localization/StringsConvertor/input/kab.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Qqen", "learn_more": "Learn more", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/kmr.lproj/app.json b/Localization/StringsConvertor/input/kmr.lproj/app.json index ff504a3bb..ef81e9351 100644 --- a/Localization/StringsConvertor/input/kmr.lproj/app.json +++ b/Localization/StringsConvertor/input/kmr.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Têkeve", "learn_more": "Bêtir fêr bibe", - "join_default_server": "Tevlî mastodon.social bibe", + "join_default_server": "Join %@", "pick_server": "Rajekarek din hilbijêre", "separator": { "or": "an jî" diff --git a/Localization/StringsConvertor/input/ko.lproj/app.json b/Localization/StringsConvertor/input/ko.lproj/app.json index 2e543a3d6..7d2a7c75b 100644 --- a/Localization/StringsConvertor/input/ko.lproj/app.json +++ b/Localization/StringsConvertor/input/ko.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "로그인", "learn_more": "Learn more", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/lv.lproj/app.json b/Localization/StringsConvertor/input/lv.lproj/app.json index 94c7ee93f..943c63a38 100644 --- a/Localization/StringsConvertor/input/lv.lproj/app.json +++ b/Localization/StringsConvertor/input/lv.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Pieteikties", "learn_more": "Learn more", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/my.lproj/app.json b/Localization/StringsConvertor/input/my.lproj/app.json index 055a99a38..9b7bacd6e 100644 --- a/Localization/StringsConvertor/input/my.lproj/app.json +++ b/Localization/StringsConvertor/input/my.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "လော့ခ်အင်ဝင်ရန်", "learn_more": "Learn more", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/nl.lproj/app.json b/Localization/StringsConvertor/input/nl.lproj/app.json index dd0f1762d..14791647e 100644 --- a/Localization/StringsConvertor/input/nl.lproj/app.json +++ b/Localization/StringsConvertor/input/nl.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Inloggen", "learn_more": "Meer leren", - "join_default_server": "Registreren op mastodon.social", + "join_default_server": "Join %@", "pick_server": "Kies een andere server", "separator": { "or": "of" diff --git a/Localization/StringsConvertor/input/pl.lproj/app.json b/Localization/StringsConvertor/input/pl.lproj/app.json index affd918b0..0766988c5 100644 --- a/Localization/StringsConvertor/input/pl.lproj/app.json +++ b/Localization/StringsConvertor/input/pl.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Zaloguj się", "learn_more": "Learn more", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/pt-BR.lproj/app.json b/Localization/StringsConvertor/input/pt-BR.lproj/app.json index 68f154151..f1014e8dc 100644 --- a/Localization/StringsConvertor/input/pt-BR.lproj/app.json +++ b/Localization/StringsConvertor/input/pt-BR.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Entrar", "learn_more": "Learn more", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/pt.lproj/app.json b/Localization/StringsConvertor/input/pt.lproj/app.json index 806a1e779..d549a04e4 100644 --- a/Localization/StringsConvertor/input/pt.lproj/app.json +++ b/Localization/StringsConvertor/input/pt.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Log In", "learn_more": "Learn more", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/ro.lproj/app.json b/Localization/StringsConvertor/input/ro.lproj/app.json index 93a073f40..50b217289 100644 --- a/Localization/StringsConvertor/input/ro.lproj/app.json +++ b/Localization/StringsConvertor/input/ro.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Log In", "learn_more": "Learn more", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/ru.lproj/app.json b/Localization/StringsConvertor/input/ru.lproj/app.json index cb58da5c6..285433599 100644 --- a/Localization/StringsConvertor/input/ru.lproj/app.json +++ b/Localization/StringsConvertor/input/ru.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Вход", "learn_more": "Learn more", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/si.lproj/app.json b/Localization/StringsConvertor/input/si.lproj/app.json index 6735c4f8c..eb761b6db 100644 --- a/Localization/StringsConvertor/input/si.lproj/app.json +++ b/Localization/StringsConvertor/input/si.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "පිවිසෙන්න", "learn_more": "Learn more", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/sl.lproj/app.json b/Localization/StringsConvertor/input/sl.lproj/app.json index 5a3e7813b..8885a623b 100644 --- a/Localization/StringsConvertor/input/sl.lproj/app.json +++ b/Localization/StringsConvertor/input/sl.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Prijava", "learn_more": "Več o tem", - "join_default_server": "Pridruži se mastodon.social", + "join_default_server": "Join %@", "pick_server": "Izberi drug strežnik", "separator": { "or": "ali" diff --git a/Localization/StringsConvertor/input/sv.lproj/app.json b/Localization/StringsConvertor/input/sv.lproj/app.json index fc9012a94..f22f547fd 100644 --- a/Localization/StringsConvertor/input/sv.lproj/app.json +++ b/Localization/StringsConvertor/input/sv.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Logga in", "learn_more": "Läs mer", - "join_default_server": "Gå med i mastodon.social", + "join_default_server": "Join %@", "pick_server": "Hitta en annan server", "separator": { "or": "eller" diff --git a/Localization/StringsConvertor/input/th.lproj/app.json b/Localization/StringsConvertor/input/th.lproj/app.json index c7d6136b9..507daab41 100644 --- a/Localization/StringsConvertor/input/th.lproj/app.json +++ b/Localization/StringsConvertor/input/th.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "เข้าสู่ระบบ", "learn_more": "เรียนรู้เพิ่มเติม", - "join_default_server": "เข้าร่วม mastodon.social", + "join_default_server": "Join %@", "pick_server": "เลือกเซิร์ฟเวอร์อื่น", "separator": { "or": "หรือ" diff --git a/Localization/StringsConvertor/input/tr.lproj/app.json b/Localization/StringsConvertor/input/tr.lproj/app.json index e4ba16c29..10e025bea 100644 --- a/Localization/StringsConvertor/input/tr.lproj/app.json +++ b/Localization/StringsConvertor/input/tr.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Oturum Aç", "learn_more": "Learn more", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/uk.lproj/app.json b/Localization/StringsConvertor/input/uk.lproj/app.json index 17156ab8f..53dacda5f 100644 --- a/Localization/StringsConvertor/input/uk.lproj/app.json +++ b/Localization/StringsConvertor/input/uk.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Увійти", "learn_more": "Learn more", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/vi.lproj/app.json b/Localization/StringsConvertor/input/vi.lproj/app.json index b44485561..254b14b20 100644 --- a/Localization/StringsConvertor/input/vi.lproj/app.json +++ b/Localization/StringsConvertor/input/vi.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "Đăng nhập", "learn_more": "Tìm hiểu thêm", - "join_default_server": "Tham gia mastodon.social", + "join_default_server": "Join %@", "pick_server": "Tìm máy chủ khác", "separator": { "or": "hoặc" diff --git a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json index 638adc19e..cd8669fb4 100644 --- a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "登录", "learn_more": "了解详情", - "join_default_server": "加入 mastodon.social", + "join_default_server": "Join %@", "pick_server": "选择另一个服务器", "separator": { "or": "或" diff --git a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json index 4b0672be8..3b1fc9fb8 100644 --- a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json @@ -269,7 +269,7 @@ "welcome": { "log_in": "登入", "learn_more": "了解更多", - "join_default_server": "加入 mastodon.social", + "join_default_server": "Join %@", "pick_server": "挑選另一個伺服器", "separator": { "or": "或" From 0937849b4dba9670ca27abf4faa5a160ceac0c20 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sun, 2 Jul 2023 16:57:06 +0200 Subject: [PATCH 24/87] Update localizables --- .../input/Base.lproj/app.json | 2 +- .../Resources/Base.lproj/Localizable.strings | 2 +- .../Resources/ar.lproj/Localizable.strings | 2 +- .../Resources/ca.lproj/Localizable.strings | 2 +- .../Resources/ckb.lproj/Localizable.strings | 2 +- .../Resources/cs.lproj/Localizable.strings | 2 +- .../Resources/de.lproj/Localizable.strings | 2 +- .../Resources/el.lproj/Localizable.strings | 92 +++++++++---------- .../Resources/en.lproj/Localizable.strings | 2 +- .../Resources/es.lproj/Localizable.strings | 2 +- .../Resources/eu.lproj/Localizable.strings | 2 +- .../Resources/fi.lproj/Localizable.strings | 2 +- .../Resources/fr.lproj/Localizable.strings | 2 +- .../Resources/gd.lproj/Localizable.strings | 2 +- .../Resources/gl.lproj/Localizable.strings | 2 +- .../Resources/it.lproj/Localizable.strings | 2 +- .../Resources/ja.lproj/Localizable.strings | 2 +- .../Resources/kab.lproj/Localizable.strings | 2 +- .../Resources/ku.lproj/Localizable.strings | 2 +- .../Resources/nl.lproj/Localizable.strings | 2 +- .../Resources/ru.lproj/Localizable.strings | 2 +- .../Resources/sl.lproj/Localizable.strings | 2 +- .../Resources/sv.lproj/Localizable.strings | 2 +- .../Resources/th.lproj/Localizable.strings | 2 +- .../Resources/tr.lproj/Localizable.strings | 2 +- .../Resources/vi.lproj/Localizable.strings | 2 +- .../zh-Hans.lproj/Localizable.strings | 2 +- .../zh-Hant.lproj/Localizable.strings | 2 +- 28 files changed, 73 insertions(+), 73 deletions(-) diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index 08a3c8327..739573267 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -266,7 +266,7 @@ "welcome": { "log_in": "Log In", "learn_more": "Learn more", - "join_default_server": "Join mastodon.social", + "join_default_server": "Join %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 44737b51f..7f00f1cc2 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -554,4 +554,4 @@ uploaded to Mastodon."; "Widget.MultipleFollowers.ConfigurationDescription" = "Show number of followers for multiple accounts."; "Widget.MultipleFollowers.ConfigurationDisplayName" = "Multiple followers"; "Widget.MultipleFollowers.MockUser.AccountName" = "another@follower.social"; -"Widget.MultipleFollowers.MockUser.DisplayName" = "Another follower"; +"Widget.MultipleFollowers.MockUser.DisplayName" = "Another follower"; \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.strings index f904471e4..034d33449 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.strings @@ -530,7 +530,7 @@ "Scene.Welcome.Education.Mastodon.Title" = "Welcome to Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Every Mastodon account is hosted on a server — each with its own values, rules, & admins. No matter which one you pick, you can follow and interact with people on any server."; "Scene.Welcome.Education.Servers.Title" = "What are servers?"; -"Scene.Welcome.JoinDefaultServer" = "Join mastodon.social"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "Learn more"; "Scene.Welcome.LogIn" = "تسجيلُ الدخول"; "Scene.Welcome.PickServer" = "Pick another server"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.strings index d3ca97d91..82e9094a5 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.strings @@ -531,7 +531,7 @@ Elegiremos un servidor basado en su idioma si continúa sin hacer una selección "Scene.Welcome.Education.Mastodon.Title" = "Benvingut a Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Cada compte a Mastodon esta allotjat en un servidor, cadascún d'ells amb els seus propis valors, normes i administradors. Tant és quin trïis, podràs seguir i interactuar amb gent de qualsevol servidor."; "Scene.Welcome.Education.Servers.Title" = "Què son els servidors?"; -"Scene.Welcome.JoinDefaultServer" = "Uneix-te a mastodon.social"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "Més informació"; "Scene.Welcome.LogIn" = "Inicia sessió"; "Scene.Welcome.PickServer" = "Tria un altre servidor"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings index 6aa5a0591..917af2eaf 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings @@ -529,7 +529,7 @@ "Scene.Welcome.Education.Mastodon.Title" = "Welcome to Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Every Mastodon account is hosted on a server — each with its own values, rules, & admins. No matter which one you pick, you can follow and interact with people on any server."; "Scene.Welcome.Education.Servers.Title" = "What are servers?"; -"Scene.Welcome.JoinDefaultServer" = "Join mastodon.social"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "Learn more"; "Scene.Welcome.LogIn" = "بچۆ ژوورەوە"; "Scene.Welcome.PickServer" = "Pick another server"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/cs.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/cs.lproj/Localizable.strings index 159a02330..0d2573b10 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/cs.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/cs.lproj/Localizable.strings @@ -526,7 +526,7 @@ nahrán do Mastodonu."; "Scene.Welcome.Education.Mastodon.Title" = "Welcome to Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Every Mastodon account is hosted on a server — each with its own values, rules, & admins. No matter which one you pick, you can follow and interact with people on any server."; "Scene.Welcome.Education.Servers.Title" = "What are servers?"; -"Scene.Welcome.JoinDefaultServer" = "Join mastodon.social"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "Zjistit více"; "Scene.Welcome.LogIn" = "Přihlásit se"; "Scene.Welcome.PickServer" = "Pick another server"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.strings index 1f16d7455..9e50133c2 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.strings @@ -530,7 +530,7 @@ kann nicht auf Mastodon hochgeladen werden."; "Scene.Welcome.Education.Mastodon.Title" = "Willkommen bei Mastodon!"; "Scene.Welcome.Education.Servers.Description" = "Jedes Mastodon-Konto wird auf einem Server gehostet. Jeder Server hat dabei seine eigenen Werte, Regeln und Administrator*innen. Aber egal, für welchen Server Du Dich entscheidest: Du kannst mit Leuten von anderen Servern interagieren und ihnen folgen."; "Scene.Welcome.Education.Servers.Title" = "Was sind Server?"; -"Scene.Welcome.JoinDefaultServer" = "mastodon.social beitreten"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "Mehr erfahren"; "Scene.Welcome.LogIn" = "Anmelden"; "Scene.Welcome.PickServer" = "Einen anderen Server auswählen"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/el.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/el.lproj/Localizable.strings index 02c30c293..8e39b214e 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/el.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/el.lproj/Localizable.strings @@ -30,7 +30,7 @@ "Common.Controls.Actions.Add" = "Προσθήκη"; "Common.Controls.Actions.Back" = "Πίσω"; "Common.Controls.Actions.BlockDomain" = "Αποκλεισμός %@"; -"Common.Controls.Actions.Bookmark" = "Bookmark"; +"Common.Controls.Actions.Bookmark" = "Σελιδοδείκτης"; "Common.Controls.Actions.Cancel" = "Άκυρο"; "Common.Controls.Actions.Compose" = "Σύνταξη"; "Common.Controls.Actions.Confirm" = "Επιβεβαίωση"; @@ -43,7 +43,7 @@ "Common.Controls.Actions.Edit" = "Επεξεργασία"; "Common.Controls.Actions.EditPost" = "Επεξεργασία"; "Common.Controls.Actions.FindPeople" = "Βρες άτομα για να ακολουθήσεις"; -"Common.Controls.Actions.Follow" = "Follow %@"; +"Common.Controls.Actions.Follow" = "Ακολούθησε %@"; "Common.Controls.Actions.ManuallySearch" = "Μη αυτόματη αναζήτηση"; "Common.Controls.Actions.Next" = "Επόμενο"; "Common.Controls.Actions.Ok" = "ΟΚ"; @@ -53,7 +53,7 @@ "Common.Controls.Actions.Preview" = "Προεπισκόπηση"; "Common.Controls.Actions.Previous" = "Προηγούμενο"; "Common.Controls.Actions.Remove" = "Αφαίρεση"; -"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; +"Common.Controls.Actions.RemoveBookmark" = "Αφαίρεση σελιδοδείκτη"; "Common.Controls.Actions.Reply" = "Απάντηση"; "Common.Controls.Actions.ReportUser" = "Αναφορά %@"; "Common.Controls.Actions.Save" = "Αποθήκευση"; @@ -70,25 +70,25 @@ "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Άγνωστο"; "Common.Controls.Actions.TryAgain" = "Προσπάθησε ξανά"; "Common.Controls.Actions.UnblockDomain" = "Άρση αποκλεισμού %@"; -"Common.Controls.Actions.Unfollow" = "Unfollow %@"; -"Common.Controls.Friendship.Block" = "Block"; -"Common.Controls.Friendship.BlockDomain" = "Block %@"; -"Common.Controls.Friendship.BlockUser" = "Block %@"; -"Common.Controls.Friendship.Blocked" = "Blocked"; -"Common.Controls.Friendship.EditInfo" = "Edit Info"; -"Common.Controls.Friendship.Follow" = "Follow"; -"Common.Controls.Friendship.Following" = "Following"; -"Common.Controls.Friendship.HideReblogs" = "Hide Reblogs"; -"Common.Controls.Friendship.Mute" = "Mute"; -"Common.Controls.Friendship.MuteUser" = "Mute %@"; -"Common.Controls.Friendship.Muted" = "Muted"; -"Common.Controls.Friendship.Pending" = "Pending"; -"Common.Controls.Friendship.Request" = "Request"; -"Common.Controls.Friendship.ShowReblogs" = "Show Reblogs"; -"Common.Controls.Friendship.Unblock" = "Unblock"; -"Common.Controls.Friendship.UnblockUser" = "Unblock %@"; -"Common.Controls.Friendship.Unmute" = "Unmute"; -"Common.Controls.Friendship.UnmuteUser" = "Unmute %@"; +"Common.Controls.Actions.Unfollow" = "Κατάργηση ακολούθησης του %@"; +"Common.Controls.Friendship.Block" = "Αποκλεισμός"; +"Common.Controls.Friendship.BlockDomain" = "Αποκλεισμός %@"; +"Common.Controls.Friendship.BlockUser" = "Αποκλεισμός %@"; +"Common.Controls.Friendship.Blocked" = "Αποκλείστηκε"; +"Common.Controls.Friendship.EditInfo" = "Επεξεργασία Πληροφοριών"; +"Common.Controls.Friendship.Follow" = "Ακολούθησε"; +"Common.Controls.Friendship.Following" = "Ακολουθείς"; +"Common.Controls.Friendship.HideReblogs" = "Απόκρυψη Αναδημοσιεύσεων"; +"Common.Controls.Friendship.Mute" = "Σίγαση"; +"Common.Controls.Friendship.MuteUser" = "Σίγαση %@"; +"Common.Controls.Friendship.Muted" = "Σε Σίγαση"; +"Common.Controls.Friendship.Pending" = "Εκκρεμεί"; +"Common.Controls.Friendship.Request" = "Αίτημα"; +"Common.Controls.Friendship.ShowReblogs" = "Εμφάνιση Αναδημοσιεύσεων"; +"Common.Controls.Friendship.Unblock" = "Άρση αποκλεισμού"; +"Common.Controls.Friendship.UnblockUser" = "Άρση αποκλεισμού %@"; +"Common.Controls.Friendship.Unmute" = "Κατάργηση σίγασης"; +"Common.Controls.Friendship.UnmuteUser" = "Κατάργηση σίγασης %@"; "Common.Controls.Keyboard.Common.ComposeNewPost" = "Σύνταξη Νέας Ανάρτησης"; "Common.Controls.Keyboard.Common.OpenSettings" = "Άνοιγμα Ρυθμίσεων"; "Common.Controls.Keyboard.Common.ShowFavorites" = "Εμφάνιση Αγαπημένων"; @@ -102,8 +102,8 @@ "Common.Controls.Keyboard.Timeline.PreviewImage" = "Προεπισκόπηση Εικόνας"; "Common.Controls.Keyboard.Timeline.PreviousStatus" = "Προηγούμενη Ανάρτηση"; "Common.Controls.Keyboard.Timeline.ReplyStatus" = "Απάντηση στην Ανάρτηση"; -"Common.Controls.Keyboard.Timeline.ToggleContentWarning" = "Toggle Content Warning"; -"Common.Controls.Keyboard.Timeline.ToggleFavorite" = "Toggle Favorite on Post"; +"Common.Controls.Keyboard.Timeline.ToggleContentWarning" = "Εναλλαγή Προειδοποίησης Περιεχομένου"; +"Common.Controls.Keyboard.Timeline.ToggleFavorite" = "Εναλλαγή Αγαπημένου στην Ανάρτηση"; "Common.Controls.Keyboard.Timeline.ToggleReblog" = "Εναλλαγή Αναδημοσίευσης στην Ανάρτηση"; "Common.Controls.Status.Actions.A11YLabels.Reblog" = "Αναδημοσίευση"; "Common.Controls.Status.Actions.A11YLabels.Unreblog" = "Αναίρεση αναδημοσίευσης"; @@ -119,20 +119,20 @@ "Common.Controls.Status.Actions.TapThenHoldToShowMenu" = "Πάτα παρατεταμένα για εμφάνιση μενού"; "Common.Controls.Status.Actions.Unfavorite" = "Αφαίρεση από αγαπημένα"; "Common.Controls.Status.Actions.Unreblog" = "Αναίρεση αναδημοσίευσης"; -"Common.Controls.Status.Buttons.EditHistoryDetail" = "Last edit %@"; -"Common.Controls.Status.Buttons.EditHistoryTitle" = "Edit History"; -"Common.Controls.Status.Buttons.FavoritesTitle" = "Favorites"; -"Common.Controls.Status.Buttons.ReblogsTitle" = "Reblogs"; +"Common.Controls.Status.Buttons.EditHistoryDetail" = "Τελευταία επεξεργασία %@"; +"Common.Controls.Status.Buttons.EditHistoryTitle" = "Επεξεργασία Ιστορικού"; +"Common.Controls.Status.Buttons.FavoritesTitle" = "Αγαπημένα"; +"Common.Controls.Status.Buttons.ReblogsTitle" = "Αναδημοσιεύσεις"; "Common.Controls.Status.ContentWarning" = "Προειδοποίηση Περιεχομένου"; -"Common.Controls.Status.EditHistory.OriginalPost" = "Original Post · %@"; -"Common.Controls.Status.EditHistory.Title" = "Edit History"; -"Common.Controls.Status.EditedAtTimestampPrefix" = "Edited %@"; +"Common.Controls.Status.EditHistory.OriginalPost" = "Αρχική Ανάρτηση · %@"; +"Common.Controls.Status.EditHistory.Title" = "Επεξεργασία Ιστορικού"; +"Common.Controls.Status.EditedAtTimestampPrefix" = "Επεξεργάστηκε στις %@"; "Common.Controls.Status.LinkViaUser" = "%@ μέσω %@"; "Common.Controls.Status.LoadEmbed" = "Φόρτωση Ενσωμάτωσης"; -"Common.Controls.Status.Media.AccessibilityLabel" = "%@, attachment %d of %d"; -"Common.Controls.Status.Media.ExpandGifHint" = "Expands the GIF. Double-tap and hold to show actions"; -"Common.Controls.Status.Media.ExpandImageHint" = "Expands the image. Double-tap and hold to show actions"; -"Common.Controls.Status.Media.ExpandVideoHint" = "Shows the video player. Double-tap and hold to show actions"; +"Common.Controls.Status.Media.AccessibilityLabel" = "%@, συνημμένο %d από %d"; +"Common.Controls.Status.Media.ExpandGifHint" = "Επεκτείνει το GIF. Πάτα δύο φορές και κράτα πατημένο για να εμφανίσεις τις ενέργειες"; +"Common.Controls.Status.Media.ExpandImageHint" = "Επεκτείνει την εικόνα. Πάτα δύο φορές και κράτα πατημένο για εμφάνιση ενεργειών"; +"Common.Controls.Status.Media.ExpandVideoHint" = "Εμφανίζει το πρόγραμμα αναπαραγωγής βίντεο. Πάτα δύο φορές και κράτα πατημένο για να δείς τις ενέργειες"; "Common.Controls.Status.MediaContentWarning" = "Πάτα οπουδήποτε για εμφάνιση"; "Common.Controls.Status.MetaEntity.Email" = "Διεύθυνση email: %@"; "Common.Controls.Status.MetaEntity.Hashtag" = "Ετικέτα: %@"; @@ -140,7 +140,7 @@ "Common.Controls.Status.MetaEntity.Url" = "Σύνδεσμος: %@"; "Common.Controls.Status.Poll.Closed" = "Κλειστή"; "Common.Controls.Status.Poll.Vote" = "Ψήφισε"; -"Common.Controls.Status.PostedViaApplication" = "%@ via %@"; +"Common.Controls.Status.PostedViaApplication" = "%@ μέσω %@"; "Common.Controls.Status.SensitiveContent" = "Ευαίσθητο Περιεχόμενο"; "Common.Controls.Status.ShowPost" = "Εμφάνιση Ανάρτησης"; "Common.Controls.Status.ShowUserProfile" = "Εμφάνιση προφίλ χρήστη"; @@ -167,13 +167,13 @@ "Common.Controls.Tabs.Notifications" = "Ειδοποιήσεις"; "Common.Controls.Tabs.Profile" = "Προφίλ"; "Common.Controls.Tabs.SearchAndExplore" = "Αναζήτηση και Εξερεύνηση"; -"Common.Controls.Timeline.Filtered" = "Filtered"; +"Common.Controls.Timeline.Filtered" = "Φιλτραρισμένα"; "Common.Controls.Timeline.Header.BlockedWarning" = "You can’t view this user’s profile until they unblock you."; -"Common.Controls.Timeline.Header.BlockingWarning" = "You can’t view this user's profile -until you unblock them. -Your profile looks like this to them."; -"Common.Controls.Timeline.Header.NoStatusFound" = "No Post Found"; +"Common.Controls.Timeline.Header.BlockingWarning" = "Δεν μπορείς να δεις το προφίλ αυτού του χρήστη +μέχρι να τον ξεμπλοκάρεις. +Το προφίλ σου μοιάζει έτσι και σε αυτόν."; +"Common.Controls.Timeline.Header.NoStatusFound" = "Δεν Βρέθηκε Ανάρτηση"; "Common.Controls.Timeline.Header.SuspendedWarning" = "This user has been suspended."; "Common.Controls.Timeline.Header.UserBlockedWarning" = "You can’t view %@’s profile until they unblock you."; @@ -181,10 +181,10 @@ until they unblock you."; until you unblock them. Your profile looks like this to them."; "Common.Controls.Timeline.Header.UserSuspendedWarning" = "%@’s account has been suspended."; -"Common.Controls.Timeline.Loader.LoadMissingPosts" = "Load missing posts"; -"Common.Controls.Timeline.Loader.LoadingMissingPosts" = "Loading missing posts..."; -"Common.Controls.Timeline.Loader.ShowMoreReplies" = "Show more replies"; -"Common.Controls.Timeline.Timestamp.Now" = "Now"; +"Common.Controls.Timeline.Loader.LoadMissingPosts" = "Φόρτωση αναρτήσεων που λείπουν"; +"Common.Controls.Timeline.Loader.LoadingMissingPosts" = "Φόρτωση αναρτήσεων που λείπουν..."; +"Common.Controls.Timeline.Loader.ShowMoreReplies" = "Εμφάνιση περισσότερων απαντήσεων"; +"Common.Controls.Timeline.Timestamp.Now" = "Τώρα"; "Common.UserList.FollowersCount" = "%@ followers"; "Common.UserList.NoVerifiedLink" = "No verified link"; "Extension.OpenIn.InvalidLinkError" = "This doesn't seem to be a valid Mastodon link."; @@ -530,7 +530,7 @@ uploaded to Mastodon."; "Scene.Welcome.Education.Mastodon.Title" = "Welcome to Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Every Mastodon account is hosted on a server — each with its own values, rules, & admins. No matter which one you pick, you can follow and interact with people on any server."; "Scene.Welcome.Education.Servers.Title" = "What are servers?"; -"Scene.Welcome.JoinDefaultServer" = "Join mastodon.social"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "Learn more"; "Scene.Welcome.LogIn" = "Log In"; "Scene.Welcome.PickServer" = "Pick another server"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings index 8f277893c..ca2cb11c0 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings @@ -556,4 +556,4 @@ uploaded to Mastodon."; "Widget.MultipleFollowers.ConfigurationDescription" = "Show number of followers for multiple accounts."; "Widget.MultipleFollowers.ConfigurationDisplayName" = "Multiple followers"; "Widget.MultipleFollowers.MockUser.AccountName" = "another@follower.social"; -"Widget.MultipleFollowers.MockUser.DisplayName" = "Another follower"; +"Widget.MultipleFollowers.MockUser.DisplayName" = "Another follower"; \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.strings index d77be43a2..8ff1cbeab 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.strings @@ -530,7 +530,7 @@ subirse a Mastodon."; "Scene.Welcome.Education.Mastodon.Title" = "Welcome to Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Every Mastodon account is hosted on a server — each with its own values, rules, & admins. No matter which one you pick, you can follow and interact with people on any server."; "Scene.Welcome.Education.Servers.Title" = "What are servers?"; -"Scene.Welcome.JoinDefaultServer" = "Join mastodon.social"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "Learn more"; "Scene.Welcome.LogIn" = "Iniciar sesión"; "Scene.Welcome.PickServer" = "Pick another server"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings index 1950a0c95..ca450b298 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings @@ -530,7 +530,7 @@ Mastodonera igo."; "Scene.Welcome.Education.Mastodon.Title" = "Welcome to Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Every Mastodon account is hosted on a server — each with its own values, rules, & admins. No matter which one you pick, you can follow and interact with people on any server."; "Scene.Welcome.Education.Servers.Title" = "What are servers?"; -"Scene.Welcome.JoinDefaultServer" = "Join mastodon.social"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "Learn more"; "Scene.Welcome.LogIn" = "Hasi saioa"; "Scene.Welcome.PickServer" = "Pick another server"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings index e1cf921d6..7a688ff51 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings @@ -530,7 +530,7 @@ uploaded to Mastodon."; "Scene.Welcome.Education.Mastodon.Title" = "Tervetuloa Mastodoniin"; "Scene.Welcome.Education.Servers.Description" = "Jokainen Mastodon-tili sijaitsee jollakin palvelimella, joilla on kaikilla omat arvot, säännöt ja ylläpitäjät. Palvelinvalinnastasi riippumatta voit seurata kaikkien palvelinten käyttäjiä ja viestiä heidän kanssaan."; "Scene.Welcome.Education.Servers.Title" = "Mitä palvelimet ovat?"; -"Scene.Welcome.JoinDefaultServer" = "Liity mastodon.social-palvelimelle"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "Lue lisää"; "Scene.Welcome.LogIn" = "Kirjaudu sisään"; "Scene.Welcome.PickServer" = "Pick another server"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.strings index e0c2b6b54..a9c9b6e2a 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.strings @@ -530,7 +530,7 @@ téléversé sur Mastodon."; "Scene.Welcome.Education.Mastodon.Title" = "Bienvenue sur Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Chaque compte Mastodon est hébergé sur un serveur — chacun avec ses propres valeurs, règles, et administrateurs. Peu importe celui que vous choisissez, vous pouvez suivre et interagir avec des personnes sur n'importe quel serveur."; "Scene.Welcome.Education.Servers.Title" = "Que sont les serveurs ?"; -"Scene.Welcome.JoinDefaultServer" = "Rejoindre mastodon.social"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "En savoir plus"; "Scene.Welcome.LogIn" = "Se connecter"; "Scene.Welcome.PickServer" = "Trouver un autre serveur"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/gd.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/gd.lproj/Localizable.strings index ea79cf5bc..496c6965d 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/gd.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/gd.lproj/Localizable.strings @@ -530,7 +530,7 @@ a luchdadh suas gu Mastodon."; "Scene.Welcome.Education.Mastodon.Title" = "Fàilte gu Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Tha gach cunntas Mastodon ’ga òstadh air frithealaiche – tha luachan, riaghailtean ⁊ rianairean sònraichte aig gach fear. Ge b’ e dè am frithealaiche a thaghas tu, ’s urrainn dhut daoine air frithealaiche sam bith a leantainn is bruidhinn riutha."; "Scene.Welcome.Education.Servers.Title" = "Dè th’ anns na frithealaichean?"; -"Scene.Welcome.JoinDefaultServer" = "Faigh ballrachd air mastodon.social"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "Barrachd fiosrachaidh"; "Scene.Welcome.LogIn" = "Clàraich a-steach"; "Scene.Welcome.PickServer" = "Tagh frithealaiche eile"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.strings index a041a4612..bd9ca1bf2 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.strings @@ -530,7 +530,7 @@ ser subido a Mastodon."; "Scene.Welcome.Education.Mastodon.Title" = "Benvida a Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Cada conta Mastodon está hospedada nun servidor — cada unha coas súas regras, valores e admins. Non importa cal elixas, podes seguir e interactuar con persoas de outros servidores."; "Scene.Welcome.Education.Servers.Title" = "Que son os servidores?"; -"Scene.Welcome.JoinDefaultServer" = "Únete a mastodon.social"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "Saber máis"; "Scene.Welcome.LogIn" = "Acceder"; "Scene.Welcome.PickServer" = "Elixe outro servidor"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.strings index 765de5d03..7fbd9f886 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.strings @@ -530,7 +530,7 @@ caricato su Mastodon."; "Scene.Welcome.Education.Mastodon.Title" = "Benvenuto/a su Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Ogni account Mastodon è ospitato su un server — ognuno con i propri valori, regole, e amministratori. Non importa quale scegliere, è possibile seguire e interagire con persone su altri server."; "Scene.Welcome.Education.Servers.Title" = "Cosa sono i server?"; -"Scene.Welcome.JoinDefaultServer" = "Unisciti a mastodon.social"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "Scopri di più"; "Scene.Welcome.LogIn" = "Accedi"; "Scene.Welcome.PickServer" = "Scegli un altro server"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.strings index 1f717141d..309a3b7d5 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.strings @@ -525,7 +525,7 @@ "Scene.Welcome.Education.Mastodon.Title" = "Mastodon とは"; "Scene.Welcome.Education.Servers.Description" = "Mastodon のアカウントはいずれかのサーバーに所属します。それぞれのサーバーは異なる価値観やルールをもち、それらを管理する管理者がいます。どのサーバーにいても、ほかのあらゆるサーバーのユーザーをフォローして、かかわりをもつことができるでしょう。"; "Scene.Welcome.Education.Servers.Title" = "サーバーとは"; -"Scene.Welcome.JoinDefaultServer" = "mastodon.social に登録"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "詳しく学ぶ"; "Scene.Welcome.LogIn" = "ログイン"; "Scene.Welcome.PickServer" = "ほかのサーバーをさがす"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.strings index fb92ce3bb..eb7f7da71 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.strings @@ -530,7 +530,7 @@ Ad d-yettwasali ɣef Mastodon."; "Scene.Welcome.Education.Mastodon.Title" = "Welcome to Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Every Mastodon account is hosted on a server — each with its own values, rules, & admins. No matter which one you pick, you can follow and interact with people on any server."; "Scene.Welcome.Education.Servers.Title" = "What are servers?"; -"Scene.Welcome.JoinDefaultServer" = "Join mastodon.social"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "Learn more"; "Scene.Welcome.LogIn" = "Qqen"; "Scene.Welcome.PickServer" = "Pick another server"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.strings index 83e0f2546..03e0faaa5 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.strings @@ -530,7 +530,7 @@ Profîla te ji wan ra wiha xuya dike."; "Scene.Welcome.Education.Mastodon.Title" = "Tu bi xêr hatî Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Her ajimêrê Mastodon li ser rajekarekê tê pêşkêşkirin - her yek bi nirx, rêbaz û rêvebirên xwe ye. Ne girîng e ku tu kîjanê hilbijêrî tu dikarî li ser her rajekar mirovan bişopînî û bi wan re têkilî daynî."; "Scene.Welcome.Education.Servers.Title" = "Rajekar çi ne?"; -"Scene.Welcome.JoinDefaultServer" = "Tevlî mastodon.social bibe"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "Bêtir fêr bibe"; "Scene.Welcome.LogIn" = "Têkeve"; "Scene.Welcome.PickServer" = "Rajekarek din hilbijêre"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings index 4cb922844..ae5c1feb5 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings @@ -524,7 +524,7 @@ Jouw profiel ziet er zo uit voor hen."; "Scene.Welcome.Education.Mastodon.Title" = "Welkom op Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Elk Mastodon account wordt gehost op een server - elk met diens eigen waarden, regels en beheerders. Het maakt niet uit welke server je kiest, je kunt mensen op elke server volgen en ermee communiceren."; "Scene.Welcome.Education.Servers.Title" = "Wat zijn servers?"; -"Scene.Welcome.JoinDefaultServer" = "Registreren op mastodon.social"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "Meer leren"; "Scene.Welcome.LogIn" = "Inloggen"; "Scene.Welcome.PickServer" = "Kies een andere server"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings index c5d95aeb4..43764bab6 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings @@ -538,7 +538,7 @@ "Scene.Welcome.Education.Mastodon.Title" = "Welcome to Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Every Mastodon account is hosted on a server — each with its own values, rules, & admins. No matter which one you pick, you can follow and interact with people on any server."; "Scene.Welcome.Education.Servers.Title" = "What are servers?"; -"Scene.Welcome.JoinDefaultServer" = "Join mastodon.social"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "Learn more"; "Scene.Welcome.LogIn" = "Вход"; "Scene.Welcome.PickServer" = "Pick another server"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/sl.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/sl.lproj/Localizable.strings index 3285e976e..862e0b119 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/sl.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/sl.lproj/Localizable.strings @@ -530,7 +530,7 @@ možno naložiti v Mastodon."; "Scene.Welcome.Education.Mastodon.Title" = "Dobrodošli na Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Vsak račun Mastodon gostuje na strežniku — vsak strežnik ima svoje vrednote, pravila in skbrnike. Vseeno je, katerega izberete - sledite in komunicirate lahko z osebbami na poljubnem strežniku."; "Scene.Welcome.Education.Servers.Title" = "Kaj so strežniki?"; -"Scene.Welcome.JoinDefaultServer" = "Pridruži se mastodon.social"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "Več o tem"; "Scene.Welcome.LogIn" = "Prijava"; "Scene.Welcome.PickServer" = "Izberi drug strežnik"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.strings index 28c89370f..cdd014501 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.strings @@ -530,7 +530,7 @@ laddas upp till Mastodon."; "Scene.Welcome.Education.Mastodon.Title" = "Välkommen till Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Varje Mastodon-konto finns på en server — var och en med sina värderingar, regler och administratörer. Oavsett vilken du väljer kan du följa och interagera med människor på vilken server som helst."; "Scene.Welcome.Education.Servers.Title" = "Vad är servrar?"; -"Scene.Welcome.JoinDefaultServer" = "Gå med i mastodon.social"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "Läs mer"; "Scene.Welcome.LogIn" = "Logga in"; "Scene.Welcome.PickServer" = "Hitta en annan server"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.strings index d00093bb0..9de86d444 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.strings @@ -530,7 +530,7 @@ "Scene.Welcome.Education.Mastodon.Title" = "ยินดีต้อนรับสู่ Mastodon"; "Scene.Welcome.Education.Servers.Description" = "ทุกบัญชี Mastodon ได้รับการโฮสต์ในเซิร์ฟเวอร์ — แต่ละแห่งมีค่า, กฎ และผู้ดูแลของเซิร์ฟเวอร์เอง ไม่ว่าคุณจะเลือกเซิร์ฟเวอร์ใด คุณสามารถติดตามและโต้ตอบกับผู้คนในเซิร์ฟเวอร์ใด ๆ"; "Scene.Welcome.Education.Servers.Title" = "เซิร์ฟเวอร์คืออะไร?"; -"Scene.Welcome.JoinDefaultServer" = "เข้าร่วม mastodon.social"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "เรียนรู้เพิ่มเติม"; "Scene.Welcome.LogIn" = "เข้าสู่ระบบ"; "Scene.Welcome.PickServer" = "เลือกเซิร์ฟเวอร์อื่น"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.strings index ab697aa37..974cb1568 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.strings @@ -529,7 +529,7 @@ yüklenemiyor."; "Scene.Welcome.Education.Mastodon.Title" = "Welcome to Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Every Mastodon account is hosted on a server — each with its own values, rules, & admins. No matter which one you pick, you can follow and interact with people on any server."; "Scene.Welcome.Education.Servers.Title" = "What are servers?"; -"Scene.Welcome.JoinDefaultServer" = "Join mastodon.social"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "Learn more"; "Scene.Welcome.LogIn" = "Oturum Aç"; "Scene.Welcome.PickServer" = "Pick another server"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.strings index 750cdc4b7..2549948f7 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.strings @@ -530,7 +530,7 @@ tải lên Mastodon."; "Scene.Welcome.Education.Mastodon.Title" = "Chào mừng đến với Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Mỗi tài khoản Mastodon được lưu trữ trên một máy chủ — với nội quy và quản trị viên riêng. Bất kể bạn chọn máy chủ nào, bạn có thể theo dõi và tương tác với mọi người trên máy chủ khác."; "Scene.Welcome.Education.Servers.Title" = "Máy chủ là gì?"; -"Scene.Welcome.JoinDefaultServer" = "Tham gia mastodon.social"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "Tìm hiểu thêm"; "Scene.Welcome.LogIn" = "Đăng nhập"; "Scene.Welcome.PickServer" = "Tìm máy chủ khác"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.strings index 5b4f2bd60..d16aae1bf 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.strings @@ -530,7 +530,7 @@ "Scene.Welcome.Education.Mastodon.Title" = "欢迎来到 Mastodon"; "Scene.Welcome.Education.Servers.Description" = "所有的 Mastodon 帐号皆托管于各自的服务器上,每个服务器有各自的价值取向、规则与管理员。无论你选择哪个服务器,你都能关注并与其他任何服务器上的用户互动。"; "Scene.Welcome.Education.Servers.Title" = "服务器是什么?"; -"Scene.Welcome.JoinDefaultServer" = "加入 mastodon.social"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "了解详情"; "Scene.Welcome.LogIn" = "登录"; "Scene.Welcome.PickServer" = "选择另一个服务器"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.strings index 3c7340620..7478109ea 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.strings @@ -525,7 +525,7 @@ "Scene.Welcome.Education.Mastodon.Title" = "歡迎來到 Mastodon"; "Scene.Welcome.Education.Servers.Description" = "所有的 Mastodon 帳號皆託管於一個伺服器上 — 其擁有各自之價值觀、規則、與管理者。無論您選擇何者,您皆能跟隨並與其他任何伺服器上的人們互動。"; "Scene.Welcome.Education.Servers.Title" = "伺服器是什麼?"; -"Scene.Welcome.JoinDefaultServer" = "加入 mastodon.social"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; "Scene.Welcome.LearnMore" = "了解更多"; "Scene.Welcome.LogIn" = "登入"; "Scene.Welcome.PickServer" = "挑選另一個伺服器"; From c5b5db04e4112c2a155f846193b5659c1b4924dd Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 3 Jul 2023 22:01:55 +0200 Subject: [PATCH 25/87] Bump version --- Mastodon.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 78682c7d7..c50bac4f1 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -4571,7 +4571,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2023.11; + MARKETING_VERSION = 2023.12; PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -4603,7 +4603,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2023.11; + MARKETING_VERSION = 2023.12; PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -4790,7 +4790,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2023.11; + MARKETING_VERSION = 2023.12; PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -5081,7 +5081,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2023.11; + MARKETING_VERSION = 2023.12; PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; From e50b9e13a6b84db12c4227827a9dfeb73ac66d37 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Tue, 4 Jul 2023 10:26:30 +0200 Subject: [PATCH 26/87] Add belarusian localization (#1083) --- .../Sources/StringsConvertor/main.swift | 1 + Mastodon.xcodeproj/project.pbxproj | 9 + Mastodon/Resources/be.lproj/InfoPlist.strings | 4 + MastodonIntent/be.lproj/Intents.strings | 51 ++ MastodonIntent/be.lproj/Intents.stringsdict | 54 ++ .../Resources/be.lproj/Localizable.strings | 559 ++++++++++++++++ .../be.lproj/Localizable.stringsdict | 601 ++++++++++++++++++ .../be.lproj/WidgetExtension.strings | 42 ++ 8 files changed, 1321 insertions(+) create mode 100644 Mastodon/Resources/be.lproj/InfoPlist.strings create mode 100644 MastodonIntent/be.lproj/Intents.strings create mode 100644 MastodonIntent/be.lproj/Intents.stringsdict create mode 100644 MastodonSDK/Sources/MastodonLocalization/Resources/be.lproj/Localizable.strings create mode 100644 MastodonSDK/Sources/MastodonLocalization/Resources/be.lproj/Localizable.stringsdict create mode 100644 WidgetExtension/be.lproj/WidgetExtension.strings diff --git a/Localization/StringsConvertor/Sources/StringsConvertor/main.swift b/Localization/StringsConvertor/Sources/StringsConvertor/main.swift index 78f962029..65d2bb457 100644 --- a/Localization/StringsConvertor/Sources/StringsConvertor/main.swift +++ b/Localization/StringsConvertor/Sources/StringsConvertor/main.swift @@ -75,6 +75,7 @@ private func map(language: String) -> String? { case "tr.lproj": return "tr" // Turkish case "vi.lproj": return "vi" // Vietnamese case "el.lproj": return "el" // Greek + case "be.lproj": return "be" // Belarussian default: return nil } } diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index c50bac4f1..0db030614 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -777,6 +777,10 @@ D8099077294BC8A30050219F /* PrivacyTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacyTableViewController.swift; sourceTree = ""; }; D8099079294BC9390050219F /* PrivacyTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacyTableViewCell.swift; sourceTree = ""; }; D809907B294D25510050219F /* PrivacyViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacyViewModel.swift; sourceTree = ""; }; + D82463522A52B47B00A3DBDD /* be */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = be; path = be.lproj/Intents.strings; sourceTree = ""; }; + D82463532A52B47B00A3DBDD /* be */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = be; path = be.lproj/WidgetExtension.strings; sourceTree = ""; }; + D82463542A52B47B00A3DBDD /* be */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = be; path = be.lproj/InfoPlist.strings; sourceTree = ""; }; + D82463552A52B47B00A3DBDD /* be */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = be; path = be.lproj/Intents.stringsdict; sourceTree = ""; }; D8363B1529469CE200A74079 /* OnboardingNextView.swift */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = OnboardingNextView.swift; sourceTree = ""; tabWidth = 4; }; D87BFC8A291D5C6B00FEE264 /* MastodonLoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonLoginView.swift; sourceTree = ""; }; D87BFC8C291EB81200FEE264 /* MastodonLoginViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonLoginViewModel.swift; sourceTree = ""; }; @@ -3231,6 +3235,7 @@ cs, sl, el, + be, ); mainGroup = DB427DC925BAA00100D1B89D; packageReferences = ( @@ -4050,6 +4055,7 @@ 2AB501522992443C00346092 /* eu */, 2AB501542992443D00346092 /* ar */, D87DC50C2A17C32F00219C5F /* el */, + D82463532A52B47B00A3DBDD /* be */, ); name = WidgetExtension.intentdefinition; sourceTree = ""; @@ -4085,6 +4091,7 @@ DB96C25D292505FE00F3B85D /* cs */, DB96C260292506D600F3B85D /* sl */, D87DC50B2A17C32E00219C5F /* el */, + D82463522A52B47B00A3DBDD /* be */, ); name = Intents.intentdefinition; sourceTree = ""; @@ -4119,6 +4126,7 @@ DB96C25E292505FF00F3B85D /* cs */, DB96C261292506D700F3B85D /* sl */, D87DC50D2A17C32F00219C5F /* el */, + D82463542A52B47B00A3DBDD /* be */, ); name = InfoPlist.strings; sourceTree = ""; @@ -4169,6 +4177,7 @@ DB96C25F292505FF00F3B85D /* cs */, DB96C262292506D700F3B85D /* sl */, D87DC50E2A17C32F00219C5F /* el */, + D82463552A52B47B00A3DBDD /* be */, ); name = Intents.stringsdict; sourceTree = ""; diff --git a/Mastodon/Resources/be.lproj/InfoPlist.strings b/Mastodon/Resources/be.lproj/InfoPlist.strings new file mode 100644 index 000000000..b7c5f498d --- /dev/null +++ b/Mastodon/Resources/be.lproj/InfoPlist.strings @@ -0,0 +1,4 @@ +"NSCameraUsageDescription" = "Выкарыстоўваецца, каб зрабіць фатаграфію для статусу допісу"; +"NSPhotoLibraryAddUsageDescription" = "Выкарыстоўваецца для захавання фатаграфій у бібліятэку"; +"NewPostShortcutItemTitle" = "Новы допіс"; +"SearchShortcutItemTitle" = "Пошук"; \ No newline at end of file diff --git a/MastodonIntent/be.lproj/Intents.strings b/MastodonIntent/be.lproj/Intents.strings new file mode 100644 index 000000000..ce65667c3 --- /dev/null +++ b/MastodonIntent/be.lproj/Intents.strings @@ -0,0 +1,51 @@ +"16wxgf" = "Апублікаваць у Mastodon"; + +"751xkl" = "Тэкставае змесціва"; + +"CsR7G2" = "Апублікаваць у Mastodon"; + +"HZSGTr" = "Які кантэнт публікаваць?"; + +"HdGikU" = "Памылка пры публікацыі"; + +"KDNTJ4" = "Прычына памылкі"; + +"RHxKOw" = "Адправіць допіс з тэкстам"; + +"RxSqsb" = "Допіс"; + +"WCIR3D" = "Апублікаваць ${content} у Mastodon"; + +"ZKJSNu" = "Допіс"; + +"ZS1XaK" = "${content}"; + +"ZbSjzC" = "Бачнасць"; + +"Zo4jgJ" = "Бачнасць допісу"; + +"apSxMG-dYQ5NN" = "Знойдзена ${count} варыянтаў, якія адпавядаюць \"Публічны\"."; + +"apSxMG-ehFLjY" = "Знойдзена ${count} варыянтаў, якія адпавядаюць \"Толькі для падпісчыкаў\"."; + +"ayoYEb-dYQ5NN" = "${content}, публічны"; + +"ayoYEb-ehFLjY" = "${content}, толькі для падпісчыкаў"; + +"dUyuGg" = "Апублікаваць у Mastodon"; + +"dYQ5NN" = "Публічны"; + +"ehFLjY" = "Толькі для падпісчыкаў"; + +"gfePDu" = "Памылка пры публікацыі. ${failureReason}"; + +"k7dbKQ" = "Допіс паспяхова адпраўлены."; + +"oGiqmY-dYQ5NN" = "Вы хочаце, каб гэты допіс быў \"Публічны\"?"; + +"oGiqmY-ehFLjY" = "Вы хочаце, каб гэты допіс быў \"Толькі для падпісчыкаў\"?"; + +"rM6dvp" = "URL"; + +"ryJLwG" = "Допіс паспяхова адпраўлены. "; diff --git a/MastodonIntent/be.lproj/Intents.stringsdict b/MastodonIntent/be.lproj/Intents.stringsdict new file mode 100644 index 000000000..5a39d5e64 --- /dev/null +++ b/MastodonIntent/be.lproj/Intents.stringsdict @@ -0,0 +1,54 @@ + + + + + There are ${count} options matching ‘${content}’. - 2 + + NSStringLocalizedFormatKey + There are %#@count_option@ matching ‘${content}’. + count_option + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + %ld + zero + 0 options + one + 1 option + two + 2 options + few + %ld options + many + %ld options + other + %ld options + + + There are ${count} options matching ‘${visibility}’. + + NSStringLocalizedFormatKey + There are %#@count_option@ matching ‘${visibility}’. + count_option + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + %ld + zero + 0 options + one + 1 option + two + 2 options + few + %ld options + many + %ld options + other + %ld options + + + + diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/be.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/be.lproj/Localizable.strings new file mode 100644 index 000000000..01b3aff93 --- /dev/null +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/be.lproj/Localizable.strings @@ -0,0 +1,559 @@ +"Common.Alerts.BlockDomain.BlockEntireDomain" = "Заблакіраваць дамен"; +"Common.Alerts.BlockDomain.Title" = "Вы абсалютна дакладна ўпэўнены, што хочаце заблакіраваць %@ зусім? У большасці выпадкаў, дастаткова некалькіх мэтавых блакіровак ці ігнараванняў. Вы перастанеце бачыць змесціва з гэтага дамену і вашы падпіскі з гэтага дамену будуць выдаленыя."; +"Common.Alerts.CleanCache.Message" = "Паспяхова ачышчаны %@ кэшу."; +"Common.Alerts.CleanCache.Title" = "Ачысціць кэш"; +"Common.Alerts.Common.PleaseTryAgain" = "Паспрабуйце яшчэ раз."; +"Common.Alerts.Common.PleaseTryAgainLater" = "Паўтарыце спробу пазней."; +"Common.Alerts.DeletePost.Message" = "Вы ўпэўненыя, што хочаце выдаліць гэты допіс?"; +"Common.Alerts.DeletePost.Title" = "Выдаліць допіс"; +"Common.Alerts.DiscardPostContent.Message" = "Пацвердзіце, каб скасаваць змесціва допісу."; +"Common.Alerts.DiscardPostContent.Title" = "Скасаваць чарнавік"; +"Common.Alerts.EditProfileFailure.Message" = "Не атрымалася змяніць профіль. Паспрабуйце яшчэ раз."; +"Common.Alerts.EditProfileFailure.Title" = "Памылка пры рэдагаванні профілю"; +"Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "Немагчыма дадаць больш за адно відэа."; +"Common.Alerts.PublishPostFailure.AttachmentsMessage.VideoAttachWithPhoto" = "Немагчыма прымацаваць відэа да допісу, які ўжо змяшчае выявы."; +"Common.Alerts.PublishPostFailure.Message" = "Не ўдалося апублікаваць допіс. +Праверце злучэнне з інтэрнэтам."; +"Common.Alerts.PublishPostFailure.Title" = "Памылка пры публікацыі"; +"Common.Alerts.SavePhotoFailure.Message" = "Дайце дазвол на доступ да бібліятэкі фатаграфій, каб захаваць фатаграфію."; +"Common.Alerts.SavePhotoFailure.Title" = "Памылка пры захаванні фотам"; +"Common.Alerts.ServerError.Title" = "Памылка сервера"; +"Common.Alerts.SignOut.Confirm" = "Выйсці"; +"Common.Alerts.SignOut.Message" = "Вы ўпэўненыя, што хочаце выйсці?"; +"Common.Alerts.SignOut.Title" = "Выйсці"; +"Common.Alerts.SignUpFailure.Title" = "Памылка пры рэгістрацыі"; +"Common.Alerts.TranslationFailed.Button" = "Добра"; +"Common.Alerts.TranslationFailed.Message" = "Збой перакладу. Магчыма, адміністратар не ўключыў пераклады на гэтым серверы або гэты сервер працуе са старой версіяй Mastodon, дзе пераклады яшчэ не падтрымліваюцца."; +"Common.Alerts.TranslationFailed.Title" = "Нататка"; +"Common.Alerts.VoteFailure.PollEnded" = "Апытанне завяршылася"; +"Common.Alerts.VoteFailure.Title" = "Памылка пры галасаванні"; +"Common.Controls.Actions.Add" = "Дадаць"; +"Common.Controls.Actions.Back" = "Назад"; +"Common.Controls.Actions.BlockDomain" = "Заблакіраваць %@"; +"Common.Controls.Actions.Bookmark" = "Bookmark"; +"Common.Controls.Actions.Cancel" = "Скасаваць"; +"Common.Controls.Actions.Compose" = "Стварыць"; +"Common.Controls.Actions.Confirm" = "Пацвердзіць"; +"Common.Controls.Actions.Continue" = "Працягнуць"; +"Common.Controls.Actions.Copy" = "Скапіраваць"; +"Common.Controls.Actions.CopyPhoto" = "Капіраваць фота"; +"Common.Controls.Actions.Delete" = "Выдаліць"; +"Common.Controls.Actions.Discard" = "Скасаваць"; +"Common.Controls.Actions.Done" = "Гатова"; +"Common.Controls.Actions.Edit" = "Рэдагаваць"; +"Common.Controls.Actions.EditPost" = "Рэдагаваць"; +"Common.Controls.Actions.FindPeople" = "Знайсці людзей, каб падпісацца"; +"Common.Controls.Actions.Follow" = "Follow %@"; +"Common.Controls.Actions.ManuallySearch" = "Замест гэтага шукайце ўручную"; +"Common.Controls.Actions.Next" = "Далей"; +"Common.Controls.Actions.Ok" = "OK"; +"Common.Controls.Actions.Open" = "Адкрыць"; +"Common.Controls.Actions.OpenInBrowser" = "Адкрыць у браўзеры"; +"Common.Controls.Actions.OpenInSafari" = "Адкрыць у Safari"; +"Common.Controls.Actions.Preview" = "Перадпрагляд"; +"Common.Controls.Actions.Previous" = "Назад"; +"Common.Controls.Actions.Remove" = "Выдаліць"; +"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; +"Common.Controls.Actions.Reply" = "Адказаць"; +"Common.Controls.Actions.ReportUser" = "Паскардзіцца на %@"; +"Common.Controls.Actions.Save" = "Захаваць"; +"Common.Controls.Actions.SavePhoto" = "Захаваць фота"; +"Common.Controls.Actions.SeeMore" = "Паказаць больш"; +"Common.Controls.Actions.Settings" = "Налады"; +"Common.Controls.Actions.Share" = "Абагуліць"; +"Common.Controls.Actions.SharePost" = "Абагуліць допіс"; +"Common.Controls.Actions.ShareUser" = "Абагуліць %@"; +"Common.Controls.Actions.SignIn" = "Увайсці"; +"Common.Controls.Actions.Skip" = "Прапусціць"; +"Common.Controls.Actions.TakePhoto" = "Зрабіць фота"; +"Common.Controls.Actions.TranslatePost.Title" = "Перакласці з %@"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Невядомая"; +"Common.Controls.Actions.TryAgain" = "Паўтарыце спробу"; +"Common.Controls.Actions.UnblockDomain" = "Разблакіраваць %@"; +"Common.Controls.Actions.Unfollow" = "Unfollow %@"; +"Common.Controls.Friendship.Block" = "Заблакіраваць"; +"Common.Controls.Friendship.BlockDomain" = "Заблакіраваць %@"; +"Common.Controls.Friendship.BlockUser" = "Заблакіраваць %@"; +"Common.Controls.Friendship.Blocked" = "Заблакіраваны"; +"Common.Controls.Friendship.EditInfo" = "Рэдагаваць інфармацыю"; +"Common.Controls.Friendship.Follow" = "Падпісацца"; +"Common.Controls.Friendship.Following" = "Падпісаны"; +"Common.Controls.Friendship.HideReblogs" = "Схаваць пашырэнні"; +"Common.Controls.Friendship.Mute" = "Ігнараваць"; +"Common.Controls.Friendship.MuteUser" = "Ігнараваць %@"; +"Common.Controls.Friendship.Muted" = "Ігнаруецца"; +"Common.Controls.Friendship.Pending" = "Чакаецца"; +"Common.Controls.Friendship.Request" = "Запыт"; +"Common.Controls.Friendship.ShowReblogs" = "Паказаць пашырэнні"; +"Common.Controls.Friendship.Unblock" = "Разблакіраваць"; +"Common.Controls.Friendship.UnblockUser" = "Разблакіраваць %@"; +"Common.Controls.Friendship.Unmute" = "Не ігнараваць"; +"Common.Controls.Friendship.UnmuteUser" = "Не ігнараваць %@"; +"Common.Controls.Keyboard.Common.ComposeNewPost" = "Стварыць новы допіс"; +"Common.Controls.Keyboard.Common.OpenSettings" = "Адкрыць налады"; +"Common.Controls.Keyboard.Common.ShowFavorites" = "Паказаць абраныя"; +"Common.Controls.Keyboard.Common.SwitchToTab" = "Пераключыць на %@"; +"Common.Controls.Keyboard.SegmentedControl.NextSection" = "Наступны раздзел"; +"Common.Controls.Keyboard.SegmentedControl.PreviousSection" = "Папярэдні раздзел"; +"Common.Controls.Keyboard.Timeline.NextStatus" = "Наступны допіс"; +"Common.Controls.Keyboard.Timeline.OpenAuthorProfile" = "Адкрыць профіль аўтара"; +"Common.Controls.Keyboard.Timeline.OpenRebloggerProfile" = "Адкрыць профіль пашырыўшага"; +"Common.Controls.Keyboard.Timeline.OpenStatus" = "Адкрыць допіс"; +"Common.Controls.Keyboard.Timeline.PreviewImage" = "Перадпрагляд відарыса"; +"Common.Controls.Keyboard.Timeline.PreviousStatus" = "Папярэдні допіс"; +"Common.Controls.Keyboard.Timeline.ReplyStatus" = "Адказаць на допіс"; +"Common.Controls.Keyboard.Timeline.ToggleContentWarning" = "Уключыць/адключыць папярэджанне аб змесціве"; +"Common.Controls.Keyboard.Timeline.ToggleFavorite" = "Дадаць ці прыбраць з абранага"; +"Common.Controls.Keyboard.Timeline.ToggleReblog" = "Пашырыць ці ўбраць пашырэнне"; +"Common.Controls.Status.Actions.A11YLabels.Reblog" = "Пашырыць"; +"Common.Controls.Status.Actions.A11YLabels.Unreblog" = "Скасаваць пашырэнне"; +"Common.Controls.Status.Actions.Favorite" = "Абранае"; +"Common.Controls.Status.Actions.Hide" = "Схаваць"; +"Common.Controls.Status.Actions.Menu" = "Меню"; +"Common.Controls.Status.Actions.Reblog" = "Пашырыць"; +"Common.Controls.Status.Actions.Reply" = "Адказаць"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Падзяліцеся спасылкай у допісе"; +"Common.Controls.Status.Actions.ShowGif" = "Паказаць GIF"; +"Common.Controls.Status.Actions.ShowImage" = "Паказаць відарыс"; +"Common.Controls.Status.Actions.ShowVideoPlayer" = "Паказаць відэаплэер"; +"Common.Controls.Status.Actions.TapThenHoldToShowMenu" = "Націсніце і ўтрымлівайце, каб паказаць меню"; +"Common.Controls.Status.Actions.Unfavorite" = "Выдаліць з абраных"; +"Common.Controls.Status.Actions.Unreblog" = "Скасаваць пашырэнне"; +"Common.Controls.Status.Buttons.EditHistoryDetail" = "Апошняе рэдагаванне %@"; +"Common.Controls.Status.Buttons.EditHistoryTitle" = "Гісторыя рэдагавання"; +"Common.Controls.Status.Buttons.FavoritesTitle" = "Абраныя"; +"Common.Controls.Status.Buttons.ReblogsTitle" = "Пашырэнні"; +"Common.Controls.Status.ContentWarning" = "Папярэджанне аб змесціве"; +"Common.Controls.Status.EditHistory.OriginalPost" = "Арыгінальнае паведамленне · %@"; +"Common.Controls.Status.EditHistory.Title" = "Гісторыя рэдагавання"; +"Common.Controls.Status.EditedAtTimestampPrefix" = "Адрэдагавана %@"; +"Common.Controls.Status.LinkViaUser" = "%@ праз %@"; +"Common.Controls.Status.LoadEmbed" = "Загрузіць убудаваны"; +"Common.Controls.Status.Media.AccessibilityLabel" = "%@, далучэнне %d з %d"; +"Common.Controls.Status.Media.ExpandGifHint" = "Разгортванне GIF. Двойчы націсніце і ўтрымлівайце, каб паказаць дзеянні"; +"Common.Controls.Status.Media.ExpandImageHint" = "Разгортванне відарыса. Двойчы націсніце і ўтрымлівайце, каб паказаць дзеянні"; +"Common.Controls.Status.Media.ExpandVideoHint" = "Паказ відэаплэера. Двойчы націсніце і ўтрымлівайце, каб паказаць дзеянні"; +"Common.Controls.Status.MediaContentWarning" = "Націсніце ў любым месцы, каб паказаць"; +"Common.Controls.Status.MetaEntity.Email" = "Электронная пошта: %@"; +"Common.Controls.Status.MetaEntity.Hashtag" = "Хэштэг: %@"; +"Common.Controls.Status.MetaEntity.Mention" = "Паказаць профіль: %@"; +"Common.Controls.Status.MetaEntity.Url" = "Спасылка: %@"; +"Common.Controls.Status.Poll.Closed" = "Завершана"; +"Common.Controls.Status.Poll.Vote" = "Прагаласаваць"; +"Common.Controls.Status.PostedViaApplication" = "%@ праз %@"; +"Common.Controls.Status.SensitiveContent" = "Далікатнае змесціва"; +"Common.Controls.Status.ShowPost" = "Паказаць допіс"; +"Common.Controls.Status.ShowUserProfile" = "Паказаць профіль карыстальніка"; +"Common.Controls.Status.Tag.Email" = "Электронная пошта"; +"Common.Controls.Status.Tag.Emoji" = "Эмодзі"; +"Common.Controls.Status.Tag.Hashtag" = "Хэштэг"; +"Common.Controls.Status.Tag.Link" = "Спасылка"; +"Common.Controls.Status.Tag.Mention" = "Згадванне"; +"Common.Controls.Status.Tag.Url" = "URL"; +"Common.Controls.Status.TapToReveal" = "Націсніце, каб паказаць"; +"Common.Controls.Status.Translation.ShowOriginal" = "Паказаць арыгінал"; +"Common.Controls.Status.Translation.TranslatedFrom" = "Перакладзена з %@ з дапамогай %@"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Невядомая"; +"Common.Controls.Status.Translation.UnknownProvider" = "Невядомы"; +"Common.Controls.Status.UserReblogged" = "%@ пашырыў"; +"Common.Controls.Status.UserRepliedTo" = "Адказаў %@"; +"Common.Controls.Status.Visibility.Direct" = "Толькі згаданы карыстальнік можа бачыць гэты пост."; +"Common.Controls.Status.Visibility.Private" = "Толькі іх падпісчыкі могуць бачыць гэты допіс."; +"Common.Controls.Status.Visibility.PrivateFromMe" = "Толькі мае падпісчыкі могуць бачыць гэты допіс."; +"Common.Controls.Status.Visibility.Unlisted" = "Кожны можа бачыць гэты допіс, але ён не адлюстроўваецца ў публічнай стужцы."; +"Common.Controls.Tabs.A11Y.Explore" = "Агляд"; +"Common.Controls.Tabs.A11Y.Search" = "Пошук"; +"Common.Controls.Tabs.Home" = "Галоўная"; +"Common.Controls.Tabs.Notifications" = "Апавяшчэнні"; +"Common.Controls.Tabs.Profile" = "Профіль"; +"Common.Controls.Tabs.SearchAndExplore" = "Шукайце і адкрывайце"; +"Common.Controls.Timeline.Filtered" = "Адфільтравана"; +"Common.Controls.Timeline.Header.BlockedWarning" = "Вы не можаце праглядаць профіль гэтага карыстальніка, +пакуль ён не разблакіруе вас."; +"Common.Controls.Timeline.Header.BlockingWarning" = "Вы не можаце праглядаць профіль гэтага карыстальніка, +пакуль не разблакіруеце яго. +Вось так для іх выглядае ваш профіль."; +"Common.Controls.Timeline.Header.NoStatusFound" = "Допіс не знойдзены"; +"Common.Controls.Timeline.Header.SuspendedWarning" = "Уліковы запіс гэтага карыстальніка прыпынены."; +"Common.Controls.Timeline.Header.UserBlockedWarning" = "Вы не можаце праглядаць профіль %@, +пакуль ён не разблакіруе вас."; +"Common.Controls.Timeline.Header.UserBlockingWarning" = "Вы не можаце праглядаць профіль %@, +пакуль не разблакіруеце яго. +Вось так для іх выглядае ваш профіль."; +"Common.Controls.Timeline.Header.UserSuspendedWarning" = "Уліковы запіс %@ прыпынены."; +"Common.Controls.Timeline.Loader.LoadMissingPosts" = "Загрузіць адсутныя допісы"; +"Common.Controls.Timeline.Loader.LoadingMissingPosts" = "Загрузка адсутных допісаў..."; +"Common.Controls.Timeline.Loader.ShowMoreReplies" = "Паказаць больш адказаў"; +"Common.Controls.Timeline.Timestamp.Now" = "Толькі што"; +"Common.UserList.FollowersCount" = "%@ followers"; +"Common.UserList.NoVerifiedLink" = "No verified link"; +"Extension.OpenIn.InvalidLinkError" = "Здаецца, гэта несапраўдная спасылка на Mastodon."; +"Scene.AccountList.AddAccount" = "Дадаць уліковы запіс"; +"Scene.AccountList.DismissAccountSwitcher" = "Закрыць пераключальнік уліковых запісаў"; +"Scene.AccountList.TabBarHint" = "Бягучы профіль: %@. Двойчы націсніце і ўтрымлівайце, каб паказаць пераключальнік уліковых запісаў"; +"Scene.Bookmark.Title" = "Закладкі"; +"Scene.Compose.Accessibility.AppendAttachment" = "Дадаць далучэнне"; +"Scene.Compose.Accessibility.AppendPoll" = "Дадаць апытанне"; +"Scene.Compose.Accessibility.CustomEmojiPicker" = "Меню карыстальніцкіх эмодзі"; +"Scene.Compose.Accessibility.DisableContentWarning" = "Адключыць папярэджанне аб змесціве"; +"Scene.Compose.Accessibility.EnableContentWarning" = "Уключыць папярэджанне аб змесціве"; +"Scene.Compose.Accessibility.PostOptions" = "Параметры допісу"; +"Scene.Compose.Accessibility.PostVisibilityMenu" = "Меню бачнасці допісу"; +"Scene.Compose.Accessibility.PostingAs" = "Апублікаваць як %@"; +"Scene.Compose.Accessibility.RemovePoll" = "Выдаліць апытанне"; +"Scene.Compose.Attachment.AttachmentBroken" = "Гэты %@ пашкоджаны і не можа быць +запампаваны ў Mastodon."; +"Scene.Compose.Attachment.AttachmentTooLarge" = "Далучэнне занадта вялікае"; +"Scene.Compose.Attachment.CanNotRecognizeThisMediaAttachment" = "Немагчыма распазнаць гэты медыяфайл"; +"Scene.Compose.Attachment.CompressingState" = "Сцісканне..."; +"Scene.Compose.Attachment.DescriptionPhoto" = "Апішыце фота для людзей са слабым зрокам..."; +"Scene.Compose.Attachment.DescriptionVideo" = "Апішыце відэа для людзей са слабым зрокам..."; +"Scene.Compose.Attachment.LoadFailed" = "Не ўдалося загрузіць"; +"Scene.Compose.Attachment.Photo" = "фота"; +"Scene.Compose.Attachment.ServerProcessingState" = "Апрацоўка сервера..."; +"Scene.Compose.Attachment.UploadFailed" = "Не ўдалося запампаваць"; +"Scene.Compose.Attachment.Video" = "відэа"; +"Scene.Compose.AutoComplete.SpaceToAdd" = "Прабел, каб дадаць"; +"Scene.Compose.ComposeAction" = "Апублікаваць"; +"Scene.Compose.ContentInputPlaceholder" = "Напішыце тое, аб чым думаеце"; +"Scene.Compose.ContentWarning.Placeholder" = "Напішыце сваё папярэджанне тут..."; +"Scene.Compose.Keyboard.AppendAttachmentEntry" = "Дадаць далучэнне - %@"; +"Scene.Compose.Keyboard.DiscardPost" = "Скасаваць допіс"; +"Scene.Compose.Keyboard.PublishPost" = "Апублікаваць допіс"; +"Scene.Compose.Keyboard.SelectVisibilityEntry" = "Выберыце бачнасць - %@"; +"Scene.Compose.Keyboard.ToggleContentWarning" = "Уключыць/адключыць папярэджанне аб змесціве"; +"Scene.Compose.Keyboard.TogglePoll" = "Адкрыць/закрыць апытанне"; +"Scene.Compose.Language.Other" = "Іншая мова…"; +"Scene.Compose.Language.Recent" = "Нядаўні"; +"Scene.Compose.Language.Suggested" = "Прапанаваныя"; +"Scene.Compose.Language.Title" = "Мова допісу"; +"Scene.Compose.MediaSelection.Browse" = "Агляд"; +"Scene.Compose.MediaSelection.Camera" = "Зрабіць фота"; +"Scene.Compose.MediaSelection.PhotoLibrary" = "Галерэя"; +"Scene.Compose.Poll.AddOption" = "Дадаць варыянт"; +"Scene.Compose.Poll.DurationTime" = "Працягласць: %@"; +"Scene.Compose.Poll.MoveDown" = "Перамясціць уніз"; +"Scene.Compose.Poll.MoveUp" = "Перамясціць уверх"; +"Scene.Compose.Poll.OneDay" = "1 дзень"; +"Scene.Compose.Poll.OneHour" = "1 гадзіна"; +"Scene.Compose.Poll.OptionNumber" = "Варыянт %ld"; +"Scene.Compose.Poll.RemoveOption" = "Выдаліць варыянт"; +"Scene.Compose.Poll.SevenDays" = "7 дзён"; +"Scene.Compose.Poll.SixHours" = "6 гадзін"; +"Scene.Compose.Poll.ThePollHasEmptyOption" = "Апытанне мае пусты варыянт"; +"Scene.Compose.Poll.ThePollIsInvalid" = "Апытанне мае памылкі"; +"Scene.Compose.Poll.ThirtyMinutes" = "30 хвілін"; +"Scene.Compose.Poll.ThreeDays" = "3 дні"; +"Scene.Compose.Poll.Title" = "Апытанне"; +"Scene.Compose.ReplyingToUser" = "адказ %@"; +"Scene.Compose.Title.EditPost" = "Рэдагаваць допіс"; +"Scene.Compose.Title.NewPost" = "Новы допіс"; +"Scene.Compose.Title.NewReply" = "Новы адказ"; +"Scene.Compose.Visibility.Direct" = "Толькі людзі, якіх я згадаў"; +"Scene.Compose.Visibility.Private" = "Толькі для падпісчыкаў"; +"Scene.Compose.Visibility.Public" = "Публічны"; +"Scene.Compose.Visibility.Unlisted" = "Не ў спісе"; +"Scene.ConfirmEmail.Button.Resend" = "Адправіць паўторна"; +"Scene.ConfirmEmail.DidntGetLink.Prefix" = "Не атрымалі спасылку?"; +"Scene.ConfirmEmail.DidntGetLink.ResendIn" = "Адправіць паўторна (%@)"; +"Scene.ConfirmEmail.DidntGetLink.ResendNow" = "Адпраўце зараз паўторна."; +"Scene.ConfirmEmail.DontReceiveEmail.Description" = "Праверце, ці правільны ваш адрас электроннай пошты, а таксама папку са спамам, калі вы гэтага яшчэ не зрабілі."; +"Scene.ConfirmEmail.DontReceiveEmail.ResendEmail" = "Адправіць email паўторна"; +"Scene.ConfirmEmail.DontReceiveEmail.Title" = "Праверце электронную пошту"; +"Scene.ConfirmEmail.OpenEmailApp.Description" = "Мы толькі што даслалі вам электронны ліст. Праверце папку са спамам, калі не знайшлі яго."; +"Scene.ConfirmEmail.OpenEmailApp.Mail" = "Пошта"; +"Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "Адкрыць паштовы кліент"; +"Scene.ConfirmEmail.OpenEmailApp.Title" = "Праверыць свой паштовую скрыню."; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Націсніце на спасылку, якую мы адправілі вам для праверкі %@. Мы чакаем вас тут."; +"Scene.ConfirmEmail.Title" = "Праверце паштовую скрыню"; +"Scene.Discovery.Intro" = "Допісы, што набіраюць папулярнасць у вашым кутку Mastodon."; +"Scene.Discovery.Tabs.Community" = "Супольнасць"; +"Scene.Discovery.Tabs.ForYou" = "Для вас"; +"Scene.Discovery.Tabs.Hashtags" = "Хэштэгі"; +"Scene.Discovery.Tabs.News" = "Навіны"; +"Scene.Discovery.Tabs.Posts" = "Допісы"; +"Scene.Familiarfollowers.FollowedByNames" = "Мае сярод падпісчыкаў %@"; +"Scene.Familiarfollowers.Title" = "Падпісчыкі, якіх вы ведаеце"; +"Scene.Favorite.Title" = "Абраны"; +"Scene.FavoritedBy.Title" = "Дадалі ў абранае"; +"Scene.FollowedTags.Actions.Follow" = "Падпісацца"; +"Scene.FollowedTags.Actions.Unfollow" = "Адпісацца"; +"Scene.FollowedTags.Header.Participants" = "ўдзельнікі"; +"Scene.FollowedTags.Header.Posts" = "допісаў"; +"Scene.FollowedTags.Header.PostsToday" = "допісаў сёння"; +"Scene.FollowedTags.Title" = "Тэгі, за якімі вы сочыце"; +"Scene.Follower.Footer" = "Падпісчыкі з іншых сервераў не адлюстроўваюцца."; +"Scene.Follower.Title" = "падпісчык"; +"Scene.Following.Footer" = "Падпіскі з іншых сервераў не адлюстроўваюцца."; +"Scene.Following.Title" = "падпісаны"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Націсніце, каб пракруціць уверх, і зноў націсніце, каб перайсці да папярэдняга месца"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon"; +"Scene.HomeTimeline.NavigationBarState.NewPosts" = "Паказаць новыя"; +"Scene.HomeTimeline.NavigationBarState.Offline" = "Па-за сеткай"; +"Scene.HomeTimeline.NavigationBarState.Published" = "Апублікавана!"; +"Scene.HomeTimeline.NavigationBarState.Publishing" = "Допіс публікуецца..."; +"Scene.HomeTimeline.Title" = "Галоўная"; +"Scene.Login.ServerSearchField.Placeholder" = "Увядзіце URL або адрас сервера"; +"Scene.Login.Subtitle" = "Увайдзіце на серверы, дзе вы стварылі свой уліковы запіс."; +"Scene.Login.Title" = "З вяртаннем"; +"Scene.Notification.FollowRequest.Accept" = "Прыняць"; +"Scene.Notification.FollowRequest.Accepted" = "Прынята"; +"Scene.Notification.FollowRequest.Reject" = "адхіліць"; +"Scene.Notification.FollowRequest.Rejected" = "Адхілена"; +"Scene.Notification.Keyobard.ShowEverything" = "Паказаць усё"; +"Scene.Notification.Keyobard.ShowMentions" = "Паказаць згадванні"; +"Scene.Notification.NotificationDescription.FavoritedYourPost" = "дадаў ваш допіс у абранае"; +"Scene.Notification.NotificationDescription.FollowedYou" = "падпісаўся на вас"; +"Scene.Notification.NotificationDescription.MentionedYou" = "згадаў вас"; +"Scene.Notification.NotificationDescription.PollHasEnded" = "апытанне завяршылася"; +"Scene.Notification.NotificationDescription.RebloggedYourPost" = "пашырыў ваш допіс"; +"Scene.Notification.NotificationDescription.RequestToFollowYou" = "адправіў запыт на падпіску"; +"Scene.Notification.Title.Everything" = "Усе"; +"Scene.Notification.Title.Mentions" = "Згадванні"; +"Scene.Preview.Keyboard.ClosePreview" = "Зачыніць перадпрагляд"; +"Scene.Preview.Keyboard.ShowNext" = "Паказаць наступнае"; +"Scene.Preview.Keyboard.ShowPrevious" = "Паказаць папярэдняе"; +"Scene.Privacy.Button.Confirm" = "Я згодны"; +"Scene.Privacy.Description" = "Хоць праграма Mastodon не збірае ніякіх даных, сервер, праз які вы зарэгістраваліся, можа мець іншую палітыку. Знайдзіце хвілінку, каб азнаёміцца і пагадзіцца з палітыкай прыватнасці праграмы Mastodon і палітыкай прыватнасці вашага сервера."; +"Scene.Privacy.Policy.Ios" = "Палітыка прыватнасці - Mastodon для iOS"; +"Scene.Privacy.Policy.Server" = "Палітыка прыватнасці - %@"; +"Scene.Privacy.Title" = "Прыватнасць"; +"Scene.Profile.Accessibility.DoubleTapToOpenTheList" = "Двойчы націсніце, каб адкрыць спіс"; +"Scene.Profile.Accessibility.EditAvatarImage" = "Рэдагаваць аватар"; +"Scene.Profile.Accessibility.ShowAvatarImage" = "Паказаць аватар карыстальніка"; +"Scene.Profile.Accessibility.ShowBannerImage" = "Паказаць відарыс банера"; +"Scene.Profile.Dashboard.FamiliarFollowers" = "узаемныя адносіны"; +"Scene.Profile.Dashboard.MyFollowers" = "падпісчыкі"; +"Scene.Profile.Dashboard.MyFollowing" = "падпісаны"; +"Scene.Profile.Dashboard.MyPosts" = "допісы"; +"Scene.Profile.Dashboard.OtherFollowers" = "падпісчыкі"; +"Scene.Profile.Dashboard.OtherFollowing" = "падпісаны"; +"Scene.Profile.Dashboard.OtherPosts" = "допісы"; +"Scene.Profile.Fields.AddRow" = "Дадаць радок"; +"Scene.Profile.Fields.Joined" = "Далучыўся"; +"Scene.Profile.Fields.Placeholder.Content" = "Змесціва"; +"Scene.Profile.Fields.Placeholder.Label" = "Пазнака"; +"Scene.Profile.Fields.Verified.Long" = "Права ўласнасці на гэтую спасылку праверана %@"; +"Scene.Profile.Fields.Verified.Short" = "Спраўджана %@"; +"Scene.Profile.Header.FollowsYou" = "Падпісаны(-а) на вас"; +"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Заблакіраваць %@?"; +"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Заблакіраваць уліковы запіс"; +"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Message" = "Пацвердзіце, каб схаваць пашырэнні"; +"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Title" = "Схаваць пашырэнні"; +"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Ігнараваць %@?"; +"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Title" = "Ігнараваць уліковы запіс"; +"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Message" = "Пацвердзіце, каб паказаць пашырэнні"; +"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Title" = "Паказаць пашырэнні"; +"Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Message" = "Разблакіраваць %@?"; +"Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Title" = "Разблакіраваць уліковы запіс"; +"Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.Message" = "Не ігнараваць %@?"; +"Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.Title" = "Не ігнараваць уліковы запіс"; +"Scene.Profile.SegmentedControl.About" = "Аб праграме"; +"Scene.Profile.SegmentedControl.Media" = "Медыя"; +"Scene.Profile.SegmentedControl.Posts" = "Допісы"; +"Scene.Profile.SegmentedControl.PostsAndReplies" = "Допісы і адказы"; +"Scene.Profile.SegmentedControl.Replies" = "Адказы"; +"Scene.RebloggedBy.Title" = "Пашырана"; +"Scene.Register.Error.Item.Agreement" = "Пагадненне"; +"Scene.Register.Error.Item.Email" = "Электронная пошта"; +"Scene.Register.Error.Item.Locale" = "Мова"; +"Scene.Register.Error.Item.Password" = "Пароль"; +"Scene.Register.Error.Item.Reason" = "Прычына"; +"Scene.Register.Error.Item.Username" = "Імя карыстальніка"; +"Scene.Register.Error.Reason.Accepted" = "%@ павінна быць прынята"; +"Scene.Register.Error.Reason.Blank" = "%@ абавязковы"; +"Scene.Register.Error.Reason.Blocked" = "%@ змяшчае забароненага пастаўшчыка email"; +"Scene.Register.Error.Reason.Inclusion" = "%@ не з'яўляецца значэннем, якое падтрымліваецца"; +"Scene.Register.Error.Reason.Invalid" = "%@ несапраўдны"; +"Scene.Register.Error.Reason.Reserved" = "%@ з'яўляецца зарэзерваваным ключавым словам"; +"Scene.Register.Error.Reason.Taken" = "%@ ужо занята. Як наконт:"; +"Scene.Register.Error.Reason.TooLong" = "%@ занадта доўгі"; +"Scene.Register.Error.Reason.TooShort" = "%@ занадта кароткі"; +"Scene.Register.Error.Reason.Unreachable" = "%@ не існуе"; +"Scene.Register.Error.Special.EmailInvalid" = "Несапраўдны адрас электроннай пошты"; +"Scene.Register.Error.Special.PasswordTooShort" = "Пароль занадта кароткі (павінен быць не менш за 8 сімвалаў)"; +"Scene.Register.Error.Special.UsernameInvalid" = "Імя карыстальніка павінна змяшчаць толькі літары, лічбы і знак падкрэслівання"; +"Scene.Register.Error.Special.UsernameTooLong" = "Імя карыстальніка занадта доўгае (не можа быць больш за 30 сімвалаў)"; +"Scene.Register.Input.Avatar.Delete" = "Выдаліць"; +"Scene.Register.Input.DisplayName.Placeholder" = "бачнае імя"; +"Scene.Register.Input.Email.Placeholder" = "электронная пошта"; +"Scene.Register.Input.Invite.RegistrationUserInviteRequest" = "Чаму вы жадаеце далучыцца?"; +"Scene.Register.Input.Password.Accessibility.Checked" = "адзначаны галачкай"; +"Scene.Register.Input.Password.Accessibility.Unchecked" = "галачка знятая"; +"Scene.Register.Input.Password.CharacterLimit" = "8 сімвалаў"; +"Scene.Register.Input.Password.ConfirmationPlaceholder" = "Пацвердзіць пароль"; +"Scene.Register.Input.Password.Hint" = "Ваш пароль павінен змяшчаць мінімум восем сімвалаў"; +"Scene.Register.Input.Password.Placeholder" = "пароль"; +"Scene.Register.Input.Password.Require" = "Ваш пароль павінен мець як мінімум:"; +"Scene.Register.Input.Username.DuplicatePrompt" = "Гэта імя карыстальніка занята."; +"Scene.Register.Input.Username.Placeholder" = "імя карыстальніка"; +"Scene.Register.Input.Username.Suggestion" = "надзвычайны_%@"; +"Scene.Register.Title" = "Стварыць уліковы запіс"; +"Scene.Report.Content1" = "Ці ёсць іншыя допісы, якія вы хацелі б дадаць да скаргі?"; +"Scene.Report.Content2" = "Ці ёсць што-небудзь, што мадэратары павінны ведаць аб гэтай скарзе?"; +"Scene.Report.ReportSentTitle" = "Дзякуй за вашу скаргу, мы яе разгледзім."; +"Scene.Report.Reported" = "Мае скаргі"; +"Scene.Report.Send" = "Адправіць скаргу"; +"Scene.Report.SkipToSend" = "Дасылаю без каментарыя"; +"Scene.Report.Step1" = "Крок 1 з 2"; +"Scene.Report.Step2" = "Крок 2 з 2"; +"Scene.Report.StepFinal.BlockUser" = "Заблакіраваць %@"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "Не хочаце бачыць гэта?"; +"Scene.Report.StepFinal.MuteUser" = "Ігнараваць %@"; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "Яны больш не змогуць падпісвацца на вас або бачыць вашыя допісы, але змогуць бачыць, што яны былі заблакіраваны."; +"Scene.Report.StepFinal.Unfollow" = "Адпісацца"; +"Scene.Report.StepFinal.UnfollowUser" = "Адпісацца ад %@"; +"Scene.Report.StepFinal.Unfollowed" = "Адпісаліся"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "Калі вы бачыце на Mastodon нешта, што вам не падабаецца, вы можаце выдаліць чалавека са свайго асяроддзя."; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "Пакуль мы разглядаем яе, вы можаце прыняць меры супраць %@"; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "Вы не ўбачыце іх допісы або пашырэнні ў сваёй хатняй стужцы. Яны не даведаюцца, што вы іх ігнаруеце."; +"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "Што-небудзь яшчэ, што мы павінны ведаць?"; +"Scene.Report.StepFour.Step4Of4" = "Крок 4 з 4"; +"Scene.Report.StepOne.IDontLikeIt" = "Мне не падабаецца"; +"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "Гэта не тое, што вы хочаце бачыць"; +"Scene.Report.StepOne.ItViolatesServerRules" = "Гэта парушае правілы сервера"; +"Scene.Report.StepOne.ItsSomethingElse" = "Гэта нешта іншае"; +"Scene.Report.StepOne.ItsSpam" = "Гэта спам"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Шкодныя спасылкі, фальшывыя ўзаемадзеянні або адказы, што паўтараюцца"; +"Scene.Report.StepOne.SelectTheBestMatch" = "Выберыце найлепшы варыянт"; +"Scene.Report.StepOne.Step1Of4" = "Крок 1 з 4"; +"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "Гэта праблема не падпадае ні пад адну з катэгорыі"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "Што не так з гэтым уліковым запісам?"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "Што не так з гэтым допісам?"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "Што не так з %@?"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "Вам вядома, што гэта парушае пэўныя правілы"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Ці ёсць допісы, якія пацвярджаюць гэтую скаргу?"; +"Scene.Report.StepThree.SelectAllThatApply" = "Абярыце ўсе варыянты, што падыходзяць"; +"Scene.Report.StepThree.Step3Of4" = "Крок 3 з 4"; +"Scene.Report.StepTwo.IJustDon’tLikeIt" = "Мне не падабаецца"; +"Scene.Report.StepTwo.SelectAllThatApply" = "Абярыце ўсе варыянты, што падыходзяць"; +"Scene.Report.StepTwo.Step2Of4" = "Крок 2 з 4"; +"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "Якія правілы былі парушаны?"; +"Scene.Report.TextPlaceholder" = "Увядзіце або ўстаўце дадатковыя каментарыі"; +"Scene.Report.Title" = "Паскардзіцца на %@"; +"Scene.Report.TitleReport" = "Скарга"; +"Scene.Search.Recommend.Accounts.Description" = "Магчыма, вы захочаце падпісацца на гэтыя профілі"; +"Scene.Search.Recommend.Accounts.Follow" = "Падпісацца"; +"Scene.Search.Recommend.Accounts.Title" = "Вам могуць спадабацца"; +"Scene.Search.Recommend.ButtonText" = "Прагледзець усе"; +"Scene.Search.Recommend.HashTag.Description" = "Хэштэгі, якія прыцягваюць увагу"; +"Scene.Search.Recommend.HashTag.PeopleTalking" = "%@ чалавек размаўляе"; +"Scene.Search.Recommend.HashTag.Title" = "Папулярныя ў Mastodon"; +"Scene.Search.SearchBar.Cancel" = "Скасаваць"; +"Scene.Search.SearchBar.Placeholder" = "Пошук хэштэгаў і карыстальнікаў"; +"Scene.Search.Searching.Clear" = "Ачысціць"; +"Scene.Search.Searching.EmptyState.NoResults" = "Няма вынікаў"; +"Scene.Search.Searching.RecentSearch" = "Нядаўнія запыты"; +"Scene.Search.Searching.Segment.All" = "Усе"; +"Scene.Search.Searching.Segment.Hashtags" = "Хэштэгі"; +"Scene.Search.Searching.Segment.People" = "Людзі"; +"Scene.Search.Searching.Segment.Posts" = "Допісы"; +"Scene.Search.Title" = "Пошук"; +"Scene.ServerPicker.Button.Category.Academia" = "акадэмія"; +"Scene.ServerPicker.Button.Category.Activism" = "актывізм"; +"Scene.ServerPicker.Button.Category.All" = "Усе"; +"Scene.ServerPicker.Button.Category.AllAccessiblityDescription" = "Катэгорыя: Усе"; +"Scene.ServerPicker.Button.Category.Art" = "мастацтва"; +"Scene.ServerPicker.Button.Category.Food" = "ежа"; +"Scene.ServerPicker.Button.Category.Furry" = "фуры"; +"Scene.ServerPicker.Button.Category.Games" = "гульні"; +"Scene.ServerPicker.Button.Category.General" = "асноўныя"; +"Scene.ServerPicker.Button.Category.Journalism" = "журналістыка"; +"Scene.ServerPicker.Button.Category.Lgbt" = "лгбт"; +"Scene.ServerPicker.Button.Category.Music" = "музыка"; +"Scene.ServerPicker.Button.Category.Regional" = "рэгіянальныя"; +"Scene.ServerPicker.Button.Category.Tech" = "тэхналогіі"; +"Scene.ServerPicker.Button.Language" = "Мова"; +"Scene.ServerPicker.Button.SeeLess" = "Паказаць менш"; +"Scene.ServerPicker.Button.SeeMore" = "Паказаць больш"; +"Scene.ServerPicker.Button.SignupSpeed" = "Хуткасць рэгістрацыі"; +"Scene.ServerPicker.EmptyState.BadNetwork" = "Нешта пайшло не так падчас загрузкі даных. Праверце інтэрнэт-злучэнне."; +"Scene.ServerPicker.EmptyState.FindingServers" = "Пошук даступных сервераў..."; +"Scene.ServerPicker.EmptyState.NoResults" = "Няма вынікаў"; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Знайдзіце супольнасць або ўвядзіце URL"; +"Scene.ServerPicker.Label.Category" = "КАТЭГОРЫЯ"; +"Scene.ServerPicker.Label.Language" = "МОВА"; +"Scene.ServerPicker.Label.Users" = "КАРЫСТАЛЬНІКІ"; +"Scene.ServerPicker.Language.All" = "Усе"; +"Scene.ServerPicker.NoServerSelectedHint" = "Калі вы не выберыце сервер, то мы выберам яго на аснове вашай мовы."; +"Scene.ServerPicker.Search.Placeholder" = "Назва пошуку або URL-адрас"; +"Scene.ServerPicker.SignupSpeed.All" = "Усе"; +"Scene.ServerPicker.SignupSpeed.Instant" = "Імгненная рэгістрацыя"; +"Scene.ServerPicker.SignupSpeed.ManuallyReviewed" = "Агляд кіраўніцтва"; +"Scene.ServerPicker.Title" = "Абярыце сервер"; +"Scene.ServerRules.Button.Confirm" = "Я згодны"; +"Scene.ServerRules.PrivacyPolicy" = "палітыка канфідэнцыяльнасці"; +"Scene.ServerRules.Prompt" = "Працягваючы, вы згаджаецеся з умовамі выкарыстання і палітыкай канфідэнцыяльнасці %@."; +"Scene.ServerRules.Subtitle" = "Правілы вызначаныя мадэратарамі дамена %@."; +"Scene.ServerRules.TermsOfService" = "умовы выкарыстання"; +"Scene.ServerRules.Title" = "Некаторыя асноўныя правілы."; +"Scene.Settings.Footer.MastodonDescription" = "Mastodon — гэта праграма з адкрытым зыходным кодам. Вы можаце паведаміць аб праблемах на GitHub па адрасе %@ (%@)"; +"Scene.Settings.Keyboard.CloseSettingsWindow" = "Закрыць акно налад"; +"Scene.Settings.Section.Appearance.Automatic" = "Аўтаматычна"; +"Scene.Settings.Section.Appearance.Dark" = "Заўсёды цёмны"; +"Scene.Settings.Section.Appearance.Light" = "Заўсёды светлы"; +"Scene.Settings.Section.Appearance.Title" = "Знешні выгляд"; +"Scene.Settings.Section.BoringZone.AccountSettings" = "Налады ўліковага запісу"; +"Scene.Settings.Section.BoringZone.Privacy" = "Палітыка канфідэнцыяльнасці"; +"Scene.Settings.Section.BoringZone.Terms" = "Умовы выкарыстання"; +"Scene.Settings.Section.BoringZone.Title" = "Нудная зона"; +"Scene.Settings.Section.LookAndFeel.Light" = "Светлы"; +"Scene.Settings.Section.LookAndFeel.ReallyDark" = "Сапраўды Цёмны"; +"Scene.Settings.Section.LookAndFeel.SortaDark" = "Накшталт Цёмны"; +"Scene.Settings.Section.LookAndFeel.Title" = "Знешні выгляд"; +"Scene.Settings.Section.LookAndFeel.UseSystem" = "Выкарыстоўваць сістэмны"; +"Scene.Settings.Section.Notifications.Boosts" = "Пашырае мой допіс"; +"Scene.Settings.Section.Notifications.Favorites" = "Дадае мой допіс у абранае"; +"Scene.Settings.Section.Notifications.Follows" = "Падпісаўся на мяне"; +"Scene.Settings.Section.Notifications.Mentions" = "Згадвае мяне"; +"Scene.Settings.Section.Notifications.Title" = "Апавяшчэнні"; +"Scene.Settings.Section.Notifications.Trigger.Anyone" = "кожны"; +"Scene.Settings.Section.Notifications.Trigger.Follow" = "нехта, на каго я падпісаны"; +"Scene.Settings.Section.Notifications.Trigger.Follower" = "падпісчык"; +"Scene.Settings.Section.Notifications.Trigger.Noone" = "ніхто"; +"Scene.Settings.Section.Notifications.Trigger.Title" = "Апавяшчаць мяне, калі"; +"Scene.Settings.Section.Preference.DisableAvatarAnimation" = "Адключыць анімацыю аватараў"; +"Scene.Settings.Section.Preference.DisableEmojiAnimation" = "Адключыць анімацыю эмодзі"; +"Scene.Settings.Section.Preference.OpenLinksInMastodon" = "Адкрываць спасылкі ў Mastodon"; +"Scene.Settings.Section.Preference.Title" = "Параметры"; +"Scene.Settings.Section.Preference.UsingDefaultBrowser" = "Выкарыстоўваць прадвызначаны браўзер для адкрыцця спасылак"; +"Scene.Settings.Section.SpicyZone.Clear" = "Ачысціць кэш медыя"; +"Scene.Settings.Section.SpicyZone.Signout" = "Выйсці"; +"Scene.Settings.Section.SpicyZone.Title" = "Вострая зона"; +"Scene.Settings.Title" = "Налады"; +"Scene.SuggestionAccount.FollowAll" = "Follow all"; +"Scene.SuggestionAccount.Title" = "Popular on Mastodon"; +"Scene.Thread.BackTitle" = "Допіс"; +"Scene.Thread.Title" = "Допіс ад %@"; +"Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "Што такое Mastodon?"; +"Scene.Welcome.Education.Mastodon.Description" = "Mastodon - гэта дэцэнтралізаваная сацыяльная сетка, што азначае, што ні адна кампанія не кантралюе яе. Ён складаецца з мноства незалежна працуюць сервераў, злучаных разам."; +"Scene.Welcome.Education.Mastodon.Title" = "Вітаем у Mastodon"; +"Scene.Welcome.Education.Servers.Description" = "Кожны акаўнт Mastodon размяшчаецца на серверы - кожны са сваімі каштоўнасцямі, правіламі і адміністратарамі. Незалежна ад таго, які сервер вы вылучыце, вы можаце сачыць і ўзаемадзейнічаць з людзьмі на любым серверы."; +"Scene.Welcome.Education.Servers.Title" = "Што такое серверы?"; +"Scene.Welcome.JoinDefaultServer" = "Join %@"; +"Scene.Welcome.LearnMore" = "Даведацца больш"; +"Scene.Welcome.LogIn" = "Увайсці"; +"Scene.Welcome.PickServer" = "Pick another server"; +"Scene.Welcome.Separator.Or" = "або"; +"Widget.Common.UnsupportedWidgetFamily" = "Выбачайце, але гэта сямейства віджэтаў не падтрымліваецца."; +"Widget.Common.UserNotLoggedIn" = "Калі ласка, адкрыйце Mastodon, каб увайсці ў уліковы запіс."; +"Widget.FollowersCount.ConfigurationDescription" = "Паказаць колькасць падпісчыкаў."; +"Widget.FollowersCount.ConfigurationDisplayName" = "Падпісчыкі"; +"Widget.FollowersCount.FollowersToday" = "%@ падпісчыкаў сёння"; +"Widget.FollowersCount.Title" = "ПАДПІСЧЫКІ"; +"Widget.Hashtag.Configuration.Description" = "Shows a recent post with the selected hashtag."; +"Widget.Hashtag.Configuration.DisplayName" = "Hashtag"; +"Widget.Hashtag.NotFound.Account" = "@johnMastodon@no-such.account"; +"Widget.Hashtag.NotFound.AccountName" = "John Mastodon"; +"Widget.Hashtag.NotFound.Content" = "Sorry, we couldn’t find any posts with the hashtag #%@. Please try a #DifferentHashtag or check the widget settings."; +"Widget.Hashtag.Placeholder.Account" = "@johnMastodon@no-such.account"; +"Widget.Hashtag.Placeholder.AccountName" = "John Mastodon"; +"Widget.Hashtag.Placeholder.Content" = "This is how a post with a #hashtag would look. Pick whichever #hashtag you want in the widget settings."; +"Widget.LatestFollowers.ConfigurationDescription" = "Паказаць апошніх падпісчыкаў."; +"Widget.LatestFollowers.ConfigurationDisplayName" = "Апошнія падпісчыкі"; +"Widget.LatestFollowers.LastUpdate" = "Апошняе абнаўленне: %@"; +"Widget.LatestFollowers.Title" = "Апошнія падпісчыкі"; +"Widget.MultipleFollowers.ConfigurationDescription" = "Паказаць колькасць падпісчыкаў для некалькіх акаўнтаў."; +"Widget.MultipleFollowers.ConfigurationDisplayName" = "Больш падпісчыкаў"; +"Widget.MultipleFollowers.MockUser.AccountName" = "another@follower.social"; +"Widget.MultipleFollowers.MockUser.DisplayName" = "Яшчэ адзін паслядоўнік"; \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/be.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/be.lproj/Localizable.stringsdict new file mode 100644 index 000000000..21ad1cb54 --- /dev/null +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/be.lproj/Localizable.stringsdict @@ -0,0 +1,601 @@ + + + + + a11y.plural.count.unread.notification + + NSStringLocalizedFormatKey + %#@notification_count_unread_notification@ + notification_count_unread_notification + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 непрачытанае апавяшчэнне + few + %ld непрачытаныя апавяшчэнні + many + %ld непрачытаных апавяшчэнняў + other + %ld непрачытаных апавяшчэнняў + + + a11y.plural.count.input_limit_exceeds + + NSStringLocalizedFormatKey + Ліміт уводу перавышаны на %#@character_count@ + character_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 сімвал + few + %ld сімвалы + many + %ld сімвалаў + other + %ld сімвалаў + + + a11y.plural.count.input_limit_remains + + NSStringLocalizedFormatKey + Ліміт уводу застаецца %#@character_count@ + character_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 сімвал + few + %ld сімвалы + many + %ld сімвалаў + other + %ld сімвалаў + + + a11y.plural.count.characters_left + + NSStringLocalizedFormatKey + %#@character_count@ + character_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Застаўся 1 сімвал + few + Засталіся %ld сімвалы + many + Засталося %ld сімвалаў + other + Засталося %ld сімвалаў + + + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + few + + many + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + %1$@ і яшчэ 1 чалавек падпісаны + few + %1$@ і яшчэ %ld чалавекі падпісаны + many + %1$@ і яшчэ %ld чалавек падпісаны + other + %1$@ і яшчэ %ld чалавек падпісаны + + + plural.count.metric_formatted.post + + NSStringLocalizedFormatKey + %@ %#@post_count@ + post_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + допіс + few + допісы + many + допісаў + other + допісаў + + + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 медыя + few + %ld медыя + many + %ld медыя + other + %ld медыя + + + plural.count.post + + NSStringLocalizedFormatKey + %#@post_count@ + post_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 допіс + few + %ld допісы + many + %ld допісаў + other + %ld допісаў + + + plural.count.favorite + + NSStringLocalizedFormatKey + %#@favorite_count@ + favorite_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 дадаў у абранае + few + %ld дадалі ў абранае + many + %ld дадалі ў абранае + other + %ld дадалі ў абранае + + + plural.count.reblog + + NSStringLocalizedFormatKey + %#@reblog_count@ + reblog_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 пашырэнне + few + %ld пашырэнні + many + %ld пашырэнняў + other + %ld пашырэнняў + + + plural.count.reblog_a11y + + NSStringLocalizedFormatKey + %#@reblog_count@ + reblog_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 пашырэнне + few + %ld пашырэнні + many + %ld пашырэнняў + other + %ld пашырэнняў + + + plural.count.reply + + NSStringLocalizedFormatKey + %#@reply_count@ + reply_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 адказ + few + %ld адказы + many + %ld адказаў + other + %ld адказаў + + + plural.count.vote + + NSStringLocalizedFormatKey + %#@vote_count@ + vote_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 голас + few + %ld галасы + many + %ld галасоў + other + %ld галасоў + + + plural.count.voter + + NSStringLocalizedFormatKey + %#@voter_count@ + voter_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 удзельнік + few + %ld удзельнікі + many + %ld удзельнікаў + other + %ld удзельнікаў + + + plural.people_talking + + NSStringLocalizedFormatKey + %#@count_people_talking@ + count_people_talking + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 чалавек размаўляе + few + %ld чалавекі размаўляюць + many + %ld чалавек размаўляюць + other + %ld чалавек размаўляюць + + + plural.count.following + + NSStringLocalizedFormatKey + %#@count_following@ + count_following + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 падпісаны + few + %ld падпісаныя + many + %ld падпісаных + other + %ld падпісаных + + + plural.count.follower + + NSStringLocalizedFormatKey + %#@count_follower@ + count_follower + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 падпісчык + few + %ld падпісчыкі + many + %ld падпісчыкаў + other + %ld падпісчыкаў + + + date.year.left + + NSStringLocalizedFormatKey + %#@count_year_left@ + count_year_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Застаўся 1 год + few + %ld гады засталося + many + %ld гадоў засталося + other + %ld гадоў засталося + + + date.month.left + + NSStringLocalizedFormatKey + %#@count_month_left@ + count_month_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Застаўся 1 месяц + few + %ld месяцы засталося + many + %ld месяцаў засталося + other + %ld месяцаў засталося + + + date.day.left + + NSStringLocalizedFormatKey + %#@count_day_left@ + count_day_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Застаўся 1 дзень + few + %ld дні засталося + many + %ld дзён засталося + other + %ld дзён засталося + + + date.hour.left + + NSStringLocalizedFormatKey + %#@count_hour_left@ + count_hour_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Засталася 1 гадзіна + few + %ld гадзіны засталося + many + %ld гадзін засталося + other + %ld гадзін засталося + + + date.minute.left + + NSStringLocalizedFormatKey + %#@count_minute_left@ + count_minute_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Засталася 1 хвіліна + few + %ld хвіліны засталося + many + %ld хвілін засталося + other + %ld хвілін засталося + + + date.second.left + + NSStringLocalizedFormatKey + %#@count_second_left@ + count_second_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Засталася 1 секунда + few + %ld секунды засталося + many + %ld секунд засталося + other + %ld секунд засталося + + + date.year.ago.abbr + + NSStringLocalizedFormatKey + %#@count_year_ago_abbr@ + count_year_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 год таму + few + %ld гады таму + many + %ld гадоў таму + other + %ld гадоў таму + + + date.month.ago.abbr + + NSStringLocalizedFormatKey + %#@count_month_ago_abbr@ + count_month_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 месяц таму + few + %ld месяцы таму + many + %ld месяцаў таму + other + %ld месяцаў таму + + + date.day.ago.abbr + + NSStringLocalizedFormatKey + %#@count_day_ago_abbr@ + count_day_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 дзень таму + few + %ld дні таму + many + %ld дзён таму + other + %ld дзён таму + + + date.hour.ago.abbr + + NSStringLocalizedFormatKey + %#@count_hour_ago_abbr@ + count_hour_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 гадзіну таму + few + %ld гадзіны таму + many + %ld гадзін таму + other + %ld гадзін таму + + + date.minute.ago.abbr + + NSStringLocalizedFormatKey + %#@count_minute_ago_abbr@ + count_minute_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 хвіліну таму + few + %ld хвіліны таму + many + %ld хвілін таму + other + %ld хвілін таму + + + date.second.ago.abbr + + NSStringLocalizedFormatKey + %#@count_second_ago_abbr@ + count_second_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 секунду таму + few + %ld секунды таму + many + %ld секунд таму + other + %ld секунд таму + + + + diff --git a/WidgetExtension/be.lproj/WidgetExtension.strings b/WidgetExtension/be.lproj/WidgetExtension.strings new file mode 100644 index 000000000..17c9cdb2b --- /dev/null +++ b/WidgetExtension/be.lproj/WidgetExtension.strings @@ -0,0 +1,42 @@ +"3d6HSO" = "Enter username"; + +"7DZrRA" = "Username"; + +"82L4Nj" = "Yes"; + +"A1rwKl" = "Hashtag"; + +"BFppgH" = "Username"; + +"GTUbZg" = "Hashtag"; + +"OL6lkx" = "Account"; + +"OcUp1W" = "Hashtag"; + +"QkKsLf" = "true"; + +"ZLZ6sg" = "Latest Followers"; + +"e0W2wo" = "Multi Followers Count"; + +"fovmPX" = "Accounts"; + +"gpCwrM" = "Followers Count"; + +"jg9D5P" = "No"; + +"sOLUtG" = "Enter follower Username"; + +"tVvJ9c" = "Followers"; + +"wftYbm" = "false"; + +"xVtyec" = "Show chart"; + +"xcBHPA" = "Ignore content warnings"; + +"zbXop9" = "Hashtag"; + +"zeJo4f" = "Should the Widget show a chart?"; + From e16185fa7178124d32d3459830e833554ce1bf02 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 4 Jul 2023 08:49:26 -0400 Subject: [PATCH 27/87] Remove unused long press gesture recognizer --- .../Image/MediaPreviewImageViewController.swift | 13 +------------ .../MediaPreview/MediaPreviewViewController.swift | 4 ---- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift b/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift index 68bc0219f..a431d4dda 100644 --- a/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift +++ b/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageViewController.swift @@ -15,7 +15,6 @@ import VisionKit protocol MediaPreviewImageViewControllerDelegate: AnyObject { func mediaPreviewImageViewController(_ viewController: MediaPreviewImageViewController, tapGestureRecognizerDidTrigger tapGestureRecognizer: UITapGestureRecognizer) - func mediaPreviewImageViewController(_ viewController: MediaPreviewImageViewController, longPressGestureRecognizerDidTrigger longPressGestureRecognizer: UILongPressGestureRecognizer) func mediaPreviewImageViewController(_ viewController: MediaPreviewImageViewController, contextMenuActionPerform action: MediaPreviewImageViewController.ContextMenuAction) } @@ -31,7 +30,6 @@ final class MediaPreviewImageViewController: UIViewController { let previewImageView = MediaPreviewImageView() let tapGestureRecognizer = UITapGestureRecognizer.singleTapGestureRecognizer - let longPressGestureRecognizer = UILongPressGestureRecognizer() deinit { os_log("%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) @@ -58,13 +56,9 @@ extension MediaPreviewImageViewController { tapGestureRecognizer.addTarget(self, action: #selector(MediaPreviewImageViewController.tapGestureRecognizerHandler(_:))) tapGestureRecognizer.delegate = self - longPressGestureRecognizer.addTarget(self, action: #selector(MediaPreviewImageViewController.longPressGestureRecognizerHandler(_:))) - longPressGestureRecognizer.delegate = self tapGestureRecognizer.require(toFail: previewImageView.doubleTapGestureRecognizer) - tapGestureRecognizer.require(toFail: longPressGestureRecognizer) previewImageView.addGestureRecognizer(tapGestureRecognizer) - previewImageView.addGestureRecognizer(longPressGestureRecognizer) - + let previewImageViewContextMenuInteraction = UIContextMenuInteraction(delegate: self) previewImageView.addInteraction(previewImageViewContextMenuInteraction) @@ -95,11 +89,6 @@ extension MediaPreviewImageViewController { delegate?.mediaPreviewImageViewController(self, tapGestureRecognizerDidTrigger: sender) } - @objc private func longPressGestureRecognizerHandler(_ sender: UILongPressGestureRecognizer) { - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) - delegate?.mediaPreviewImageViewController(self, longPressGestureRecognizerDidTrigger: sender) - } - } extension MediaPreviewImageViewController: MediaPreviewPage { diff --git a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift index f68bd1b70..cd94a7f8d 100644 --- a/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift +++ b/Mastodon/Scene/MediaPreview/MediaPreviewViewController.swift @@ -273,10 +273,6 @@ extension MediaPreviewViewController: MediaPreviewImageViewControllerDelegate { } } - func mediaPreviewImageViewController(_ viewController: MediaPreviewImageViewController, longPressGestureRecognizerDidTrigger longPressGestureRecognizer: UILongPressGestureRecognizer) { - // do nothing - } - func mediaPreviewImageViewController( _ viewController: MediaPreviewImageViewController, contextMenuActionPerform action: MediaPreviewImageViewController.ContextMenuAction From 967b7e5b534327d2e403d97639457a0b78c9af0f Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 4 Jul 2023 08:49:55 -0400 Subject: [PATCH 28/87] Prioritize the double-tap-to-zoom gesture over other double-tap gestures --- .../Image/MediaPreviewImageView.swift | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageView.swift b/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageView.swift index 7df8861b0..defb02fde 100644 --- a/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageView.swift +++ b/Mastodon/Scene/MediaPreview/Image/MediaPreviewImageView.swift @@ -70,6 +70,8 @@ extension MediaPreviewImageView { addSubview(imageView) doubleTapGestureRecognizer.addTarget(self, action: #selector(MediaPreviewImageView.doubleTapGestureRecognizerHandler(_:))) + doubleTapGestureRecognizer.delegate = self + imageView.addGestureRecognizer(doubleTapGestureRecognizer) if #available(iOS 16.0, *) { imageView.addInteraction(liveTextInteraction) @@ -113,6 +115,21 @@ extension MediaPreviewImageView { } +extension MediaPreviewImageView: UIGestureRecognizerDelegate { + func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool { + guard gestureRecognizer == doubleTapGestureRecognizer else { return false } + // block double-tap to select text gesture + // but only if the Live Text button is toggled off + if let gr = otherGestureRecognizer as? UITapGestureRecognizer, + gr.numberOfTapsRequired == 2, + #available(iOS 16, *), + !liveTextInteraction.selectableItemsHighlighted { + return true + } + return false + } +} + extension MediaPreviewImageView { func setup(image: UIImage, container: UIView, forceUpdate: Bool = false) { From cc2f7f0b8cda33bdceb0774b1cb3dd5845665a33 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Tue, 4 Jul 2023 16:08:11 +0200 Subject: [PATCH 29/87] Hide activity indicator in case of no emojis (#1088) --- Mastodon.xcodeproj/project.pbxproj | 4 - .../Compose/View/ComposeToolbarView.swift | 384 ------------------ .../Model/Compose/ComposeStatusSection.swift | 58 --- .../EmojiService+CustomEmojiViewModel.swift | 19 +- .../ComposeContentViewController.swift | 6 +- .../ComposeContentViewModel+DataSource.swift | 4 +- .../View/Utility/ViewLayoutFrame.swift | 6 - 7 files changed, 18 insertions(+), 463 deletions(-) delete mode 100644 Mastodon/Scene/Compose/View/ComposeToolbarView.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 0db030614..f8743b3da 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -395,7 +395,6 @@ DB9F58EC26EF435000E7BBE9 /* AccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9F58EB26EF435000E7BBE9 /* AccountViewController.swift */; }; DB9F58EF26EF491E00E7BBE9 /* AccountListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9F58EE26EF491E00E7BBE9 /* AccountListViewModel.swift */; }; DB9F58F126EF512300E7BBE9 /* AccountListTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9F58F026EF512300E7BBE9 /* AccountListTableViewCell.swift */; }; - DBA0A11325FB3FC10079C110 /* ComposeToolbarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA0A11225FB3FC10079C110 /* ComposeToolbarView.swift */; }; DBA4B0F626C269880077136E /* Intents.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = DBA4B0F926C269880077136E /* Intents.stringsdict */; }; DBA4B0F726C269880077136E /* Intents.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = DBA4B0F926C269880077136E /* Intents.stringsdict */; }; DBA5A53126F08EF000CACBAA /* DragIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA5A53026F08EF000CACBAA /* DragIndicatorView.swift */; }; @@ -1103,7 +1102,6 @@ DB9F58EB26EF435000E7BBE9 /* AccountViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountViewController.swift; sourceTree = ""; }; DB9F58EE26EF491E00E7BBE9 /* AccountListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountListViewModel.swift; sourceTree = ""; }; DB9F58F026EF512300E7BBE9 /* AccountListTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountListTableViewCell.swift; sourceTree = ""; }; - DBA0A11225FB3FC10079C110 /* ComposeToolbarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeToolbarView.swift; sourceTree = ""; }; DBA4B0D326BD10AC0077136E /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Intents.strings"; sourceTree = ""; }; DBA4B0D626BD10AD0077136E /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; DBA4B0D726BD10F40077136E /* ca */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ca; path = ca.lproj/Intents.strings; sourceTree = ""; }; @@ -2166,7 +2164,6 @@ DB55D32225FB4D320002F825 /* View */ = { isa = PBXGroup; children = ( - DBA0A11225FB3FC10079C110 /* ComposeToolbarView.swift */, DB8190C52601FF0400020C08 /* AttachmentContainerView.swift */, DB9A486B26032AC1008B817C /* AttachmentContainerView+EmptyStateView.swift */, DBC7A671260C897100E57475 /* StatusContentWarningEditorView.swift */, @@ -3839,7 +3836,6 @@ DB45FAB625CA5485005A8AC7 /* UIAlertController.swift in Sources */, DBE0821525CD382600FD6BBD /* MastodonRegisterViewController.swift in Sources */, DBEFCD74282A130400C0ABEA /* ReportReasonViewModel.swift in Sources */, - DBA0A11325FB3FC10079C110 /* ComposeToolbarView.swift in Sources */, DBFEEC96279BDC67004F81DD /* ProfileAboutViewController.swift in Sources */, DB63F74F2799405600455B82 /* SearchHistoryViewModel+Diffable.swift in Sources */, DB0EF72B26FDB1D200347686 /* SidebarListCollectionViewCell.swift in Sources */, diff --git a/Mastodon/Scene/Compose/View/ComposeToolbarView.swift b/Mastodon/Scene/Compose/View/ComposeToolbarView.swift deleted file mode 100644 index a993da228..000000000 --- a/Mastodon/Scene/Compose/View/ComposeToolbarView.swift +++ /dev/null @@ -1,384 +0,0 @@ -// -// ComposeToolbarView.swift -// Mastodon -// -// Created by MainasuK Cirno on 2021-3-12. -// - -import os.log -import UIKit -import Combine -import MastodonSDK -import MastodonAsset -import MastodonCore -import MastodonUI -import MastodonLocalization - -protocol ComposeToolbarViewDelegate: AnyObject { - func composeToolbarView(_ composeToolbarView: ComposeToolbarView, mediaButtonDidPressed sender: Any, mediaSelectionType type: ComposeToolbarView.MediaSelectionType) - func composeToolbarView(_ composeToolbarView: ComposeToolbarView, pollButtonDidPressed sender: Any) - func composeToolbarView(_ composeToolbarView: ComposeToolbarView, emojiButtonDidPressed sender: Any) - func composeToolbarView(_ composeToolbarView: ComposeToolbarView, contentWarningButtonDidPressed sender: Any) - func composeToolbarView(_ composeToolbarView: ComposeToolbarView, visibilityButtonDidPressed sender: Any, visibilitySelectionType type: ComposeToolbarView.VisibilitySelectionType) -} - -final class ComposeToolbarView: UIView { - - var disposeBag = Set() - - static let toolbarButtonSize: CGSize = CGSize(width: 44, height: 44) - static let toolbarHeight: CGFloat = 44 - - weak var delegate: ComposeToolbarViewDelegate? - - // barButtonItem - private(set) lazy var mediaBarButtonItem: UIBarButtonItem = { - let barButtonItem = UIBarButtonItem() - barButtonItem.image = UIImage(systemName: "photo") - barButtonItem.accessibilityLabel = L10n.Scene.Compose.Accessibility.appendAttachment - return barButtonItem - }() - - let pollBarButtonItem: UIBarButtonItem = { - let barButtonItem = UIBarButtonItem() - barButtonItem.image = UIImage(systemName: "list.bullet") - barButtonItem.accessibilityLabel = L10n.Scene.Compose.Accessibility.appendPoll - return barButtonItem - }() - - let contentWarningBarButtonItem: UIBarButtonItem = { - let barButtonItem = UIBarButtonItem() - barButtonItem.image = UIImage(systemName: "exclamationmark.shield") - barButtonItem.accessibilityLabel = L10n.Scene.Compose.Accessibility.enableContentWarning - return barButtonItem - }() - - let visibilityBarButtonItem: UIBarButtonItem = { - let barButtonItem = UIBarButtonItem() - barButtonItem.image = UIImage(systemName: "person.3") - barButtonItem.accessibilityLabel = L10n.Scene.Compose.Accessibility.postVisibilityMenu - return barButtonItem - }() - - // button - - let mediaButton: UIButton = { - let button = HighlightDimmableButton() - ComposeToolbarView.configureToolbarButtonAppearance(button: button) - button.setImage(UIImage(systemName: "photo", withConfiguration: UIImage.SymbolConfiguration(pointSize: 20, weight: .regular)), for: .normal) - button.accessibilityLabel = L10n.Scene.Compose.Accessibility.appendAttachment - return button - }() - - let pollButton: UIButton = { - let button = HighlightDimmableButton(type: .custom) - ComposeToolbarView.configureToolbarButtonAppearance(button: button) - button.setImage(UIImage(systemName: "list.bullet", withConfiguration: UIImage.SymbolConfiguration(pointSize: 20, weight: .medium)), for: .normal) - button.accessibilityLabel = L10n.Scene.Compose.Accessibility.appendPoll - return button - }() - - let emojiButton: UIButton = { - let button = HighlightDimmableButton() - ComposeToolbarView.configureToolbarButtonAppearance(button: button) - let image = Asset.Human.faceSmilingAdaptive.image - .af.imageScaled(to: CGSize(width: 20, height: 20)) - .withRenderingMode(.alwaysTemplate) - button.setImage(image, for: .normal) - button.accessibilityLabel = L10n.Scene.Compose.Accessibility.customEmojiPicker - return button - }() - - let contentWarningButton: UIButton = { - let button = HighlightDimmableButton() - ComposeToolbarView.configureToolbarButtonAppearance(button: button) - button.setImage(UIImage(systemName: "exclamationmark.shield", withConfiguration: UIImage.SymbolConfiguration(pointSize: 20, weight: .regular)), for: .normal) - button.accessibilityLabel = L10n.Scene.Compose.Accessibility.enableContentWarning - return button - }() - - let visibilityButton: UIButton = { - let button = HighlightDimmableButton() - ComposeToolbarView.configureToolbarButtonAppearance(button: button) - button.setImage(UIImage(systemName: "person.3", withConfiguration: UIImage.SymbolConfiguration(pointSize: 15, weight: .medium)), for: .normal) - button.accessibilityLabel = L10n.Scene.Compose.Accessibility.postVisibilityMenu - return button - }() - - let characterCountLabel: UILabel = { - let label = UILabel() - label.font = .systemFont(ofSize: 15, weight: .regular) - label.text = "500" - label.textColor = Asset.Colors.Label.secondary.color - label.accessibilityLabel = L10n.A11y.Plural.Count.inputLimitRemains(500) - return label - }() - - let activeVisibilityType = CurrentValueSubject(.public) - - override init(frame: CGRect) { - super.init(frame: frame) - _init() - } - - required init?(coder: NSCoder) { - super.init(coder: coder) - _init() - } - -} - -extension ComposeToolbarView { - - private func _init() { - setupBackgroundColor(theme: ThemeService.shared.currentTheme.value) - ThemeService.shared.currentTheme - .receive(on: DispatchQueue.main) - .sink { [weak self] theme in - guard let self = self else { return } - self.setupBackgroundColor(theme: theme) - } - .store(in: &disposeBag) - - let stackView = UIStackView() - stackView.axis = .horizontal - stackView.spacing = 0 - stackView.distribution = .fillEqually - stackView.translatesAutoresizingMaskIntoConstraints = false - addSubview(stackView) - NSLayoutConstraint.activate([ - stackView.centerYAnchor.constraint(equalTo: centerYAnchor), - layoutMarginsGuide.leadingAnchor.constraint(equalTo: stackView.leadingAnchor, constant: 8), // tweak button margin offset - ]) - - let buttons = [ - mediaButton, - pollButton, - emojiButton, - contentWarningButton, - visibilityButton, - ] - buttons.forEach { button in - button.translatesAutoresizingMaskIntoConstraints = false - stackView.addArrangedSubview(button) - NSLayoutConstraint.activate([ - button.widthAnchor.constraint(equalToConstant: 44), - button.heightAnchor.constraint(equalToConstant: 44), - ]) - } - - characterCountLabel.translatesAutoresizingMaskIntoConstraints = false - addSubview(characterCountLabel) - NSLayoutConstraint.activate([ - characterCountLabel.topAnchor.constraint(equalTo: topAnchor), - characterCountLabel.leadingAnchor.constraint(greaterThanOrEqualTo: stackView.trailingAnchor, constant: 8), - characterCountLabel.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor), - characterCountLabel.bottomAnchor.constraint(equalTo: bottomAnchor), - ]) - characterCountLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal) - - mediaBarButtonItem.menu = createMediaContextMenu() - mediaButton.menu = createMediaContextMenu() - mediaButton.showsMenuAsPrimaryAction = true - pollBarButtonItem.target = self - pollBarButtonItem.action = #selector(ComposeToolbarView.pollButtonDidPressed(_:)) - pollButton.addTarget(self, action: #selector(ComposeToolbarView.pollButtonDidPressed(_:)), for: .touchUpInside) - emojiButton.addTarget(self, action: #selector(ComposeToolbarView.emojiButtonDidPressed(_:)), for: .touchUpInside) - contentWarningBarButtonItem.target = self - contentWarningBarButtonItem.action = #selector(ComposeToolbarView.contentWarningButtonDidPressed(_:)) - contentWarningButton.addTarget(self, action: #selector(ComposeToolbarView.contentWarningButtonDidPressed(_:)), for: .touchUpInside) - visibilityBarButtonItem.menu = createVisibilityContextMenu(interfaceStyle: traitCollection.userInterfaceStyle) - visibilityButton.menu = createVisibilityContextMenu(interfaceStyle: traitCollection.userInterfaceStyle) - visibilityButton.showsMenuAsPrimaryAction = true - - updateToolbarButtonUserInterfaceStyle() - - // update menu when selected visibility type changed - activeVisibilityType - .receive(on: RunLoop.main) - .sink { [weak self] type in - guard let self = self else { return } - self.visibilityBarButtonItem.menu = self.createVisibilityContextMenu(interfaceStyle: self.traitCollection.userInterfaceStyle) - self.visibilityButton.menu = self.createVisibilityContextMenu(interfaceStyle: self.traitCollection.userInterfaceStyle) - } - .store(in: &disposeBag) - } - - override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { - super.traitCollectionDidChange(previousTraitCollection) - - updateToolbarButtonUserInterfaceStyle() - } - -} - -extension ComposeToolbarView { - enum MediaSelectionType: String { - case camera - case photoLibrary - case browse - } - - enum VisibilitySelectionType: String, CaseIterable { - case `public` - // TODO: remove unlisted option from codebase - // case unlisted - case `private` - case direct - - var title: String { - switch self { - case .public: return L10n.Scene.Compose.Visibility.public - // case .unlisted: return L10n.Scene.Compose.Visibility.unlisted - case .private: return L10n.Scene.Compose.Visibility.private - case .direct: return L10n.Scene.Compose.Visibility.direct - } - } - - func image(interfaceStyle: UIUserInterfaceStyle) -> UIImage { - switch self { - case .public: return UIImage(systemName: "globe", withConfiguration: UIImage.SymbolConfiguration(pointSize: 19, weight: .medium))! - // case .unlisted: return UIImage(systemName: "eye.slash", withConfiguration: UIImage.SymbolConfiguration(pointSize: 18, weight: .regular))! - case .private: - switch interfaceStyle { - case .light: return UIImage(systemName: "person.3", withConfiguration: UIImage.SymbolConfiguration(pointSize: 15, weight: .medium))! - default: return UIImage(systemName: "person.3.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: 15, weight: .medium))! - } - case .direct: return UIImage(systemName: "at", withConfiguration: UIImage.SymbolConfiguration(pointSize: 19, weight: .regular))! - } - } - - var visibility: Mastodon.Entity.Status.Visibility { - switch self { - case .public: return .public - // case .unlisted: return .unlisted - case .private: return .private - case .direct: return .direct - } - } - } -} - -extension ComposeToolbarView { - - private func setupBackgroundColor(theme: Theme) { - backgroundColor = theme.composeToolbarBackgroundColor - } - - private static func configureToolbarButtonAppearance(button: UIButton) { - button.tintColor = ThemeService.tintColor - button.setBackgroundImage(.placeholder(size: ComposeToolbarView.toolbarButtonSize, color: .systemFill), for: .highlighted) - button.layer.masksToBounds = true - button.layer.cornerRadius = 5 - button.layer.cornerCurve = .continuous - } - - private func updateToolbarButtonUserInterfaceStyle() { - // reset emoji - let emojiButtonImage = Asset.Human.faceSmilingAdaptive.image - .af.imageScaled(to: CGSize(width: 20, height: 20)) - .withRenderingMode(.alwaysTemplate) - emojiButton.setImage(emojiButtonImage, for: .normal) - - switch traitCollection.userInterfaceStyle { - case .light: - mediaBarButtonItem.image = UIImage(systemName: "photo") - mediaButton.setImage(UIImage(systemName: "photo", withConfiguration: UIImage.SymbolConfiguration(pointSize: 20, weight: .regular))!, for: .normal) - contentWarningBarButtonItem.image = UIImage(systemName: "exclamationmark.shield") - contentWarningButton.setImage(UIImage(systemName: "exclamationmark.shield", withConfiguration: UIImage.SymbolConfiguration(pointSize: 20, weight: .regular))!, for: .normal) - - case .dark: - mediaBarButtonItem.image = UIImage(systemName: "photo.fill") - mediaButton.setImage(UIImage(systemName: "photo.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: 20, weight: .regular))!, for: .normal) - contentWarningBarButtonItem.image = UIImage(systemName: "exclamationmark.shield.fill") - contentWarningButton.setImage(UIImage(systemName: "exclamationmark.shield.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: 20, weight: .regular))!, for: .normal) - - default: - assertionFailure() - } - - visibilityBarButtonItem.menu = createVisibilityContextMenu(interfaceStyle: traitCollection.userInterfaceStyle) - visibilityButton.menu = createVisibilityContextMenu(interfaceStyle: traitCollection.userInterfaceStyle) - } - - private func createMediaContextMenu() -> UIMenu { - var children: [UIMenuElement] = [] - let photoLibraryAction = UIAction(title: L10n.Scene.Compose.MediaSelection.photoLibrary, image: UIImage(systemName: "rectangle.on.rectangle"), identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off) { [weak self] _ in - guard let self = self else { return } - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: mediaSelectionType: .photoLibrary", ((#file as NSString).lastPathComponent), #line, #function) - self.delegate?.composeToolbarView(self, mediaButtonDidPressed: self.mediaButton, mediaSelectionType: .photoLibrary) - } - children.append(photoLibraryAction) - if UIImagePickerController.isSourceTypeAvailable(.camera) { - let cameraAction = UIAction(title: L10n.Scene.Compose.MediaSelection.camera, image: UIImage(systemName: "camera"), identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off, handler: { [weak self] _ in - guard let self = self else { return } - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: mediaSelectionType: .camera", ((#file as NSString).lastPathComponent), #line, #function) - self.delegate?.composeToolbarView(self, mediaButtonDidPressed: self.mediaButton, mediaSelectionType: .camera) - }) - children.append(cameraAction) - } - let browseAction = UIAction(title: L10n.Scene.Compose.MediaSelection.browse, image: UIImage(systemName: "ellipsis"), identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off) { [weak self] _ in - guard let self = self else { return } - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: mediaSelectionType: .browse", ((#file as NSString).lastPathComponent), #line, #function) - self.delegate?.composeToolbarView(self, mediaButtonDidPressed: self.mediaButton, mediaSelectionType: .browse) - } - children.append(browseAction) - - return UIMenu(title: "", image: nil, identifier: nil, options: .displayInline, children: children) - } - - private func createVisibilityContextMenu(interfaceStyle: UIUserInterfaceStyle) -> UIMenu { - let children: [UIMenuElement] = VisibilitySelectionType.allCases.map { type in - let state: UIMenuElement.State = activeVisibilityType.value == type ? .on : .off - return UIAction(title: type.title, image: type.image(interfaceStyle: interfaceStyle), identifier: nil, discoverabilityTitle: nil, attributes: [], state: state) { [weak self] action in - guard let self = self else { return } - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: visibilitySelectionType: %s", ((#file as NSString).lastPathComponent), #line, #function, type.rawValue) - self.delegate?.composeToolbarView(self, visibilityButtonDidPressed: self.visibilityButton, visibilitySelectionType: type) - } - } - return UIMenu(title: "", image: nil, identifier: nil, options: .displayInline, children: children) - } - -} - -extension ComposeToolbarView { - - @objc private func pollButtonDidPressed(_ sender: Any) { - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) - delegate?.composeToolbarView(self, pollButtonDidPressed: sender) - } - - @objc private func emojiButtonDidPressed(_ sender: Any) { - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) - delegate?.composeToolbarView(self, emojiButtonDidPressed: sender) - } - - @objc private func contentWarningButtonDidPressed(_ sender: Any) { - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) - delegate?.composeToolbarView(self, contentWarningButtonDidPressed: sender) - } - -} - -#if canImport(SwiftUI) && DEBUG -import SwiftUI - -struct ComposeToolbarView_Previews: PreviewProvider { - - static var previews: some View { - UIViewPreview(width: 375) { - let toolbarView = ComposeToolbarView() - toolbarView.translatesAutoresizingMaskIntoConstraints = false - NSLayoutConstraint.activate([ - toolbarView.widthAnchor.constraint(equalToConstant: 375).priority(.defaultHigh), - toolbarView.heightAnchor.constraint(equalToConstant: 64).priority(.defaultHigh), - ]) - return toolbarView - } - .previewLayout(.fixed(width: 375, height: 100)) - } - -} - -#endif - diff --git a/MastodonSDK/Sources/MastodonCore/Model/Compose/ComposeStatusSection.swift b/MastodonSDK/Sources/MastodonCore/Model/Compose/ComposeStatusSection.swift index 12dc88053..b91183e90 100644 --- a/MastodonSDK/Sources/MastodonCore/Model/Compose/ComposeStatusSection.swift +++ b/MastodonSDK/Sources/MastodonCore/Model/Compose/ComposeStatusSection.swift @@ -20,43 +20,6 @@ public enum ComposeStatusSection: Equatable, Hashable { case poll } -extension ComposeStatusSection { - -// static func configure( -// cell: ComposeStatusContentTableViewCell, -// attribute: ComposeStatusItem.ComposeStatusAttribute -// ) { -// cell.prepa -// // set avatar -// attribute.avatarURL -// .receive(on: DispatchQueue.main) -// .sink { avatarURL in -// cell.statusView.configure(with: AvatarConfigurableViewConfiguration(avatarImageURL: avatarURL)) -// } -// .store(in: &cell.disposeBag) -// // set display name and username -// Publishers.CombineLatest3( -// attribute.displayName, -// attribute.emojiMeta, -// attribute.username -// ) -// .receive(on: DispatchQueue.main) -// .sink { displayName, emojiMeta, username in -// do { -// let mastodonContent = MastodonContent(content: displayName ?? " ", emojis: emojiMeta) -// let metaContent = try MastodonMetaContent.convert(document: mastodonContent) -// cell.statusView.nameLabel.configure(content: metaContent) -// } catch { -// let metaContent = PlaintextMetaContent(string: " ") -// cell.statusView.nameLabel.configure(content: metaContent) -// } -// cell.statusView.usernameLabel.text = username.flatMap { "@" + $0 } ?? " " -// } -// .store(in: &cell.disposeBag) -// } - -} - public protocol CustomEmojiReplaceableTextInput: UITextInput & UIResponder { var inputView: UIView? { get set } } @@ -71,24 +34,3 @@ public class CustomEmojiReplaceableTextInputReference { extension UITextField: CustomEmojiReplaceableTextInput { } extension UITextView: CustomEmojiReplaceableTextInput { } - -extension ComposeStatusSection { - -// static func configureCustomEmojiPicker( -// viewModel: CustomEmojiPickerInputViewModel?, -// customEmojiReplaceableTextInput: CustomEmojiReplaceableTextInput, -// disposeBag: inout Set -// ) { -// guard let viewModel = viewModel else { return } -// viewModel.isCustomEmojiComposing -// .receive(on: DispatchQueue.main) -// .sink { [weak viewModel] isCustomEmojiComposing in -// guard let viewModel = viewModel else { return } -// customEmojiReplaceableTextInput.inputView = isCustomEmojiComposing ? viewModel.customEmojiPickerInputView : nil -// customEmojiReplaceableTextInput.reloadInputViews() -// viewModel.append(customEmojiReplaceableTextInput: customEmojiReplaceableTextInput) -// } -// .store(in: &disposeBag) -// } - -} diff --git a/MastodonSDK/Sources/MastodonCore/Service/Emoji/EmojiService+CustomEmojiViewModel.swift b/MastodonSDK/Sources/MastodonCore/Service/Emoji/EmojiService+CustomEmojiViewModel.swift index 38e1e1f7a..0cba10d6d 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/Emoji/EmojiService+CustomEmojiViewModel.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/Emoji/EmojiService+CustomEmojiViewModel.swift @@ -32,8 +32,8 @@ extension EmojiService { stateMachine.enter(LoadState.Initial.self) return stateMachine }() - public let emojis = CurrentValueSubject<[Mastodon.Entity.Emoji], Never>([]) - public let emojiDict = CurrentValueSubject<[String: [Mastodon.Entity.Emoji]], Never>([:]) + public let emojis = CurrentValueSubject<[Mastodon.Entity.Emoji]?, Never>(nil) + public let emojiDict = CurrentValueSubject<[String: [Mastodon.Entity.Emoji]]?, Never>(nil) public let emojiMapping = CurrentValueSubject<[String: String], Never>([:]) public let emojiTrie = CurrentValueSubject?, Never>(nil) @@ -44,12 +44,17 @@ extension EmojiService { self.service = service emojis - .map { Dictionary(grouping: $0, by: { $0.shortcode }) } + .compactMap { value in + guard let value else { return nil } + return Dictionary(grouping: value, by: { value in value.shortcode }) + } .assign(to: \.value, on: emojiDict) .store(in: &disposeBag) emojiDict - .map { dict in + .compactMap { dict in + guard let dict else { return nil } + var mapping: [String: String] = [:] for (key, values) in dict { guard let emoji = values.first else { continue } @@ -61,8 +66,8 @@ extension EmojiService { .store(in: &disposeBag) emojis - .map { emojis -> Trie? in - guard !emojis.isEmpty else { return nil } + .compactMap { emojis -> Trie? in + guard let emojis, emojis.isEmpty == false else { return nil } var trie: Trie = Trie() for emoji in emojis { let key = emoji.shortcode.lowercased() @@ -84,7 +89,7 @@ extension EmojiService { } } - return emojiDict.value[shortcode]?.first + return emojiDict.value?[shortcode]?.first } } diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewController.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewController.swift index 41813e232..787847705 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewController.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewController.swift @@ -272,10 +272,10 @@ extension ComposeContentViewController { .receive(on: DispatchQueue.main) .sink(receiveValue: { [weak self] emojis in guard let self = self else { return } - if emojis.isEmpty { - self.customEmojiPickerInputView.activityIndicatorView.startAnimating() - } else { + if emojis != nil { self.customEmojiPickerInputView.activityIndicatorView.stopAnimating() + } else { + self.customEmojiPickerInputView.activityIndicatorView.startAnimating() } }) .store(in: &disposeBag) diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel+DataSource.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel+DataSource.swift index 0cf093339..9f036643b 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel+DataSource.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel+DataSource.swift @@ -111,7 +111,9 @@ extension ComposeContentViewModel { // Don't block the main queue .receive(on: DispatchQueue.global(qos: .userInteractive)) // Sort emojis - .map({ (emojis) -> [Mastodon.Entity.Emoji] in + .compactMap({ (emojis) -> [Mastodon.Entity.Emoji]? in + guard let emojis else { return nil } + return emojis.sorted { a, b in a.shortcode.lowercased() < b.shortcode.lowercased() } diff --git a/MastodonSDK/Sources/MastodonUI/View/Utility/ViewLayoutFrame.swift b/MastodonSDK/Sources/MastodonUI/View/Utility/ViewLayoutFrame.swift index 183364abc..e97453fdb 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Utility/ViewLayoutFrame.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Utility/ViewLayoutFrame.swift @@ -30,7 +30,6 @@ public struct ViewLayoutFrame { extension ViewLayoutFrame { public mutating func update(view: UIView) { guard view.window != nil else { - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): layoutFrame update for a view without attached window. Skip this invalid update") return } @@ -48,10 +47,5 @@ extension ViewLayoutFrame { if self.readableContentLayoutFrame != readableContentLayoutFrame { self.readableContentLayoutFrame = readableContentLayoutFrame } - - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): layoutFrame: \(layoutFrame.debugDescription)") - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): safeAreaLayoutFrame: \(safeAreaLayoutFrame.debugDescription)") - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): readableContentLayoutFrame: \(readableContentLayoutFrame.debugDescription)") - } } From 49c273e05692ca43153a45ddff2108005da77315 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Thu, 20 Jul 2023 11:49:47 +0200 Subject: [PATCH 30/87] Increment number of errors by one (#898) --- .../View/HomeTimelineNavigationBarTitleViewModel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleViewModel.swift b/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleViewModel.swift index 79f568edf..9862d7e0d 100644 --- a/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleViewModel.swift +++ b/Mastodon/Scene/HomeTimeline/View/HomeTimelineNavigationBarTitleViewModel.swift @@ -37,7 +37,7 @@ final class HomeTimelineNavigationBarTitleViewModel { .receive(on: DispatchQueue.main) .sink { [weak self] _ in guard let self = self else { return } - self.networkErrorCount.value += self.networkErrorCount.value + 1 + self.networkErrorCount.value = self.networkErrorCount.value + 1 } .store(in: &disposeBag) From a20f9a57c2c527405c73b4eabccba4da946dd4a7 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 21 Aug 2023 11:29:48 +0200 Subject: [PATCH 31/87] Add authentication to trends (#1104) And clean up here and there. --- .../DiscoveryCommunityViewController.swift | 5 --- .../DiscoveryCommunityViewModel+State.swift | 11 ------- .../DiscoveryCommunityViewModel.swift | 7 ----- .../DiscoveryForYouViewController.swift | 11 +------ .../ForYou/DiscoveryForYouViewModel.swift | 6 ---- .../Hashtags/DiscoveryHashtagsViewModel.swift | 31 ++++++++++--------- .../News/DiscoveryNewsViewModel+State.swift | 13 +++----- .../News/DiscoveryNewsViewModel.swift | 8 ++--- .../Posts/DiscoveryPostsViewController.swift | 5 --- .../Posts/DiscoveryPostsViewModel+State.swift | 3 +- .../Posts/DiscoveryPostsViewModel.swift | 9 ++---- .../Service/API/APIService+Trend.swift | 19 ++++++++---- .../MastodonSDK/API/Mastodon+API+Trends.swift | 15 +++++---- 13 files changed, 49 insertions(+), 94 deletions(-) diff --git a/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewController.swift b/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewController.swift index 870bfc72a..0ef14b4ca 100644 --- a/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewController.swift +++ b/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewController.swift @@ -34,11 +34,6 @@ final class DiscoveryCommunityViewController: UIViewController, NeedsDependency, }() let refreshControl = RefreshControl() - - deinit { - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) - } - } extension DiscoveryCommunityViewController { diff --git a/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewModel+State.swift b/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewModel+State.swift index 5045e825a..6f1e5d5ec 100644 --- a/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewModel+State.swift +++ b/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewModel+State.swift @@ -5,15 +5,12 @@ // Created by MainasuK on 2022-4-29. // -import os.log import Foundation import GameplayKit import MastodonSDK extension DiscoveryCommunityViewModel { class State: GKState { - - let logger = Logger(subsystem: "DiscoveryCommunityViewModel.State", category: "StateMachine") let id = UUID() @@ -28,17 +25,12 @@ extension DiscoveryCommunityViewModel { let from = previousState.flatMap { String(describing: $0) } ?? "nil" let to = String(describing: self) - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): \(from) -> \(to)") } @MainActor func enter(state: State.Type) { stateMachine?.enter(state) } - - deinit { - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): [\(self.id.uuidString)] \(String(describing: self))") - } } } @@ -87,9 +79,7 @@ extension DiscoveryCommunityViewModel.State { super.didEnter(from: previousState) guard let _ = viewModel, let stateMachine = stateMachine else { return } - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: retry loading 3s later…", ((#file as NSString).lastPathComponent), #line, #function) DispatchQueue.main.asyncAfter(deadline: .now() + 3) { - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: retry loading", ((#file as NSString).lastPathComponent), #line, #function) stateMachine.enter(Loading.self) } } @@ -174,7 +164,6 @@ extension DiscoveryCommunityViewModel.State { viewModel.didLoadLatest.send() } catch { - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): fetch user timeline fail: \(error.localizedDescription)") await enter(state: Fail.self) } } // end Task diff --git a/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewModel.swift b/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewModel.swift index eaf8646c4..5e98a1ba2 100644 --- a/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewModel.swift +++ b/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewModel.swift @@ -16,8 +16,6 @@ import MastodonCore final class DiscoveryCommunityViewModel { - let logger = Logger(subsystem: "DiscoveryCommunityViewModel", category: "ViewModel") - var disposeBag = Set() // input @@ -54,9 +52,4 @@ final class DiscoveryCommunityViewModel { ) // end init } - - deinit { - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) - } - } diff --git a/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewController.swift b/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewController.swift index 007abd901..30865d1b5 100644 --- a/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewController.swift +++ b/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewController.swift @@ -5,16 +5,13 @@ // Created by MainasuK on 2022-4-14. // -import os.log import UIKit import Combine import MastodonUI import MastodonCore final class DiscoveryForYouViewController: UIViewController, NeedsDependency, MediaPreviewableViewController { - - let logger = Logger(subsystem: "DiscoveryForYouViewController", category: "ViewController") - + weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } @@ -33,11 +30,6 @@ final class DiscoveryForYouViewController: UIViewController, NeedsDependency, Me }() let refreshControl = RefreshControl() - - deinit { - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) - } - } extension DiscoveryForYouViewController { @@ -111,7 +103,6 @@ extension DiscoveryForYouViewController: AuthContextProvider { extension DiscoveryForYouViewController: UITableViewDelegate { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): \(indexPath)") guard case let .user(record) = viewModel.diffableDataSource?.itemIdentifier(for: indexPath) else { return } guard let user = record.object(in: context.managedObjectContext) else { return } let profileViewModel = CachedProfileViewModel( diff --git a/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel.swift b/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel.swift index 89122c06e..fcd521a36 100644 --- a/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel.swift +++ b/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel.swift @@ -5,7 +5,6 @@ // Created by MainasuK on 2022-4-14. // -import os.log import UIKit import Combine import GameplayKit @@ -41,11 +40,6 @@ final class DiscoveryForYouViewModel { ) // end init } - - deinit { - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) - } - } extension DiscoveryForYouViewModel { diff --git a/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewModel.swift b/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewModel.swift index 7727a2358..a4c4d7814 100644 --- a/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewModel.swift +++ b/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewModel.swift @@ -16,8 +16,6 @@ import MastodonSDK final class DiscoveryHashtagsViewModel { - let logger = Logger(subsystem: "DiscoveryHashtagsViewModel", category: "ViewModel") - var disposeBag = Set() // input @@ -36,8 +34,12 @@ final class DiscoveryHashtagsViewModel { viewDidAppeared .throttle(for: 3, scheduler: DispatchQueue.main, latest: true) - .asyncMap { authenticationBox in - try await context.apiService.trendHashtags(domain: authContext.mastodonAuthenticationBox.domain, query: nil) + .asyncMap { _ in + let authenticationBox = authContext.mastodonAuthenticationBox + return try await context.apiService.trendHashtags(domain: authenticationBox.domain, + query: nil, + authenticationBox: authenticationBox + ) } .retry(3) .map { response in Result, Error> { response } } @@ -46,28 +48,27 @@ final class DiscoveryHashtagsViewModel { .sink { [weak self] result in guard let self = self else { return } switch result { - case .success(let response): - self.hashtags = response.value.filter { !$0.name.isEmpty } - case .failure: - break + case .success(let response): + self.hashtags = response.value.filter { !$0.name.isEmpty } + case .failure: + break } } .store(in: &disposeBag) } - - deinit { - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) - } - } extension DiscoveryHashtagsViewModel { @MainActor func fetch() async throws { - let response = try await context.apiService.trendHashtags(domain: authContext.mastodonAuthenticationBox.domain, query: nil) + + let authenticationBox = authContext.mastodonAuthenticationBox + let response = try await context.apiService.trendHashtags(domain: authenticationBox.domain, + query: nil, + authenticationBox: authenticationBox + ) hashtags = response.value.filter { !$0.name.isEmpty } - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): fetch tags: \(response.value.count)") } } diff --git a/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel+State.swift b/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel+State.swift index 8170d5b1c..f06c1dc44 100644 --- a/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel+State.swift +++ b/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel+State.swift @@ -35,10 +35,6 @@ extension DiscoveryNewsViewModel { func enter(state: State.Type) { stateMachine?.enter(state) } - - deinit { - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): [\(self.id.uuidString)] \(String(describing: self))") - } } } @@ -86,10 +82,9 @@ extension DiscoveryNewsViewModel.State { override func didEnter(from previousState: GKState?) { super.didEnter(from: previousState) guard let _ = viewModel, let stateMachine = stateMachine else { return } - - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: retry loading 3s later…", ((#file as NSString).lastPathComponent), #line, #function) + + // try reloading three seconds later DispatchQueue.main.asyncAfter(deadline: .now() + 3) { - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: retry loading", ((#file as NSString).lastPathComponent), #line, #function) stateMachine.enter(Loading.self) } } @@ -144,7 +139,8 @@ extension DiscoveryNewsViewModel.State { query: Mastodon.API.Trends.StatusQuery( offset: offset, limit: nil - ) + ), + authenticationBox: viewModel.authContext.mastodonAuthenticationBox ) let newOffset: Int? = { guard let offset = response.link?.offset else { return nil } @@ -174,7 +170,6 @@ extension DiscoveryNewsViewModel.State { viewModel.links = links viewModel.didLoadLatest.send() } catch { - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): fetch news fail: \(error.localizedDescription)") if let error = error as? Mastodon.API.Error, error.httpResponseStatus.code == 404 { viewModel.isServerSupportEndpoint = false await enter(state: NoMore.self) diff --git a/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel.swift b/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel.swift index d440e9528..7e6bcbde5 100644 --- a/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel.swift +++ b/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel.swift @@ -51,11 +51,6 @@ final class DiscoveryNewsViewModel { await checkServerEndpoint() } // end Task } - - deinit { - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) - } - } @@ -64,7 +59,8 @@ extension DiscoveryNewsViewModel { do { _ = try await context.apiService.trendLinks( domain: authContext.mastodonAuthenticationBox.domain, - query: .init(offset: nil, limit: nil) + query: .init(offset: nil, limit: nil), + authenticationBox: authContext.mastodonAuthenticationBox ) } catch let error as Mastodon.API.Error where error.httpResponseStatus.code == 404 { isServerSupportEndpoint = false diff --git a/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewController.swift b/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewController.swift index 9d772a27e..01b4f7ba8 100644 --- a/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewController.swift +++ b/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewController.swift @@ -35,11 +35,6 @@ final class DiscoveryPostsViewController: UIViewController, NeedsDependency, Med let refreshControl = RefreshControl() let discoveryIntroBannerView = DiscoveryIntroBannerView() - - deinit { - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) - } - } extension DiscoveryPostsViewController { diff --git a/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel+State.swift b/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel+State.swift index fd413927e..b17622255 100644 --- a/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel+State.swift +++ b/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel+State.swift @@ -145,7 +145,8 @@ extension DiscoveryPostsViewModel.State { query: Mastodon.API.Trends.StatusQuery( offset: offset, limit: nil - ) + ), + authenticationBox: viewModel.authContext.mastodonAuthenticationBox ) let newOffset: Int? = { guard let offset = response.link?.offset else { return nil } diff --git a/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel.swift b/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel.swift index 7a1b044fd..3024f03be 100644 --- a/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel.swift +++ b/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel.swift @@ -5,7 +5,6 @@ // Created by MainasuK on 2022-4-12. // -import os.log import UIKit import Combine import GameplayKit @@ -56,11 +55,6 @@ final class DiscoveryPostsViewModel { await checkServerEndpoint() } // end Task } - - deinit { - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) - } - } extension DiscoveryPostsViewModel { @@ -68,7 +62,8 @@ extension DiscoveryPostsViewModel { do { _ = try await context.apiService.trendStatuses( domain: authContext.mastodonAuthenticationBox.domain, - query: .init(offset: nil, limit: nil) + query: .init(offset: nil, limit: nil), + authenticationBox: authContext.mastodonAuthenticationBox ) } catch let error as Mastodon.API.Error where error.httpResponseStatus.code == 404 { isServerSupportEndpoint = false diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Trend.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Trend.swift index 5432b02a0..06e92874e 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Trend.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Trend.swift @@ -7,17 +7,20 @@ import Foundation import MastodonSDK +import CoreDataStack extension APIService { public func trendHashtags( domain: String, - query: Mastodon.API.Trends.HashtagQuery? + query: Mastodon.API.Trends.HashtagQuery?, + authenticationBox: MastodonAuthenticationBox ) async throws -> Mastodon.Response.Content<[Mastodon.Entity.Tag]> { let response = try await Mastodon.API.Trends.hashtags( session: session, domain: domain, - query: query + query: query, + authorization: authenticationBox.userAuthorization ).singleOutput() return response @@ -25,12 +28,14 @@ extension APIService { public func trendStatuses( domain: String, - query: Mastodon.API.Trends.StatusQuery + query: Mastodon.API.Trends.StatusQuery, + authenticationBox: MastodonAuthenticationBox ) async throws -> Mastodon.Response.Content<[Mastodon.Entity.Status]> { let response = try await Mastodon.API.Trends.statuses( session: session, domain: domain, - query: query + query: query, + authorization: authenticationBox.userAuthorization ).singleOutput() let managedObjectContext = backgroundManagedObjectContext @@ -55,12 +60,14 @@ extension APIService { public func trendLinks( domain: String, - query: Mastodon.API.Trends.LinkQuery + query: Mastodon.API.Trends.LinkQuery, + authenticationBox: MastodonAuthenticationBox ) async throws -> Mastodon.Response.Content<[Mastodon.Entity.Link]> { let response = try await Mastodon.API.Trends.links( session: session, domain: domain, - query: query + query: query, + authorization: authenticationBox.userAuthorization ).singleOutput() return response diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Trends.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Trends.swift index d2dca8245..dbb18c360 100644 --- a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Trends.swift +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Trends.swift @@ -31,12 +31,13 @@ extension Mastodon.API.Trends { public static func hashtags( session: URLSession, domain: String, - query: Mastodon.API.Trends.HashtagQuery? + query: Mastodon.API.Trends.HashtagQuery?, + authorization: Mastodon.API.OAuth.Authorization ) -> AnyPublisher, Error> { let request = Mastodon.API.get( url: trendsURL(domain: domain), query: query, - authorization: nil + authorization: authorization ) return session.dataTaskPublisher(for: request) .tryMap { data, response in @@ -88,12 +89,13 @@ extension Mastodon.API.Trends { public static func statuses( session: URLSession, domain: String, - query: Mastodon.API.Trends.StatusQuery? + query: Mastodon.API.Trends.StatusQuery?, + authorization: Mastodon.API.OAuth.Authorization ) -> AnyPublisher, Error> { let request = Mastodon.API.get( url: trendStatusesURL(domain: domain), query: query, - authorization: nil + authorization: authorization ) return session.dataTaskPublisher(for: request) .tryMap { data, response in @@ -152,12 +154,13 @@ extension Mastodon.API.Trends { public static func links( session: URLSession, domain: String, - query: Mastodon.API.Trends.LinkQuery? + query: Mastodon.API.Trends.LinkQuery?, + authorization: Mastodon.API.OAuth.Authorization ) -> AnyPublisher, Error> { let request = Mastodon.API.get( url: trendLinksURL(domain: domain), query: query, - authorization: nil + authorization: authorization ) return session.dataTaskPublisher(for: request) .tryMap { data, response in From 075b8a739a321e107eb419886cb8225e63fe5718 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 21 Aug 2023 11:32:00 +0200 Subject: [PATCH 32/87] Fix some warnings --- .../Community/DiscoveryCommunityViewModel+State.swift | 3 --- .../Scene/Onboarding/Login/MastodonLoginViewController.swift | 1 - Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift | 2 +- Mastodon/Scene/Thread/ThreadViewModel+LoadThreadState.swift | 2 +- .../Scene/ComposeContent/ComposeContentViewModel.swift | 2 -- .../ComposeContent/Publisher/MastodonStatusEditPublisher.swift | 3 +-- 6 files changed, 3 insertions(+), 10 deletions(-) diff --git a/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewModel+State.swift b/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewModel+State.swift index 6f1e5d5ec..14910f791 100644 --- a/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewModel+State.swift +++ b/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewModel+State.swift @@ -22,9 +22,6 @@ extension DiscoveryCommunityViewModel { override func didEnter(from previousState: GKState?) { super.didEnter(from: previousState) - - let from = previousState.flatMap { String(describing: $0) } ?? "nil" - let to = String(describing: self) } @MainActor diff --git a/Mastodon/Scene/Onboarding/Login/MastodonLoginViewController.swift b/Mastodon/Scene/Onboarding/Login/MastodonLoginViewController.swift index 8f1cbecf2..839750145 100644 --- a/Mastodon/Scene/Onboarding/Login/MastodonLoginViewController.swift +++ b/Mastodon/Scene/Onboarding/Login/MastodonLoginViewController.swift @@ -236,7 +236,6 @@ class MastodonLoginViewController: UIViewController, NeedsDependency { let keyboardFrame = keyboardFrameValue.cgRectValue let keyboardOrigin = view.convert(keyboardFrame.origin, from: nil) - let intersectionY = CGRectGetMaxY(view.frame) - keyboardOrigin.y; UIView.animate(withDuration: duration.doubleValue, delay: 0, options: .curveEaseInOut) { self.view.layoutIfNeeded() diff --git a/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift b/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift index 506487504..da97a7888 100644 --- a/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift +++ b/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift @@ -333,7 +333,7 @@ extension WelcomeViewController { self.authenticationViewModel.isAuthenticating.send(false) switch completion { - case .failure(let error ): + case .failure(_): guard let randomServer = self.viewModel.pickRandomDefaultServer() else { return } self.viewModel.randomDefaultServer = randomServer diff --git a/Mastodon/Scene/Thread/ThreadViewModel+LoadThreadState.swift b/Mastodon/Scene/Thread/ThreadViewModel+LoadThreadState.swift index c11da082c..6d26b9fa4 100644 --- a/Mastodon/Scene/Thread/ThreadViewModel+LoadThreadState.swift +++ b/Mastodon/Scene/Thread/ThreadViewModel+LoadThreadState.swift @@ -85,7 +85,7 @@ extension ThreadViewModel.LoadThreadState { // assert(!Thread.isMainThread) // await Task.sleep(1_000_000_000) // 1s delay to prevent UI render issue - let statusHistory = try await viewModel.context.apiService.getHistory(forStatusID: threadContext.statusID, + _ = try await viewModel.context.apiService.getHistory(forStatusID: threadContext.statusID, authenticationBox: viewModel.authContext.mastodonAuthenticationBox) viewModel.mastodonStatusThreadViewModel.appendAncestor( diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift index c2e13fb40..835740b21 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/ComposeContentViewModel.swift @@ -480,8 +480,6 @@ extension ComposeContentViewModel { ) .receive(on: DispatchQueue.main) .map { contentWarning, content, hasPoll, attachments in - let canDiscardContentWarning = contentWarning.isEmpty - let trimmedContent = content.trimmingCharacters(in: .whitespacesAndNewlines) let initialContent = self.initialContent.trimmingCharacters(in: .whitespacesAndNewlines) let canDiscardContent = trimmedContent.isEmpty || trimmedContent == initialContent diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Publisher/MastodonStatusEditPublisher.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Publisher/MastodonStatusEditPublisher.swift index 76ad758bc..893fb1a28 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Publisher/MastodonStatusEditPublisher.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Publisher/MastodonStatusEditPublisher.swift @@ -5,6 +5,7 @@ import CoreData import CoreDataStack import MastodonCore import MastodonSDK +import Combine public final class MastodonEditStatusPublisher: NSObject, ProgressReporting { @@ -77,8 +78,6 @@ extension MastodonEditStatusPublisher: StatusPublisher { api: APIService, authContext: AuthContext ) async throws -> StatusPublishResult { - let idempotencyKey = UUID().uuidString - let publishStatusTaskStartDelayWeight: Int64 = 20 let publishStatusTaskStartDelayCount: Int64 = publishStatusTaskStartDelayWeight From a18872340f45f35f87c186b26ab5e482f2758f9d Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 21 Aug 2023 13:20:13 +0200 Subject: [PATCH 33/87] Don't try to reload every three seconds in case of 401 (#1104) --- .../Community/DiscoveryCommunityViewModel+State.swift | 8 +++++++- .../Discovery/News/DiscoveryNewsViewModel+State.swift | 10 +++++++--- .../Posts/DiscoveryPostsViewModel+State.swift | 11 +++++++---- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewModel+State.swift b/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewModel+State.swift index 14910f791..f61df078d 100644 --- a/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewModel+State.swift +++ b/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewModel+State.swift @@ -8,6 +8,7 @@ import Foundation import GameplayKit import MastodonSDK +import enum NIOHTTP1.HTTPResponseStatus extension DiscoveryCommunityViewModel { class State: GKState { @@ -161,7 +162,12 @@ extension DiscoveryCommunityViewModel.State { viewModel.didLoadLatest.send() } catch { - await enter(state: Fail.self) + if let error = error as? Mastodon.API.Error, + [HTTPResponseStatus.unauthorized, .notFound].contains(error.httpResponseStatus) { + await enter(state: NoMore.self) + } else { + await enter(state: Fail.self) + } } } // end Task } // end func diff --git a/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel+State.swift b/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel+State.swift index f06c1dc44..adc8a786e 100644 --- a/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel+State.swift +++ b/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel+State.swift @@ -170,9 +170,13 @@ extension DiscoveryNewsViewModel.State { viewModel.links = links viewModel.didLoadLatest.send() } catch { - if let error = error as? Mastodon.API.Error, error.httpResponseStatus.code == 404 { - viewModel.isServerSupportEndpoint = false - await enter(state: NoMore.self) + if let error = error as? Mastodon.API.Error { + if error.httpResponseStatus == .notFound { + viewModel.isServerSupportEndpoint = false + await enter(state: NoMore.self) + } else if error.httpResponseStatus == .unauthorized { + await enter(state: NoMore.self) + } } else { await enter(state: Fail.self) } diff --git a/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel+State.swift b/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel+State.swift index b17622255..7585e5387 100644 --- a/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel+State.swift +++ b/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewModel+State.swift @@ -177,10 +177,13 @@ extension DiscoveryPostsViewModel.State { viewModel.didLoadLatest.send() } catch { - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): fetch posts fail: \(error.localizedDescription)") - if let error = error as? Mastodon.API.Error, error.httpResponseStatus.code == 404 { - viewModel.isServerSupportEndpoint = false - await enter(state: NoMore.self) + if let error = error as? Mastodon.API.Error { + if error.httpResponseStatus == .notFound { + viewModel.isServerSupportEndpoint = false + await enter(state: NoMore.self) + } else if error.httpResponseStatus == .unauthorized { + await enter(state: NoMore.self) + } } else { await enter(state: Fail.self) } From bbda8c41b6b8d532b81e5351f3116f06c725e332 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 28 Aug 2023 12:58:46 +0200 Subject: [PATCH 34/87] Add post-visibility to notifications (#594) --- .../Share/View/Content/NotificationView+Configuration.swift | 3 +++ .../Sources/MastodonUI/View/Content/NotificationView.swift | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Mastodon/Scene/Share/View/Content/NotificationView+Configuration.swift b/Mastodon/Scene/Share/View/Content/NotificationView+Configuration.swift index 011435fff..576d2eadf 100644 --- a/Mastodon/Scene/Share/View/Content/NotificationView+Configuration.swift +++ b/Mastodon/Scene/Share/View/Content/NotificationView+Configuration.swift @@ -99,6 +99,9 @@ extension NotificationView { .store(in: &disposeBag) // timestamp viewModel.timestamp = notification.createAt + + viewModel.visibility = notification.status?.visibility ?? ._other("") + // notification type indicator Publishers.CombineLatest3( notification.publisher(for: \.typeRaw), diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift index 47b9ea65e..8900b4cb3 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift @@ -299,9 +299,6 @@ extension NotificationView { authorSecondaryMetaContainer.addArrangedSubview(dateTrailingDotLabel) dateTrailingDotLabel.setContentCompressionResistancePriority(.required, for: .horizontal) - authorSecondaryMetaContainer.addArrangedSubview(dateTrailingDotLabel) - dateTrailingDotLabel.setContentCompressionResistancePriority(.required, for: .horizontal) - authorSecondaryMetaContainer.addArrangedSubview(visibilityIconImageView) NSLayoutConstraint.activate([ visibilityIconImageView.heightAnchor.constraint(equalTo: authorUsernameLabel.heightAnchor), From ad3855a173b14833caa73f374ba1ee63f0bec8b6 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 28 Aug 2023 12:59:17 +0200 Subject: [PATCH 35/87] New Crowdin updates (#1082) --- .../Intents/input/el.lproj/Intents.strings | 42 +- .../input/el.lproj/Intents.stringsdict | 12 +- .../StringsConvertor/input/an.lproj/app.json | 4 - .../StringsConvertor/input/ar.lproj/app.json | 4 - .../StringsConvertor/input/be.lproj/app.json | 36 +- .../StringsConvertor/input/ca.lproj/app.json | 6 +- .../StringsConvertor/input/ckb.lproj/app.json | 4 - .../StringsConvertor/input/cs.lproj/app.json | 6 +- .../StringsConvertor/input/cy.lproj/app.json | 32 +- .../StringsConvertor/input/da.lproj/app.json | 4 - .../StringsConvertor/input/de.lproj/app.json | 4 - .../input/el.lproj/Localizable.stringsdict | 120 +-- .../StringsConvertor/input/el.lproj/app.json | 740 +++++++++--------- .../input/el.lproj/ios-infoPlist.json | 8 +- .../input/en-US.lproj/app.json | 4 - .../StringsConvertor/input/en.lproj/app.json | 4 - .../input/es-AR.lproj/app.json | 6 +- .../StringsConvertor/input/es.lproj/app.json | 4 - .../StringsConvertor/input/eu.lproj/app.json | 4 - .../StringsConvertor/input/fi.lproj/app.json | 6 +- .../StringsConvertor/input/fr.lproj/app.json | 4 - .../StringsConvertor/input/gd.lproj/app.json | 18 +- .../StringsConvertor/input/gl.lproj/app.json | 6 +- .../StringsConvertor/input/he.lproj/app.json | 4 - .../StringsConvertor/input/hi.lproj/app.json | 4 - .../StringsConvertor/input/id.lproj/app.json | 4 - .../StringsConvertor/input/is.lproj/app.json | 6 +- .../StringsConvertor/input/it.lproj/app.json | 6 +- .../StringsConvertor/input/ja.lproj/app.json | 6 +- .../StringsConvertor/input/kab.lproj/app.json | 4 - .../StringsConvertor/input/kmr.lproj/app.json | 4 - .../StringsConvertor/input/ko.lproj/app.json | 4 - .../StringsConvertor/input/lv.lproj/app.json | 4 - .../StringsConvertor/input/my.lproj/app.json | 4 - .../StringsConvertor/input/nl.lproj/app.json | 4 - .../StringsConvertor/input/pl.lproj/app.json | 126 ++- .../input/pt-BR.lproj/app.json | 4 - .../StringsConvertor/input/pt.lproj/app.json | 4 - .../StringsConvertor/input/ro.lproj/app.json | 4 - .../StringsConvertor/input/ru.lproj/app.json | 4 - .../StringsConvertor/input/si.lproj/app.json | 4 - .../StringsConvertor/input/sl.lproj/app.json | 6 +- .../StringsConvertor/input/sv.lproj/app.json | 28 +- .../StringsConvertor/input/th.lproj/app.json | 8 +- .../input/tr.lproj/Localizable.stringsdict | 4 +- .../StringsConvertor/input/tr.lproj/app.json | 134 ++-- .../input/uk.lproj/Localizable.stringsdict | 24 +- .../StringsConvertor/input/uk.lproj/app.json | 210 +++-- .../StringsConvertor/input/vi.lproj/app.json | 24 +- .../input/vi.lproj/ios-infoPlist.json | 2 +- .../input/zh-Hans.lproj/app.json | 4 - .../input/zh-Hant.lproj/app.json | 6 +- 52 files changed, 774 insertions(+), 954 deletions(-) diff --git a/Localization/StringsConvertor/Intents/input/el.lproj/Intents.strings b/Localization/StringsConvertor/Intents/input/el.lproj/Intents.strings index 484cc94b2..df186daea 100644 --- a/Localization/StringsConvertor/Intents/input/el.lproj/Intents.strings +++ b/Localization/StringsConvertor/Intents/input/el.lproj/Intents.strings @@ -4,48 +4,48 @@ "CsR7G2" = "Ανάρτηση στο Mastodon"; -"HZSGTr" = "What content to post?"; +"HZSGTr" = "Τι περιεχόμενο θα αναρτήσεις;"; -"HdGikU" = "Posting failed"; +"HdGikU" = "Αποτυχία δημοσίευσης"; -"KDNTJ4" = "Failure Reason"; +"KDNTJ4" = "Λόγος Αποτυχίας"; -"RHxKOw" = "Send Post with text content"; +"RHxKOw" = "Αποστολή ανάρτησης με περιεχόμενο κειμένου"; -"RxSqsb" = "Post"; +"RxSqsb" = "Ανάρτηση"; -"WCIR3D" = "Post ${content} on Mastodon"; +"WCIR3D" = "Ανάρτηση ${content} στο Mastodon"; -"ZKJSNu" = "Post"; +"ZKJSNu" = "Ανάρτηση"; "ZS1XaK" = "${content}"; -"ZbSjzC" = "Visibility"; +"ZbSjzC" = "Ορατότητα"; -"Zo4jgJ" = "Post Visibility"; +"Zo4jgJ" = "Ορατότητα Ανάρτησης"; -"apSxMG-dYQ5NN" = "There are ${count} options matching ‘Public’."; +"apSxMG-dYQ5NN" = "Υπάρχουν ${count} επιλογές που ταιριάζουν στο «Δημόσιο»."; -"apSxMG-ehFLjY" = "There are ${count} options matching ‘Followers Only’."; +"apSxMG-ehFLjY" = "Υπάρχουν ${count} επιλογές που ταιριάζουν στο «Μόνο για Ακόλουθους»."; -"ayoYEb-dYQ5NN" = "${content}, Public"; +"ayoYEb-dYQ5NN" = "${content}, Δημόσιο"; -"ayoYEb-ehFLjY" = "${content}, Followers Only"; +"ayoYEb-ehFLjY" = "${content}, Μόνο Ακόλουθοι"; -"dUyuGg" = "Post on Mastodon"; +"dUyuGg" = "Ανάρτηση στο Mastodon"; -"dYQ5NN" = "Public"; +"dYQ5NN" = "Δημόσιο"; -"ehFLjY" = "Followers Only"; +"ehFLjY" = "Μόνο Ακόλουθοι"; -"gfePDu" = "Posting failed. ${failureReason}"; +"gfePDu" = "Αποτυχία ανάρτησης. ${failureReason}"; -"k7dbKQ" = "Post was sent successfully."; +"k7dbKQ" = "Η ανάρτηση στάλθηκε με επιτυχία."; -"oGiqmY-dYQ5NN" = "Just to confirm, you wanted ‘Public’?"; +"oGiqmY-dYQ5NN" = "Απλά για να επιβεβαίωση, θες «Δημόσιο»;"; -"oGiqmY-ehFLjY" = "Just to confirm, you wanted ‘Followers Only’?"; +"oGiqmY-ehFLjY" = "Απλά για επιβεβαίωση, θες «Μόνο Ακόλουθοι»;"; "rM6dvp" = "URL"; -"ryJLwG" = "Post was sent successfully. "; +"ryJLwG" = "Η ανάρτηση στάλθηκε με επιτυχία. "; diff --git a/Localization/StringsConvertor/Intents/input/el.lproj/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/el.lproj/Intents.stringsdict index 18422c772..811a3dba9 100644 --- a/Localization/StringsConvertor/Intents/input/el.lproj/Intents.stringsdict +++ b/Localization/StringsConvertor/Intents/input/el.lproj/Intents.stringsdict @@ -5,7 +5,7 @@ There are ${count} options matching ‘${content}’. - 2 NSStringLocalizedFormatKey - There are %#@count_option@ matching ‘${content}’. + Υπάρχουν %#@count_option@ που ταιριάζουν με το ‘${content}’. count_option NSStringFormatSpecTypeKey @@ -13,15 +13,15 @@ NSStringFormatValueTypeKey %ld one - 1 option + 1 επιλογή other - %ld options + %ld επιλογές There are ${count} options matching ‘${visibility}’. NSStringLocalizedFormatKey - There are %#@count_option@ matching ‘${visibility}’. + Υπάρχουν %#@count_option@ που ταιριάζουν με το ‘${visibility}’. count_option NSStringFormatSpecTypeKey @@ -29,9 +29,9 @@ NSStringFormatValueTypeKey %ld one - 1 option + 1 επιλογή other - %ld options + %ld επιλογές diff --git a/Localization/StringsConvertor/input/an.lproj/app.json b/Localization/StringsConvertor/input/an.lproj/app.json index 398e163d8..91d7d7631 100644 --- a/Localization/StringsConvertor/input/an.lproj/app.json +++ b/Localization/StringsConvertor/input/an.lproj/app.json @@ -15,10 +15,6 @@ "title": "Voto fallido", "poll_ended": "La enquesta ha rematau" }, - "discard_post_content": { - "title": "Descartar borrador", - "message": "Confirma pa descartar lo conteniu d'a publicación." - }, "publish_post_failure": { "title": "Error de publicación", "message": "No s'ha puesto publicar la publicación. Per favor, revise la suya connexión a internet.", diff --git a/Localization/StringsConvertor/input/ar.lproj/app.json b/Localization/StringsConvertor/input/ar.lproj/app.json index 24d446a3e..a5992d018 100644 --- a/Localization/StringsConvertor/input/ar.lproj/app.json +++ b/Localization/StringsConvertor/input/ar.lproj/app.json @@ -15,10 +15,6 @@ "title": "إخفاقٌ فِي التَّصويت", "poll_ended": "اِنتَهَى اِستِطلاعُ الرَّأي" }, - "discard_post_content": { - "title": "التخلص من المسودة", - "message": "أكِّد للتخلص مِن مُحتوى مَنشور مؤلَّف." - }, "publish_post_failure": { "title": "إخفاق في عمليَّة النشر", "message": "فَشَلَ نَشر المَنشور.\nيُرجى التحقق من اتصالك بالإنترنت.", diff --git a/Localization/StringsConvertor/input/be.lproj/app.json b/Localization/StringsConvertor/input/be.lproj/app.json index 819c56e63..54e80198d 100644 --- a/Localization/StringsConvertor/input/be.lproj/app.json +++ b/Localization/StringsConvertor/input/be.lproj/app.json @@ -15,10 +15,6 @@ "title": "Памылка пры галасаванні", "poll_ended": "Апытанне завяршылася" }, - "discard_post_content": { - "title": "Скасаваць чарнавік", - "message": "Пацвердзіце, каб скасаваць змесціва допісу." - }, "publish_post_failure": { "title": "Памылка пры публікацыі", "message": "Не ўдалося апублікаваць допіс.\nПраверце злучэнне з інтэрнэтам.", @@ -102,10 +98,10 @@ "unknown_language": "Невядомая" }, "edit_post": "Рэдагаваць", - "bookmark": "Bookmark", - "remove_bookmark": "Remove Bookmark", - "follow": "Follow %s", - "unfollow": "Unfollow %s" + "bookmark": "Закладка", + "remove_bookmark": "Выдаліць закладку", + "follow": "Падпісацца на %s", + "unfollow": "Адпісацца ад %s" }, "tabs": { "home": "Галоўная", @@ -261,16 +257,16 @@ } }, "user_list": { - "no_verified_link": "No verified link", - "followers_count": "%@ followers" + "no_verified_link": "Няма спраўджанай спасылкі", + "followers_count": "%@ падпісчыкаў" } }, "scene": { "welcome": { "log_in": "Увайсці", "learn_more": "Даведацца больш", - "join_default_server": "Join %@", - "pick_server": "Pick another server", + "join_default_server": "Далучыцца да %@", + "pick_server": "Выбраць іншы сервер", "separator": { "or": "або" }, @@ -466,8 +462,8 @@ } }, "suggestion_account": { - "title": "Popular on Mastodon", - "follow_all": "Follow all" + "title": "Папулярна ў Mastodon", + "follow_all": "Падпісацца на ўсіх" }, "compose": { "title": { @@ -879,18 +875,18 @@ }, "hashtag": { "configuration": { - "display_name": "Hashtag", - "description": "Shows a recent post with the selected hashtag." + "display_name": "Хэштэг", + "description": "Паказвае нядаўні допіс з выбраным хэштэгам." }, "not_found": { - "account_name": "John Mastodon", + "account_name": "Джон Мастадон", "account": "@johnMastodon@no-such.account", - "content": "Sorry, we couldn’t find any posts with the hashtag #%@. Please try a #DifferentHashtag or check the widget settings." + "content": "На жаль, мы не змаглі знайсці допісы з хэштэгам #%@. Калі ласка, паспрабуйце #ІншыХэштэг або праверце налады віджэта." }, "placeholder": { - "account_name": "John Mastodon", + "account_name": "Джон Мастадон", "account": "@johnMastodon@no-such.account", - "content": "This is how a post with a #hashtag would look. Pick whichever #hashtag you want in the widget settings." + "content": "Вось як будзе выглядаць допіс з #хэштэгам. Выберыце любы #хэштэг у наладах віджэта." } } } diff --git a/Localization/StringsConvertor/input/ca.lproj/app.json b/Localization/StringsConvertor/input/ca.lproj/app.json index b44017705..d63c685f3 100644 --- a/Localization/StringsConvertor/input/ca.lproj/app.json +++ b/Localization/StringsConvertor/input/ca.lproj/app.json @@ -15,10 +15,6 @@ "title": "Error en votar", "poll_ended": "L'enquesta ha finalitzat" }, - "discard_post_content": { - "title": "Descarta l'esborrany", - "message": "Confirma per a descartar el contingut del tut." - }, "publish_post_failure": { "title": "Error en publicar", "message": "No s'ha pogut enviar la publicació.\nComprova la connexió a Internet.", @@ -269,7 +265,7 @@ "welcome": { "log_in": "Inicia sessió", "learn_more": "Més informació", - "join_default_server": "Join %@", + "join_default_server": "Uneix-te a %@", "pick_server": "Tria un altre servidor", "separator": { "or": "o" diff --git a/Localization/StringsConvertor/input/ckb.lproj/app.json b/Localization/StringsConvertor/input/ckb.lproj/app.json index 80af30fc1..c670a81e8 100644 --- a/Localization/StringsConvertor/input/ckb.lproj/app.json +++ b/Localization/StringsConvertor/input/ckb.lproj/app.json @@ -15,10 +15,6 @@ "title": "نەتوانرا دەنگ بدرێت", "poll_ended": "دەنگدانەکە کۆتایی هاتووە" }, - "discard_post_content": { - "title": "ڕەشنووس هەڵمەگرە", - "message": "دڵنیا ببەوە بۆ وازهێنان لە ناوەڕۆکەت." - }, "publish_post_failure": { "title": "نەتوانرا پۆستەکە بکرێت", "message": "نەتوانرا پۆستەکە بکرێت.\nتکایە لە بەردەستبوونی هێڵی ئینتەرنێت دڵنیا بە.", diff --git a/Localization/StringsConvertor/input/cs.lproj/app.json b/Localization/StringsConvertor/input/cs.lproj/app.json index 96cd1fbb2..9e806ef3b 100644 --- a/Localization/StringsConvertor/input/cs.lproj/app.json +++ b/Localization/StringsConvertor/input/cs.lproj/app.json @@ -15,10 +15,6 @@ "title": "Selhání hlasování", "poll_ended": "Anketa skončila" }, - "discard_post_content": { - "title": "Zahodit koncept", - "message": "Potvrďte odstranění obsahu složeného příspěvku." - }, "publish_post_failure": { "title": "Publikování selhalo", "message": "Nepodařilo se publikovat příspěvek.\nZkontrolujte prosím připojení k internetu.", @@ -269,7 +265,7 @@ "welcome": { "log_in": "Přihlásit se", "learn_more": "Zjistit více", - "join_default_server": "Join %@", + "join_default_server": "Připojit se k %@", "pick_server": "Pick another server", "separator": { "or": "or" diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json index 7eddc6e8a..1de450cd3 100644 --- a/Localization/StringsConvertor/input/cy.lproj/app.json +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -15,10 +15,6 @@ "title": "Gwall Pleidleisio", "poll_ended": "Mae'r pôl wedi dod i ben" }, - "discard_post_content": { - "title": "Dileu Drafft", - "message": "Cadarnhau i ddileu post drafft." - }, "publish_post_failure": { "title": "Gwall Cyhoeddi", "message": "Gwall wrth gyhoeddi'r tŵt.\nGwiriwch eich cysylltiad i'r rhyngrhwyd.", @@ -103,9 +99,9 @@ }, "edit_post": "Golygu", "bookmark": "Bookmark", - "remove_bookmark": "Remove Bookmark", - "follow": "Follow %s", - "unfollow": "Unfollow %s" + "remove_bookmark": "Dileu Llyfrnod", + "follow": "Dilyn %s", + "unfollow": "Dad-ddilyn %s" }, "tabs": { "home": "Hafan", @@ -213,7 +209,7 @@ "edit_history_title": "Edit History", "edit_history_detail": "Last edit %s" }, - "edited_at_timestamp_prefix": "Edited %s", + "edited_at_timestamp_prefix": "Wedi'i olygu %s", "edit_history": { "title": "Edit History", "original_post": "Original Post · %s" @@ -291,7 +287,7 @@ } }, "login": { - "title": "Welcome back", + "title": "Croeso nôl", "subtitle": "Mewngofnodi ar y gweinydd y rydych chi wedi creu cyfrif arno.", "server_search_field": { "placeholder": "Mewnosod URL neu chwilio am eich gweinydd" @@ -340,7 +336,7 @@ "manually_reviewed": "Manual Review" }, "language": { - "all": "All" + "all": "Popeth" }, "search": { "placeholder": "Search name or URL" @@ -547,7 +543,7 @@ "language": { "title": "Post Language", "suggested": "Suggested", - "recent": "Recent", + "recent": "Diweddar", "other": "Other Language…" } }, @@ -678,7 +674,7 @@ "intro": "Dyma'r postiadau sy'n denu tipyn o sylw yn eich cŵr Mastodon." }, "favorite": { - "title": "Favorites" + "title": "Ffefrynnau" }, "notification": { "title": { @@ -858,7 +854,7 @@ "user_not_logged_in": "Please open Mastodon to log in to an Account." }, "followers_count": { - "configuration_display_name": "Followers", + "configuration_display_name": "Dilynwyr", "configuration_description": "Show number of followers.", "title": "FOLLOWERS", "followers_today": "%s followers today" @@ -879,17 +875,17 @@ }, "hashtag": { "configuration": { - "display_name": "Hashtag", + "display_name": "Hashnod", "description": "Shows a recent post with the selected hashtag." }, "not_found": { - "account_name": "John Mastodon", - "account": "@johnMastodon@no-such.account", + "account_name": "Ieuan Mastodon", + "account": "@ieuanMastodon@dim-cyfrif-or.fath", "content": "Sorry, we couldn’t find any posts with the hashtag #%@. Please try a #DifferentHashtag or check the widget settings." }, "placeholder": { - "account_name": "John Mastodon", - "account": "@johnMastodon@no-such.account", + "account_name": "Ieuan Mastodon", + "account": "@ieuanMastodon@dim-cyfrif-or.fath", "content": "This is how a post with a #hashtag would look. Pick whichever #hashtag you want in the widget settings." } } diff --git a/Localization/StringsConvertor/input/da.lproj/app.json b/Localization/StringsConvertor/input/da.lproj/app.json index 8b2e51f11..486b96b5e 100644 --- a/Localization/StringsConvertor/input/da.lproj/app.json +++ b/Localization/StringsConvertor/input/da.lproj/app.json @@ -15,10 +15,6 @@ "title": "Vote Failure", "poll_ended": "The poll has ended" }, - "discard_post_content": { - "title": "Discard Draft", - "message": "Confirm to discard composed post content." - }, "publish_post_failure": { "title": "Publish Failure", "message": "Failed to publish the post.\nPlease check your internet connection.", diff --git a/Localization/StringsConvertor/input/de.lproj/app.json b/Localization/StringsConvertor/input/de.lproj/app.json index 5b8ca6ec3..89f071571 100644 --- a/Localization/StringsConvertor/input/de.lproj/app.json +++ b/Localization/StringsConvertor/input/de.lproj/app.json @@ -15,10 +15,6 @@ "title": "Fehler bei Abstimmung", "poll_ended": "Die Umfrage ist beendet" }, - "discard_post_content": { - "title": "Entwurf verwerfen", - "message": "Bestätige, um den Beitrag zu verwerfen." - }, "publish_post_failure": { "title": "Fehler bei Veröffentlichung", "message": "Fehler beim Veröffentlichen des Beitrags.\nBitte überprüfe deine Internetverbindung.", diff --git a/Localization/StringsConvertor/input/el.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/el.lproj/Localizable.stringsdict index 2b09ee004..7705da056 100644 --- a/Localization/StringsConvertor/input/el.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/el.lproj/Localizable.stringsdict @@ -13,15 +13,15 @@ NSStringFormatValueTypeKey ld one - 1 unread notification + 1 μη αναγνωσμένη ειδοποίηση other - %ld unread notifications + %ld μη αναγνωσμένες ειδοποιήσεις a11y.plural.count.input_limit_exceeds NSStringLocalizedFormatKey - Input limit exceeds %#@character_count@ + Το όριο εισόδου υπερβαίνει το %#@character_count@ character_count NSStringFormatSpecTypeKey @@ -29,15 +29,15 @@ NSStringFormatValueTypeKey ld one - 1 character + 1 χαρακτήρας other - %ld characters + %ld χαρακτήρες a11y.plural.count.input_limit_remains NSStringLocalizedFormatKey - Input limit remains %#@character_count@ + Το όριο εισόδου παραμένει %#@character_count@ character_count NSStringFormatSpecTypeKey @@ -45,9 +45,9 @@ NSStringFormatValueTypeKey ld one - 1 character + 1 χαρακτήρας other - %ld characters + %ld χαρακτήρες a11y.plural.count.characters_left @@ -61,9 +61,9 @@ NSStringFormatValueTypeKey ld one - 1 character left + απομένει 1 χαρακτήρας other - %ld characters left + απομένουν %ld χαρακτήρες plural.count.followed_by_and_mutual @@ -88,9 +88,9 @@ NSStringFormatValueTypeKey ld one - Followed by %1$@, and another mutual + Ακολουθείται από %1$@ και έναν ακόμα κοινό other - Followed by %1$@, and %ld mutuals + Ακολουθείται από %1$@, και %ld κοινούς plural.count.metric_formatted.post @@ -104,9 +104,9 @@ NSStringFormatValueTypeKey ld one - post + ανάρτηση other - posts + αναρτήσεις plural.count.media @@ -120,9 +120,9 @@ NSStringFormatValueTypeKey ld one - 1 media + 1 πολυμέσο other - %ld media + %ld πολυμέσα plural.count.post @@ -136,9 +136,9 @@ NSStringFormatValueTypeKey ld one - 1 post + 1 ανάρτηση other - %ld posts + %ld αναρτήσεις plural.count.favorite @@ -152,9 +152,9 @@ NSStringFormatValueTypeKey ld one - 1 favorite + 1 αγαπημένο other - %ld favorites + %ld αγαπημένα plural.count.reblog @@ -168,9 +168,9 @@ NSStringFormatValueTypeKey ld one - 1 reblog + 1 αναδημοσίευση other - %ld reblogs + %ld αναδημοσιεύσεις plural.count.reblog_a11y @@ -184,9 +184,9 @@ NSStringFormatValueTypeKey ld one - 1 re-blog + 1 αναδημοσίευση other - %ld re-blogs + %ld αναδημοσιεύσεις plural.count.reply @@ -200,9 +200,9 @@ NSStringFormatValueTypeKey ld one - 1 reply + 1 απάντηση other - %ld replies + %ld απαντήσεις plural.count.vote @@ -216,9 +216,9 @@ NSStringFormatValueTypeKey ld one - 1 vote + 1 ψήφος other - %ld votes + %ld ψήφοι plural.count.voter @@ -232,9 +232,9 @@ NSStringFormatValueTypeKey ld one - 1 voter + 1 ψηφοφόρος other - %ld voters + %ld ψηφοφόροι plural.people_talking @@ -248,9 +248,9 @@ NSStringFormatValueTypeKey ld one - 1 people talking + 1 άτομο που μιλάει other - %ld people talking + %ld άτομα μιλούν plural.count.following @@ -264,9 +264,9 @@ NSStringFormatValueTypeKey ld one - 1 following + 1 ακολουθεί other - %ld following + %ld ακολουθούν plural.count.follower @@ -280,9 +280,9 @@ NSStringFormatValueTypeKey ld one - 1 follower + 1 ακόλουθος other - %ld followers + %ld ακόλουθοι date.year.left @@ -296,9 +296,9 @@ NSStringFormatValueTypeKey ld one - 1 year left + Απομένει 1 χρόνος other - %ld years left + Απομένουν %ld χρόνια date.month.left @@ -312,9 +312,9 @@ NSStringFormatValueTypeKey ld one - 1 months left + Απομένει 1 μήνας other - %ld months left + Απομένουν %ld μήνες date.day.left @@ -328,9 +328,9 @@ NSStringFormatValueTypeKey ld one - 1 day left + Απομένει 1 ημέρα other - %ld days left + απομένουν %ld ημέρες date.hour.left @@ -344,9 +344,9 @@ NSStringFormatValueTypeKey ld one - 1 hour left + απομένει 1 ώρα other - %ld hours left + απομένουν %ld ώρες date.minute.left @@ -360,9 +360,9 @@ NSStringFormatValueTypeKey ld one - 1 minute left + απομένει 1 λεπτό other - %ld minutes left + Απομένουν %ld λεπτά date.second.left @@ -376,9 +376,9 @@ NSStringFormatValueTypeKey ld one - 1 second left + απομένει 1 δευτερόλεπτο other - %ld seconds left + Απομένουν %ld δευτερόλεπτα date.year.ago.abbr @@ -392,9 +392,9 @@ NSStringFormatValueTypeKey ld one - 1y ago + 1χρ πριν other - %ldy ago + %ldχρ πριν date.month.ago.abbr @@ -408,9 +408,9 @@ NSStringFormatValueTypeKey ld one - 1M ago + 1μην πριν other - %ldM ago + %ldμην πριν date.day.ago.abbr @@ -424,9 +424,9 @@ NSStringFormatValueTypeKey ld one - 1d ago + %1ημ πριν other - %ldd ago + %ldημ πριν date.hour.ago.abbr @@ -440,9 +440,9 @@ NSStringFormatValueTypeKey ld one - 1h ago + 1ώ πριν other - %ldh ago + %ldώ πριν date.minute.ago.abbr @@ -456,9 +456,9 @@ NSStringFormatValueTypeKey ld one - 1m ago + 1λ πριν other - %ldm ago + %ldλ πριν date.second.ago.abbr @@ -472,9 +472,9 @@ NSStringFormatValueTypeKey ld one - 1s ago + 1δλ πριν other - %lds ago + %ldδλ πριν diff --git a/Localization/StringsConvertor/input/el.lproj/app.json b/Localization/StringsConvertor/input/el.lproj/app.json index f570e8534..f87dbec4c 100644 --- a/Localization/StringsConvertor/input/el.lproj/app.json +++ b/Localization/StringsConvertor/input/el.lproj/app.json @@ -15,10 +15,6 @@ "title": "Αποτυχία Ψήφου", "poll_ended": "Η δημοσκόπηση έληξε" }, - "discard_post_content": { - "title": "Απόρριψη Προχείρου", - "message": "Επιβεβαίωση για απόρριψη του περιεχομένου της ανάρτησης." - }, "publish_post_failure": { "title": "Αποτυχία Ανάρτησης", "message": "Αποτυχία δημοσίευσης της ανάρτησης.\nΠαρακαλούμε έλεγξε τη σύνδεσή σου στο διαδίκτυο.", @@ -252,645 +248,645 @@ "header": { "no_status_found": "Δεν Βρέθηκε Ανάρτηση", "blocking_warning": "Δεν μπορείς να δεις το προφίλ αυτού του χρήστη\nμέχρι να τον ξεμπλοκάρεις.\nΤο προφίλ σου μοιάζει έτσι και σε αυτόν.", - "user_blocking_warning": "You can’t view %s’s profile\nuntil you unblock them.\nYour profile looks like this to them.", - "blocked_warning": "You can’t view this user’s profile\nuntil they unblock you.", - "user_blocked_warning": "You can’t view %s’s profile\nuntil they unblock you.", - "suspended_warning": "This user has been suspended.", - "user_suspended_warning": "%s’s account has been suspended." + "user_blocking_warning": "Δεν μπορείς να δεις το προφίλ του %s\nμέχρι να τον ξεμπλοκάρεις.\nΤο προφίλ σου μοιάζει έτσι κι σ' αυτούς.", + "blocked_warning": "Δεν μπορείς να δεις το προφίλ αυτού του χρήστη\nμέχρι να σε ξεμπλοκάρει.", + "user_blocked_warning": "Δεν μπορείς να δεις το προφίλ %s\nμέχρι να σε ξεμπλοκάρουν.", + "suspended_warning": "Αυτός ο χρήστης έχει ανασταλεί.", + "user_suspended_warning": "Ο λογαριασμός του %s έχει ανασταλεί." } } }, "user_list": { - "no_verified_link": "No verified link", - "followers_count": "%@ followers" + "no_verified_link": "Χωρίς επαληθευμένο σύνδεσμο", + "followers_count": "%@ ακόλουθοι" } }, "scene": { "welcome": { - "log_in": "Log In", - "learn_more": "Learn more", - "join_default_server": "Join %@", - "pick_server": "Pick another server", + "log_in": "Σύνδεση", + "learn_more": "Μάθε περισσότερα", + "join_default_server": "Γίνε μέλος %@", + "pick_server": "Διάλεξε άλλο διακομιστή", "separator": { - "or": "or" + "or": "ή" }, "education": { "mastodon": { - "title": "Welcome to Mastodon", - "description": "Mastodon is a decentralized social network, meaning no single company controls it. It’s made up of many independently-run servers, all connected together." + "title": "Καλώς ήρθες στο Mastodon", + "description": "Το Mastodon είναι ένα αποκεντρωμένο κοινωνικό δίκτυο που σημαίνει ότι καμία εταιρεία δεν το ελέγχει. Αποτελείται από πολλούς ανεξάρτητους διακομιστές, όλοι συνδεδεμένοι μαζί." }, "servers": { - "title": "What are servers?", - "description": "Every Mastodon account is hosted on a server — each with its own values, rules, & admins. No matter which one you pick, you can follow and interact with people on any server." + "title": "Τι είναι οι διακομιστές;", + "description": "Κάθε λογαριασμός Mastodon φιλοξενείται σε ένα διακομιστή - ο καθένας με τις δικές του αξίες, κανόνες και διαχειριστές. Ανεξάρτητα από το ποιον μπορεί να επιλέξεις, μπορείς να ακολουθήσεις και να αλληλεπιδράσεις με άτομα από οποιονδήποτε διακομιστή." }, "a11y": { "what_is_mastodon": { - "title": "What is Mastodon?" + "title": "Τι είναι το Mastodon;" } } } }, "login": { - "title": "Welcome back", - "subtitle": "Log you in on the server you created your account on.", + "title": "Καλωσόρισες και πάλι", + "subtitle": "Συνδέσου στο διακομιστή στον οποίο δημιούργησες τον λογαριασμό σου.", "server_search_field": { - "placeholder": "Enter URL or search for your server" + "placeholder": "Εισαγωγή URL ή αναζήτησε τον διακομιστή σου" } }, "server_picker": { - "title": "Pick Server", + "title": "Επιλογή Διακομιστή", "button": { - "language": "Language", - "signup_speed": "Sign-up Speed", + "language": "Γλώσσα", + "signup_speed": "Ταχύτητα Εγγραφής", "category": { - "all": "All", - "all_accessiblity_description": "Category: All", - "academia": "academia", - "activism": "activism", - "food": "food", - "furry": "furry", - "games": "games", - "general": "general", - "journalism": "journalism", - "lgbt": "lgbt", - "regional": "regional", - "art": "art", - "music": "music", - "tech": "tech" + "all": "Όλοι", + "all_accessiblity_description": "Κατηγορία: Όλα", + "academia": "ακαδημαϊκά", + "activism": "ακτιβισμός", + "food": "φαγητό", + "furry": "γούνινο", + "games": "παιχνίδια", + "general": "γενικά", + "journalism": "δημοσιογραφία", + "lgbt": "λοατκι", + "regional": "τοπικό", + "art": "τέχνη", + "music": "μουσική", + "tech": "τεχνολογία" }, - "see_less": "See Less", - "see_more": "See More" + "see_less": "Δες Λιγότερα", + "see_more": "Δες Περισσότερα" }, "label": { - "language": "LANGUAGE", - "users": "USERS", - "category": "CATEGORY" + "language": "ΓΛΩΣΣΑ", + "users": "ΧΡΗΣΤΕΣ", + "category": "ΚΑΤΗΓΟΡΙΑ" }, "input": { - "search_servers_or_enter_url": "Search communities or enter URL" + "search_servers_or_enter_url": "Αναζήτησε κοινότητες ή εισήγαγε URL" }, "empty_state": { - "finding_servers": "Finding available servers...", - "bad_network": "Something went wrong while loading the data. Check your internet connection.", - "no_results": "No results" + "finding_servers": "Εύρεση διαθέσιμων διακομιστών...", + "bad_network": "Κάτι πήγε στραβά κατά τη φόρτωση των δεδομένων. Έλεγξε τη σύνδεσή σου στο διαδίκτυο.", + "no_results": "Κανένα αποτέλεσμα" }, "signup_speed": { - "all": "All", - "instant": "Instant Sign-up", - "manually_reviewed": "Manual Review" + "all": "Όλες", + "instant": "Άμεση Εγγραφή", + "manually_reviewed": "Χειροκίνητη Αξιολόγηση" }, "language": { - "all": "All" + "all": "Όλες" }, "search": { - "placeholder": "Search name or URL" + "placeholder": "Αναζήτηση ονόματος ή URL" }, - "no_server_selected_hint": "We’ll pick a server based on your language if you continue without making a selection." + "no_server_selected_hint": "Θα επιλέξουμε έναν διακομιστή με βάση τη γλώσσα σου αν συνεχίσεις χωρίς να κάνεις κάποια επιλογή." }, "privacy": { - "title": "Privacy", - "description": "Although the Mastodon app does not collect any data, the server you sign up through may have a different policy. Take a minute to review and agree to the Mastodon app privacy policy and your server’s privacy policy.", + "title": "Απόρρητο", + "description": "Αν και η εφαρμογή Mastodon δε συλλέγει δεδομένα, ο διακομιστής που εγγράφεσαι μπορεί να έχει διαφορετική πολιτική. Πάρε ένα λεπτό για να ελέγξεις και να συμφωνήσεις με την πολιτική απορρήτου της εφαρμογής Mastodon και την πολιτική απορρήτου του διακομιστή σου.", "policy": { - "ios": "Privacy Policy - Mastodon for iOS", - "server": "Privacy Policy - %s" + "ios": "Πολιτική Απορρήτου - Mastodon για iOS", + "server": "Πολιτική Απορρήτου - %s" }, "button": { - "confirm": "I Agree" + "confirm": "Συμφωνώ" } }, "register": { - "title": "Create Account", + "title": "Δημιουργία Λογαριασμού", "input": { "avatar": { - "delete": "Delete" + "delete": "Διαγραφή" }, "username": { - "placeholder": "username", - "duplicate_prompt": "This username is taken.", - "suggestion": "amazing_%@" + "placeholder": "όνομα χρήστη", + "duplicate_prompt": "Αυτό το όνομα χρήστη χρησιμοποιείται.", + "suggestion": "εκπληκτικό_%@" }, "display_name": { - "placeholder": "display name" + "placeholder": "εμφανιζόμενο όνομα" }, "email": { "placeholder": "email" }, "password": { - "placeholder": "password", - "confirmation_placeholder": "Confirm Password", - "require": "Your password needs at least:", - "character_limit": "8 characters", + "placeholder": "κωδικός πρόσβασης", + "confirmation_placeholder": "Επιβεβαίωση Κωδικού Πρόσβασης", + "require": "Ο κωδικός σου χρειάζεται τουλάχιστον:", + "character_limit": "8 χαρακτήρες", "accessibility": { - "checked": "checked", - "unchecked": "unchecked" + "checked": "επιλεγμένο", + "unchecked": "μη επιλεγμένο" }, - "hint": "Your password needs at least eight characters" + "hint": "Ο κωδικός πρόσβασής σου χρειάζεται τουλάχιστον οκτώ χαρακτήρες" }, "invite": { - "registration_user_invite_request": "Why do you want to join?" + "registration_user_invite_request": "Γιατί θέλεις να συμμετάσχεις;" } }, "error": { "item": { - "username": "Username", + "username": "Όνομα χρήστη", "email": "Email", - "password": "Password", - "agreement": "Agreement", - "locale": "Locale", - "reason": "Reason" + "password": "Κωδικός πρόσβασης", + "agreement": "Συμφωνία", + "locale": "Γλώσσα", + "reason": "Αιτιολογία" }, "reason": { - "blocked": "%s contains a disallowed email provider", - "unreachable": "%s does not seem to exist", - "taken": "%s is already taken. How about:", - "reserved": "%s is a reserved keyword", - "accepted": "%s must be accepted", - "blank": "%s is required", - "invalid": "%s is invalid", - "too_long": "%s is too long", - "too_short": "%s is too short", - "inclusion": "%s is not a supported value" + "blocked": "%s περιέχει πάροχο μη επιτρεπόμενων email", + "unreachable": "%s δεν φαίνεται να υπάρχει", + "taken": "%s χρησιμοποιείται ήδη. Τι θα έλεγες για:", + "reserved": "%s είναι δεσμευμένη λέξη-κλειδί", + "accepted": "%s πρέπει να γίνει αποδεκτό", + "blank": "%s απαιτείται", + "invalid": "%s δεν είναι έγκυρο", + "too_long": "%s είναι πολύ μεγάλο", + "too_short": "%s είναι πολύ μικρό", + "inclusion": "%s δεν είναι υποστηριζόμενη τιμή" }, "special": { - "username_invalid": "Username must only contain alphanumeric characters and underscores", - "username_too_long": "Username is too long (can’t be longer than 30 characters)", - "email_invalid": "This is not a valid email address", - "password_too_short": "Password is too short (must be at least 8 characters)" + "username_invalid": "Το όνομα χρήστη πρέπει να περιέχει μόνο αλφαριθμητικούς χαρακτήρες και κάτω παύλες", + "username_too_long": "Το όνομα χρήστη είναι πολύ μεγάλο (δεν μπορεί να υπερβαίνει τους 30 χαρακτήρες)", + "email_invalid": "Αυτή η διεύθυνση email δεν είναι έγκυρη", + "password_too_short": "Ο κωδικός πρόσβασης είναι πολύ μικρός (πρέπει να είναι τουλάχιστον 8 χαρακτήρες)" } } }, "server_rules": { - "title": "Some ground rules.", - "subtitle": "These are set and enforced by the %s moderators.", - "prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.", - "terms_of_service": "terms of service", - "privacy_policy": "privacy policy", + "title": "Ορισμένοι βασικοί κανόνες.", + "subtitle": "Αυτά ορίζονται και επιβάλλονται από τους συντονιστές %s.", + "prompt": "Συνεχίζοντας, υπόκεισαι στους όρους της υπηρεσίας και της πολιτικής απορρήτου για %s.", + "terms_of_service": "όροι υπηρεσίας", + "privacy_policy": "πολιτική απορρήτου", "button": { - "confirm": "I Agree" + "confirm": "Συμφωνώ" } }, "confirm_email": { - "title": "Check Your Inbox", - "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we sent you to verify %@. We’ll wait right here.", + "title": "Έλεγξε τα Εισερχόμενα σου", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "Πάτησε το σύνδεσμο που σού στείλαμε για να επαληθεύσεις το %@. Θα σε περιμένουμε εδώ.", "button": { - "resend": "Resend" + "resend": "Επαναποστολή" }, "dont_receive_email": { - "title": "Check your Email", - "description": "Check if your email address is correct as well as your junk folder if you haven’t.", - "resend_email": "Resend Email" + "title": "Έλεγξε το Email σου", + "description": "Έλεγξε αν η διεύθυνση email σου είναι σωστή καθώς και τον φάκελο ανεπιθύμητης αλληλογραφίας σας αν δεν το έχεις κάνει ήδη.", + "resend_email": "Επαναποστολή Email" }, "open_email_app": { - "title": "Check your Inbox.", - "description": "We just sent you an email. Check your junk folder if you haven’t.", + "title": "Έλεγξε τα Εισερχόμενα σου.", + "description": "Μόλις σου στείλαμε ένα email. Έλεγξε το φάκελο ανεπιθύμητης αλληλογραφίας αν δεν το έχεις κάνει ήδη.", "mail": "Mail", - "open_email_client": "Open Email Client" + "open_email_client": "Άνοιγμα Πελάτη Email" }, "didnt_get_link": { - "prefix": "Didn’t get a link?", - "resend_in": "Resend (%@)", - "resend_now": "Resend now." + "prefix": "Δεν έλαβες τον σύνδεσμο;", + "resend_in": "Επαναποστολή (%@)", + "resend_now": "Επαναποστολή τώρα." } }, "home_timeline": { - "title": "Home", + "title": "Αρχική", "navigation_bar_state": { - "offline": "Offline", - "new_posts": "See new posts", - "published": "Published!", - "Publishing": "Publishing post...", + "offline": "Εκτός σύνδεσης", + "new_posts": "Δες νέες αναρτήσεις", + "published": "Δημοσιεύθηκε!", + "Publishing": "Δημοσίευση ανάρτησης...", "accessibility": { "logo_label": "Mastodon", - "logo_hint": "Tap to scroll to top and tap again to previous location" + "logo_hint": "Πάτα για κύλιση στην κορυφή και πάτα ξανά για προηγούμενη τοποθεσία" } } }, "suggestion_account": { - "title": "Popular on Mastodon", - "follow_all": "Follow all" + "title": "Δημοφιλή στο Mastodon", + "follow_all": "Ακολούθησε τους όλους" }, "compose": { "title": { - "new_post": "New Post", - "new_reply": "New Reply", - "edit_post": "Edit Post" + "new_post": "Νέα Ανάρτηση", + "new_reply": "Νέα Απάντηση", + "edit_post": "Επεξεργασία Ανάρτησης" }, "media_selection": { - "camera": "Take Photo", - "photo_library": "Photo Library", - "browse": "Browse" + "camera": "Λήψη Φωτογραφίας", + "photo_library": "Βιβλιοθήκη Φωτογραφιών", + "browse": "Περιήγηση" }, - "content_input_placeholder": "Type or paste what’s on your mind", - "compose_action": "Publish", - "replying_to_user": "replying to %s", + "content_input_placeholder": "Πληκτρολόγησε ή επικόλλησε τί έχεις στο μυαλό σου", + "compose_action": "Δημοσίευση", + "replying_to_user": "απάντηση σε %s", "attachment": { - "photo": "photo", - "video": "video", - "attachment_broken": "This %s is broken and can’t be\nuploaded to Mastodon.", - "description_photo": "Describe the photo for the visually-impaired...", - "description_video": "Describe the video for the visually-impaired...", - "load_failed": "Load Failed", - "upload_failed": "Upload Failed", - "can_not_recognize_this_media_attachment": "Can not recognize this media attachment", - "attachment_too_large": "Attachment too large", - "compressing_state": "Compressing...", - "server_processing_state": "Server Processing..." + "photo": "φωτογραφία", + "video": "βίντεο", + "attachment_broken": "Το %s έχει χαλάσει και δεν μπορεί να\nφορτωθεί στο Mastodon.", + "description_photo": "Περιέγραψε τη φωτογραφία για τα άτομα με προβλήματα όρασης...", + "description_video": "Περιέγραψε το βίντεο για τα άτομα με προβλήματα όρασης...", + "load_failed": "Αποτυχία Φόρτωσης", + "upload_failed": "Η Μεταφόρτωση Απέτυχε", + "can_not_recognize_this_media_attachment": "Αυτό το συνημμένο πολυμέσων δεν μπορεί να αναγνωριστεί", + "attachment_too_large": "Υπερβολικά μεγάλο συνημμένο", + "compressing_state": "Συμπίεση...", + "server_processing_state": "Επεξεργασία Διακομιστή..." }, "poll": { - "title": "Poll", - "duration_time": "Duration: %s", - "thirty_minutes": "30 minutes", - "one_hour": "1 Hour", - "six_hours": "6 Hours", - "one_day": "1 Day", - "three_days": "3 Days", - "seven_days": "7 Days", - "option_number": "Option %ld", - "the_poll_is_invalid": "The poll is invalid", - "the_poll_has_empty_option": "The poll has empty option", - "add_option": "Add Option", - "remove_option": "Remove Option", - "move_up": "Move Up", - "move_down": "Move Down" + "title": "Δημοσκόπηση", + "duration_time": "Διάρκεια: %s", + "thirty_minutes": "30 λεπτά", + "one_hour": "1 Ώρα", + "six_hours": "6 Ώρες", + "one_day": "1 Ημέρα", + "three_days": "3 Ημέρες", + "seven_days": "7 Ημέρες", + "option_number": "Επιλογή %ld", + "the_poll_is_invalid": "Η δημοσκόπηση δεν είναι έγκυρη", + "the_poll_has_empty_option": "Η δημοσκόπηση έχει κενή επιλογή", + "add_option": "Προσθήκη Επιλογής", + "remove_option": "Αφαίρεση Επιλογής", + "move_up": "Μετακίνηση Πάνω", + "move_down": "Μετακίνηση Κάτω" }, "content_warning": { - "placeholder": "Write an accurate warning here..." + "placeholder": "Γράψε εδώ μια ακριβή προειδοποίηση..." }, "visibility": { - "public": "Public", - "unlisted": "Unlisted", - "private": "Followers only", - "direct": "Only people I mention" + "public": "Δημόσιο", + "unlisted": "Μη καταχωρημένο", + "private": "Μόνο ακόλουθοι", + "direct": "Μόνο άτομα που επισημαίνω" }, "auto_complete": { - "space_to_add": "Space to add" + "space_to_add": "\"Διάστημα\" για προσθήκη" }, "accessibility": { - "append_attachment": "Add Attachment", - "append_poll": "Add Poll", - "remove_poll": "Remove Poll", - "custom_emoji_picker": "Custom Emoji Picker", - "enable_content_warning": "Enable Content Warning", - "disable_content_warning": "Disable Content Warning", - "post_visibility_menu": "Post Visibility Menu", - "post_options": "Post Options", - "posting_as": "Posting as %s" + "append_attachment": "Προσθήκη Συνημμένου", + "append_poll": "Προσθήκη Δημοσκ.", + "remove_poll": "Αφαίρεση Δημοσκόπησης", + "custom_emoji_picker": "Προσαρμοσμένος Επιλογέας Emoji", + "enable_content_warning": "Ενεργοποίηση Προειδοποίησης Περιεχομένου", + "disable_content_warning": "Απενεργοποίηση Προειδοποίησης Περιεχομένου", + "post_visibility_menu": "Μενού Ορατότητας Ανάρτησης", + "post_options": "Επιλογές Ανάρτησης", + "posting_as": "Ανάρτηση ως %s" }, "keyboard": { - "discard_post": "Discard Post", - "publish_post": "Publish Post", - "toggle_poll": "Toggle Poll", - "toggle_content_warning": "Toggle Content Warning", - "append_attachment_entry": "Add Attachment - %s", - "select_visibility_entry": "Select Visibility - %s" + "discard_post": "Απόρριψη Ανάρτησης", + "publish_post": "Δημοσίευση Ανάρτησης", + "toggle_poll": "Εναλλαγή Δημοσκόπησης", + "toggle_content_warning": "Εναλλαγή Προειδοποίησης Περιεχομένου", + "append_attachment_entry": "Προσθήκη Συνημμένου - %s", + "select_visibility_entry": "Επιλογή ορατότητας - %s" }, "language": { - "title": "Post Language", - "suggested": "Suggested", - "recent": "Recent", - "other": "Other Language…" + "title": "Γλώσσα Ανάρτησης", + "suggested": "Προτεινόμενες", + "recent": "Πρόσφατα", + "other": "Άλλη γλώσσα…" } }, "profile": { "header": { - "follows_you": "Follows You" + "follows_you": "Σε Ακολουθεί" }, "dashboard": { - "my_posts": "posts", - "my_following": "following", - "my_followers": "followers", - "other_posts": "posts", - "other_following": "following", - "other_followers": "followers", - "familiar_followers": "mutuals" + "my_posts": "αναρτήσεις", + "my_following": "ακολουθείς", + "my_followers": "ακόλουθοι", + "other_posts": "αναρτήσεις", + "other_following": "ακολουθεί", + "other_followers": "ακόλουθοι", + "familiar_followers": "κοινοί" }, "fields": { - "joined": "Joined", - "add_row": "Add Row", + "joined": "Έγινε μέλος", + "add_row": "Προσθήκη Γραμμής", "placeholder": { - "label": "Label", - "content": "Content" + "label": "Ετικέτα", + "content": "Περιεχόμενο" }, "verified": { - "short": "Verified on %s", - "long": "Ownership of this link was checked on %s" + "short": "Επαληθεύτηκε στις %s", + "long": "Η ιδιοκτησία αυτού του συνδέσμου ελέχθηκε στις %s" } }, "segmented_control": { - "posts": "Posts", - "replies": "Replies", - "posts_and_replies": "Posts and Replies", - "media": "Media", - "about": "About" + "posts": "Αναρτήσεις", + "replies": "Απαντήσεις", + "posts_and_replies": "Αναρτήσεις και Απαντήσεις", + "media": "Πολυμέσα", + "about": "Σχετικά" }, "relationship_action_alert": { "confirm_mute_user": { - "title": "Mute Account", - "message": "Confirm to mute %s" + "title": "Σίγαση Λογαριασμού", + "message": "Επιβεβαίωσε για σίγαση %s" }, "confirm_unmute_user": { - "title": "Unmute Account", - "message": "Confirm to unmute %s" + "title": "Άρση Σίγασης Λογαριασμού", + "message": "Επιβεβαίωσε για άρση σίγασης %s" }, "confirm_block_user": { - "title": "Block Account", - "message": "Confirm to block %s" + "title": "Αποκλεισμός Λογαριασμού", + "message": "Επιβεβαίωση αποκλεισμού %s" }, "confirm_unblock_user": { - "title": "Unblock Account", - "message": "Confirm to unblock %s" + "title": "Άρση Αποκλεισμού Λογαριασμού", + "message": "Επιβεβαίωση άρσης αποκλεισμού %s" }, "confirm_show_reblogs": { - "title": "Show Reblogs", - "message": "Confirm to show reblogs" + "title": "Εμφάνιση Αναδημοσιεύσεων", + "message": "Επιβεβαίωση εμφάνισης αναδημοσιεύσεων" }, "confirm_hide_reblogs": { - "title": "Hide Reblogs", - "message": "Confirm to hide reblogs" + "title": "Απόκρυψη Αναδημοσιεύσεων", + "message": "Επιβεβαίωση απόκρυψης αναδημοσιεύσεων" } }, "accessibility": { - "show_avatar_image": "Show avatar image", - "edit_avatar_image": "Edit avatar image", - "show_banner_image": "Show banner image", - "double_tap_to_open_the_list": "Double tap to open the list" + "show_avatar_image": "Εμφάνιση εικόνας avatar", + "edit_avatar_image": "Επεξεργασία εικόνας avatar", + "show_banner_image": "Εμφάνιση εικόνας banner", + "double_tap_to_open_the_list": "Διπλό πάτημα για άνοιγμα της λίστας" } }, "follower": { - "title": "follower", - "footer": "Followers from other servers are not displayed." + "title": "ακόλουθος", + "footer": "Οι ακόλουθοι από άλλους διακομιστές δεν εμφανίζονται." }, "following": { - "title": "following", - "footer": "Follows from other servers are not displayed." + "title": "ακολουθεί", + "footer": "Δεν εμφανίζονται ακολουθήσεις από άλλους διακομιστές." }, "familiarFollowers": { - "title": "Followers you familiar", - "followed_by_names": "Followed by %s" + "title": "Ακόλουθοι που γνωρίζεις", + "followed_by_names": "Ακολουθείται από %s" }, "favorited_by": { - "title": "Favorited By" + "title": "Αγαπημένο Από" }, "reblogged_by": { - "title": "Reblogged By" + "title": "Αναδημοσίευση Από" }, "search": { - "title": "Search", + "title": "Αναζήτηση", "search_bar": { - "placeholder": "Search hashtags and users", - "cancel": "Cancel" + "placeholder": "Αναζήτησε ετικέτες και χρήστες", + "cancel": "Άκυρο" }, "recommend": { - "button_text": "See All", + "button_text": "Προβολή Όλων", "hash_tag": { - "title": "Trending on Mastodon", - "description": "Hashtags that are getting quite a bit of attention", - "people_talking": "%s people are talking" + "title": "Δημοφιλή στο Mastodon", + "description": "Ετικέτες που τραβάνε την προσοχή", + "people_talking": "%s άτομα μιλάνε" }, "accounts": { - "title": "Accounts you might like", - "description": "You may like to follow these accounts", - "follow": "Follow" + "title": "Λογαριασμοί που μπορεί να σου αρέσουν", + "description": "Μπορεί να θες να ακολουθήσεις αυτούς τους λογαριασμούς", + "follow": "Ακολούθησε" } }, "searching": { "segment": { - "all": "All", - "people": "People", - "hashtags": "Hashtags", - "posts": "Posts" + "all": "Όλα", + "people": "Άτομα", + "hashtags": "Ετικέτες", + "posts": "Αναρτήσεις" }, "empty_state": { - "no_results": "No results" + "no_results": "Κανένα αποτέλεσμα" }, - "recent_search": "Recent searches", - "clear": "Clear" + "recent_search": "Πρόσφατες αναζητήσεις", + "clear": "Εκκαθάριση" } }, "discovery": { "tabs": { - "posts": "Posts", - "hashtags": "Hashtags", - "news": "News", - "community": "Community", - "for_you": "For You" + "posts": "Αναρτήσεις", + "hashtags": "Ετικέτες", + "news": "Ειδήσεις", + "community": "Κοινότητα", + "for_you": "Για Σένα" }, - "intro": "These are the posts gaining traction in your corner of Mastodon." + "intro": "Αυτές είναι οι αναρτήσεις που κερδίζουν την προσοχή στη δική σου γωνιά του Mastodon." }, "favorite": { - "title": "Favorites" + "title": "Αγαπημένα" }, "notification": { "title": { - "Everything": "Everything", - "Mentions": "Mentions" + "Everything": "Όλα", + "Mentions": "Επισημάνσεις" }, "notification_description": { - "followed_you": "followed you", - "favorited_your_post": "favorited your post", - "reblogged_your_post": "reblogged your post", - "mentioned_you": "mentioned you", - "request_to_follow_you": "request to follow you", - "poll_has_ended": "poll has ended" + "followed_you": "σε ακολούθησε", + "favorited_your_post": "σημείωσε ως αγαπημένη την ανάρτησή σου", + "reblogged_your_post": "αναδημοσίευσε την ανάρτηση σου", + "mentioned_you": "σε επισήμανε", + "request_to_follow_you": "ζήτησε να σε ακολουθήσει", + "poll_has_ended": "η δημοσκόπηση έληξε" }, "keyobard": { - "show_everything": "Show Everything", - "show_mentions": "Show Mentions" + "show_everything": "Εμφάνιση Όλων", + "show_mentions": "Εμφάνιση Επισημάνσεων" }, "follow_request": { - "accept": "Accept", - "accepted": "Accepted", - "reject": "reject", - "rejected": "Rejected" + "accept": "Αποδοχή", + "accepted": "Αποδέχθηκε", + "reject": "απόρριψη", + "rejected": "Απορρίφθηκε" } }, "thread": { - "back_title": "Post", - "title": "Post from %s" + "back_title": "Ανάρτηση", + "title": "Ανάρτηση από %s" }, "settings": { - "title": "Settings", + "title": "Ρυθμίσεις", "section": { "appearance": { - "title": "Appearance", - "automatic": "Automatic", - "light": "Always Light", - "dark": "Always Dark" + "title": "Εμφάνιση", + "automatic": "Αυτόματο", + "light": "Πάντα Φωτεινό", + "dark": "Πάντα Σκοτεινό" }, "look_and_feel": { - "title": "Look and Feel", - "use_system": "Use System", - "really_dark": "Really Dark", - "sorta_dark": "Sorta Dark", - "light": "Light" + "title": "Eμφάνιση και Αίσθηση", + "use_system": "Χρήση Συστήματος", + "really_dark": "Πραγματικά Σκοτεινό", + "sorta_dark": "Περίπου Σκοτεινό", + "light": "Φωτεινό" }, "notifications": { - "title": "Notifications", - "favorites": "Favorites my post", - "follows": "Follows me", - "boosts": "Reblogs my post", - "mentions": "Mentions me", + "title": "Ειδοποιήσεις", + "favorites": "Ορίζει ως αγαπημένη την ανάρτησή μου", + "follows": "Με ακολουθεί", + "boosts": "Αναδημοσιεύει την ανάρτησή μου", + "mentions": "Με επισημαίνει", "trigger": { - "anyone": "anyone", - "follower": "a follower", - "follow": "anyone I follow", - "noone": "no one", - "title": "Notify me when" + "anyone": "οποιοσδήποτε", + "follower": "ακόλουθος", + "follow": "όποιον ακολουθώ", + "noone": "κανείς", + "title": "Να ειδοποιούμαι όταν" } }, "preference": { - "title": "Preferences", - "disable_avatar_animation": "Disable animated avatars", - "disable_emoji_animation": "Disable animated emojis", - "using_default_browser": "Use default browser to open links", - "open_links_in_mastodon": "Open links in Mastodon" + "title": "Προτιμήσεις", + "disable_avatar_animation": "Απενεργοποίηση κινούμενων avatars", + "disable_emoji_animation": "Απενεργοποίηση κινούμενων emojis", + "using_default_browser": "Χρησιμοποίησε τον προεπιλεγμένο περιηγητή για να ανοίξεις συνδέσμους", + "open_links_in_mastodon": "Άνοιγμα συνδέσμων στο Mastodon" }, "boring_zone": { - "title": "The Boring Zone", - "account_settings": "Account Settings", - "terms": "Terms of Service", - "privacy": "Privacy Policy" + "title": "Η Βαρετή Ζώνη", + "account_settings": "Ρυθμίσεις Λογαριασμού", + "terms": "Όροι Χρήσης", + "privacy": "Πολιτική Απορρήτου" }, "spicy_zone": { - "title": "The Spicy Zone", - "clear": "Clear Media Cache", - "signout": "Sign Out" + "title": "Η Πικάντικη Ζώνη", + "clear": "Καθαρισμός Κρυφής Μνήμης Πολυμέσων", + "signout": "Αποσύνδεση" } }, "footer": { - "mastodon_description": "Mastodon is open source software. You can report issues on GitHub at %s (%s)" + "mastodon_description": "Το Mastodon είναι λογισμικό ανοιχτού κώδικα. Μπορείς να αναφέρεις ζητήματα στο GitHub στο %s (%s)" }, "keyboard": { - "close_settings_window": "Close Settings Window" + "close_settings_window": "Κλείσιμο Παραθύρου Ρυθμίσεων" } }, "report": { - "title_report": "Report", - "title": "Report %s", - "step1": "Step 1 of 2", - "step2": "Step 2 of 2", - "content1": "Are there any other posts you’d like to add to the report?", - "content2": "Is there anything the moderators should know about this report?", - "report_sent_title": "Thanks for reporting, we’ll look into this.", - "send": "Send Report", - "skip_to_send": "Send without comment", - "text_placeholder": "Type or paste additional comments", - "reported": "REPORTED", + "title_report": "Αναφορά", + "title": "Αναφορά %s", + "step1": "Βήμα 1 από 2", + "step2": "Βήμα 2 από 2", + "content1": "Υπάρχουν άλλες αναρτήσεις που θα ήθελες να προσθέσεις στην αναφορά;", + "content2": "Υπάρχει κάτι που οι συντονιστές θα πρέπει να γνωρίζουν για αυτή την αναφορά;", + "report_sent_title": "Σε ευχαριστούμε για την αναφορά, θα το διερευνήσουμε.", + "send": "Αποστολή Αναφοράς", + "skip_to_send": "Αποστολή χωρίς σχόλιο", + "text_placeholder": "Πληκτρολόγησε ή επικόλλησε επιπρόσθετα σχόλια", + "reported": "ΑΝΑΦΈΡΘΗΚΕ", "step_one": { - "step_1_of_4": "Step 1 of 4", - "whats_wrong_with_this_post": "What's wrong with this post?", - "whats_wrong_with_this_account": "What's wrong with this account?", - "whats_wrong_with_this_username": "What's wrong with %s?", - "select_the_best_match": "Select the best match", - "i_dont_like_it": "I don’t like it", - "it_is_not_something_you_want_to_see": "It is not something you want to see", - "its_spam": "It’s spam", - "malicious_links_fake_engagement_or_repetetive_replies": "Malicious links, fake engagement, or repetetive replies", - "it_violates_server_rules": "It violates server rules", - "you_are_aware_that_it_breaks_specific_rules": "You are aware that it breaks specific rules", - "its_something_else": "It’s something else", - "the_issue_does_not_fit_into_other_categories": "The issue does not fit into other categories" + "step_1_of_4": "Βήμα 1 από 4", + "whats_wrong_with_this_post": "Τι πάει στραβά με αυτή την ανάρτηση;", + "whats_wrong_with_this_account": "Τι πάει στραβά με αυτόν τον λογαριασμό;", + "whats_wrong_with_this_username": "Τι πάει στραβά με τον/την %s;", + "select_the_best_match": "Διάλεξε την καλύτερη αντιστοίχιση", + "i_dont_like_it": "Δεν μου αρέσει", + "it_is_not_something_you_want_to_see": "Δεν είναι κάτι που θα ήθελες να δεις", + "its_spam": "Είναι σπαμ", + "malicious_links_fake_engagement_or_repetetive_replies": "Κακόβουλοι σύνδεσμοι, πλαστή αλληλεπίδραση ή επαναλαμβανόμενες απαντήσεις", + "it_violates_server_rules": "Παραβαίνει τους κανόνες του διακομιστή", + "you_are_aware_that_it_breaks_specific_rules": "Γνωρίζεις ότι παραβιάζει συγκεκριμένους κανόνες", + "its_something_else": "Είναι κάτι άλλο", + "the_issue_does_not_fit_into_other_categories": "Το ζήτημα δεν ταιριάζει σε άλλες κατηγορίες" }, "step_two": { - "step_2_of_4": "Step 2 of 4", - "which_rules_are_being_violated": "Which rules are being violated?", - "select_all_that_apply": "Select all that apply", - "i_just_don’t_like_it": "I just don’t like it" + "step_2_of_4": "Βήμα 2 από 4", + "which_rules_are_being_violated": "Ποιοι κανόνες παραβιάζονται;", + "select_all_that_apply": "Επίλεξε όλα όσα ισχύουν", + "i_just_don’t_like_it": "Απλώς δεν μου αρέσει" }, "step_three": { - "step_3_of_4": "Step 3 of 4", - "are_there_any_posts_that_back_up_this_report": "Are there any posts that back up this report?", - "select_all_that_apply": "Select all that apply" + "step_3_of_4": "Βήμα 3 από 4", + "are_there_any_posts_that_back_up_this_report": "Υπάρχουν αναρτήσεις που τεκμηριώνουν αυτή την αναφορά;", + "select_all_that_apply": "Επίλεξε όλα όσα ισχύουν" }, "step_four": { - "step_4_of_4": "Step 4 of 4", - "is_there_anything_else_we_should_know": "Is there anything else we should know?" + "step_4_of_4": "Βήμα 4 από 4", + "is_there_anything_else_we_should_know": "Υπάρχει κάτι άλλο που πρέπει να γνωρίζουμε;" }, "step_final": { - "dont_want_to_see_this": "Don’t want to see this?", - "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "When you see something you don’t like on Mastodon, you can remove the person from your experience.", - "unfollow": "Unfollow", - "unfollowed": "Unfollowed", - "unfollow_user": "Unfollow %s", - "mute_user": "Mute %s", - "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted.", - "block_user": "Block %s", - "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked.", - "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + "dont_want_to_see_this": "Δε θες να το βλέπεις;", + "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "Όταν βλέπεις κάτι που δε σου αρέσει στο Mastodon, μπορείς να αφαιρέσεις το άτομο από την εμπειρία σου.", + "unfollow": "Άρση ακολούθησης", + "unfollowed": "Σταμάτησες να ακολουθείς", + "unfollow_user": "Άρση ακολούθησης του %s", + "mute_user": "Σίγαση %s", + "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "Δε θα βλέπεις τις αναρτήσεις ή τις αναδημοσιεύσεις τους στην αρχική σελίδα σου. Δε θα ξέρει ότι βρίσκεται σε σίγαση.", + "block_user": "Αποκλεισμός %s", + "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "Δε θα μπορούν πλέον να σε ακολουθούν ή να βλέπουν τις αναρτήσεις σου, αλλά μπορούν να δουν αν έχουν αποκλειστεί.", + "while_we_review_this_you_can_take_action_against_user": "Ενώ το εξετάζουμε, μπορείς να δράσεις εναντίον του %s" } }, "preview": { "keyboard": { - "close_preview": "Close Preview", - "show_next": "Show Next", - "show_previous": "Show Previous" + "close_preview": "Κλείσιμο Προεπισκόπησης", + "show_next": "Εμφάνιση Επομένου", + "show_previous": "Εμφάνιση Προηγούμενου" } }, "account_list": { - "tab_bar_hint": "Current selected profile: %s. Double tap then hold to show account switcher", - "dismiss_account_switcher": "Dismiss Account Switcher", - "add_account": "Add Account" + "tab_bar_hint": "Τρέχον επιλεγμένο προφίλ: %s. Πάτα δύο φορές και κράτησε πατημένο για να εμφανίσεις την εναλλαγή λογαριασμού", + "dismiss_account_switcher": "Απόρριψη Εναλλαγής Λογαριασμού", + "add_account": "Προσθήκη Λογαριασμού" }, "bookmark": { - "title": "Bookmarks" + "title": "Σελιδοδείκτες" }, "followed_tags": { - "title": "Followed Tags", + "title": "Ακολουθούμενες Ετικέτες", "header": { - "posts": "posts", - "participants": "participants", - "posts_today": "posts today" + "posts": "αναρτήσεις", + "participants": "συμμετέχοντες", + "posts_today": "αναρτήσεις σήμερα" }, "actions": { - "follow": "Follow", - "unfollow": "Unfollow" + "follow": "Ακολούθησε", + "unfollow": "Άρση ακολούθησης" } } }, "extension": { "open_in": { - "invalid_link_error": "This doesn't seem to be a valid Mastodon link." + "invalid_link_error": "Αυτό δεν φαίνεται να είναι ένας έγκυρος σύνδεσμος Mastodon." } }, "widget": { "common": { - "unsupported_widget_family": "Sorry but this Widget family is unsupported.", - "user_not_logged_in": "Please open Mastodon to log in to an Account." + "unsupported_widget_family": "Λυπούμαστε, αλλά αυτή η οικογένεια Widget δεν υποστηρίζεται.", + "user_not_logged_in": "Παρακαλώ άνοιξε το Mastodon για να συνδεθείς σε έναν Λογαριασμό." }, "followers_count": { - "configuration_display_name": "Followers", - "configuration_description": "Show number of followers.", - "title": "FOLLOWERS", - "followers_today": "%s followers today" + "configuration_display_name": "Ακόλουθοι", + "configuration_description": "Εμφάνιση αριθμού των ακολούθων.", + "title": "ΑΚΟΛΟΥΘΟΙ", + "followers_today": "%s ακόλουθοι σήμερα" }, "multiple_followers": { - "configuration_display_name": "Multiple followers", - "configuration_description": "Show number of followers for multiple accounts.", + "configuration_display_name": "Πολλαπλοί ακόλουθοι", + "configuration_description": "Εμφάνιση αριθμού ακολούθων για πολλαπλούς λογαριασμούς.", "mock_user": { - "display_name": "Another follower", + "display_name": "Κι άλλος ακόλουθος", "account_name": "another@follower.social" } }, "latest_followers": { - "configuration_display_name": "Latest followers", - "configuration_description": "Show latest followers.", - "title": "Latest followers", - "last_update": "Last update: %s" + "configuration_display_name": "Τελευταίοι ακόλουθοι", + "configuration_description": "Εμφάνιση πιο πρόσφατων ακολούθων.", + "title": "Τελευταίοι ακόλουθοι", + "last_update": "Τελευταία ενημέρωση: %s" }, "hashtag": { "configuration": { - "display_name": "Hashtag", - "description": "Shows a recent post with the selected hashtag." + "display_name": "Ετικέτα", + "description": "Εμφανίζει μια πρόσφατη ανάρτηση με την επιλεγμένη ετικέτα." }, "not_found": { "account_name": "John Mastodon", "account": "@johnMastodon@no-such.account", - "content": "Sorry, we couldn’t find any posts with the hashtag #%@. Please try a #DifferentHashtag or check the widget settings." + "content": "Λυπούμαστε, δεν μπορέσαμε να βρούμε αναρτήσεις με την ετικέτα #%@. Παρακαλώ δοκίμασε ένα #DifferentHashtag ή έλεγξε τις ρυθμίσεις widget." }, "placeholder": { - "account_name": "John Mastodon", + "account_name": "Γιάννης Mastodon", "account": "@johnMastodon@no-such.account", - "content": "This is how a post with a #hashtag would look. Pick whichever #hashtag you want in the widget settings." + "content": "Έτσι θα φαινόταν μια ανάρτηση με #hashtag. Επίλεξε όποιο #hashtag θες στις ρυθμίσεις widget." } } } diff --git a/Localization/StringsConvertor/input/el.lproj/ios-infoPlist.json b/Localization/StringsConvertor/input/el.lproj/ios-infoPlist.json index c6db73de0..16b02292c 100644 --- a/Localization/StringsConvertor/input/el.lproj/ios-infoPlist.json +++ b/Localization/StringsConvertor/input/el.lproj/ios-infoPlist.json @@ -1,6 +1,6 @@ { - "NSCameraUsageDescription": "Used to take photo for post status", - "NSPhotoLibraryAddUsageDescription": "Used to save photo into the Photo Library", - "NewPostShortcutItemTitle": "New Post", - "SearchShortcutItemTitle": "Search" + "NSCameraUsageDescription": "Χρησιμοποιείται για λήψη φωτογραφίας για την κατάσταση της ανάρτησης", + "NSPhotoLibraryAddUsageDescription": "Χρησιμοποιείται για αποθήκευση φωτογραφιών στις Φωτογραφίες", + "NewPostShortcutItemTitle": "Νέα Ανάρτηση", + "SearchShortcutItemTitle": "Αναζήτηση" } diff --git a/Localization/StringsConvertor/input/en-US.lproj/app.json b/Localization/StringsConvertor/input/en-US.lproj/app.json index 76d932356..74eaa7634 100644 --- a/Localization/StringsConvertor/input/en-US.lproj/app.json +++ b/Localization/StringsConvertor/input/en-US.lproj/app.json @@ -15,10 +15,6 @@ "title": "Vote Failure", "poll_ended": "The poll has ended" }, - "discard_post_content": { - "title": "Discard Draft", - "message": "Confirm to discard composed post content." - }, "publish_post_failure": { "title": "Publish Failure", "message": "Failed to publish the post.\nPlease check your internet connection.", diff --git a/Localization/StringsConvertor/input/en.lproj/app.json b/Localization/StringsConvertor/input/en.lproj/app.json index 76d932356..74eaa7634 100644 --- a/Localization/StringsConvertor/input/en.lproj/app.json +++ b/Localization/StringsConvertor/input/en.lproj/app.json @@ -15,10 +15,6 @@ "title": "Vote Failure", "poll_ended": "The poll has ended" }, - "discard_post_content": { - "title": "Discard Draft", - "message": "Confirm to discard composed post content." - }, "publish_post_failure": { "title": "Publish Failure", "message": "Failed to publish the post.\nPlease check your internet connection.", diff --git a/Localization/StringsConvertor/input/es-AR.lproj/app.json b/Localization/StringsConvertor/input/es-AR.lproj/app.json index 4b2be65bd..5c443f275 100644 --- a/Localization/StringsConvertor/input/es-AR.lproj/app.json +++ b/Localization/StringsConvertor/input/es-AR.lproj/app.json @@ -15,10 +15,6 @@ "title": "Error al votar", "poll_ended": "La encuesta finalizó" }, - "discard_post_content": { - "title": "Descartar borrador", - "message": "Confirmá para descartar el contenido del mensaje redactado." - }, "publish_post_failure": { "title": "Error al enviar el mensaje", "message": "Error al enviar en mensaje.\nPor favor, revisá tu conexión a Internet.", @@ -269,7 +265,7 @@ "welcome": { "log_in": "Iniciar sesión", "learn_more": "Aprendé más", - "join_default_server": "Join %@", + "join_default_server": "Unite a %@", "pick_server": "Elegí otro servidor", "separator": { "or": "o" diff --git a/Localization/StringsConvertor/input/es.lproj/app.json b/Localization/StringsConvertor/input/es.lproj/app.json index 2298eda97..7dbd1af30 100644 --- a/Localization/StringsConvertor/input/es.lproj/app.json +++ b/Localization/StringsConvertor/input/es.lproj/app.json @@ -15,10 +15,6 @@ "title": "Voto fallido", "poll_ended": "La encuesta ha terminado" }, - "discard_post_content": { - "title": "Descartar borrador", - "message": "Confirma para descartar el contenido de la publicación." - }, "publish_post_failure": { "title": "Error de publicación", "message": "No se pudo publicar la publicación.\nPor favor, revise su conexión a internet.", diff --git a/Localization/StringsConvertor/input/eu.lproj/app.json b/Localization/StringsConvertor/input/eu.lproj/app.json index ec716e2b7..1a9bdeb64 100644 --- a/Localization/StringsConvertor/input/eu.lproj/app.json +++ b/Localization/StringsConvertor/input/eu.lproj/app.json @@ -15,10 +15,6 @@ "title": "Hutsegitea botoa ematean", "poll_ended": "Inkesta amaitu da" }, - "discard_post_content": { - "title": "Baztertu zirriborroa", - "message": "Berretsi idatzitako bidalketaren edukia baztertzea." - }, "publish_post_failure": { "title": "Hutsegitea argitaratzean", "message": "Huts egin du bidalketa argitaratzean.\nEgiaztatu Interneteko konexioa.", diff --git a/Localization/StringsConvertor/input/fi.lproj/app.json b/Localization/StringsConvertor/input/fi.lproj/app.json index c091d7e3e..f6befb35c 100644 --- a/Localization/StringsConvertor/input/fi.lproj/app.json +++ b/Localization/StringsConvertor/input/fi.lproj/app.json @@ -15,10 +15,6 @@ "title": "Vote Failure", "poll_ended": "Kysely on päättynyt" }, - "discard_post_content": { - "title": "Hylkää luonnos", - "message": "Confirm to discard composed post content." - }, "publish_post_failure": { "title": "Julkaiseminen epäonnistui", "message": "Julkaisun julkaiseminen epäonnistui.\nTarkista internet-yhteytesi.", @@ -269,7 +265,7 @@ "welcome": { "log_in": "Kirjaudu sisään", "learn_more": "Lue lisää", - "join_default_server": "Join %@", + "join_default_server": "Liity palvelimelle %@", "pick_server": "Pick another server", "separator": { "or": "tai" diff --git a/Localization/StringsConvertor/input/fr.lproj/app.json b/Localization/StringsConvertor/input/fr.lproj/app.json index ec296540c..21568bc8b 100644 --- a/Localization/StringsConvertor/input/fr.lproj/app.json +++ b/Localization/StringsConvertor/input/fr.lproj/app.json @@ -15,10 +15,6 @@ "title": "Échec du vote", "poll_ended": "Le sondage est terminé" }, - "discard_post_content": { - "title": "Abandonner le brouillon", - "message": "Confirmez pour abandonner le contenu de votre message." - }, "publish_post_failure": { "title": "La publication a échoué", "message": "La publication a échoué.\nVeuillez vérifier votre accès à Internet.", diff --git a/Localization/StringsConvertor/input/gd.lproj/app.json b/Localization/StringsConvertor/input/gd.lproj/app.json index ffa67fbbc..06cb72576 100644 --- a/Localization/StringsConvertor/input/gd.lproj/app.json +++ b/Localization/StringsConvertor/input/gd.lproj/app.json @@ -15,10 +15,6 @@ "title": "Dh’fhàillig leis a’ bhòt", "poll_ended": "Thàinig an cunntas-bheachd gu crìoch" }, - "discard_post_content": { - "title": "Tilg air falbh an dreachd", - "message": "Dearbh tilgeil air falbh susbaint a’ phuist a sgrìobh thu." - }, "publish_post_failure": { "title": "Dh’fhàillig leis an fhoillseachadh", "message": "Cha deach leinn am post fhoillseachadh.\nThoir sùil air a’ cheangal agad ris an eadar-lìon.", @@ -88,7 +84,7 @@ "share_post": "Co-roinn am post", "open_in_safari": "Fosgail ann an Safari", "open_in_browser": "Fosgail sa bhrabhsair", - "find_people": "Lorg daoine a leanas tu", + "find_people": "Lorg daoine gus an leantainn", "manually_search": "Lorg a làimh ’na àite", "skip": "Leum thairis air", "reply": "Freagair", @@ -102,10 +98,10 @@ "unknown_language": "Chan eil fhios" }, "edit_post": "Deasaich", - "bookmark": "Bookmark", - "remove_bookmark": "Remove Bookmark", - "follow": "Follow %s", - "unfollow": "Unfollow %s" + "bookmark": "Comharra-lìn", + "remove_bookmark": "Thoir air falbh an comharra-lìn", + "follow": "Lean %s", + "unfollow": "Na lean %s tuilleadh" }, "tabs": { "home": "Dachaigh", @@ -269,7 +265,7 @@ "welcome": { "log_in": "Clàraich a-steach", "learn_more": "Barrachd fiosrachaidh", - "join_default_server": "Join %@", + "join_default_server": "Faigh ballrachd aig %@", "pick_server": "Tagh frithealaiche eile", "separator": { "or": "no" @@ -788,7 +784,7 @@ "malicious_links_fake_engagement_or_repetetive_replies": "Ceanglaichean droch-rùnach, conaltradh fuadain no an dearbh fhreagairt a-rithist ’s a-rithist", "it_violates_server_rules": "Tha e a’ briseadh riaghailtean an fhrithealaiche", "you_are_aware_that_it_breaks_specific_rules": "Mhothaich thu gu bheil e a’ briseadh riaghailtean sònraichte", - "its_something_else": "’S rud eile a tha ann", + "its_something_else": "’S e rud eile a tha ann", "the_issue_does_not_fit_into_other_categories": "Chan eil na roinnean-seòrsa eile iomchaidh dhan chùis" }, "step_two": { diff --git a/Localization/StringsConvertor/input/gl.lproj/app.json b/Localization/StringsConvertor/input/gl.lproj/app.json index ba529ab2f..d0c97ceec 100644 --- a/Localization/StringsConvertor/input/gl.lproj/app.json +++ b/Localization/StringsConvertor/input/gl.lproj/app.json @@ -15,10 +15,6 @@ "title": "Fallou a votación", "poll_ended": "A enquisa rematou" }, - "discard_post_content": { - "title": "Descartar Borrador", - "message": "Confirma que queres descartar o contido do borrador." - }, "publish_post_failure": { "title": "Fallou a publicación", "message": "Fallou a publicación.\nComproba a conexión a internet.", @@ -269,7 +265,7 @@ "welcome": { "log_in": "Acceder", "learn_more": "Saber máis", - "join_default_server": "Join %@", + "join_default_server": "Únete a %@", "pick_server": "Elixe outro servidor", "separator": { "or": "ou" diff --git a/Localization/StringsConvertor/input/he.lproj/app.json b/Localization/StringsConvertor/input/he.lproj/app.json index 44c3608ed..ea7d88e7f 100644 --- a/Localization/StringsConvertor/input/he.lproj/app.json +++ b/Localization/StringsConvertor/input/he.lproj/app.json @@ -15,10 +15,6 @@ "title": "Vote Failure", "poll_ended": "The poll has ended" }, - "discard_post_content": { - "title": "Discard Draft", - "message": "Confirm to discard composed post content." - }, "publish_post_failure": { "title": "Publish Failure", "message": "Failed to publish the post.\nPlease check your internet connection.", diff --git a/Localization/StringsConvertor/input/hi.lproj/app.json b/Localization/StringsConvertor/input/hi.lproj/app.json index df2c9c5a9..334b9918f 100644 --- a/Localization/StringsConvertor/input/hi.lproj/app.json +++ b/Localization/StringsConvertor/input/hi.lproj/app.json @@ -15,10 +15,6 @@ "title": "Vote Failure", "poll_ended": "The poll has ended" }, - "discard_post_content": { - "title": "Discard Draft", - "message": "Confirm to discard composed post content." - }, "publish_post_failure": { "title": "Publish Failure", "message": "Failed to publish the post.\nPlease check your internet connection.", diff --git a/Localization/StringsConvertor/input/id.lproj/app.json b/Localization/StringsConvertor/input/id.lproj/app.json index d32eb4d1b..51579bc8a 100644 --- a/Localization/StringsConvertor/input/id.lproj/app.json +++ b/Localization/StringsConvertor/input/id.lproj/app.json @@ -15,10 +15,6 @@ "title": "Gagal Voting", "poll_ended": "Japat telah berakhir" }, - "discard_post_content": { - "title": "Hapus Draf", - "message": "Konfirmasi untuk mengabaikan postingan yang dibuat." - }, "publish_post_failure": { "title": "Gagal Mempublikasikan", "message": "Gagal mempublikasikan postingan.\nMohon periksa koneksi Internet Anda.", diff --git a/Localization/StringsConvertor/input/is.lproj/app.json b/Localization/StringsConvertor/input/is.lproj/app.json index 0cc337bda..624101cd9 100644 --- a/Localization/StringsConvertor/input/is.lproj/app.json +++ b/Localization/StringsConvertor/input/is.lproj/app.json @@ -15,10 +15,6 @@ "title": "Greiðsla atkvæðis mistókst", "poll_ended": "Könnuninni er lokið" }, - "discard_post_content": { - "title": "Henda drögum", - "message": "Staðfestu til að henda efni úr saminni færslu." - }, "publish_post_failure": { "title": "Mistókst að birta", "message": "Mistókst að birta færsluna.\nAthugaðu nettenginguna þína.", @@ -269,7 +265,7 @@ "welcome": { "log_in": "Skrá inn", "learn_more": "Kanna nánar", - "join_default_server": "Join %@", + "join_default_server": "Taka þátt í %@", "pick_server": "Veldu annan netþjón", "separator": { "or": "eða" diff --git a/Localization/StringsConvertor/input/it.lproj/app.json b/Localization/StringsConvertor/input/it.lproj/app.json index fc4162c50..e7099d929 100644 --- a/Localization/StringsConvertor/input/it.lproj/app.json +++ b/Localization/StringsConvertor/input/it.lproj/app.json @@ -15,10 +15,6 @@ "title": "Voto fallito", "poll_ended": "Il sondaggio è terminato" }, - "discard_post_content": { - "title": "Elimina bozza", - "message": "Confermare di scartare il contenuto del post composto." - }, "publish_post_failure": { "title": "Pubblicazione fallita", "message": "Pubblicazione del post fallita.\nPer favore verifica la tua connessione internet.", @@ -269,7 +265,7 @@ "welcome": { "log_in": "Accedi", "learn_more": "Scopri di più", - "join_default_server": "Join %@", + "join_default_server": "Unisciti a %@", "pick_server": "Scegli un altro server", "separator": { "or": "o" diff --git a/Localization/StringsConvertor/input/ja.lproj/app.json b/Localization/StringsConvertor/input/ja.lproj/app.json index d0190b313..480274380 100644 --- a/Localization/StringsConvertor/input/ja.lproj/app.json +++ b/Localization/StringsConvertor/input/ja.lproj/app.json @@ -15,10 +15,6 @@ "title": "投票の失敗", "poll_ended": "投票は終了しました" }, - "discard_post_content": { - "title": "投稿を破棄しますか?", - "message": "この操作は取り消しできません。下書きは失われます。" - }, "publish_post_failure": { "title": "失敗", "message": "投稿に失敗しました。\nインターネットに接続されているか確認してください。", @@ -269,7 +265,7 @@ "welcome": { "log_in": "ログイン", "learn_more": "詳しく学ぶ", - "join_default_server": "Join %@", + "join_default_server": "%@ に登録", "pick_server": "ほかのサーバーをさがす", "separator": { "or": "または" diff --git a/Localization/StringsConvertor/input/kab.lproj/app.json b/Localization/StringsConvertor/input/kab.lproj/app.json index 2f933def1..654371983 100644 --- a/Localization/StringsConvertor/input/kab.lproj/app.json +++ b/Localization/StringsConvertor/input/kab.lproj/app.json @@ -15,10 +15,6 @@ "title": "Tuccḍa deg ufran", "poll_ended": "Tafrant tfuk" }, - "discard_post_content": { - "title": "Kkes arewway", - "message": "Sentem i wakken ad yettusefsax ugbur n tsuffeɣt." - }, "publish_post_failure": { "title": "Yecceḍ usuffeɣ", "message": "Yecceḍ usuffeɣ n tsuffeɣt.\nMa ulac aɣilif, senqed tuqqna-inek internet.", diff --git a/Localization/StringsConvertor/input/kmr.lproj/app.json b/Localization/StringsConvertor/input/kmr.lproj/app.json index ef81e9351..3e71dfe28 100644 --- a/Localization/StringsConvertor/input/kmr.lproj/app.json +++ b/Localization/StringsConvertor/input/kmr.lproj/app.json @@ -15,10 +15,6 @@ "title": "Dengdayîn têkçû", "poll_ended": "Rapirsîya qediya" }, - "discard_post_content": { - "title": "Reşnivîsê paşguh bike", - "message": "Bipejrîne ku naveroka şandiyê ya hatiye nivîsandin paşguh bikî." - }, "publish_post_failure": { "title": "Weşandin têkçû", "message": "Weşandina şandiyê têkçû.\nJkx girêdana înternetê xwe kontrol bike.", diff --git a/Localization/StringsConvertor/input/ko.lproj/app.json b/Localization/StringsConvertor/input/ko.lproj/app.json index 7d2a7c75b..813bf12b8 100644 --- a/Localization/StringsConvertor/input/ko.lproj/app.json +++ b/Localization/StringsConvertor/input/ko.lproj/app.json @@ -15,10 +15,6 @@ "title": "투표 실패", "poll_ended": "투표가 끝났습니다" }, - "discard_post_content": { - "title": "초안 버리기", - "message": "Confirm to discard composed post content." - }, "publish_post_failure": { "title": "게시 실패", "message": "글을 게시하는데 실패했습니다.\n인터넷 연결을 확인해 주세요.", diff --git a/Localization/StringsConvertor/input/lv.lproj/app.json b/Localization/StringsConvertor/input/lv.lproj/app.json index 943c63a38..1ce04a728 100644 --- a/Localization/StringsConvertor/input/lv.lproj/app.json +++ b/Localization/StringsConvertor/input/lv.lproj/app.json @@ -15,10 +15,6 @@ "title": "Balsošanas Neveiksme", "poll_ended": "Aptauja ir noslēgusies" }, - "discard_post_content": { - "title": "Atmest malnrakstu", - "message": "Apstiprini, lai atmestu izveidotās ziņas saturu." - }, "publish_post_failure": { "title": "Publicēšanas Neveiksme", "message": "Neizdevās publicēt ziņu.\nLūdzu, pārbaudi savu interneta savienojumu.", diff --git a/Localization/StringsConvertor/input/my.lproj/app.json b/Localization/StringsConvertor/input/my.lproj/app.json index 9b7bacd6e..a75334beb 100644 --- a/Localization/StringsConvertor/input/my.lproj/app.json +++ b/Localization/StringsConvertor/input/my.lproj/app.json @@ -15,10 +15,6 @@ "title": "မဲပေးမှု မအောင်မြင်ခြင်း", "poll_ended": "စစ်တမ်းကောက်မှု ပြီးဆုံးပါပြီ" }, - "discard_post_content": { - "title": "မူကြမ်းကို ပယ်ဖျက်ပါ", - "message": "ရေးသားထားသောမူကြမ်းကို ပယ်ဖျက်ရန် အတည်ပြုပါ" - }, "publish_post_failure": { "title": "ပို့စ်တင်ခြင်း မအောင်မြင်မှု", "message": "ပို့စ်တင်ခြင်း မအောင်မြင်ပါ၊ သင်၏ အင်တာနက်ချိတ်ဆက်မှုကို စစ်ဆေးပါ။", diff --git a/Localization/StringsConvertor/input/nl.lproj/app.json b/Localization/StringsConvertor/input/nl.lproj/app.json index 14791647e..c6fdeb239 100644 --- a/Localization/StringsConvertor/input/nl.lproj/app.json +++ b/Localization/StringsConvertor/input/nl.lproj/app.json @@ -15,10 +15,6 @@ "title": "Stemmen Mislukt", "poll_ended": "De peiling is beëindigd" }, - "discard_post_content": { - "title": "Verwijder concept", - "message": "Bevestig het verwijderen van het conceptbericht." - }, "publish_post_failure": { "title": "Publicatiefout", "message": "Het publiceren van het bericht is mislukt. Controleer je internetverbinding.", diff --git a/Localization/StringsConvertor/input/pl.lproj/app.json b/Localization/StringsConvertor/input/pl.lproj/app.json index 0766988c5..fddd23aaf 100644 --- a/Localization/StringsConvertor/input/pl.lproj/app.json +++ b/Localization/StringsConvertor/input/pl.lproj/app.json @@ -15,10 +15,6 @@ "title": "Niepowodzenie głosowania", "poll_ended": "Ankieta zakończyła się" }, - "discard_post_content": { - "title": "Anuluj wersje roboczą", - "message": "Potwierdź odrzucenie treści posta." - }, "publish_post_failure": { "title": "Błąd publikowania", "message": "Nie udało się opublikować posta.\nSprawdź swoje połączenie internetowe.", @@ -206,7 +202,7 @@ "expand_gif_hint": "Rozszerza GIF. Podwójne dotknięcie i przytrzymaj, aby pokazać akcje", "expand_video_hint": "Pokazuje odtwarzacz wideo. Dwukrotnie stuknij i przytrzymaj aby pokazać akcje" }, - "posted_via_application": "%s via %s", + "posted_via_application": "%s przez %s", "buttons": { "reblogs_title": "Reblogs", "favorites_title": "Ulubione", @@ -254,34 +250,34 @@ "blocking_warning": "Nie możesz wyświetlić profilu tego użytkownika\ndopóki nie odblokujesz go.\nTwój profil wygląda tak dla nich.", "user_blocking_warning": "Nie możesz wyświetlić profilu %s\ndopóki nie odblokujesz go.\nTwój profil wygląda tak dla nich.", "blocked_warning": "Nie możesz zobaczyć profilu tego użytkownika\n dopóki nie odblokują Cię.", - "user_blocked_warning": "You can’t view %s’s profile\nuntil they unblock you.", + "user_blocked_warning": "Nie możesz zobaczyć profilu %s dopóki Cię nie odblokuje.", "suspended_warning": "Ten użytkownik został zawieszony.", "user_suspended_warning": "Konto %s zostało zawieszone." } } }, "user_list": { - "no_verified_link": "No verified link", - "followers_count": "%@ followers" + "no_verified_link": "Niezweryfikowany link", + "followers_count": "%@ obserwujących" } }, "scene": { "welcome": { "log_in": "Zaloguj się", - "learn_more": "Learn more", - "join_default_server": "Join %@", - "pick_server": "Pick another server", + "learn_more": "Dowiedz się więcej", + "join_default_server": "Dołącz do %@", + "pick_server": "Wybierz inną instancję", "separator": { - "or": "or" + "or": "lub" }, "education": { "mastodon": { - "title": "Welcome to Mastodon", - "description": "Mastodon is a decentralized social network, meaning no single company controls it. It’s made up of many independently-run servers, all connected together." + "title": "Witaj na Mastodonie", + "description": "Mastodon to zdecentralizowana sieć społecznościowa, co oznacza że żadna firma nie może nią kontrolować w całości. Składa się z wielu niezależnych od siebie serwerów, które się ze sobą komunikują." }, "servers": { - "title": "What are servers?", - "description": "Every Mastodon account is hosted on a server — each with its own values, rules, & admins. No matter which one you pick, you can follow and interact with people on any server." + "title": "Czym są serwery?", + "description": "Każde konto na Mastodonie jest hostowane na instancjach, które wyróżniają się wartościami, zasadami i administracją. Nieważne, jaką wybierzesz - i tak będziesz mógł/mogła kontaktować się nawet z tymi spoza Twojej instancji." }, "a11y": { "what_is_mastodon": { @@ -291,7 +287,7 @@ } }, "login": { - "title": "Welcome back", + "title": "Witaj ponownie", "subtitle": "Zaloguj się na serwerze, na którym utworzyłeś swoje konto.", "server_search_field": { "placeholder": "Wprowadź adres URL lub wyszukaj swój serwer" @@ -304,55 +300,55 @@ "signup_speed": "Szybkość rejestracji", "category": { "all": "Wszystkie", - "all_accessiblity_description": "Category: All", - "academia": "academia", - "activism": "activism", - "food": "food", - "furry": "furry", - "games": "games", - "general": "general", - "journalism": "journalism", - "lgbt": "lgbt", - "regional": "regional", - "art": "art", - "music": "music", - "tech": "tech" + "all_accessiblity_description": "Kategoria: Wszystkie", + "academia": "środowiska akademickie", + "activism": "aktywizm", + "food": "jedzenie", + "furry": "„futrzaki”", + "games": "gry", + "general": "ogólne", + "journalism": "dziennikarstwo", + "lgbt": "LGBT", + "regional": "regionalne", + "art": "sztuka", + "music": "muzyka", + "tech": "technologia" }, - "see_less": "See Less", - "see_more": "See More" + "see_less": "Zobacz mniej", + "see_more": "Zobacz więcej" }, "label": { - "language": "LANGUAGE", - "users": "USERS", - "category": "CATEGORY" + "language": "JĘZYK", + "users": "UŻYTKOWNICY", + "category": "KATEGORIA" }, "input": { - "search_servers_or_enter_url": "Search communities or enter URL" + "search_servers_or_enter_url": "Szukaj społeczności lub wprowadź adres URL" }, "empty_state": { - "finding_servers": "Finding available servers...", - "bad_network": "Something went wrong while loading the data. Check your internet connection.", - "no_results": "No results" + "finding_servers": "Szukanie dostępnych instancji...", + "bad_network": "Coś poszło nie tak podczas ładowania danych. Sprawdź swoje połączenie internetowe.", + "no_results": "Brak wyników" }, "signup_speed": { - "all": "All", - "instant": "Instant Sign-up", - "manually_reviewed": "Manual Review" + "all": "Wszystko", + "instant": "Natychmiastowa rejestracja", + "manually_reviewed": "Ręczne sprawdzenie" }, "language": { - "all": "All" + "all": "Wszystko" }, "search": { - "placeholder": "Search name or URL" + "placeholder": "Nazwa serwera lub jego adres URL" }, - "no_server_selected_hint": "We’ll pick a server based on your language if you continue without making a selection." + "no_server_selected_hint": "Wybierzemy Tobie instancję opartą na Twoim języku, jeżeli kontynuujesz bez żadnego wyboru." }, "privacy": { - "title": "Privacy", - "description": "Although the Mastodon app does not collect any data, the server you sign up through may have a different policy. Take a minute to review and agree to the Mastodon app privacy policy and your server’s privacy policy.", + "title": "Prywatność", + "description": "Choć aplikacja Mastodona nie zbiera żadnych danych na Twój temat, serwer na którym się rejestrujesz może działać zgodnie z inną polityką. Poświęć chwilę na przejrzenie i akceptację polityki prywatności aplikacji Mastodona oraz Twojego serwera.", "policy": { - "ios": "Privacy Policy - Mastodon for iOS", - "server": "Privacy Policy - %s" + "ios": "Polityka prywatności - Mastodon dla iOS", + "server": "Polityka Prywatności - %s" }, "button": { "confirm": "I Agree" @@ -482,27 +478,27 @@ }, "content_input_placeholder": "Type or paste what’s on your mind", "compose_action": "Publish", - "replying_to_user": "replying to %s", + "replying_to_user": "odpowiadanie %s", "attachment": { - "photo": "photo", - "video": "video", - "attachment_broken": "This %s is broken and can’t be\nuploaded to Mastodon.", + "photo": "zdjęcie", + "video": "film", + "attachment_broken": "Ten %s jest uszkodzony i nie może zostać\nprzesłany do Mastodona.", "description_photo": "Describe the photo for the visually-impaired...", "description_video": "Describe the video for the visually-impaired...", - "load_failed": "Load Failed", - "upload_failed": "Upload Failed", - "can_not_recognize_this_media_attachment": "Can not recognize this media attachment", - "attachment_too_large": "Attachment too large", - "compressing_state": "Compressing...", - "server_processing_state": "Server Processing..." + "load_failed": "Załadowanie nie powiodło się", + "upload_failed": "Nie udało się przesłać", + "can_not_recognize_this_media_attachment": "Nie można rozpoznać tego załącznika", + "attachment_too_large": "Załącznik jest zbyt duży", + "compressing_state": "Kompresja...", + "server_processing_state": "Przetwarzanie..." }, "poll": { - "title": "Poll", - "duration_time": "Duration: %s", - "thirty_minutes": "30 minutes", - "one_hour": "1 Hour", - "six_hours": "6 Hours", - "one_day": "1 Day", + "title": "Ankieta", + "duration_time": "Czas trwania: %s", + "thirty_minutes": "30 minutach", + "one_hour": "Godzinie", + "six_hours": "6 Godzinach", + "one_day": "Dobie", "three_days": "3 Days", "seven_days": "7 Days", "option_number": "Option %ld", diff --git a/Localization/StringsConvertor/input/pt-BR.lproj/app.json b/Localization/StringsConvertor/input/pt-BR.lproj/app.json index f1014e8dc..357478885 100644 --- a/Localization/StringsConvertor/input/pt-BR.lproj/app.json +++ b/Localization/StringsConvertor/input/pt-BR.lproj/app.json @@ -15,10 +15,6 @@ "title": "Falha ao votar", "poll_ended": "Essa enquete terminou" }, - "discard_post_content": { - "title": "Deletar Rascunho", - "message": "Confirme para descartar o conteúdo da publicação composta." - }, "publish_post_failure": { "title": "Falha ao publicar", "message": "Falha ao publicar o post.\nPor favor verifique a sua conexão de internet.", diff --git a/Localization/StringsConvertor/input/pt.lproj/app.json b/Localization/StringsConvertor/input/pt.lproj/app.json index d549a04e4..045f054af 100644 --- a/Localization/StringsConvertor/input/pt.lproj/app.json +++ b/Localization/StringsConvertor/input/pt.lproj/app.json @@ -15,10 +15,6 @@ "title": "Erro na votação", "poll_ended": "Esta sondagem está fechada" }, - "discard_post_content": { - "title": "Descartar rascunho", - "message": "Confirm to discard composed post content." - }, "publish_post_failure": { "title": "Falha ao publicar", "message": "Falha na publicação.\nPor favor verifique a sua ligação à Internet.", diff --git a/Localization/StringsConvertor/input/ro.lproj/app.json b/Localization/StringsConvertor/input/ro.lproj/app.json index 50b217289..80d5b8333 100644 --- a/Localization/StringsConvertor/input/ro.lproj/app.json +++ b/Localization/StringsConvertor/input/ro.lproj/app.json @@ -15,10 +15,6 @@ "title": "Eșec la vot", "poll_ended": "Sondajul tău s-a încheiat" }, - "discard_post_content": { - "title": "Șterge Schită", - "message": "Confirmă renunțarea la conținutul postării." - }, "publish_post_failure": { "title": "Eșec la publicare", "message": "Datele nu au putut fi încărcate. Te rugăm să-ți verifici conexiunea la internet.", diff --git a/Localization/StringsConvertor/input/ru.lproj/app.json b/Localization/StringsConvertor/input/ru.lproj/app.json index 285433599..381256cef 100644 --- a/Localization/StringsConvertor/input/ru.lproj/app.json +++ b/Localization/StringsConvertor/input/ru.lproj/app.json @@ -15,10 +15,6 @@ "title": "Не удалось проголосовать", "poll_ended": "Опрос уже завершился" }, - "discard_post_content": { - "title": "Удалить черновик", - "message": "Вы действительно хотите удалить набранное содержимое поста?" - }, "publish_post_failure": { "title": "Ошибка публикации", "message": "Не удалось опубликовать пост.\nПожалуйста, проверьте подключение к интернету.", diff --git a/Localization/StringsConvertor/input/si.lproj/app.json b/Localization/StringsConvertor/input/si.lproj/app.json index eb761b6db..abd257761 100644 --- a/Localization/StringsConvertor/input/si.lproj/app.json +++ b/Localization/StringsConvertor/input/si.lproj/app.json @@ -15,10 +15,6 @@ "title": "Vote Failure", "poll_ended": "The poll has ended" }, - "discard_post_content": { - "title": "Discard Draft", - "message": "Confirm to discard composed post content." - }, "publish_post_failure": { "title": "Publish Failure", "message": "Failed to publish the post.\nPlease check your internet connection.", diff --git a/Localization/StringsConvertor/input/sl.lproj/app.json b/Localization/StringsConvertor/input/sl.lproj/app.json index 8885a623b..dfd2f83de 100644 --- a/Localization/StringsConvertor/input/sl.lproj/app.json +++ b/Localization/StringsConvertor/input/sl.lproj/app.json @@ -15,10 +15,6 @@ "title": "Napaka glasovanja", "poll_ended": "Anketa je zaključena" }, - "discard_post_content": { - "title": "Zavrzi osnutek", - "message": "Potrdite za opustitev sestavljene vsebine objave." - }, "publish_post_failure": { "title": "Spodletela objava", "message": "Objava je spodletela.\nPreverite svojo internetno povezavo.", @@ -269,7 +265,7 @@ "welcome": { "log_in": "Prijava", "learn_more": "Več o tem", - "join_default_server": "Join %@", + "join_default_server": "Pridruži se %@", "pick_server": "Izberi drug strežnik", "separator": { "or": "ali" diff --git a/Localization/StringsConvertor/input/sv.lproj/app.json b/Localization/StringsConvertor/input/sv.lproj/app.json index f22f547fd..24ea32a25 100644 --- a/Localization/StringsConvertor/input/sv.lproj/app.json +++ b/Localization/StringsConvertor/input/sv.lproj/app.json @@ -15,10 +15,6 @@ "title": "Röstning misslyckades", "poll_ended": "Omröstningen har avslutats" }, - "discard_post_content": { - "title": "Släng utkast", - "message": "Bekräfta för att slänga inläggsutkast." - }, "publish_post_failure": { "title": "Publicering misslyckades", "message": "Det gick inte att publicera inlägget.\nKontrollera din internetanslutning.", @@ -102,10 +98,10 @@ "unknown_language": "Okänt" }, "edit_post": "Redigera", - "bookmark": "Bookmark", - "remove_bookmark": "Remove Bookmark", - "follow": "Follow %s", - "unfollow": "Unfollow %s" + "bookmark": "Bokmärk", + "remove_bookmark": "Ta bort bokmärke", + "follow": "Följ %s", + "unfollow": "Avfölj %s" }, "tabs": { "home": "Hem", @@ -198,7 +194,7 @@ "translated_from": "Översatt från %s med %s", "unknown_language": "Okänt", "unknown_provider": "Okänd", - "show_original": "Show Original" + "show_original": "Visa original" }, "media": { "accessibility_label": "%s, bilaga %d av %d", @@ -269,7 +265,7 @@ "welcome": { "log_in": "Logga in", "learn_more": "Läs mer", - "join_default_server": "Join %@", + "join_default_server": "Gå med %@", "pick_server": "Hitta en annan server", "separator": { "or": "eller" @@ -335,7 +331,7 @@ "no_results": "Inga resultat" }, "signup_speed": { - "all": "All", + "all": "Allt", "instant": "Instant Sign-up", "manually_reviewed": "Manuell granskning" }, @@ -348,7 +344,7 @@ "no_server_selected_hint": "Vi kommer att välja en server baserat på ditt språk om du fortsätter utan att göra ett val." }, "privacy": { - "title": "Privacy", + "title": "Integritet", "description": "Även om Mastodon-appen inte samlar in någon data kan servern du registrerar dig genom ha en annan policy. Ta en stund till att granska och godkänna Mastodon-appens sekretesspolicy och din servers sekretesspolicy.", "policy": { "ios": "Integritetspolicy - Mastodon för iOS", @@ -508,7 +504,7 @@ "option_number": "Alternativ %ld", "the_poll_is_invalid": "Undersökningen är ogiltig", "the_poll_has_empty_option": "Undersökningen har ett tomt alternativ", - "add_option": "Add Option", + "add_option": "Lägg till alternativ", "remove_option": "Remove Option", "move_up": "Flytta upp", "move_down": "Flytta ned" @@ -545,7 +541,7 @@ "select_visibility_entry": "Välj synlighet - %s" }, "language": { - "title": "Post Language", + "title": "Inläggsspråk", "suggested": "Suggested", "recent": "Senaste", "other": "Andra språk…" @@ -875,7 +871,7 @@ "configuration_display_name": "Latest followers", "configuration_description": "Show latest followers.", "title": "Latest followers", - "last_update": "Last update: %s" + "last_update": "Senaste uppdatering: %s" }, "hashtag": { "configuration": { @@ -885,7 +881,7 @@ "not_found": { "account_name": "John Mastodon", "account": "@johnMastodon@no-such.account", - "content": "Sorry, we couldn’t find any posts with the hashtag #%@. Please try a #DifferentHashtag or check the widget settings." + "content": "Ledsen, vi kunde inte hitta några inlägg med hashtaggen #%@. Prova en #AnnanHashtagg eller kontrollera widgetinställningarna." }, "placeholder": { "account_name": "John Mastodon", diff --git a/Localization/StringsConvertor/input/th.lproj/app.json b/Localization/StringsConvertor/input/th.lproj/app.json index 507daab41..3532dc69d 100644 --- a/Localization/StringsConvertor/input/th.lproj/app.json +++ b/Localization/StringsConvertor/input/th.lproj/app.json @@ -15,10 +15,6 @@ "title": "การลงคะแนนล้มเหลว", "poll_ended": "การสำรวจความคิดเห็นได้สิ้นสุดแล้ว" }, - "discard_post_content": { - "title": "ละทิ้งแบบร่าง", - "message": "ยืนยันเพื่อละทิ้งเนื้อหาโพสต์ที่เขียน" - }, "publish_post_failure": { "title": "การเผยแพร่ล้มเหลว", "message": "ไม่สามารถเผยแพร่โพสต์\nโปรดตรวจสอบการเชื่อมต่ออินเทอร์เน็ตของคุณ", @@ -269,7 +265,7 @@ "welcome": { "log_in": "เข้าสู่ระบบ", "learn_more": "เรียนรู้เพิ่มเติม", - "join_default_server": "Join %@", + "join_default_server": "เข้าร่วม %@", "pick_server": "เลือกเซิร์ฟเวอร์อื่น", "separator": { "or": "หรือ" @@ -838,7 +834,7 @@ "title": "แท็กที่ติดตาม", "header": { "posts": "โพสต์", - "participants": "ผู้เข้าร่วม", + "participants": "ผู้มีส่วนร่วม", "posts_today": "โพสต์วันนี้" }, "actions": { diff --git a/Localization/StringsConvertor/input/tr.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/tr.lproj/Localizable.stringsdict index 93c405761..ac2d102be 100644 --- a/Localization/StringsConvertor/input/tr.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/tr.lproj/Localizable.stringsdict @@ -61,7 +61,7 @@ NSStringFormatValueTypeKey ld one - 1 character left + 1 karakter kaldı other %ld characters left @@ -184,7 +184,7 @@ NSStringFormatValueTypeKey ld one - 1 re-blog + 1 yeniden paylaşım other %ld re-blogs diff --git a/Localization/StringsConvertor/input/tr.lproj/app.json b/Localization/StringsConvertor/input/tr.lproj/app.json index 10e025bea..cf974de11 100644 --- a/Localization/StringsConvertor/input/tr.lproj/app.json +++ b/Localization/StringsConvertor/input/tr.lproj/app.json @@ -15,10 +15,6 @@ "title": "Oy Verme Başarısız", "poll_ended": "Anket bitti" }, - "discard_post_content": { - "title": "Taslağı Sil", - "message": "Yazdığın gönderiyi paylaşmadan silmek istiyor musun?" - }, "publish_post_failure": { "title": "Paylaşılamadı", "message": "Gönderi paylaşılamadı. Lütfen internet bağlantını kontrol et.", @@ -55,7 +51,7 @@ "translation_failed": { "title": "Note", "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", - "button": "OK" + "button": "Tamam" } }, "controls": { @@ -82,7 +78,7 @@ "sign_in": "Giriş Yap", "see_more": "Daha Fazla Gör", "preview": "Önizleme", - "copy": "Copy", + "copy": "Kopyala", "share": "Paylaş", "share_user": "%s ile paylaş", "share_post": "Gönderiyi Paylaş", @@ -98,13 +94,13 @@ "settings": "Ayarlar", "delete": "Sil", "translate_post": { - "title": "Translate from %s", - "unknown_language": "Unknown" + "title": "%s dilinden çevrildi", + "unknown_language": "Bilinmeyen" }, - "edit_post": "Edit", - "bookmark": "Bookmark", - "remove_bookmark": "Remove Bookmark", - "follow": "Follow %s", + "edit_post": "Düzenle", + "bookmark": "Yer işareti", + "remove_bookmark": "Yer işaretini kaldır", + "follow": "%s takip et", "unfollow": "Unfollow %s" }, "tabs": { @@ -113,8 +109,8 @@ "notifications": "Bildirimler", "profile": "Profil", "a11y": { - "search": "Search", - "explore": "Explore" + "search": "Ara", + "explore": "Keşfet" } }, "keyboard": { @@ -173,11 +169,11 @@ "show_image": "Görüntüyü göster", "show_gif": "GIF'i göster", "show_video_player": "Video oynatıcıyı göster", - "share_link_in_post": "Share Link in Post", + "share_link_in_post": "Bağlantıyı Gönderide Paylaş", "tap_then_hold_to_show_menu": "Menüyü göstermek için dokunun ve basılı tutun", "a11y_labels": { - "reblog": "Re-blog", - "unreblog": "Undo re-blog" + "reblog": "Yeniden paylaş", + "unreblog": "Yeniden paylaşımı geri al" } }, "tag": { @@ -196,9 +192,9 @@ }, "translation": { "translated_from": "Translated from %s using %s", - "unknown_language": "Unknown", - "unknown_provider": "Unknown", - "show_original": "Show Original" + "unknown_language": "Bilinmeyen", + "unknown_provider": "Bilinmeyen", + "show_original": "Orijinali Göster" }, "media": { "accessibility_label": "%s, attachment %d of %d", @@ -209,13 +205,13 @@ "posted_via_application": "%s via %s", "buttons": { "reblogs_title": "Reblogs", - "favorites_title": "Favorites", - "edit_history_title": "Edit History", - "edit_history_detail": "Last edit %s" + "favorites_title": "Favoriler", + "edit_history_title": "Düzenleme Geçmişi", + "edit_history_detail": "Son güncelleme: %s" }, "edited_at_timestamp_prefix": "Edited %s", "edit_history": { - "title": "Edit History", + "title": "Düzenleme Geçmişi", "original_post": "Original Post · %s" } }, @@ -261,22 +257,22 @@ } }, "user_list": { - "no_verified_link": "No verified link", + "no_verified_link": "Doğrulanmamış bağlantı", "followers_count": "%@ followers" } }, "scene": { "welcome": { "log_in": "Oturum Aç", - "learn_more": "Learn more", - "join_default_server": "Join %@", - "pick_server": "Pick another server", + "learn_more": "Daha fazla bilgi edin", + "join_default_server": "%@ katıl", + "pick_server": "Başka sunucu seç", "separator": { - "or": "or" + "or": "veya" }, "education": { "mastodon": { - "title": "Welcome to Mastodon", + "title": "Mastodon'a Hoş Geldin", "description": "Mastodon is a decentralized social network, meaning no single company controls it. It’s made up of many independently-run servers, all connected together." }, "servers": { @@ -285,22 +281,22 @@ }, "a11y": { "what_is_mastodon": { - "title": "What is Mastodon?" + "title": "Mastodon nedir?" } } } }, "login": { - "title": "Welcome back", + "title": "Tekrar hoş geldiniz", "subtitle": "Hesabını oluşturduğun sunucuya giriş yap.", "server_search_field": { "placeholder": "Bir URL girin ya da sunucunuzu arayın" } }, "server_picker": { - "title": "Pick Server", + "title": "Sunucu Seç", "button": { - "language": "Language", + "language": "Dil", "signup_speed": "Sign-up Speed", "category": { "all": "Tümü", @@ -335,31 +331,31 @@ "no_results": "Sonuç yok" }, "signup_speed": { - "all": "All", + "all": "Hepsi", "instant": "Instant Sign-up", "manually_reviewed": "Manual Review" }, "language": { - "all": "All" + "all": "Hepsi" }, "search": { - "placeholder": "Search name or URL" + "placeholder": "İsim ya da bağlantı arayın" }, "no_server_selected_hint": "We’ll pick a server based on your language if you continue without making a selection." }, "privacy": { - "title": "Privacy", + "title": "Gizlilik", "description": "Although the Mastodon app does not collect any data, the server you sign up through may have a different policy. Take a minute to review and agree to the Mastodon app privacy policy and your server’s privacy policy.", "policy": { - "ios": "Privacy Policy - Mastodon for iOS", - "server": "Privacy Policy - %s" + "ios": "Gizlilik Politikası - iOS için Mastodon", + "server": "Gizlilik Politikası - %s" }, "button": { - "confirm": "I Agree" + "confirm": "Kabul Ediyorum" } }, "register": { - "title": "Create Account", + "title": "Hesap Oluştur", "input": { "avatar": { "delete": "Sil" @@ -377,7 +373,7 @@ }, "password": { "placeholder": "parola", - "confirmation_placeholder": "Confirm Password", + "confirmation_placeholder": "Parolanızı Doğrulayın", "require": "Parolanızda en azından şunlar olmalı:", "character_limit": "8 karakter", "accessibility": { @@ -402,7 +398,7 @@ "reason": { "blocked": "%s izin verilmeyen bir e-posta sağlayıcı içeriyor", "unreachable": "%s mevcut değil", - "taken": "%s is already taken. How about:", + "taken": "%s zaten alınmış. Buna ne dersiniz:", "reserved": "%s rezerve edilen bir kelime", "accepted": "%s kabul edilmelidir", "blank": "%s gerekli", @@ -426,30 +422,30 @@ "terms_of_service": "kullanım şartları", "privacy_policy": "gizlilik politikası", "button": { - "confirm": "I Agree" + "confirm": "Kabul Ediyorum" } }, "confirm_email": { - "title": "Check Your Inbox", + "title": "Gelen kutunuzu kontrol edin", "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we sent you to verify %@. We’ll wait right here.", "button": { "resend": "Yeniden gönder" }, "dont_receive_email": { - "title": "Check your Email", + "title": "E-postanızı kontrol edin", "description": "E-posta adresinizin doğru olup olmadığını ve doğru ise gereksiz klasörünüzü kontrol edin.", "resend_email": "E-postayı Yeniden Gönder" }, "open_email_app": { - "title": "Check your Inbox.", + "title": "Gelen kutunuzu kontrol edin.", "description": "Size bir e-posta gönderdik. Eğer e-postayı almadıysanız, gereksiz klasörünü kontrol edin.", "mail": "Posta", "open_email_client": "E-posta İstemcisini Aç" }, "didnt_get_link": { - "prefix": "Didn’t get a link?", + "prefix": "Bağlantı gelmedi mi?", "resend_in": "Resend (%@)", - "resend_now": "Resend now." + "resend_now": "Yeniden gönder." } }, "home_timeline": { @@ -466,14 +462,14 @@ } }, "suggestion_account": { - "title": "Popular on Mastodon", - "follow_all": "Follow all" + "title": "Mastodon'da popüler", + "follow_all": "Hepsini takip et" }, "compose": { "title": { "new_post": "Yeni Gönderi", "new_reply": "Yeni Yanıt", - "edit_post": "Edit Post" + "edit_post": "Gönderiyi Düzenle" }, "media_selection": { "camera": "Fotoğraf Çek", @@ -497,7 +493,7 @@ "server_processing_state": "Sunucu İşliyor..." }, "poll": { - "title": "Poll", + "title": "Anket", "duration_time": "Süre: %s", "thirty_minutes": "30 dakika", "one_hour": "1 Saat", @@ -508,8 +504,8 @@ "option_number": "Seçenek %ld", "the_poll_is_invalid": "Anket geçersiz", "the_poll_has_empty_option": "The poll has empty option", - "add_option": "Add Option", - "remove_option": "Remove Option", + "add_option": "Seçenek Ekle", + "remove_option": "Seçeneği Kaldır", "move_up": "Move Up", "move_down": "Move Down" }, @@ -545,8 +541,8 @@ "select_visibility_entry": "Görünürlüğü Seç - %s" }, "language": { - "title": "Post Language", - "suggested": "Suggested", + "title": "Gönderi dili", + "suggested": "Önerilen", "recent": "Recent", "other": "Other Language…" } @@ -556,10 +552,10 @@ "follows_you": "Seni takip ediyor" }, "dashboard": { - "my_posts": "posts", - "my_following": "following", - "my_followers": "followers", - "other_posts": "posts", + "my_posts": "gönderiler", + "my_following": "takip ediliyor", + "my_followers": "takipçiler", + "other_posts": "gönderiler", "other_following": "following", "other_followers": "followers", "familiar_followers": "mutuals" @@ -678,7 +674,7 @@ "intro": "Bunlar, Mastodon'un köşesinde ilgi çeken gönderilerdir." }, "favorite": { - "title": "Favorites" + "title": "Favoriler" }, "notification": { "title": { @@ -858,9 +854,9 @@ "user_not_logged_in": "Please open Mastodon to log in to an Account." }, "followers_count": { - "configuration_display_name": "Followers", + "configuration_display_name": "Takipçiler", "configuration_description": "Show number of followers.", - "title": "FOLLOWERS", + "title": "TAKİPÇİLER", "followers_today": "%s followers today" }, "multiple_followers": { @@ -872,14 +868,14 @@ } }, "latest_followers": { - "configuration_display_name": "Latest followers", - "configuration_description": "Show latest followers.", - "title": "Latest followers", + "configuration_display_name": "Son takipçiler", + "configuration_description": "Son takipçileri göster.", + "title": "Son takipçiler", "last_update": "Last update: %s" }, "hashtag": { "configuration": { - "display_name": "Hashtag", + "display_name": "Etiket", "description": "Shows a recent post with the selected hashtag." }, "not_found": { diff --git a/Localization/StringsConvertor/input/uk.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/uk.lproj/Localizable.stringsdict index e008c9d67..923782531 100644 --- a/Localization/StringsConvertor/input/uk.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/uk.lproj/Localizable.stringsdict @@ -15,7 +15,7 @@ one 1 не прочитане сповіщення few - %ld не прочитаних сповіщень + %ld не прочитані сповіщення many %ld не прочитаних сповіщень other @@ -25,7 +25,7 @@ a11y.plural.count.input_limit_exceeds NSStringLocalizedFormatKey - Перевищено ліміт вводу на %#@character_count@ + Перевищено ліміт вводу символів на %#@character_count@ character_count NSStringFormatSpecTypeKey @@ -45,7 +45,7 @@ a11y.plural.count.input_limit_remains NSStringLocalizedFormatKey - Залишається вхідний ліміт %#@character_count@ + Залишається ліміт вводу символів %#@character_count@ character_count NSStringFormatSpecTypeKey @@ -73,13 +73,13 @@ NSStringFormatValueTypeKey ld one - 1 character left + 1 символ залишився few - %ld characters left + %ld символи залишилось many - %ld characters left + %ld символів залишилось other - %ld characters left + %ld символів залишилось plural.count.followed_by_and_mutual @@ -108,7 +108,7 @@ NSStringFormatValueTypeKey ld one - Читають %1$@ та інші + Читає %1$@ та ще один few Читають %1$@, та %ld взаємних many @@ -228,13 +228,13 @@ NSStringFormatValueTypeKey ld one - 1 re-blog + 1 репост few - %ld re-blogs + %ld репости many - %ld re-blogs + %ld репостів other - %ld re-blogs + %ld репостів plural.count.reply diff --git a/Localization/StringsConvertor/input/uk.lproj/app.json b/Localization/StringsConvertor/input/uk.lproj/app.json index 53dacda5f..652674b9e 100644 --- a/Localization/StringsConvertor/input/uk.lproj/app.json +++ b/Localization/StringsConvertor/input/uk.lproj/app.json @@ -15,10 +15,6 @@ "title": "Помилка голосування", "poll_ended": "Опитування завершено" }, - "discard_post_content": { - "title": "Видалити чернетку", - "message": "Підтвердьте, щоб відхилити створений вміст публікації." - }, "publish_post_failure": { "title": "Помилка публікації", "message": "Не вдалося опублікувати допис.\nПеревірте підключення до Інтернету.", @@ -53,8 +49,8 @@ "message": "%s успішно очищено." }, "translation_failed": { - "title": "Note", - "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "title": "Нотатка", + "message": "Не вдалося виконати переклад. Можливо, адміністратор не активував переклади на цьому сервері або цей сервер використовує стару версію Mastodon, де переклади ще не підтримуються.", "button": "OK" } }, @@ -82,7 +78,7 @@ "sign_in": "Увійти", "see_more": "Дивіться більше", "preview": "Попередній перегляд", - "copy": "Copy", + "copy": "Копіювати", "share": "Поділитись", "share_user": "Поділитися %s", "share_post": "Поділитися записом", @@ -98,22 +94,22 @@ "settings": "Налаштування", "delete": "Видалити", "translate_post": { - "title": "Translate from %s", - "unknown_language": "Unknown" + "title": "Перекладено з %s", + "unknown_language": "Невідомо" }, - "edit_post": "Edit", - "bookmark": "Bookmark", - "remove_bookmark": "Remove Bookmark", - "follow": "Follow %s", - "unfollow": "Unfollow %s" + "edit_post": "Редагувати", + "bookmark": "Закладка", + "remove_bookmark": "Видалити Закладку", + "follow": "Стежити за %s", + "unfollow": "Не стежити за %s" }, "tabs": { "home": "Головна", "search_and_explore": "Search and Explore", - "notifications": "Notifications", + "notifications": "Сповіщення", "profile": "Профіль", "a11y": { - "search": "Search", + "search": "Пошук", "explore": "Explore" } }, @@ -151,7 +147,7 @@ "media_content_warning": "Натисніть будь-де, щоб показати більше", "tap_to_reveal": "Натисніть, щоб відобразити", "load_embed": "Load Embed", - "link_via_user": "%s via %s", + "link_via_user": "%s через %s", "poll": { "vote": "Проголосувати", "closed": "Зачинено" @@ -176,8 +172,8 @@ "share_link_in_post": "Share Link in Post", "tap_then_hold_to_show_menu": "Натисніть та утримуйте, щоб показати меню", "a11y_labels": { - "reblog": "Re-blog", - "unreblog": "Undo re-blog" + "reblog": "Репост", + "unreblog": "Скасувати репост" } }, "tag": { @@ -195,28 +191,28 @@ "direct": "Тільки згаданий користувач може бачити цю публікацію." }, "translation": { - "translated_from": "Translated from %s using %s", - "unknown_language": "Unknown", - "unknown_provider": "Unknown", - "show_original": "Show Original" + "translated_from": "Перекладено з %s за допомогою %s", + "unknown_language": "Невідомо", + "unknown_provider": "Невідомо", + "show_original": "Показати оригінал" }, "media": { - "accessibility_label": "%s, attachment %d of %d", - "expand_image_hint": "Expands the image. Double-tap and hold to show actions", + "accessibility_label": "%s, вкладення %d із %d", + "expand_image_hint": "Розгортає зображення. Двічі торкніться та утримуйте, щоб показати дії", "expand_gif_hint": "Expands the GIF. Double-tap and hold to show actions", - "expand_video_hint": "Shows the video player. Double-tap and hold to show actions" + "expand_video_hint": "Показує відеоплеєр. Натисніть двічі і утримуйте, щоб показати дії" }, - "posted_via_application": "%s via %s", + "posted_via_application": "%s через %s", "buttons": { - "reblogs_title": "Reblogs", - "favorites_title": "Favorites", - "edit_history_title": "Edit History", - "edit_history_detail": "Last edit %s" + "reblogs_title": "Репости", + "favorites_title": "Улюблені", + "edit_history_title": "Редагувати історію", + "edit_history_detail": "Останнє редагування %s" }, - "edited_at_timestamp_prefix": "Edited %s", + "edited_at_timestamp_prefix": "Відредаговано %s", "edit_history": { - "title": "Edit History", - "original_post": "Original Post · %s" + "title": "Редагувати історію", + "original_post": "Оригінальна публікація · %s" } }, "friendship": { @@ -261,47 +257,47 @@ } }, "user_list": { - "no_verified_link": "No verified link", - "followers_count": "%@ followers" + "no_verified_link": "Нема підтвердженого посилання", + "followers_count": "%@ підписників" } }, "scene": { "welcome": { "log_in": "Увійти", - "learn_more": "Learn more", - "join_default_server": "Join %@", - "pick_server": "Pick another server", + "learn_more": "Докладніше", + "join_default_server": "Приєднатися до %@", + "pick_server": "Обрати інший сервер", "separator": { - "or": "or" + "or": "або" }, "education": { "mastodon": { - "title": "Welcome to Mastodon", - "description": "Mastodon is a decentralized social network, meaning no single company controls it. It’s made up of many independently-run servers, all connected together." + "title": "Вітаємо у Mastodon", + "description": "Mastodon - це децентралізована соціальна мережа, тобто жодна компанія не контролює її. У її склад входить велика кількість незалежних серверів пов'язаних між собою." }, "servers": { - "title": "What are servers?", - "description": "Every Mastodon account is hosted on a server — each with its own values, rules, & admins. No matter which one you pick, you can follow and interact with people on any server." + "title": "Що таке сервери?", + "description": "Кожен обліковий запис Mastodon розміщений на сервері - кожен сервер має особисті цінності, правила, й адмінів. Немає різниці, який ви оберете, ви можете слідкувати та спілкуватися з користувачами з будь-яких серверів." }, "a11y": { "what_is_mastodon": { - "title": "What is Mastodon?" + "title": "Що таке Mastodon?" } } } }, "login": { - "title": "Welcome back", + "title": "З поверненням", "subtitle": "Увійдіть на сервері, де ви створили свій обліковий запис.", "server_search_field": { "placeholder": "Введіть URL-адресу або адресу сервера" } }, "server_picker": { - "title": "Pick Server", + "title": "Оберіть сервер", "button": { - "language": "Language", - "signup_speed": "Sign-up Speed", + "language": "Мова", + "signup_speed": "Швидкість реєстрації", "category": { "all": "Всі", "all_accessiblity_description": "Категорія: Усі", @@ -335,31 +331,31 @@ "no_results": "Жодних результатів" }, "signup_speed": { - "all": "All", - "instant": "Instant Sign-up", - "manually_reviewed": "Manual Review" + "all": "Всі", + "instant": "Миттєва реєстрація", + "manually_reviewed": "Ручна перевірка" }, "language": { - "all": "All" + "all": "Всі" }, "search": { - "placeholder": "Search name or URL" + "placeholder": "Пошук по імені або URL" }, - "no_server_selected_hint": "We’ll pick a server based on your language if you continue without making a selection." + "no_server_selected_hint": "Ми підберемо сервер на основі вашої мови, якщо ви продовжите без вибору." }, "privacy": { - "title": "Privacy", - "description": "Although the Mastodon app does not collect any data, the server you sign up through may have a different policy. Take a minute to review and agree to the Mastodon app privacy policy and your server’s privacy policy.", + "title": "Приватність", + "description": "Хоча додаток Mastodon не збирає жодних даних, сервер, на якому ви зареєструвались, може мати іншу політику. Витратьте хвилину, щоб переглянути та погодитися з політикою конфіденційності Mastodon і політикою конфіденційності Вашого сервера.", "policy": { - "ios": "Privacy Policy - Mastodon for iOS", - "server": "Privacy Policy - %s" + "ios": "Політика конфіденційності - Mastodon для iOS", + "server": "Політика конфіденційності - %s" }, "button": { - "confirm": "I Agree" + "confirm": "Я погоджуюся" } }, "register": { - "title": "Create Account", + "title": "Створить аккаунт", "input": { "avatar": { "delete": "Видалити" @@ -377,7 +373,7 @@ }, "password": { "placeholder": "пароль", - "confirmation_placeholder": "Confirm Password", + "confirmation_placeholder": "Підтвердіть Пароль", "require": "Ваш пароль повинен містити як мінімум:", "character_limit": "8 символів", "accessibility": { @@ -402,7 +398,7 @@ "reason": { "blocked": "%s містить заборонених провайдерів email", "unreachable": "%s здається, не існує", - "taken": "%s is already taken. How about:", + "taken": "%s вже зайняте. Як щодо:", "reserved": "%s є зарезервованим ключовим словом", "accepted": "%s має бути прийнято", "blank": "%s необхідно", @@ -426,30 +422,30 @@ "terms_of_service": "умови використання", "privacy_policy": "політика конфіденційності", "button": { - "confirm": "I Agree" + "confirm": "Я погоджуюся" } }, "confirm_email": { - "title": "Check Your Inbox", - "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we sent you to verify %@. We’ll wait right here.", + "title": "Перевірте вхідні", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "Натисніть на посилання, яке ми надіслали вам, щоб підтвердити %@. Ми чекатимемо прямо тут.", "button": { "resend": "Повторно надіслати" }, "dont_receive_email": { - "title": "Check your Email", + "title": "Перевірте свою пошту", "description": "Перевірте правильність адреси електронної пошти, а також теку зі спамом, якщо ви ще не зробили цього.", "resend_email": "Повторно надіслати лист" }, "open_email_app": { - "title": "Check your Inbox.", + "title": "Перевірте вашу поштову скриньку.", "description": "Ми щойно надіслали вам електронного листа. Перевірте вашу спам теку, якщо ви не зробили цього.", "mail": "Пошта", "open_email_client": "Відкрити поштового клієнта" }, "didnt_get_link": { - "prefix": "Didn’t get a link?", - "resend_in": "Resend (%@)", - "resend_now": "Resend now." + "prefix": "Не отримали посилання?", + "resend_in": "Надіслати повторно (%@)", + "resend_now": "Надіслати ще раз." } }, "home_timeline": { @@ -466,14 +462,14 @@ } }, "suggestion_account": { - "title": "Popular on Mastodon", - "follow_all": "Follow all" + "title": "Популярне на Mastodon", + "follow_all": "Стежити за всіма" }, "compose": { "title": { "new_post": "Новий допис", "new_reply": "Нова відповідь", - "edit_post": "Edit Post" + "edit_post": "Редагувати допис" }, "media_selection": { "camera": "Зробити фото", @@ -497,7 +493,7 @@ "server_processing_state": "Обробка сервера..." }, "poll": { - "title": "Poll", + "title": "Опитування", "duration_time": "Тривалість: %s", "thirty_minutes": "30 хвилин", "one_hour": "1 Година", @@ -508,10 +504,10 @@ "option_number": "Параметр %ld", "the_poll_is_invalid": "Неприпустимий варіант опитування", "the_poll_has_empty_option": "В опитуванні є порожній варіант", - "add_option": "Add Option", - "remove_option": "Remove Option", - "move_up": "Move Up", - "move_down": "Move Down" + "add_option": "Додати відповідь", + "remove_option": "Видалити відповідь", + "move_up": "Вище", + "move_down": "Нижче" }, "content_warning": { "placeholder": "Напишіть своє попередження тут..." @@ -545,10 +541,10 @@ "select_visibility_entry": "Оберіть видимість - %s" }, "language": { - "title": "Post Language", - "suggested": "Suggested", - "recent": "Recent", - "other": "Other Language…" + "title": "Мова допису", + "suggested": "Рекомендовані", + "recent": "Останні", + "other": "Інші мови…" } }, "profile": { @@ -556,16 +552,16 @@ "follows_you": "Підписаний(-на) на вас" }, "dashboard": { - "my_posts": "posts", + "my_posts": "публікації", "my_following": "following", - "my_followers": "followers", - "other_posts": "posts", - "other_following": "following", - "other_followers": "followers", + "my_followers": "підписники", + "other_posts": "публікації", + "other_following": "підписок", + "other_followers": "підписники", "familiar_followers": "mutuals" }, "fields": { - "joined": "Joined", + "joined": "Приєднався", "add_row": "Додати рядок", "placeholder": { "label": "Позначка", @@ -678,7 +674,7 @@ "intro": "Ось найбільш популярні дописи серед вашого серверу Mastodon." }, "favorite": { - "title": "Favorites" + "title": "Вподобане" }, "notification": { "title": { @@ -835,15 +831,15 @@ "title": "Закладки" }, "followed_tags": { - "title": "Followed Tags", + "title": "Відстежувані мітки", "header": { - "posts": "posts", - "participants": "participants", - "posts_today": "posts today" + "posts": "публікації", + "participants": "учасників", + "posts_today": "публікацій сьогодні" }, "actions": { - "follow": "Follow", - "unfollow": "Unfollow" + "follow": "Стежити", + "unfollow": "Не стежити" } } }, @@ -858,28 +854,28 @@ "user_not_logged_in": "Please open Mastodon to log in to an Account." }, "followers_count": { - "configuration_display_name": "Followers", - "configuration_description": "Show number of followers.", - "title": "FOLLOWERS", - "followers_today": "%s followers today" + "configuration_display_name": "Підписники", + "configuration_description": "Показати кількість підписників.", + "title": "ПІДПИСНИКИ", + "followers_today": "%s підписників сьогодні" }, "multiple_followers": { "configuration_display_name": "Multiple followers", "configuration_description": "Show number of followers for multiple accounts.", "mock_user": { - "display_name": "Another follower", + "display_name": "Інший підписник", "account_name": "another@follower.social" } }, "latest_followers": { - "configuration_display_name": "Latest followers", - "configuration_description": "Show latest followers.", - "title": "Latest followers", - "last_update": "Last update: %s" + "configuration_display_name": "Останні підписники", + "configuration_description": "Показати останніх підписників.", + "title": "Останні підписники", + "last_update": "Останнє оновлення: %s" }, "hashtag": { "configuration": { - "display_name": "Hashtag", + "display_name": "Хештеґ", "description": "Shows a recent post with the selected hashtag." }, "not_found": { @@ -890,7 +886,7 @@ "placeholder": { "account_name": "John Mastodon", "account": "@johnMastodon@no-such.account", - "content": "This is how a post with a #hashtag would look. Pick whichever #hashtag you want in the widget settings." + "content": "Таким чином буде виглядати пост з позначкою #hashtag. Виберіть будь-який #hashtag у налаштуваннях віджету." } } } diff --git a/Localization/StringsConvertor/input/vi.lproj/app.json b/Localization/StringsConvertor/input/vi.lproj/app.json index 254b14b20..50ffc44e2 100644 --- a/Localization/StringsConvertor/input/vi.lproj/app.json +++ b/Localization/StringsConvertor/input/vi.lproj/app.json @@ -15,10 +15,6 @@ "title": "Bình chọn không thành công", "poll_ended": "Cuộc bình chọn đã kết thúc" }, - "discard_post_content": { - "title": "Bỏ bản nháp", - "message": "Xác nhận bỏ qua nội dung tút đã viết." - }, "publish_post_failure": { "title": "Đăng tút không thành công", "message": "Không thể đăng tút.\nVui lòng kiểm tra kết nối mạng.", @@ -72,7 +68,7 @@ "done": "Xong", "confirm": "Xác nhận", "continue": "Tiếp tục", - "compose": "Viết tút", + "compose": "Soạn tút", "cancel": "Hủy bỏ", "discard": "Bỏ qua", "try_again": "Thử lại", @@ -108,7 +104,7 @@ "unfollow": "Bỏ theo dõi %s" }, "tabs": { - "home": "Bảng tin", + "home": "Trang chính", "search_and_explore": "Tìm và Khám Phá", "notifications": "Thông báo", "profile": "Trang hồ sơ", @@ -120,7 +116,7 @@ "keyboard": { "common": { "switch_to_tab": "Chuyển thành %s", - "compose_new_post": "Viết tút mới", + "compose_new_post": "Soạn tút mới", "show_favorites": "Hiện lượt thích", "open_settings": "Mở cài đặt" }, @@ -128,7 +124,7 @@ "previous_status": "Tút trước", "next_status": "Tút sau", "open_status": "Mở tút", - "open_author_profile": "Mở trang người viết tút", + "open_author_profile": "Mở trang người đăng tút", "open_reblogger_profile": "Mở trang người đăng lại tút", "reply_status": "Trả lời tút", "toggle_reblog": "Chọn đăng lại tút", @@ -154,7 +150,7 @@ "link_via_user": "%s bởi %s", "poll": { "vote": "Bình chọn", - "closed": "Kết thúc" + "closed": "Đóng" }, "meta_entity": { "url": "Link: %s", @@ -269,7 +265,7 @@ "welcome": { "log_in": "Đăng nhập", "learn_more": "Tìm hiểu thêm", - "join_default_server": "Join %@", + "join_default_server": "Tham gia %@", "pick_server": "Tìm máy chủ khác", "separator": { "or": "hoặc" @@ -453,7 +449,7 @@ } }, "home_timeline": { - "title": "Bảng tin", + "title": "Trang chính", "navigation_bar_state": { "offline": "Ngoại tuyến", "new_posts": "Đọc những tút mới", @@ -471,7 +467,7 @@ }, "compose": { "title": { - "new_post": "Viết tút", + "new_post": "Soạn tút", "new_reply": "Viết trả lời", "edit_post": "Sửa tút" }, @@ -648,7 +644,7 @@ "people_talking": "%s người đang thảo luận" }, "accounts": { - "title": "Những người bạn có thể thích", + "title": "Những người bạn có thể quen", "description": "Bạn có thể muốn theo dõi những người này", "follow": "Theo dõi" } @@ -731,7 +727,7 @@ "boosts": "Đăng lại tút của tôi", "mentions": "Nhắc đến tôi", "trigger": { - "anyone": "ai đó", + "anyone": "bất cứ ai", "follower": "người theo dõi tôi", "follow": "người tôi theo dõi", "noone": "không một ai", diff --git a/Localization/StringsConvertor/input/vi.lproj/ios-infoPlist.json b/Localization/StringsConvertor/input/vi.lproj/ios-infoPlist.json index 2170219a4..29b40c524 100644 --- a/Localization/StringsConvertor/input/vi.lproj/ios-infoPlist.json +++ b/Localization/StringsConvertor/input/vi.lproj/ios-infoPlist.json @@ -1,6 +1,6 @@ { "NSCameraUsageDescription": "Được sử dụng để chụp ảnh cho tút", "NSPhotoLibraryAddUsageDescription": "Được sử dụng để lưu ảnh vào Thư viện ảnh", - "NewPostShortcutItemTitle": "Viết tút", + "NewPostShortcutItemTitle": "Soạn tút", "SearchShortcutItemTitle": "Tìm kiếm" } diff --git a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json index cd8669fb4..0f9726942 100644 --- a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json @@ -15,10 +15,6 @@ "title": "投票失败", "poll_ended": "投票已结束" }, - "discard_post_content": { - "title": "丢弃草案", - "message": "确认要丢弃正在编辑的内容" - }, "publish_post_failure": { "title": "发布失败", "message": "帖子发送失败。\n请检查你的网络连接。", diff --git a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json index 3b1fc9fb8..3c9bdb150 100644 --- a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json @@ -15,10 +15,6 @@ "title": "投票失敗", "poll_ended": "投票已結束" }, - "discard_post_content": { - "title": "捨棄草稿", - "message": "確認放棄編寫中的嘟文內容。" - }, "publish_post_failure": { "title": "發表嘟文失敗", "message": "發表嘟文失敗。\n請檢查您的網路連線。", @@ -269,7 +265,7 @@ "welcome": { "log_in": "登入", "learn_more": "了解更多", - "join_default_server": "Join %@", + "join_default_server": "加入 %@", "pick_server": "挑選另一個伺服器", "separator": { "or": "或" From 97418db0b51668832c7957f1d6ab36186f873ce0 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 28 Aug 2023 13:01:01 +0200 Subject: [PATCH 36/87] Update localizations --- Mastodon/Resources/el.lproj/InfoPlist.strings | 8 +- Mastodon/Resources/vi.lproj/InfoPlist.strings | 2 +- MastodonIntent/el.lproj/Intents.strings | 42 +- .../Resources/ar.lproj/Localizable.strings | 2 - .../Resources/be.lproj/Localizable.strings | 34 +- .../Resources/ca.lproj/Localizable.strings | 4 +- .../Resources/ckb.lproj/Localizable.strings | 2 - .../Resources/cs.lproj/Localizable.strings | 4 +- .../Resources/de.lproj/Localizable.strings | 2 - .../Resources/el.lproj/Localizable.strings | 748 +++++++++--------- .../el.lproj/Localizable.stringsdict | 120 +-- .../Resources/en.lproj/Localizable.strings | 2 - .../Resources/es.lproj/Localizable.strings | 2 - .../Resources/eu.lproj/Localizable.strings | 2 - .../Resources/fi.lproj/Localizable.strings | 4 +- .../Resources/fr.lproj/Localizable.strings | 2 - .../Resources/gd.lproj/Localizable.strings | 16 +- .../Resources/gl.lproj/Localizable.strings | 4 +- .../Resources/it.lproj/Localizable.strings | 4 +- .../Resources/ja.lproj/Localizable.strings | 4 +- .../Resources/kab.lproj/Localizable.strings | 2 - .../Resources/ku.lproj/Localizable.strings | 2 - .../Resources/nl.lproj/Localizable.strings | 2 - .../Resources/ru.lproj/Localizable.strings | 2 - .../Resources/sl.lproj/Localizable.strings | 4 +- .../Resources/sv.lproj/Localizable.strings | 26 +- .../Resources/th.lproj/Localizable.strings | 6 +- .../Resources/tr.lproj/Localizable.strings | 132 ++-- .../tr.lproj/Localizable.stringsdict | 4 +- .../Resources/vi.lproj/Localizable.strings | 22 +- .../zh-Hans.lproj/Localizable.strings | 2 - .../zh-Hant.lproj/Localizable.strings | 4 +- 32 files changed, 581 insertions(+), 635 deletions(-) diff --git a/Mastodon/Resources/el.lproj/InfoPlist.strings b/Mastodon/Resources/el.lproj/InfoPlist.strings index 710865573..0e9c331e8 100644 --- a/Mastodon/Resources/el.lproj/InfoPlist.strings +++ b/Mastodon/Resources/el.lproj/InfoPlist.strings @@ -1,4 +1,4 @@ -"NSCameraUsageDescription" = "Used to take photo for post status"; -"NSPhotoLibraryAddUsageDescription" = "Used to save photo into the Photo Library"; -"NewPostShortcutItemTitle" = "New Post"; -"SearchShortcutItemTitle" = "Search"; \ No newline at end of file +"NSCameraUsageDescription" = "Χρησιμοποιείται για λήψη φωτογραφίας για την κατάσταση της ανάρτησης"; +"NSPhotoLibraryAddUsageDescription" = "Χρησιμοποιείται για αποθήκευση φωτογραφιών στις Φωτογραφίες"; +"NewPostShortcutItemTitle" = "Νέα Ανάρτηση"; +"SearchShortcutItemTitle" = "Αναζήτηση"; \ No newline at end of file diff --git a/Mastodon/Resources/vi.lproj/InfoPlist.strings b/Mastodon/Resources/vi.lproj/InfoPlist.strings index 5dd27b7bc..1fab38f98 100644 --- a/Mastodon/Resources/vi.lproj/InfoPlist.strings +++ b/Mastodon/Resources/vi.lproj/InfoPlist.strings @@ -1,4 +1,4 @@ "NSCameraUsageDescription" = "Được sử dụng để chụp ảnh cho tút"; "NSPhotoLibraryAddUsageDescription" = "Được sử dụng để lưu ảnh vào Thư viện ảnh"; -"NewPostShortcutItemTitle" = "Viết tút"; +"NewPostShortcutItemTitle" = "Soạn tút"; "SearchShortcutItemTitle" = "Tìm kiếm"; \ No newline at end of file diff --git a/MastodonIntent/el.lproj/Intents.strings b/MastodonIntent/el.lproj/Intents.strings index 484cc94b2..df186daea 100644 --- a/MastodonIntent/el.lproj/Intents.strings +++ b/MastodonIntent/el.lproj/Intents.strings @@ -4,48 +4,48 @@ "CsR7G2" = "Ανάρτηση στο Mastodon"; -"HZSGTr" = "What content to post?"; +"HZSGTr" = "Τι περιεχόμενο θα αναρτήσεις;"; -"HdGikU" = "Posting failed"; +"HdGikU" = "Αποτυχία δημοσίευσης"; -"KDNTJ4" = "Failure Reason"; +"KDNTJ4" = "Λόγος Αποτυχίας"; -"RHxKOw" = "Send Post with text content"; +"RHxKOw" = "Αποστολή ανάρτησης με περιεχόμενο κειμένου"; -"RxSqsb" = "Post"; +"RxSqsb" = "Ανάρτηση"; -"WCIR3D" = "Post ${content} on Mastodon"; +"WCIR3D" = "Ανάρτηση ${content} στο Mastodon"; -"ZKJSNu" = "Post"; +"ZKJSNu" = "Ανάρτηση"; "ZS1XaK" = "${content}"; -"ZbSjzC" = "Visibility"; +"ZbSjzC" = "Ορατότητα"; -"Zo4jgJ" = "Post Visibility"; +"Zo4jgJ" = "Ορατότητα Ανάρτησης"; -"apSxMG-dYQ5NN" = "There are ${count} options matching ‘Public’."; +"apSxMG-dYQ5NN" = "Υπάρχουν ${count} επιλογές που ταιριάζουν στο «Δημόσιο»."; -"apSxMG-ehFLjY" = "There are ${count} options matching ‘Followers Only’."; +"apSxMG-ehFLjY" = "Υπάρχουν ${count} επιλογές που ταιριάζουν στο «Μόνο για Ακόλουθους»."; -"ayoYEb-dYQ5NN" = "${content}, Public"; +"ayoYEb-dYQ5NN" = "${content}, Δημόσιο"; -"ayoYEb-ehFLjY" = "${content}, Followers Only"; +"ayoYEb-ehFLjY" = "${content}, Μόνο Ακόλουθοι"; -"dUyuGg" = "Post on Mastodon"; +"dUyuGg" = "Ανάρτηση στο Mastodon"; -"dYQ5NN" = "Public"; +"dYQ5NN" = "Δημόσιο"; -"ehFLjY" = "Followers Only"; +"ehFLjY" = "Μόνο Ακόλουθοι"; -"gfePDu" = "Posting failed. ${failureReason}"; +"gfePDu" = "Αποτυχία ανάρτησης. ${failureReason}"; -"k7dbKQ" = "Post was sent successfully."; +"k7dbKQ" = "Η ανάρτηση στάλθηκε με επιτυχία."; -"oGiqmY-dYQ5NN" = "Just to confirm, you wanted ‘Public’?"; +"oGiqmY-dYQ5NN" = "Απλά για να επιβεβαίωση, θες «Δημόσιο»;"; -"oGiqmY-ehFLjY" = "Just to confirm, you wanted ‘Followers Only’?"; +"oGiqmY-ehFLjY" = "Απλά για επιβεβαίωση, θες «Μόνο Ακόλουθοι»;"; "rM6dvp" = "URL"; -"ryJLwG" = "Post was sent successfully. "; +"ryJLwG" = "Η ανάρτηση στάλθηκε με επιτυχία. "; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.strings index 034d33449..caa5f4d9f 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "يُرجى المُحاولة مرة أُخرى لاحقًا."; "Common.Alerts.DeletePost.Message" = "هَل أنتَ مُتأكِدٌ مِن رَغبتِكَ فِي حَذفِ هَذَا المَنشُور؟"; "Common.Alerts.DeletePost.Title" = "هل أنت متأكد من رغبتك في حذف هذا المنشور؟"; -"Common.Alerts.DiscardPostContent.Message" = "أكِّد للتخلص مِن مُحتوى مَنشور مؤلَّف."; -"Common.Alerts.DiscardPostContent.Title" = "التخلص من المسودة"; "Common.Alerts.EditProfileFailure.Message" = "يتعذَّر تعديل الملف التعريفي. يُرجى المُحاولة مرة أُخرى."; "Common.Alerts.EditProfileFailure.Title" = "خطأ في تَحرير الملف التعريفي"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "لا يُمكِنُ إرفاق أكثر مِن مَقطع مرئي واحِد."; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/be.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/be.lproj/Localizable.strings index 01b3aff93..4d8f7d218 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/be.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/be.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "Паўтарыце спробу пазней."; "Common.Alerts.DeletePost.Message" = "Вы ўпэўненыя, што хочаце выдаліць гэты допіс?"; "Common.Alerts.DeletePost.Title" = "Выдаліць допіс"; -"Common.Alerts.DiscardPostContent.Message" = "Пацвердзіце, каб скасаваць змесціва допісу."; -"Common.Alerts.DiscardPostContent.Title" = "Скасаваць чарнавік"; "Common.Alerts.EditProfileFailure.Message" = "Не атрымалася змяніць профіль. Паспрабуйце яшчэ раз."; "Common.Alerts.EditProfileFailure.Title" = "Памылка пры рэдагаванні профілю"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "Немагчыма дадаць больш за адно відэа."; @@ -30,7 +28,7 @@ "Common.Controls.Actions.Add" = "Дадаць"; "Common.Controls.Actions.Back" = "Назад"; "Common.Controls.Actions.BlockDomain" = "Заблакіраваць %@"; -"Common.Controls.Actions.Bookmark" = "Bookmark"; +"Common.Controls.Actions.Bookmark" = "Закладка"; "Common.Controls.Actions.Cancel" = "Скасаваць"; "Common.Controls.Actions.Compose" = "Стварыць"; "Common.Controls.Actions.Confirm" = "Пацвердзіць"; @@ -43,7 +41,7 @@ "Common.Controls.Actions.Edit" = "Рэдагаваць"; "Common.Controls.Actions.EditPost" = "Рэдагаваць"; "Common.Controls.Actions.FindPeople" = "Знайсці людзей, каб падпісацца"; -"Common.Controls.Actions.Follow" = "Follow %@"; +"Common.Controls.Actions.Follow" = "Падпісацца на %@"; "Common.Controls.Actions.ManuallySearch" = "Замест гэтага шукайце ўручную"; "Common.Controls.Actions.Next" = "Далей"; "Common.Controls.Actions.Ok" = "OK"; @@ -53,7 +51,7 @@ "Common.Controls.Actions.Preview" = "Перадпрагляд"; "Common.Controls.Actions.Previous" = "Назад"; "Common.Controls.Actions.Remove" = "Выдаліць"; -"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; +"Common.Controls.Actions.RemoveBookmark" = "Выдаліць закладку"; "Common.Controls.Actions.Reply" = "Адказаць"; "Common.Controls.Actions.ReportUser" = "Паскардзіцца на %@"; "Common.Controls.Actions.Save" = "Захаваць"; @@ -70,7 +68,7 @@ "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Невядомая"; "Common.Controls.Actions.TryAgain" = "Паўтарыце спробу"; "Common.Controls.Actions.UnblockDomain" = "Разблакіраваць %@"; -"Common.Controls.Actions.Unfollow" = "Unfollow %@"; +"Common.Controls.Actions.Unfollow" = "Адпісацца ад %@"; "Common.Controls.Friendship.Block" = "Заблакіраваць"; "Common.Controls.Friendship.BlockDomain" = "Заблакіраваць %@"; "Common.Controls.Friendship.BlockUser" = "Заблакіраваць %@"; @@ -185,8 +183,8 @@ "Common.Controls.Timeline.Loader.LoadingMissingPosts" = "Загрузка адсутных допісаў..."; "Common.Controls.Timeline.Loader.ShowMoreReplies" = "Паказаць больш адказаў"; "Common.Controls.Timeline.Timestamp.Now" = "Толькі што"; -"Common.UserList.FollowersCount" = "%@ followers"; -"Common.UserList.NoVerifiedLink" = "No verified link"; +"Common.UserList.FollowersCount" = "%@ падпісчыкаў"; +"Common.UserList.NoVerifiedLink" = "Няма спраўджанай спасылкі"; "Extension.OpenIn.InvalidLinkError" = "Здаецца, гэта несапраўдная спасылка на Mastodon."; "Scene.AccountList.AddAccount" = "Дадаць уліковы запіс"; "Scene.AccountList.DismissAccountSwitcher" = "Закрыць пераключальнік уліковых запісаў"; @@ -521,8 +519,8 @@ "Scene.Settings.Section.SpicyZone.Signout" = "Выйсці"; "Scene.Settings.Section.SpicyZone.Title" = "Вострая зона"; "Scene.Settings.Title" = "Налады"; -"Scene.SuggestionAccount.FollowAll" = "Follow all"; -"Scene.SuggestionAccount.Title" = "Popular on Mastodon"; +"Scene.SuggestionAccount.FollowAll" = "Падпісацца на ўсіх"; +"Scene.SuggestionAccount.Title" = "Папулярна ў Mastodon"; "Scene.Thread.BackTitle" = "Допіс"; "Scene.Thread.Title" = "Допіс ад %@"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "Што такое Mastodon?"; @@ -530,10 +528,10 @@ "Scene.Welcome.Education.Mastodon.Title" = "Вітаем у Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Кожны акаўнт Mastodon размяшчаецца на серверы - кожны са сваімі каштоўнасцямі, правіламі і адміністратарамі. Незалежна ад таго, які сервер вы вылучыце, вы можаце сачыць і ўзаемадзейнічаць з людзьмі на любым серверы."; "Scene.Welcome.Education.Servers.Title" = "Што такое серверы?"; -"Scene.Welcome.JoinDefaultServer" = "Join %@"; +"Scene.Welcome.JoinDefaultServer" = "Далучыцца да %@"; "Scene.Welcome.LearnMore" = "Даведацца больш"; "Scene.Welcome.LogIn" = "Увайсці"; -"Scene.Welcome.PickServer" = "Pick another server"; +"Scene.Welcome.PickServer" = "Выбраць іншы сервер"; "Scene.Welcome.Separator.Or" = "або"; "Widget.Common.UnsupportedWidgetFamily" = "Выбачайце, але гэта сямейства віджэтаў не падтрымліваецца."; "Widget.Common.UserNotLoggedIn" = "Калі ласка, адкрыйце Mastodon, каб увайсці ў уліковы запіс."; @@ -541,14 +539,14 @@ "Widget.FollowersCount.ConfigurationDisplayName" = "Падпісчыкі"; "Widget.FollowersCount.FollowersToday" = "%@ падпісчыкаў сёння"; "Widget.FollowersCount.Title" = "ПАДПІСЧЫКІ"; -"Widget.Hashtag.Configuration.Description" = "Shows a recent post with the selected hashtag."; -"Widget.Hashtag.Configuration.DisplayName" = "Hashtag"; +"Widget.Hashtag.Configuration.Description" = "Паказвае нядаўні допіс з выбраным хэштэгам."; +"Widget.Hashtag.Configuration.DisplayName" = "Хэштэг"; "Widget.Hashtag.NotFound.Account" = "@johnMastodon@no-such.account"; -"Widget.Hashtag.NotFound.AccountName" = "John Mastodon"; -"Widget.Hashtag.NotFound.Content" = "Sorry, we couldn’t find any posts with the hashtag #%@. Please try a #DifferentHashtag or check the widget settings."; +"Widget.Hashtag.NotFound.AccountName" = "Джон Мастадон"; +"Widget.Hashtag.NotFound.Content" = "На жаль, мы не змаглі знайсці допісы з хэштэгам #%@. Калі ласка, паспрабуйце #ІншыХэштэг або праверце налады віджэта."; "Widget.Hashtag.Placeholder.Account" = "@johnMastodon@no-such.account"; -"Widget.Hashtag.Placeholder.AccountName" = "John Mastodon"; -"Widget.Hashtag.Placeholder.Content" = "This is how a post with a #hashtag would look. Pick whichever #hashtag you want in the widget settings."; +"Widget.Hashtag.Placeholder.AccountName" = "Джон Мастадон"; +"Widget.Hashtag.Placeholder.Content" = "Вось як будзе выглядаць допіс з #хэштэгам. Выберыце любы #хэштэг у наладах віджэта."; "Widget.LatestFollowers.ConfigurationDescription" = "Паказаць апошніх падпісчыкаў."; "Widget.LatestFollowers.ConfigurationDisplayName" = "Апошнія падпісчыкі"; "Widget.LatestFollowers.LastUpdate" = "Апошняе абнаўленне: %@"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.strings index 82e9094a5..4c93afc67 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "Prova-ho més tard."; "Common.Alerts.DeletePost.Message" = "Segur que vols eliminar aquesta publicació?"; "Common.Alerts.DeletePost.Title" = "Eliminar la publicació"; -"Common.Alerts.DiscardPostContent.Message" = "Confirma per a descartar el contingut del tut."; -"Common.Alerts.DiscardPostContent.Title" = "Descarta l'esborrany"; "Common.Alerts.EditProfileFailure.Message" = "No es pot editar el perfil. Torna-ho a provar."; "Common.Alerts.EditProfileFailure.Title" = "Error en editar el perfil"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "No es pot adjuntar més d'un vídeo."; @@ -531,7 +529,7 @@ Elegiremos un servidor basado en su idioma si continúa sin hacer una selección "Scene.Welcome.Education.Mastodon.Title" = "Benvingut a Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Cada compte a Mastodon esta allotjat en un servidor, cadascún d'ells amb els seus propis valors, normes i administradors. Tant és quin trïis, podràs seguir i interactuar amb gent de qualsevol servidor."; "Scene.Welcome.Education.Servers.Title" = "Què son els servidors?"; -"Scene.Welcome.JoinDefaultServer" = "Join %@"; +"Scene.Welcome.JoinDefaultServer" = "Uneix-te a %@"; "Scene.Welcome.LearnMore" = "Més informació"; "Scene.Welcome.LogIn" = "Inicia sessió"; "Scene.Welcome.PickServer" = "Tria un altre servidor"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings index 917af2eaf..d7d009c0a 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "تکایە دواتر هەوڵ بدەوە."; "Common.Alerts.DeletePost.Message" = "دڵنیایت دەتەوێت ئەم پۆستە بسڕیتەوە؟"; "Common.Alerts.DeletePost.Title" = "بیسڕەوە"; -"Common.Alerts.DiscardPostContent.Message" = "دڵنیا ببەوە بۆ وازهێنان لە ناوەڕۆکەت."; -"Common.Alerts.DiscardPostContent.Title" = "ڕەشنووس هەڵمەگرە"; "Common.Alerts.EditProfileFailure.Message" = "ناتوانرێت دەستکاریی پرۆفایل بکرێت. تکایە دووبارە هەوڵ بدەوە."; "Common.Alerts.EditProfileFailure.Title" = "نەتوانرا دەستکاریی پرۆفایل بکرێت"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "ناتوانیت زیاتر لە یەک ڤیدیۆی پێوە بلکێنیت."; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/cs.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/cs.lproj/Localizable.strings index 0d2573b10..136c4f9e4 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/cs.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/cs.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "Zkuste to prosím znovu později."; "Common.Alerts.DeletePost.Message" = "Opravdu chcete smazat tento příspěvek?"; "Common.Alerts.DeletePost.Title" = "Odstranit příspěvek"; -"Common.Alerts.DiscardPostContent.Message" = "Potvrďte odstranění obsahu složeného příspěvku."; -"Common.Alerts.DiscardPostContent.Title" = "Zahodit koncept"; "Common.Alerts.EditProfileFailure.Message" = "Nelze upravit profil. Zkuste to prosím znovu."; "Common.Alerts.EditProfileFailure.Title" = "Chyba při úpravě profilu"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "Nelze připojit více než jedno video."; @@ -526,7 +524,7 @@ nahrán do Mastodonu."; "Scene.Welcome.Education.Mastodon.Title" = "Welcome to Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Every Mastodon account is hosted on a server — each with its own values, rules, & admins. No matter which one you pick, you can follow and interact with people on any server."; "Scene.Welcome.Education.Servers.Title" = "What are servers?"; -"Scene.Welcome.JoinDefaultServer" = "Join %@"; +"Scene.Welcome.JoinDefaultServer" = "Připojit se k %@"; "Scene.Welcome.LearnMore" = "Zjistit více"; "Scene.Welcome.LogIn" = "Přihlásit se"; "Scene.Welcome.PickServer" = "Pick another server"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.strings index 9e50133c2..8013f1b61 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "Bitte versuche es später nochmal."; "Common.Alerts.DeletePost.Message" = "Bist du dir sicher, dass du diesen Beitrag löschen willst?"; "Common.Alerts.DeletePost.Title" = "Beiträge löschen"; -"Common.Alerts.DiscardPostContent.Message" = "Bestätige, um den Beitrag zu verwerfen."; -"Common.Alerts.DiscardPostContent.Title" = "Entwurf verwerfen"; "Common.Alerts.EditProfileFailure.Message" = "Profil kann nicht bearbeitet werden. Bitte versuche es erneut."; "Common.Alerts.EditProfileFailure.Title" = "Fehler beim Bearbeiten des Profils"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "Es kann nicht mehr als ein Video angehängt werden."; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/el.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/el.lproj/Localizable.strings index 8e39b214e..f46391a81 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/el.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/el.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "Παρακαλώ δοκίμασε ξανά αργότερα."; "Common.Alerts.DeletePost.Message" = "Είσαι βέβαιος ότι θες να διαγράψεις την ανάρτηση;"; "Common.Alerts.DeletePost.Title" = "Διαγραφή Ανάρτησης"; -"Common.Alerts.DiscardPostContent.Message" = "Επιβεβαίωση για απόρριψη του περιεχομένου της ανάρτησης."; -"Common.Alerts.DiscardPostContent.Title" = "Απόρριψη Προχείρου"; "Common.Alerts.EditProfileFailure.Message" = "Αδυναμία επεξεργασίας προφίλ. Παρακαλώ δοκίμασε ξανά."; "Common.Alerts.EditProfileFailure.Title" = "Σφάλμα Επεξεργασίας Προφίλ"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "Δεν γίνεται να επισυνάψεις περισσότερα από 1 βίντεο."; @@ -168,392 +166,392 @@ "Common.Controls.Tabs.Profile" = "Προφίλ"; "Common.Controls.Tabs.SearchAndExplore" = "Αναζήτηση και Εξερεύνηση"; "Common.Controls.Timeline.Filtered" = "Φιλτραρισμένα"; -"Common.Controls.Timeline.Header.BlockedWarning" = "You can’t view this user’s profile -until they unblock you."; +"Common.Controls.Timeline.Header.BlockedWarning" = "Δεν μπορείς να δεις το προφίλ αυτού του χρήστη +μέχρι να σε ξεμπλοκάρει."; "Common.Controls.Timeline.Header.BlockingWarning" = "Δεν μπορείς να δεις το προφίλ αυτού του χρήστη μέχρι να τον ξεμπλοκάρεις. Το προφίλ σου μοιάζει έτσι και σε αυτόν."; "Common.Controls.Timeline.Header.NoStatusFound" = "Δεν Βρέθηκε Ανάρτηση"; -"Common.Controls.Timeline.Header.SuspendedWarning" = "This user has been suspended."; -"Common.Controls.Timeline.Header.UserBlockedWarning" = "You can’t view %@’s profile -until they unblock you."; -"Common.Controls.Timeline.Header.UserBlockingWarning" = "You can’t view %@’s profile -until you unblock them. -Your profile looks like this to them."; -"Common.Controls.Timeline.Header.UserSuspendedWarning" = "%@’s account has been suspended."; +"Common.Controls.Timeline.Header.SuspendedWarning" = "Αυτός ο χρήστης έχει ανασταλεί."; +"Common.Controls.Timeline.Header.UserBlockedWarning" = "Δεν μπορείς να δεις το προφίλ %@ +μέχρι να σε ξεμπλοκάρουν."; +"Common.Controls.Timeline.Header.UserBlockingWarning" = "Δεν μπορείς να δεις το προφίλ του %@ +μέχρι να τον ξεμπλοκάρεις. +Το προφίλ σου μοιάζει έτσι κι σ' αυτούς."; +"Common.Controls.Timeline.Header.UserSuspendedWarning" = "Ο λογαριασμός του %@ έχει ανασταλεί."; "Common.Controls.Timeline.Loader.LoadMissingPosts" = "Φόρτωση αναρτήσεων που λείπουν"; "Common.Controls.Timeline.Loader.LoadingMissingPosts" = "Φόρτωση αναρτήσεων που λείπουν..."; "Common.Controls.Timeline.Loader.ShowMoreReplies" = "Εμφάνιση περισσότερων απαντήσεων"; "Common.Controls.Timeline.Timestamp.Now" = "Τώρα"; -"Common.UserList.FollowersCount" = "%@ followers"; -"Common.UserList.NoVerifiedLink" = "No verified link"; -"Extension.OpenIn.InvalidLinkError" = "This doesn't seem to be a valid Mastodon link."; -"Scene.AccountList.AddAccount" = "Add Account"; -"Scene.AccountList.DismissAccountSwitcher" = "Dismiss Account Switcher"; -"Scene.AccountList.TabBarHint" = "Current selected profile: %@. Double tap then hold to show account switcher"; -"Scene.Bookmark.Title" = "Bookmarks"; -"Scene.Compose.Accessibility.AppendAttachment" = "Add Attachment"; -"Scene.Compose.Accessibility.AppendPoll" = "Add Poll"; -"Scene.Compose.Accessibility.CustomEmojiPicker" = "Custom Emoji Picker"; -"Scene.Compose.Accessibility.DisableContentWarning" = "Disable Content Warning"; -"Scene.Compose.Accessibility.EnableContentWarning" = "Enable Content Warning"; -"Scene.Compose.Accessibility.PostOptions" = "Post Options"; -"Scene.Compose.Accessibility.PostVisibilityMenu" = "Post Visibility Menu"; -"Scene.Compose.Accessibility.PostingAs" = "Posting as %@"; -"Scene.Compose.Accessibility.RemovePoll" = "Remove Poll"; -"Scene.Compose.Attachment.AttachmentBroken" = "This %@ is broken and can’t be -uploaded to Mastodon."; -"Scene.Compose.Attachment.AttachmentTooLarge" = "Attachment too large"; -"Scene.Compose.Attachment.CanNotRecognizeThisMediaAttachment" = "Can not recognize this media attachment"; -"Scene.Compose.Attachment.CompressingState" = "Compressing..."; -"Scene.Compose.Attachment.DescriptionPhoto" = "Describe the photo for the visually-impaired..."; -"Scene.Compose.Attachment.DescriptionVideo" = "Describe the video for the visually-impaired..."; -"Scene.Compose.Attachment.LoadFailed" = "Load Failed"; -"Scene.Compose.Attachment.Photo" = "photo"; -"Scene.Compose.Attachment.ServerProcessingState" = "Server Processing..."; -"Scene.Compose.Attachment.UploadFailed" = "Upload Failed"; -"Scene.Compose.Attachment.Video" = "video"; -"Scene.Compose.AutoComplete.SpaceToAdd" = "Space to add"; -"Scene.Compose.ComposeAction" = "Publish"; -"Scene.Compose.ContentInputPlaceholder" = "Type or paste what’s on your mind"; -"Scene.Compose.ContentWarning.Placeholder" = "Write an accurate warning here..."; -"Scene.Compose.Keyboard.AppendAttachmentEntry" = "Add Attachment - %@"; -"Scene.Compose.Keyboard.DiscardPost" = "Discard Post"; -"Scene.Compose.Keyboard.PublishPost" = "Publish Post"; -"Scene.Compose.Keyboard.SelectVisibilityEntry" = "Select Visibility - %@"; -"Scene.Compose.Keyboard.ToggleContentWarning" = "Toggle Content Warning"; -"Scene.Compose.Keyboard.TogglePoll" = "Toggle Poll"; -"Scene.Compose.Language.Other" = "Other Language…"; -"Scene.Compose.Language.Recent" = "Recent"; -"Scene.Compose.Language.Suggested" = "Suggested"; -"Scene.Compose.Language.Title" = "Post Language"; -"Scene.Compose.MediaSelection.Browse" = "Browse"; -"Scene.Compose.MediaSelection.Camera" = "Take Photo"; -"Scene.Compose.MediaSelection.PhotoLibrary" = "Photo Library"; -"Scene.Compose.Poll.AddOption" = "Add Option"; -"Scene.Compose.Poll.DurationTime" = "Duration: %@"; -"Scene.Compose.Poll.MoveDown" = "Move Down"; -"Scene.Compose.Poll.MoveUp" = "Move Up"; -"Scene.Compose.Poll.OneDay" = "1 Day"; -"Scene.Compose.Poll.OneHour" = "1 Hour"; -"Scene.Compose.Poll.OptionNumber" = "Option %ld"; -"Scene.Compose.Poll.RemoveOption" = "Remove Option"; -"Scene.Compose.Poll.SevenDays" = "7 Days"; -"Scene.Compose.Poll.SixHours" = "6 Hours"; -"Scene.Compose.Poll.ThePollHasEmptyOption" = "The poll has empty option"; -"Scene.Compose.Poll.ThePollIsInvalid" = "The poll is invalid"; -"Scene.Compose.Poll.ThirtyMinutes" = "30 minutes"; -"Scene.Compose.Poll.ThreeDays" = "3 Days"; -"Scene.Compose.Poll.Title" = "Poll"; -"Scene.Compose.ReplyingToUser" = "replying to %@"; -"Scene.Compose.Title.EditPost" = "Edit Post"; -"Scene.Compose.Title.NewPost" = "New Post"; -"Scene.Compose.Title.NewReply" = "New Reply"; -"Scene.Compose.Visibility.Direct" = "Only people I mention"; -"Scene.Compose.Visibility.Private" = "Followers only"; -"Scene.Compose.Visibility.Public" = "Public"; -"Scene.Compose.Visibility.Unlisted" = "Unlisted"; -"Scene.ConfirmEmail.Button.Resend" = "Resend"; -"Scene.ConfirmEmail.DidntGetLink.Prefix" = "Didn’t get a link?"; -"Scene.ConfirmEmail.DidntGetLink.ResendIn" = "Resend (%@)"; -"Scene.ConfirmEmail.DidntGetLink.ResendNow" = "Resend now."; -"Scene.ConfirmEmail.DontReceiveEmail.Description" = "Check if your email address is correct as well as your junk folder if you haven’t."; -"Scene.ConfirmEmail.DontReceiveEmail.ResendEmail" = "Resend Email"; -"Scene.ConfirmEmail.DontReceiveEmail.Title" = "Check your Email"; -"Scene.ConfirmEmail.OpenEmailApp.Description" = "We just sent you an email. Check your junk folder if you haven’t."; +"Common.UserList.FollowersCount" = "%@ ακόλουθοι"; +"Common.UserList.NoVerifiedLink" = "Χωρίς επαληθευμένο σύνδεσμο"; +"Extension.OpenIn.InvalidLinkError" = "Αυτό δεν φαίνεται να είναι ένας έγκυρος σύνδεσμος Mastodon."; +"Scene.AccountList.AddAccount" = "Προσθήκη Λογαριασμού"; +"Scene.AccountList.DismissAccountSwitcher" = "Απόρριψη Εναλλαγής Λογαριασμού"; +"Scene.AccountList.TabBarHint" = "Τρέχον επιλεγμένο προφίλ: %@. Πάτα δύο φορές και κράτησε πατημένο για να εμφανίσεις την εναλλαγή λογαριασμού"; +"Scene.Bookmark.Title" = "Σελιδοδείκτες"; +"Scene.Compose.Accessibility.AppendAttachment" = "Προσθήκη Συνημμένου"; +"Scene.Compose.Accessibility.AppendPoll" = "Προσθήκη Δημοσκ."; +"Scene.Compose.Accessibility.CustomEmojiPicker" = "Προσαρμοσμένος Επιλογέας Emoji"; +"Scene.Compose.Accessibility.DisableContentWarning" = "Απενεργοποίηση Προειδοποίησης Περιεχομένου"; +"Scene.Compose.Accessibility.EnableContentWarning" = "Ενεργοποίηση Προειδοποίησης Περιεχομένου"; +"Scene.Compose.Accessibility.PostOptions" = "Επιλογές Ανάρτησης"; +"Scene.Compose.Accessibility.PostVisibilityMenu" = "Μενού Ορατότητας Ανάρτησης"; +"Scene.Compose.Accessibility.PostingAs" = "Ανάρτηση ως %@"; +"Scene.Compose.Accessibility.RemovePoll" = "Αφαίρεση Δημοσκόπησης"; +"Scene.Compose.Attachment.AttachmentBroken" = "Το %@ έχει χαλάσει και δεν μπορεί να +φορτωθεί στο Mastodon."; +"Scene.Compose.Attachment.AttachmentTooLarge" = "Υπερβολικά μεγάλο συνημμένο"; +"Scene.Compose.Attachment.CanNotRecognizeThisMediaAttachment" = "Αυτό το συνημμένο πολυμέσων δεν μπορεί να αναγνωριστεί"; +"Scene.Compose.Attachment.CompressingState" = "Συμπίεση..."; +"Scene.Compose.Attachment.DescriptionPhoto" = "Περιέγραψε τη φωτογραφία για τα άτομα με προβλήματα όρασης..."; +"Scene.Compose.Attachment.DescriptionVideo" = "Περιέγραψε το βίντεο για τα άτομα με προβλήματα όρασης..."; +"Scene.Compose.Attachment.LoadFailed" = "Αποτυχία Φόρτωσης"; +"Scene.Compose.Attachment.Photo" = "φωτογραφία"; +"Scene.Compose.Attachment.ServerProcessingState" = "Επεξεργασία Διακομιστή..."; +"Scene.Compose.Attachment.UploadFailed" = "Η Μεταφόρτωση Απέτυχε"; +"Scene.Compose.Attachment.Video" = "βίντεο"; +"Scene.Compose.AutoComplete.SpaceToAdd" = ""Διάστημα" για προσθήκη"; +"Scene.Compose.ComposeAction" = "Δημοσίευση"; +"Scene.Compose.ContentInputPlaceholder" = "Πληκτρολόγησε ή επικόλλησε τί έχεις στο μυαλό σου"; +"Scene.Compose.ContentWarning.Placeholder" = "Γράψε εδώ μια ακριβή προειδοποίηση..."; +"Scene.Compose.Keyboard.AppendAttachmentEntry" = "Προσθήκη Συνημμένου - %@"; +"Scene.Compose.Keyboard.DiscardPost" = "Απόρριψη Ανάρτησης"; +"Scene.Compose.Keyboard.PublishPost" = "Δημοσίευση Ανάρτησης"; +"Scene.Compose.Keyboard.SelectVisibilityEntry" = "Επιλογή ορατότητας - %@"; +"Scene.Compose.Keyboard.ToggleContentWarning" = "Εναλλαγή Προειδοποίησης Περιεχομένου"; +"Scene.Compose.Keyboard.TogglePoll" = "Εναλλαγή Δημοσκόπησης"; +"Scene.Compose.Language.Other" = "Άλλη γλώσσα…"; +"Scene.Compose.Language.Recent" = "Πρόσφατα"; +"Scene.Compose.Language.Suggested" = "Προτεινόμενες"; +"Scene.Compose.Language.Title" = "Γλώσσα Ανάρτησης"; +"Scene.Compose.MediaSelection.Browse" = "Περιήγηση"; +"Scene.Compose.MediaSelection.Camera" = "Λήψη Φωτογραφίας"; +"Scene.Compose.MediaSelection.PhotoLibrary" = "Βιβλιοθήκη Φωτογραφιών"; +"Scene.Compose.Poll.AddOption" = "Προσθήκη Επιλογής"; +"Scene.Compose.Poll.DurationTime" = "Διάρκεια: %@"; +"Scene.Compose.Poll.MoveDown" = "Μετακίνηση Κάτω"; +"Scene.Compose.Poll.MoveUp" = "Μετακίνηση Πάνω"; +"Scene.Compose.Poll.OneDay" = "1 Ημέρα"; +"Scene.Compose.Poll.OneHour" = "1 Ώρα"; +"Scene.Compose.Poll.OptionNumber" = "Επιλογή %ld"; +"Scene.Compose.Poll.RemoveOption" = "Αφαίρεση Επιλογής"; +"Scene.Compose.Poll.SevenDays" = "7 Ημέρες"; +"Scene.Compose.Poll.SixHours" = "6 Ώρες"; +"Scene.Compose.Poll.ThePollHasEmptyOption" = "Η δημοσκόπηση έχει κενή επιλογή"; +"Scene.Compose.Poll.ThePollIsInvalid" = "Η δημοσκόπηση δεν είναι έγκυρη"; +"Scene.Compose.Poll.ThirtyMinutes" = "30 λεπτά"; +"Scene.Compose.Poll.ThreeDays" = "3 Ημέρες"; +"Scene.Compose.Poll.Title" = "Δημοσκόπηση"; +"Scene.Compose.ReplyingToUser" = "απάντηση σε %@"; +"Scene.Compose.Title.EditPost" = "Επεξεργασία Ανάρτησης"; +"Scene.Compose.Title.NewPost" = "Νέα Ανάρτηση"; +"Scene.Compose.Title.NewReply" = "Νέα Απάντηση"; +"Scene.Compose.Visibility.Direct" = "Μόνο άτομα που επισημαίνω"; +"Scene.Compose.Visibility.Private" = "Μόνο ακόλουθοι"; +"Scene.Compose.Visibility.Public" = "Δημόσιο"; +"Scene.Compose.Visibility.Unlisted" = "Μη καταχωρημένο"; +"Scene.ConfirmEmail.Button.Resend" = "Επαναποστολή"; +"Scene.ConfirmEmail.DidntGetLink.Prefix" = "Δεν έλαβες τον σύνδεσμο;"; +"Scene.ConfirmEmail.DidntGetLink.ResendIn" = "Επαναποστολή (%@)"; +"Scene.ConfirmEmail.DidntGetLink.ResendNow" = "Επαναποστολή τώρα."; +"Scene.ConfirmEmail.DontReceiveEmail.Description" = "Έλεγξε αν η διεύθυνση email σου είναι σωστή καθώς και τον φάκελο ανεπιθύμητης αλληλογραφίας σας αν δεν το έχεις κάνει ήδη."; +"Scene.ConfirmEmail.DontReceiveEmail.ResendEmail" = "Επαναποστολή Email"; +"Scene.ConfirmEmail.DontReceiveEmail.Title" = "Έλεγξε το Email σου"; +"Scene.ConfirmEmail.OpenEmailApp.Description" = "Μόλις σου στείλαμε ένα email. Έλεγξε το φάκελο ανεπιθύμητης αλληλογραφίας αν δεν το έχεις κάνει ήδη."; "Scene.ConfirmEmail.OpenEmailApp.Mail" = "Mail"; -"Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "Open Email Client"; -"Scene.ConfirmEmail.OpenEmailApp.Title" = "Check your Inbox."; -"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Tap the link we sent you to verify %@. We’ll wait right here."; -"Scene.ConfirmEmail.Title" = "Check Your Inbox"; -"Scene.Discovery.Intro" = "These are the posts gaining traction in your corner of Mastodon."; -"Scene.Discovery.Tabs.Community" = "Community"; -"Scene.Discovery.Tabs.ForYou" = "For You"; -"Scene.Discovery.Tabs.Hashtags" = "Hashtags"; -"Scene.Discovery.Tabs.News" = "News"; -"Scene.Discovery.Tabs.Posts" = "Posts"; -"Scene.Familiarfollowers.FollowedByNames" = "Followed by %@"; -"Scene.Familiarfollowers.Title" = "Followers you familiar"; -"Scene.Favorite.Title" = "Favorites"; -"Scene.FavoritedBy.Title" = "Favorited By"; -"Scene.FollowedTags.Actions.Follow" = "Follow"; -"Scene.FollowedTags.Actions.Unfollow" = "Unfollow"; -"Scene.FollowedTags.Header.Participants" = "participants"; -"Scene.FollowedTags.Header.Posts" = "posts"; -"Scene.FollowedTags.Header.PostsToday" = "posts today"; -"Scene.FollowedTags.Title" = "Followed Tags"; -"Scene.Follower.Footer" = "Followers from other servers are not displayed."; -"Scene.Follower.Title" = "follower"; -"Scene.Following.Footer" = "Follows from other servers are not displayed."; -"Scene.Following.Title" = "following"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; +"Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "Άνοιγμα Πελάτη Email"; +"Scene.ConfirmEmail.OpenEmailApp.Title" = "Έλεγξε τα Εισερχόμενα σου."; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Πάτησε το σύνδεσμο που σού στείλαμε για να επαληθεύσεις το %@. Θα σε περιμένουμε εδώ."; +"Scene.ConfirmEmail.Title" = "Έλεγξε τα Εισερχόμενα σου"; +"Scene.Discovery.Intro" = "Αυτές είναι οι αναρτήσεις που κερδίζουν την προσοχή στη δική σου γωνιά του Mastodon."; +"Scene.Discovery.Tabs.Community" = "Κοινότητα"; +"Scene.Discovery.Tabs.ForYou" = "Για Σένα"; +"Scene.Discovery.Tabs.Hashtags" = "Ετικέτες"; +"Scene.Discovery.Tabs.News" = "Ειδήσεις"; +"Scene.Discovery.Tabs.Posts" = "Αναρτήσεις"; +"Scene.Familiarfollowers.FollowedByNames" = "Ακολουθείται από %@"; +"Scene.Familiarfollowers.Title" = "Ακόλουθοι που γνωρίζεις"; +"Scene.Favorite.Title" = "Αγαπημένα"; +"Scene.FavoritedBy.Title" = "Αγαπημένο Από"; +"Scene.FollowedTags.Actions.Follow" = "Ακολούθησε"; +"Scene.FollowedTags.Actions.Unfollow" = "Άρση ακολούθησης"; +"Scene.FollowedTags.Header.Participants" = "συμμετέχοντες"; +"Scene.FollowedTags.Header.Posts" = "αναρτήσεις"; +"Scene.FollowedTags.Header.PostsToday" = "αναρτήσεις σήμερα"; +"Scene.FollowedTags.Title" = "Ακολουθούμενες Ετικέτες"; +"Scene.Follower.Footer" = "Οι ακόλουθοι από άλλους διακομιστές δεν εμφανίζονται."; +"Scene.Follower.Title" = "ακόλουθος"; +"Scene.Following.Footer" = "Δεν εμφανίζονται ακολουθήσεις από άλλους διακομιστές."; +"Scene.Following.Title" = "ακολουθεί"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Πάτα για κύλιση στην κορυφή και πάτα ξανά για προηγούμενη τοποθεσία"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon"; -"Scene.HomeTimeline.NavigationBarState.NewPosts" = "See new posts"; -"Scene.HomeTimeline.NavigationBarState.Offline" = "Offline"; -"Scene.HomeTimeline.NavigationBarState.Published" = "Published!"; -"Scene.HomeTimeline.NavigationBarState.Publishing" = "Publishing post..."; -"Scene.HomeTimeline.Title" = "Home"; -"Scene.Login.ServerSearchField.Placeholder" = "Enter URL or search for your server"; -"Scene.Login.Subtitle" = "Log you in on the server you created your account on."; -"Scene.Login.Title" = "Welcome back"; -"Scene.Notification.FollowRequest.Accept" = "Accept"; -"Scene.Notification.FollowRequest.Accepted" = "Accepted"; -"Scene.Notification.FollowRequest.Reject" = "reject"; -"Scene.Notification.FollowRequest.Rejected" = "Rejected"; -"Scene.Notification.Keyobard.ShowEverything" = "Show Everything"; -"Scene.Notification.Keyobard.ShowMentions" = "Show Mentions"; -"Scene.Notification.NotificationDescription.FavoritedYourPost" = "favorited your post"; -"Scene.Notification.NotificationDescription.FollowedYou" = "followed you"; -"Scene.Notification.NotificationDescription.MentionedYou" = "mentioned you"; -"Scene.Notification.NotificationDescription.PollHasEnded" = "poll has ended"; -"Scene.Notification.NotificationDescription.RebloggedYourPost" = "reblogged your post"; -"Scene.Notification.NotificationDescription.RequestToFollowYou" = "request to follow you"; -"Scene.Notification.Title.Everything" = "Everything"; -"Scene.Notification.Title.Mentions" = "Mentions"; -"Scene.Preview.Keyboard.ClosePreview" = "Close Preview"; -"Scene.Preview.Keyboard.ShowNext" = "Show Next"; -"Scene.Preview.Keyboard.ShowPrevious" = "Show Previous"; -"Scene.Privacy.Button.Confirm" = "I Agree"; -"Scene.Privacy.Description" = "Although the Mastodon app does not collect any data, the server you sign up through may have a different policy. Take a minute to review and agree to the Mastodon app privacy policy and your server’s privacy policy."; -"Scene.Privacy.Policy.Ios" = "Privacy Policy - Mastodon for iOS"; -"Scene.Privacy.Policy.Server" = "Privacy Policy - %@"; -"Scene.Privacy.Title" = "Privacy"; -"Scene.Profile.Accessibility.DoubleTapToOpenTheList" = "Double tap to open the list"; -"Scene.Profile.Accessibility.EditAvatarImage" = "Edit avatar image"; -"Scene.Profile.Accessibility.ShowAvatarImage" = "Show avatar image"; -"Scene.Profile.Accessibility.ShowBannerImage" = "Show banner image"; -"Scene.Profile.Dashboard.FamiliarFollowers" = "mutuals"; -"Scene.Profile.Dashboard.MyFollowers" = "followers"; -"Scene.Profile.Dashboard.MyFollowing" = "following"; -"Scene.Profile.Dashboard.MyPosts" = "posts"; -"Scene.Profile.Dashboard.OtherFollowers" = "followers"; -"Scene.Profile.Dashboard.OtherFollowing" = "following"; -"Scene.Profile.Dashboard.OtherPosts" = "posts"; -"Scene.Profile.Fields.AddRow" = "Add Row"; -"Scene.Profile.Fields.Joined" = "Joined"; -"Scene.Profile.Fields.Placeholder.Content" = "Content"; -"Scene.Profile.Fields.Placeholder.Label" = "Label"; -"Scene.Profile.Fields.Verified.Long" = "Ownership of this link was checked on %@"; -"Scene.Profile.Fields.Verified.Short" = "Verified on %@"; -"Scene.Profile.Header.FollowsYou" = "Follows You"; -"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Confirm to block %@"; -"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Block Account"; -"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Message" = "Confirm to hide reblogs"; -"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Title" = "Hide Reblogs"; -"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Confirm to mute %@"; -"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Title" = "Mute Account"; -"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Message" = "Confirm to show reblogs"; -"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Title" = "Show Reblogs"; -"Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Message" = "Confirm to unblock %@"; -"Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Title" = "Unblock Account"; -"Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.Message" = "Confirm to unmute %@"; -"Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.Title" = "Unmute Account"; -"Scene.Profile.SegmentedControl.About" = "About"; -"Scene.Profile.SegmentedControl.Media" = "Media"; -"Scene.Profile.SegmentedControl.Posts" = "Posts"; -"Scene.Profile.SegmentedControl.PostsAndReplies" = "Posts and Replies"; -"Scene.Profile.SegmentedControl.Replies" = "Replies"; -"Scene.RebloggedBy.Title" = "Reblogged By"; -"Scene.Register.Error.Item.Agreement" = "Agreement"; +"Scene.HomeTimeline.NavigationBarState.NewPosts" = "Δες νέες αναρτήσεις"; +"Scene.HomeTimeline.NavigationBarState.Offline" = "Εκτός σύνδεσης"; +"Scene.HomeTimeline.NavigationBarState.Published" = "Δημοσιεύθηκε!"; +"Scene.HomeTimeline.NavigationBarState.Publishing" = "Δημοσίευση ανάρτησης..."; +"Scene.HomeTimeline.Title" = "Αρχική"; +"Scene.Login.ServerSearchField.Placeholder" = "Εισαγωγή URL ή αναζήτησε τον διακομιστή σου"; +"Scene.Login.Subtitle" = "Συνδέσου στο διακομιστή στον οποίο δημιούργησες τον λογαριασμό σου."; +"Scene.Login.Title" = "Καλωσόρισες και πάλι"; +"Scene.Notification.FollowRequest.Accept" = "Αποδοχή"; +"Scene.Notification.FollowRequest.Accepted" = "Αποδέχθηκε"; +"Scene.Notification.FollowRequest.Reject" = "απόρριψη"; +"Scene.Notification.FollowRequest.Rejected" = "Απορρίφθηκε"; +"Scene.Notification.Keyobard.ShowEverything" = "Εμφάνιση Όλων"; +"Scene.Notification.Keyobard.ShowMentions" = "Εμφάνιση Επισημάνσεων"; +"Scene.Notification.NotificationDescription.FavoritedYourPost" = "σημείωσε ως αγαπημένη την ανάρτησή σου"; +"Scene.Notification.NotificationDescription.FollowedYou" = "σε ακολούθησε"; +"Scene.Notification.NotificationDescription.MentionedYou" = "σε επισήμανε"; +"Scene.Notification.NotificationDescription.PollHasEnded" = "η δημοσκόπηση έληξε"; +"Scene.Notification.NotificationDescription.RebloggedYourPost" = "αναδημοσίευσε την ανάρτηση σου"; +"Scene.Notification.NotificationDescription.RequestToFollowYou" = "ζήτησε να σε ακολουθήσει"; +"Scene.Notification.Title.Everything" = "Όλα"; +"Scene.Notification.Title.Mentions" = "Επισημάνσεις"; +"Scene.Preview.Keyboard.ClosePreview" = "Κλείσιμο Προεπισκόπησης"; +"Scene.Preview.Keyboard.ShowNext" = "Εμφάνιση Επομένου"; +"Scene.Preview.Keyboard.ShowPrevious" = "Εμφάνιση Προηγούμενου"; +"Scene.Privacy.Button.Confirm" = "Συμφωνώ"; +"Scene.Privacy.Description" = "Αν και η εφαρμογή Mastodon δε συλλέγει δεδομένα, ο διακομιστής που εγγράφεσαι μπορεί να έχει διαφορετική πολιτική. Πάρε ένα λεπτό για να ελέγξεις και να συμφωνήσεις με την πολιτική απορρήτου της εφαρμογής Mastodon και την πολιτική απορρήτου του διακομιστή σου."; +"Scene.Privacy.Policy.Ios" = "Πολιτική Απορρήτου - Mastodon για iOS"; +"Scene.Privacy.Policy.Server" = "Πολιτική Απορρήτου - %@"; +"Scene.Privacy.Title" = "Απόρρητο"; +"Scene.Profile.Accessibility.DoubleTapToOpenTheList" = "Διπλό πάτημα για άνοιγμα της λίστας"; +"Scene.Profile.Accessibility.EditAvatarImage" = "Επεξεργασία εικόνας avatar"; +"Scene.Profile.Accessibility.ShowAvatarImage" = "Εμφάνιση εικόνας avatar"; +"Scene.Profile.Accessibility.ShowBannerImage" = "Εμφάνιση εικόνας banner"; +"Scene.Profile.Dashboard.FamiliarFollowers" = "κοινοί"; +"Scene.Profile.Dashboard.MyFollowers" = "ακόλουθοι"; +"Scene.Profile.Dashboard.MyFollowing" = "ακολουθείς"; +"Scene.Profile.Dashboard.MyPosts" = "αναρτήσεις"; +"Scene.Profile.Dashboard.OtherFollowers" = "ακόλουθοι"; +"Scene.Profile.Dashboard.OtherFollowing" = "ακολουθεί"; +"Scene.Profile.Dashboard.OtherPosts" = "αναρτήσεις"; +"Scene.Profile.Fields.AddRow" = "Προσθήκη Γραμμής"; +"Scene.Profile.Fields.Joined" = "Έγινε μέλος"; +"Scene.Profile.Fields.Placeholder.Content" = "Περιεχόμενο"; +"Scene.Profile.Fields.Placeholder.Label" = "Ετικέτα"; +"Scene.Profile.Fields.Verified.Long" = "Η ιδιοκτησία αυτού του συνδέσμου ελέχθηκε στις %@"; +"Scene.Profile.Fields.Verified.Short" = "Επαληθεύτηκε στις %@"; +"Scene.Profile.Header.FollowsYou" = "Σε Ακολουθεί"; +"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Επιβεβαίωση αποκλεισμού %@"; +"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Αποκλεισμός Λογαριασμού"; +"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Message" = "Επιβεβαίωση απόκρυψης αναδημοσιεύσεων"; +"Scene.Profile.RelationshipActionAlert.ConfirmHideReblogs.Title" = "Απόκρυψη Αναδημοσιεύσεων"; +"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Επιβεβαίωσε για σίγαση %@"; +"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Title" = "Σίγαση Λογαριασμού"; +"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Message" = "Επιβεβαίωση εμφάνισης αναδημοσιεύσεων"; +"Scene.Profile.RelationshipActionAlert.ConfirmShowReblogs.Title" = "Εμφάνιση Αναδημοσιεύσεων"; +"Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Message" = "Επιβεβαίωση άρσης αποκλεισμού %@"; +"Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Title" = "Άρση Αποκλεισμού Λογαριασμού"; +"Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.Message" = "Επιβεβαίωσε για άρση σίγασης %@"; +"Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.Title" = "Άρση Σίγασης Λογαριασμού"; +"Scene.Profile.SegmentedControl.About" = "Σχετικά"; +"Scene.Profile.SegmentedControl.Media" = "Πολυμέσα"; +"Scene.Profile.SegmentedControl.Posts" = "Αναρτήσεις"; +"Scene.Profile.SegmentedControl.PostsAndReplies" = "Αναρτήσεις και Απαντήσεις"; +"Scene.Profile.SegmentedControl.Replies" = "Απαντήσεις"; +"Scene.RebloggedBy.Title" = "Αναδημοσίευση Από"; +"Scene.Register.Error.Item.Agreement" = "Συμφωνία"; "Scene.Register.Error.Item.Email" = "Email"; -"Scene.Register.Error.Item.Locale" = "Locale"; -"Scene.Register.Error.Item.Password" = "Password"; -"Scene.Register.Error.Item.Reason" = "Reason"; -"Scene.Register.Error.Item.Username" = "Username"; -"Scene.Register.Error.Reason.Accepted" = "%@ must be accepted"; -"Scene.Register.Error.Reason.Blank" = "%@ is required"; -"Scene.Register.Error.Reason.Blocked" = "%@ contains a disallowed email provider"; -"Scene.Register.Error.Reason.Inclusion" = "%@ is not a supported value"; -"Scene.Register.Error.Reason.Invalid" = "%@ is invalid"; -"Scene.Register.Error.Reason.Reserved" = "%@ is a reserved keyword"; -"Scene.Register.Error.Reason.Taken" = "%@ is already taken. How about:"; -"Scene.Register.Error.Reason.TooLong" = "%@ is too long"; -"Scene.Register.Error.Reason.TooShort" = "%@ is too short"; -"Scene.Register.Error.Reason.Unreachable" = "%@ does not seem to exist"; -"Scene.Register.Error.Special.EmailInvalid" = "This is not a valid email address"; -"Scene.Register.Error.Special.PasswordTooShort" = "Password is too short (must be at least 8 characters)"; -"Scene.Register.Error.Special.UsernameInvalid" = "Username must only contain alphanumeric characters and underscores"; -"Scene.Register.Error.Special.UsernameTooLong" = "Username is too long (can’t be longer than 30 characters)"; -"Scene.Register.Input.Avatar.Delete" = "Delete"; -"Scene.Register.Input.DisplayName.Placeholder" = "display name"; +"Scene.Register.Error.Item.Locale" = "Γλώσσα"; +"Scene.Register.Error.Item.Password" = "Κωδικός πρόσβασης"; +"Scene.Register.Error.Item.Reason" = "Αιτιολογία"; +"Scene.Register.Error.Item.Username" = "Όνομα χρήστη"; +"Scene.Register.Error.Reason.Accepted" = "%@ πρέπει να γίνει αποδεκτό"; +"Scene.Register.Error.Reason.Blank" = "%@ απαιτείται"; +"Scene.Register.Error.Reason.Blocked" = "%@ περιέχει πάροχο μη επιτρεπόμενων email"; +"Scene.Register.Error.Reason.Inclusion" = "%@ δεν είναι υποστηριζόμενη τιμή"; +"Scene.Register.Error.Reason.Invalid" = "%@ δεν είναι έγκυρο"; +"Scene.Register.Error.Reason.Reserved" = "%@ είναι δεσμευμένη λέξη-κλειδί"; +"Scene.Register.Error.Reason.Taken" = "%@ χρησιμοποιείται ήδη. Τι θα έλεγες για:"; +"Scene.Register.Error.Reason.TooLong" = "%@ είναι πολύ μεγάλο"; +"Scene.Register.Error.Reason.TooShort" = "%@ είναι πολύ μικρό"; +"Scene.Register.Error.Reason.Unreachable" = "%@ δεν φαίνεται να υπάρχει"; +"Scene.Register.Error.Special.EmailInvalid" = "Αυτή η διεύθυνση email δεν είναι έγκυρη"; +"Scene.Register.Error.Special.PasswordTooShort" = "Ο κωδικός πρόσβασης είναι πολύ μικρός (πρέπει να είναι τουλάχιστον 8 χαρακτήρες)"; +"Scene.Register.Error.Special.UsernameInvalid" = "Το όνομα χρήστη πρέπει να περιέχει μόνο αλφαριθμητικούς χαρακτήρες και κάτω παύλες"; +"Scene.Register.Error.Special.UsernameTooLong" = "Το όνομα χρήστη είναι πολύ μεγάλο (δεν μπορεί να υπερβαίνει τους 30 χαρακτήρες)"; +"Scene.Register.Input.Avatar.Delete" = "Διαγραφή"; +"Scene.Register.Input.DisplayName.Placeholder" = "εμφανιζόμενο όνομα"; "Scene.Register.Input.Email.Placeholder" = "email"; -"Scene.Register.Input.Invite.RegistrationUserInviteRequest" = "Why do you want to join?"; -"Scene.Register.Input.Password.Accessibility.Checked" = "checked"; -"Scene.Register.Input.Password.Accessibility.Unchecked" = "unchecked"; -"Scene.Register.Input.Password.CharacterLimit" = "8 characters"; -"Scene.Register.Input.Password.ConfirmationPlaceholder" = "Confirm Password"; -"Scene.Register.Input.Password.Hint" = "Your password needs at least eight characters"; -"Scene.Register.Input.Password.Placeholder" = "password"; -"Scene.Register.Input.Password.Require" = "Your password needs at least:"; -"Scene.Register.Input.Username.DuplicatePrompt" = "This username is taken."; -"Scene.Register.Input.Username.Placeholder" = "username"; -"Scene.Register.Input.Username.Suggestion" = "amazing_%@"; -"Scene.Register.Title" = "Create Account"; -"Scene.Report.Content1" = "Are there any other posts you’d like to add to the report?"; -"Scene.Report.Content2" = "Is there anything the moderators should know about this report?"; -"Scene.Report.ReportSentTitle" = "Thanks for reporting, we’ll look into this."; -"Scene.Report.Reported" = "REPORTED"; -"Scene.Report.Send" = "Send Report"; -"Scene.Report.SkipToSend" = "Send without comment"; -"Scene.Report.Step1" = "Step 1 of 2"; -"Scene.Report.Step2" = "Step 2 of 2"; -"Scene.Report.StepFinal.BlockUser" = "Block %@"; -"Scene.Report.StepFinal.DontWantToSeeThis" = "Don’t want to see this?"; -"Scene.Report.StepFinal.MuteUser" = "Mute %@"; -"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked."; -"Scene.Report.StepFinal.Unfollow" = "Unfollow"; -"Scene.Report.StepFinal.UnfollowUser" = "Unfollow %@"; -"Scene.Report.StepFinal.Unfollowed" = "Unfollowed"; -"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "When you see something you don’t like on Mastodon, you can remove the person from your experience."; -"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "While we review this, you can take action against %@"; -"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted."; -"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "Is there anything else we should know?"; -"Scene.Report.StepFour.Step4Of4" = "Step 4 of 4"; -"Scene.Report.StepOne.IDontLikeIt" = "I don’t like it"; -"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "It is not something you want to see"; -"Scene.Report.StepOne.ItViolatesServerRules" = "It violates server rules"; -"Scene.Report.StepOne.ItsSomethingElse" = "It’s something else"; -"Scene.Report.StepOne.ItsSpam" = "It’s spam"; -"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Malicious links, fake engagement, or repetetive replies"; -"Scene.Report.StepOne.SelectTheBestMatch" = "Select the best match"; -"Scene.Report.StepOne.Step1Of4" = "Step 1 of 4"; -"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "The issue does not fit into other categories"; -"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "What's wrong with this account?"; -"Scene.Report.StepOne.WhatsWrongWithThisPost" = "What's wrong with this post?"; -"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "What's wrong with %@?"; -"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "You are aware that it breaks specific rules"; -"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Are there any posts that back up this report?"; -"Scene.Report.StepThree.SelectAllThatApply" = "Select all that apply"; -"Scene.Report.StepThree.Step3Of4" = "Step 3 of 4"; -"Scene.Report.StepTwo.IJustDon’tLikeIt" = "I just don’t like it"; -"Scene.Report.StepTwo.SelectAllThatApply" = "Select all that apply"; -"Scene.Report.StepTwo.Step2Of4" = "Step 2 of 4"; -"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "Which rules are being violated?"; -"Scene.Report.TextPlaceholder" = "Type or paste additional comments"; -"Scene.Report.Title" = "Report %@"; -"Scene.Report.TitleReport" = "Report"; -"Scene.Search.Recommend.Accounts.Description" = "You may like to follow these accounts"; -"Scene.Search.Recommend.Accounts.Follow" = "Follow"; -"Scene.Search.Recommend.Accounts.Title" = "Accounts you might like"; -"Scene.Search.Recommend.ButtonText" = "See All"; -"Scene.Search.Recommend.HashTag.Description" = "Hashtags that are getting quite a bit of attention"; -"Scene.Search.Recommend.HashTag.PeopleTalking" = "%@ people are talking"; -"Scene.Search.Recommend.HashTag.Title" = "Trending on Mastodon"; -"Scene.Search.SearchBar.Cancel" = "Cancel"; -"Scene.Search.SearchBar.Placeholder" = "Search hashtags and users"; -"Scene.Search.Searching.Clear" = "Clear"; -"Scene.Search.Searching.EmptyState.NoResults" = "No results"; -"Scene.Search.Searching.RecentSearch" = "Recent searches"; -"Scene.Search.Searching.Segment.All" = "All"; -"Scene.Search.Searching.Segment.Hashtags" = "Hashtags"; -"Scene.Search.Searching.Segment.People" = "People"; -"Scene.Search.Searching.Segment.Posts" = "Posts"; -"Scene.Search.Title" = "Search"; -"Scene.ServerPicker.Button.Category.Academia" = "academia"; -"Scene.ServerPicker.Button.Category.Activism" = "activism"; -"Scene.ServerPicker.Button.Category.All" = "All"; -"Scene.ServerPicker.Button.Category.AllAccessiblityDescription" = "Category: All"; -"Scene.ServerPicker.Button.Category.Art" = "art"; -"Scene.ServerPicker.Button.Category.Food" = "food"; -"Scene.ServerPicker.Button.Category.Furry" = "furry"; -"Scene.ServerPicker.Button.Category.Games" = "games"; -"Scene.ServerPicker.Button.Category.General" = "general"; -"Scene.ServerPicker.Button.Category.Journalism" = "journalism"; -"Scene.ServerPicker.Button.Category.Lgbt" = "lgbt"; -"Scene.ServerPicker.Button.Category.Music" = "music"; -"Scene.ServerPicker.Button.Category.Regional" = "regional"; -"Scene.ServerPicker.Button.Category.Tech" = "tech"; -"Scene.ServerPicker.Button.Language" = "Language"; -"Scene.ServerPicker.Button.SeeLess" = "See Less"; -"Scene.ServerPicker.Button.SeeMore" = "See More"; -"Scene.ServerPicker.Button.SignupSpeed" = "Sign-up Speed"; -"Scene.ServerPicker.EmptyState.BadNetwork" = "Something went wrong while loading the data. Check your internet connection."; -"Scene.ServerPicker.EmptyState.FindingServers" = "Finding available servers..."; -"Scene.ServerPicker.EmptyState.NoResults" = "No results"; -"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Search communities or enter URL"; -"Scene.ServerPicker.Label.Category" = "CATEGORY"; -"Scene.ServerPicker.Label.Language" = "LANGUAGE"; -"Scene.ServerPicker.Label.Users" = "USERS"; -"Scene.ServerPicker.Language.All" = "All"; -"Scene.ServerPicker.NoServerSelectedHint" = "We’ll pick a server based on your language if you continue without making a selection."; -"Scene.ServerPicker.Search.Placeholder" = "Search name or URL"; -"Scene.ServerPicker.SignupSpeed.All" = "All"; -"Scene.ServerPicker.SignupSpeed.Instant" = "Instant Sign-up"; -"Scene.ServerPicker.SignupSpeed.ManuallyReviewed" = "Manual Review"; -"Scene.ServerPicker.Title" = "Pick Server"; -"Scene.ServerRules.Button.Confirm" = "I Agree"; -"Scene.ServerRules.PrivacyPolicy" = "privacy policy"; -"Scene.ServerRules.Prompt" = "By continuing, you’re subject to the terms of service and privacy policy for %@."; -"Scene.ServerRules.Subtitle" = "These are set and enforced by the %@ moderators."; -"Scene.ServerRules.TermsOfService" = "terms of service"; -"Scene.ServerRules.Title" = "Some ground rules."; -"Scene.Settings.Footer.MastodonDescription" = "Mastodon is open source software. You can report issues on GitHub at %@ (%@)"; -"Scene.Settings.Keyboard.CloseSettingsWindow" = "Close Settings Window"; -"Scene.Settings.Section.Appearance.Automatic" = "Automatic"; -"Scene.Settings.Section.Appearance.Dark" = "Always Dark"; -"Scene.Settings.Section.Appearance.Light" = "Always Light"; -"Scene.Settings.Section.Appearance.Title" = "Appearance"; -"Scene.Settings.Section.BoringZone.AccountSettings" = "Account Settings"; -"Scene.Settings.Section.BoringZone.Privacy" = "Privacy Policy"; -"Scene.Settings.Section.BoringZone.Terms" = "Terms of Service"; -"Scene.Settings.Section.BoringZone.Title" = "The Boring Zone"; -"Scene.Settings.Section.LookAndFeel.Light" = "Light"; -"Scene.Settings.Section.LookAndFeel.ReallyDark" = "Really Dark"; -"Scene.Settings.Section.LookAndFeel.SortaDark" = "Sorta Dark"; -"Scene.Settings.Section.LookAndFeel.Title" = "Look and Feel"; -"Scene.Settings.Section.LookAndFeel.UseSystem" = "Use System"; -"Scene.Settings.Section.Notifications.Boosts" = "Reblogs my post"; -"Scene.Settings.Section.Notifications.Favorites" = "Favorites my post"; -"Scene.Settings.Section.Notifications.Follows" = "Follows me"; -"Scene.Settings.Section.Notifications.Mentions" = "Mentions me"; -"Scene.Settings.Section.Notifications.Title" = "Notifications"; -"Scene.Settings.Section.Notifications.Trigger.Anyone" = "anyone"; -"Scene.Settings.Section.Notifications.Trigger.Follow" = "anyone I follow"; -"Scene.Settings.Section.Notifications.Trigger.Follower" = "a follower"; -"Scene.Settings.Section.Notifications.Trigger.Noone" = "no one"; -"Scene.Settings.Section.Notifications.Trigger.Title" = "Notify me when"; -"Scene.Settings.Section.Preference.DisableAvatarAnimation" = "Disable animated avatars"; -"Scene.Settings.Section.Preference.DisableEmojiAnimation" = "Disable animated emojis"; -"Scene.Settings.Section.Preference.OpenLinksInMastodon" = "Open links in Mastodon"; -"Scene.Settings.Section.Preference.Title" = "Preferences"; -"Scene.Settings.Section.Preference.UsingDefaultBrowser" = "Use default browser to open links"; -"Scene.Settings.Section.SpicyZone.Clear" = "Clear Media Cache"; -"Scene.Settings.Section.SpicyZone.Signout" = "Sign Out"; -"Scene.Settings.Section.SpicyZone.Title" = "The Spicy Zone"; -"Scene.Settings.Title" = "Settings"; -"Scene.SuggestionAccount.FollowAll" = "Follow all"; -"Scene.SuggestionAccount.Title" = "Popular on Mastodon"; -"Scene.Thread.BackTitle" = "Post"; -"Scene.Thread.Title" = "Post from %@"; -"Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "What is Mastodon?"; -"Scene.Welcome.Education.Mastodon.Description" = "Mastodon is a decentralized social network, meaning no single company controls it. It’s made up of many independently-run servers, all connected together."; -"Scene.Welcome.Education.Mastodon.Title" = "Welcome to Mastodon"; -"Scene.Welcome.Education.Servers.Description" = "Every Mastodon account is hosted on a server — each with its own values, rules, & admins. No matter which one you pick, you can follow and interact with people on any server."; -"Scene.Welcome.Education.Servers.Title" = "What are servers?"; -"Scene.Welcome.JoinDefaultServer" = "Join %@"; -"Scene.Welcome.LearnMore" = "Learn more"; -"Scene.Welcome.LogIn" = "Log In"; -"Scene.Welcome.PickServer" = "Pick another server"; -"Scene.Welcome.Separator.Or" = "or"; -"Widget.Common.UnsupportedWidgetFamily" = "Sorry but this Widget family is unsupported."; -"Widget.Common.UserNotLoggedIn" = "Please open Mastodon to log in to an Account."; -"Widget.FollowersCount.ConfigurationDescription" = "Show number of followers."; -"Widget.FollowersCount.ConfigurationDisplayName" = "Followers"; -"Widget.FollowersCount.FollowersToday" = "%@ followers today"; -"Widget.FollowersCount.Title" = "FOLLOWERS"; -"Widget.Hashtag.Configuration.Description" = "Shows a recent post with the selected hashtag."; -"Widget.Hashtag.Configuration.DisplayName" = "Hashtag"; +"Scene.Register.Input.Invite.RegistrationUserInviteRequest" = "Γιατί θέλεις να συμμετάσχεις;"; +"Scene.Register.Input.Password.Accessibility.Checked" = "επιλεγμένο"; +"Scene.Register.Input.Password.Accessibility.Unchecked" = "μη επιλεγμένο"; +"Scene.Register.Input.Password.CharacterLimit" = "8 χαρακτήρες"; +"Scene.Register.Input.Password.ConfirmationPlaceholder" = "Επιβεβαίωση Κωδικού Πρόσβασης"; +"Scene.Register.Input.Password.Hint" = "Ο κωδικός πρόσβασής σου χρειάζεται τουλάχιστον οκτώ χαρακτήρες"; +"Scene.Register.Input.Password.Placeholder" = "κωδικός πρόσβασης"; +"Scene.Register.Input.Password.Require" = "Ο κωδικός σου χρειάζεται τουλάχιστον:"; +"Scene.Register.Input.Username.DuplicatePrompt" = "Αυτό το όνομα χρήστη χρησιμοποιείται."; +"Scene.Register.Input.Username.Placeholder" = "όνομα χρήστη"; +"Scene.Register.Input.Username.Suggestion" = "εκπληκτικό_%@"; +"Scene.Register.Title" = "Δημιουργία Λογαριασμού"; +"Scene.Report.Content1" = "Υπάρχουν άλλες αναρτήσεις που θα ήθελες να προσθέσεις στην αναφορά;"; +"Scene.Report.Content2" = "Υπάρχει κάτι που οι συντονιστές θα πρέπει να γνωρίζουν για αυτή την αναφορά;"; +"Scene.Report.ReportSentTitle" = "Σε ευχαριστούμε για την αναφορά, θα το διερευνήσουμε."; +"Scene.Report.Reported" = "ΑΝΑΦΈΡΘΗΚΕ"; +"Scene.Report.Send" = "Αποστολή Αναφοράς"; +"Scene.Report.SkipToSend" = "Αποστολή χωρίς σχόλιο"; +"Scene.Report.Step1" = "Βήμα 1 από 2"; +"Scene.Report.Step2" = "Βήμα 2 από 2"; +"Scene.Report.StepFinal.BlockUser" = "Αποκλεισμός %@"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "Δε θες να το βλέπεις;"; +"Scene.Report.StepFinal.MuteUser" = "Σίγαση %@"; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "Δε θα μπορούν πλέον να σε ακολουθούν ή να βλέπουν τις αναρτήσεις σου, αλλά μπορούν να δουν αν έχουν αποκλειστεί."; +"Scene.Report.StepFinal.Unfollow" = "Άρση ακολούθησης"; +"Scene.Report.StepFinal.UnfollowUser" = "Άρση ακολούθησης του %@"; +"Scene.Report.StepFinal.Unfollowed" = "Σταμάτησες να ακολουθείς"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "Όταν βλέπεις κάτι που δε σου αρέσει στο Mastodon, μπορείς να αφαιρέσεις το άτομο από την εμπειρία σου."; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "Ενώ το εξετάζουμε, μπορείς να δράσεις εναντίον του %@"; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "Δε θα βλέπεις τις αναρτήσεις ή τις αναδημοσιεύσεις τους στην αρχική σελίδα σου. Δε θα ξέρει ότι βρίσκεται σε σίγαση."; +"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "Υπάρχει κάτι άλλο που πρέπει να γνωρίζουμε;"; +"Scene.Report.StepFour.Step4Of4" = "Βήμα 4 από 4"; +"Scene.Report.StepOne.IDontLikeIt" = "Δεν μου αρέσει"; +"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "Δεν είναι κάτι που θα ήθελες να δεις"; +"Scene.Report.StepOne.ItViolatesServerRules" = "Παραβαίνει τους κανόνες του διακομιστή"; +"Scene.Report.StepOne.ItsSomethingElse" = "Είναι κάτι άλλο"; +"Scene.Report.StepOne.ItsSpam" = "Είναι σπαμ"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Κακόβουλοι σύνδεσμοι, πλαστή αλληλεπίδραση ή επαναλαμβανόμενες απαντήσεις"; +"Scene.Report.StepOne.SelectTheBestMatch" = "Διάλεξε την καλύτερη αντιστοίχιση"; +"Scene.Report.StepOne.Step1Of4" = "Βήμα 1 από 4"; +"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "Το ζήτημα δεν ταιριάζει σε άλλες κατηγορίες"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "Τι πάει στραβά με αυτόν τον λογαριασμό;"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "Τι πάει στραβά με αυτή την ανάρτηση;"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "Τι πάει στραβά με τον/την %@;"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "Γνωρίζεις ότι παραβιάζει συγκεκριμένους κανόνες"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Υπάρχουν αναρτήσεις που τεκμηριώνουν αυτή την αναφορά;"; +"Scene.Report.StepThree.SelectAllThatApply" = "Επίλεξε όλα όσα ισχύουν"; +"Scene.Report.StepThree.Step3Of4" = "Βήμα 3 από 4"; +"Scene.Report.StepTwo.IJustDon’tLikeIt" = "Απλώς δεν μου αρέσει"; +"Scene.Report.StepTwo.SelectAllThatApply" = "Επίλεξε όλα όσα ισχύουν"; +"Scene.Report.StepTwo.Step2Of4" = "Βήμα 2 από 4"; +"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "Ποιοι κανόνες παραβιάζονται;"; +"Scene.Report.TextPlaceholder" = "Πληκτρολόγησε ή επικόλλησε επιπρόσθετα σχόλια"; +"Scene.Report.Title" = "Αναφορά %@"; +"Scene.Report.TitleReport" = "Αναφορά"; +"Scene.Search.Recommend.Accounts.Description" = "Μπορεί να θες να ακολουθήσεις αυτούς τους λογαριασμούς"; +"Scene.Search.Recommend.Accounts.Follow" = "Ακολούθησε"; +"Scene.Search.Recommend.Accounts.Title" = "Λογαριασμοί που μπορεί να σου αρέσουν"; +"Scene.Search.Recommend.ButtonText" = "Προβολή Όλων"; +"Scene.Search.Recommend.HashTag.Description" = "Ετικέτες που τραβάνε την προσοχή"; +"Scene.Search.Recommend.HashTag.PeopleTalking" = "%@ άτομα μιλάνε"; +"Scene.Search.Recommend.HashTag.Title" = "Δημοφιλή στο Mastodon"; +"Scene.Search.SearchBar.Cancel" = "Άκυρο"; +"Scene.Search.SearchBar.Placeholder" = "Αναζήτησε ετικέτες και χρήστες"; +"Scene.Search.Searching.Clear" = "Εκκαθάριση"; +"Scene.Search.Searching.EmptyState.NoResults" = "Κανένα αποτέλεσμα"; +"Scene.Search.Searching.RecentSearch" = "Πρόσφατες αναζητήσεις"; +"Scene.Search.Searching.Segment.All" = "Όλα"; +"Scene.Search.Searching.Segment.Hashtags" = "Ετικέτες"; +"Scene.Search.Searching.Segment.People" = "Άτομα"; +"Scene.Search.Searching.Segment.Posts" = "Αναρτήσεις"; +"Scene.Search.Title" = "Αναζήτηση"; +"Scene.ServerPicker.Button.Category.Academia" = "ακαδημαϊκά"; +"Scene.ServerPicker.Button.Category.Activism" = "ακτιβισμός"; +"Scene.ServerPicker.Button.Category.All" = "Όλοι"; +"Scene.ServerPicker.Button.Category.AllAccessiblityDescription" = "Κατηγορία: Όλα"; +"Scene.ServerPicker.Button.Category.Art" = "τέχνη"; +"Scene.ServerPicker.Button.Category.Food" = "φαγητό"; +"Scene.ServerPicker.Button.Category.Furry" = "γούνινο"; +"Scene.ServerPicker.Button.Category.Games" = "παιχνίδια"; +"Scene.ServerPicker.Button.Category.General" = "γενικά"; +"Scene.ServerPicker.Button.Category.Journalism" = "δημοσιογραφία"; +"Scene.ServerPicker.Button.Category.Lgbt" = "λοατκι"; +"Scene.ServerPicker.Button.Category.Music" = "μουσική"; +"Scene.ServerPicker.Button.Category.Regional" = "τοπικό"; +"Scene.ServerPicker.Button.Category.Tech" = "τεχνολογία"; +"Scene.ServerPicker.Button.Language" = "Γλώσσα"; +"Scene.ServerPicker.Button.SeeLess" = "Δες Λιγότερα"; +"Scene.ServerPicker.Button.SeeMore" = "Δες Περισσότερα"; +"Scene.ServerPicker.Button.SignupSpeed" = "Ταχύτητα Εγγραφής"; +"Scene.ServerPicker.EmptyState.BadNetwork" = "Κάτι πήγε στραβά κατά τη φόρτωση των δεδομένων. Έλεγξε τη σύνδεσή σου στο διαδίκτυο."; +"Scene.ServerPicker.EmptyState.FindingServers" = "Εύρεση διαθέσιμων διακομιστών..."; +"Scene.ServerPicker.EmptyState.NoResults" = "Κανένα αποτέλεσμα"; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Αναζήτησε κοινότητες ή εισήγαγε URL"; +"Scene.ServerPicker.Label.Category" = "ΚΑΤΗΓΟΡΙΑ"; +"Scene.ServerPicker.Label.Language" = "ΓΛΩΣΣΑ"; +"Scene.ServerPicker.Label.Users" = "ΧΡΗΣΤΕΣ"; +"Scene.ServerPicker.Language.All" = "Όλες"; +"Scene.ServerPicker.NoServerSelectedHint" = "Θα επιλέξουμε έναν διακομιστή με βάση τη γλώσσα σου αν συνεχίσεις χωρίς να κάνεις κάποια επιλογή."; +"Scene.ServerPicker.Search.Placeholder" = "Αναζήτηση ονόματος ή URL"; +"Scene.ServerPicker.SignupSpeed.All" = "Όλες"; +"Scene.ServerPicker.SignupSpeed.Instant" = "Άμεση Εγγραφή"; +"Scene.ServerPicker.SignupSpeed.ManuallyReviewed" = "Χειροκίνητη Αξιολόγηση"; +"Scene.ServerPicker.Title" = "Επιλογή Διακομιστή"; +"Scene.ServerRules.Button.Confirm" = "Συμφωνώ"; +"Scene.ServerRules.PrivacyPolicy" = "πολιτική απορρήτου"; +"Scene.ServerRules.Prompt" = "Συνεχίζοντας, υπόκεισαι στους όρους της υπηρεσίας και της πολιτικής απορρήτου για %@."; +"Scene.ServerRules.Subtitle" = "Αυτά ορίζονται και επιβάλλονται από τους συντονιστές %@."; +"Scene.ServerRules.TermsOfService" = "όροι υπηρεσίας"; +"Scene.ServerRules.Title" = "Ορισμένοι βασικοί κανόνες."; +"Scene.Settings.Footer.MastodonDescription" = "Το Mastodon είναι λογισμικό ανοιχτού κώδικα. Μπορείς να αναφέρεις ζητήματα στο GitHub στο %@ (%@)"; +"Scene.Settings.Keyboard.CloseSettingsWindow" = "Κλείσιμο Παραθύρου Ρυθμίσεων"; +"Scene.Settings.Section.Appearance.Automatic" = "Αυτόματο"; +"Scene.Settings.Section.Appearance.Dark" = "Πάντα Σκοτεινό"; +"Scene.Settings.Section.Appearance.Light" = "Πάντα Φωτεινό"; +"Scene.Settings.Section.Appearance.Title" = "Εμφάνιση"; +"Scene.Settings.Section.BoringZone.AccountSettings" = "Ρυθμίσεις Λογαριασμού"; +"Scene.Settings.Section.BoringZone.Privacy" = "Πολιτική Απορρήτου"; +"Scene.Settings.Section.BoringZone.Terms" = "Όροι Χρήσης"; +"Scene.Settings.Section.BoringZone.Title" = "Η Βαρετή Ζώνη"; +"Scene.Settings.Section.LookAndFeel.Light" = "Φωτεινό"; +"Scene.Settings.Section.LookAndFeel.ReallyDark" = "Πραγματικά Σκοτεινό"; +"Scene.Settings.Section.LookAndFeel.SortaDark" = "Περίπου Σκοτεινό"; +"Scene.Settings.Section.LookAndFeel.Title" = "Eμφάνιση και Αίσθηση"; +"Scene.Settings.Section.LookAndFeel.UseSystem" = "Χρήση Συστήματος"; +"Scene.Settings.Section.Notifications.Boosts" = "Αναδημοσιεύει την ανάρτησή μου"; +"Scene.Settings.Section.Notifications.Favorites" = "Ορίζει ως αγαπημένη την ανάρτησή μου"; +"Scene.Settings.Section.Notifications.Follows" = "Με ακολουθεί"; +"Scene.Settings.Section.Notifications.Mentions" = "Με επισημαίνει"; +"Scene.Settings.Section.Notifications.Title" = "Ειδοποιήσεις"; +"Scene.Settings.Section.Notifications.Trigger.Anyone" = "οποιοσδήποτε"; +"Scene.Settings.Section.Notifications.Trigger.Follow" = "όποιον ακολουθώ"; +"Scene.Settings.Section.Notifications.Trigger.Follower" = "ακόλουθος"; +"Scene.Settings.Section.Notifications.Trigger.Noone" = "κανείς"; +"Scene.Settings.Section.Notifications.Trigger.Title" = "Να ειδοποιούμαι όταν"; +"Scene.Settings.Section.Preference.DisableAvatarAnimation" = "Απενεργοποίηση κινούμενων avatars"; +"Scene.Settings.Section.Preference.DisableEmojiAnimation" = "Απενεργοποίηση κινούμενων emojis"; +"Scene.Settings.Section.Preference.OpenLinksInMastodon" = "Άνοιγμα συνδέσμων στο Mastodon"; +"Scene.Settings.Section.Preference.Title" = "Προτιμήσεις"; +"Scene.Settings.Section.Preference.UsingDefaultBrowser" = "Χρησιμοποίησε τον προεπιλεγμένο περιηγητή για να ανοίξεις συνδέσμους"; +"Scene.Settings.Section.SpicyZone.Clear" = "Καθαρισμός Κρυφής Μνήμης Πολυμέσων"; +"Scene.Settings.Section.SpicyZone.Signout" = "Αποσύνδεση"; +"Scene.Settings.Section.SpicyZone.Title" = "Η Πικάντικη Ζώνη"; +"Scene.Settings.Title" = "Ρυθμίσεις"; +"Scene.SuggestionAccount.FollowAll" = "Ακολούθησε τους όλους"; +"Scene.SuggestionAccount.Title" = "Δημοφιλή στο Mastodon"; +"Scene.Thread.BackTitle" = "Ανάρτηση"; +"Scene.Thread.Title" = "Ανάρτηση από %@"; +"Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "Τι είναι το Mastodon;"; +"Scene.Welcome.Education.Mastodon.Description" = "Το Mastodon είναι ένα αποκεντρωμένο κοινωνικό δίκτυο που σημαίνει ότι καμία εταιρεία δεν το ελέγχει. Αποτελείται από πολλούς ανεξάρτητους διακομιστές, όλοι συνδεδεμένοι μαζί."; +"Scene.Welcome.Education.Mastodon.Title" = "Καλώς ήρθες στο Mastodon"; +"Scene.Welcome.Education.Servers.Description" = "Κάθε λογαριασμός Mastodon φιλοξενείται σε ένα διακομιστή - ο καθένας με τις δικές του αξίες, κανόνες και διαχειριστές. Ανεξάρτητα από το ποιον μπορεί να επιλέξεις, μπορείς να ακολουθήσεις και να αλληλεπιδράσεις με άτομα από οποιονδήποτε διακομιστή."; +"Scene.Welcome.Education.Servers.Title" = "Τι είναι οι διακομιστές;"; +"Scene.Welcome.JoinDefaultServer" = "Γίνε μέλος %@"; +"Scene.Welcome.LearnMore" = "Μάθε περισσότερα"; +"Scene.Welcome.LogIn" = "Σύνδεση"; +"Scene.Welcome.PickServer" = "Διάλεξε άλλο διακομιστή"; +"Scene.Welcome.Separator.Or" = "ή"; +"Widget.Common.UnsupportedWidgetFamily" = "Λυπούμαστε, αλλά αυτή η οικογένεια Widget δεν υποστηρίζεται."; +"Widget.Common.UserNotLoggedIn" = "Παρακαλώ άνοιξε το Mastodon για να συνδεθείς σε έναν Λογαριασμό."; +"Widget.FollowersCount.ConfigurationDescription" = "Εμφάνιση αριθμού των ακολούθων."; +"Widget.FollowersCount.ConfigurationDisplayName" = "Ακόλουθοι"; +"Widget.FollowersCount.FollowersToday" = "%@ ακόλουθοι σήμερα"; +"Widget.FollowersCount.Title" = "ΑΚΟΛΟΥΘΟΙ"; +"Widget.Hashtag.Configuration.Description" = "Εμφανίζει μια πρόσφατη ανάρτηση με την επιλεγμένη ετικέτα."; +"Widget.Hashtag.Configuration.DisplayName" = "Ετικέτα"; "Widget.Hashtag.NotFound.Account" = "@johnMastodon@no-such.account"; "Widget.Hashtag.NotFound.AccountName" = "John Mastodon"; -"Widget.Hashtag.NotFound.Content" = "Sorry, we couldn’t find any posts with the hashtag #%@. Please try a #DifferentHashtag or check the widget settings."; +"Widget.Hashtag.NotFound.Content" = "Λυπούμαστε, δεν μπορέσαμε να βρούμε αναρτήσεις με την ετικέτα #%@. Παρακαλώ δοκίμασε ένα #DifferentHashtag ή έλεγξε τις ρυθμίσεις widget."; "Widget.Hashtag.Placeholder.Account" = "@johnMastodon@no-such.account"; -"Widget.Hashtag.Placeholder.AccountName" = "John Mastodon"; -"Widget.Hashtag.Placeholder.Content" = "This is how a post with a #hashtag would look. Pick whichever #hashtag you want in the widget settings."; -"Widget.LatestFollowers.ConfigurationDescription" = "Show latest followers."; -"Widget.LatestFollowers.ConfigurationDisplayName" = "Latest followers"; -"Widget.LatestFollowers.LastUpdate" = "Last update: %@"; -"Widget.LatestFollowers.Title" = "Latest followers"; -"Widget.MultipleFollowers.ConfigurationDescription" = "Show number of followers for multiple accounts."; -"Widget.MultipleFollowers.ConfigurationDisplayName" = "Multiple followers"; +"Widget.Hashtag.Placeholder.AccountName" = "Γιάννης Mastodon"; +"Widget.Hashtag.Placeholder.Content" = "Έτσι θα φαινόταν μια ανάρτηση με #hashtag. Επίλεξε όποιο #hashtag θες στις ρυθμίσεις widget."; +"Widget.LatestFollowers.ConfigurationDescription" = "Εμφάνιση πιο πρόσφατων ακολούθων."; +"Widget.LatestFollowers.ConfigurationDisplayName" = "Τελευταίοι ακόλουθοι"; +"Widget.LatestFollowers.LastUpdate" = "Τελευταία ενημέρωση: %@"; +"Widget.LatestFollowers.Title" = "Τελευταίοι ακόλουθοι"; +"Widget.MultipleFollowers.ConfigurationDescription" = "Εμφάνιση αριθμού ακολούθων για πολλαπλούς λογαριασμούς."; +"Widget.MultipleFollowers.ConfigurationDisplayName" = "Πολλαπλοί ακόλουθοι"; "Widget.MultipleFollowers.MockUser.AccountName" = "another@follower.social"; -"Widget.MultipleFollowers.MockUser.DisplayName" = "Another follower"; \ No newline at end of file +"Widget.MultipleFollowers.MockUser.DisplayName" = "Κι άλλος ακόλουθος"; \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/el.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/el.lproj/Localizable.stringsdict index 2b09ee004..7705da056 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/el.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/el.lproj/Localizable.stringsdict @@ -13,15 +13,15 @@ NSStringFormatValueTypeKey ld one - 1 unread notification + 1 μη αναγνωσμένη ειδοποίηση other - %ld unread notifications + %ld μη αναγνωσμένες ειδοποιήσεις a11y.plural.count.input_limit_exceeds NSStringLocalizedFormatKey - Input limit exceeds %#@character_count@ + Το όριο εισόδου υπερβαίνει το %#@character_count@ character_count NSStringFormatSpecTypeKey @@ -29,15 +29,15 @@ NSStringFormatValueTypeKey ld one - 1 character + 1 χαρακτήρας other - %ld characters + %ld χαρακτήρες a11y.plural.count.input_limit_remains NSStringLocalizedFormatKey - Input limit remains %#@character_count@ + Το όριο εισόδου παραμένει %#@character_count@ character_count NSStringFormatSpecTypeKey @@ -45,9 +45,9 @@ NSStringFormatValueTypeKey ld one - 1 character + 1 χαρακτήρας other - %ld characters + %ld χαρακτήρες a11y.plural.count.characters_left @@ -61,9 +61,9 @@ NSStringFormatValueTypeKey ld one - 1 character left + απομένει 1 χαρακτήρας other - %ld characters left + απομένουν %ld χαρακτήρες plural.count.followed_by_and_mutual @@ -88,9 +88,9 @@ NSStringFormatValueTypeKey ld one - Followed by %1$@, and another mutual + Ακολουθείται από %1$@ και έναν ακόμα κοινό other - Followed by %1$@, and %ld mutuals + Ακολουθείται από %1$@, και %ld κοινούς plural.count.metric_formatted.post @@ -104,9 +104,9 @@ NSStringFormatValueTypeKey ld one - post + ανάρτηση other - posts + αναρτήσεις plural.count.media @@ -120,9 +120,9 @@ NSStringFormatValueTypeKey ld one - 1 media + 1 πολυμέσο other - %ld media + %ld πολυμέσα plural.count.post @@ -136,9 +136,9 @@ NSStringFormatValueTypeKey ld one - 1 post + 1 ανάρτηση other - %ld posts + %ld αναρτήσεις plural.count.favorite @@ -152,9 +152,9 @@ NSStringFormatValueTypeKey ld one - 1 favorite + 1 αγαπημένο other - %ld favorites + %ld αγαπημένα plural.count.reblog @@ -168,9 +168,9 @@ NSStringFormatValueTypeKey ld one - 1 reblog + 1 αναδημοσίευση other - %ld reblogs + %ld αναδημοσιεύσεις plural.count.reblog_a11y @@ -184,9 +184,9 @@ NSStringFormatValueTypeKey ld one - 1 re-blog + 1 αναδημοσίευση other - %ld re-blogs + %ld αναδημοσιεύσεις plural.count.reply @@ -200,9 +200,9 @@ NSStringFormatValueTypeKey ld one - 1 reply + 1 απάντηση other - %ld replies + %ld απαντήσεις plural.count.vote @@ -216,9 +216,9 @@ NSStringFormatValueTypeKey ld one - 1 vote + 1 ψήφος other - %ld votes + %ld ψήφοι plural.count.voter @@ -232,9 +232,9 @@ NSStringFormatValueTypeKey ld one - 1 voter + 1 ψηφοφόρος other - %ld voters + %ld ψηφοφόροι plural.people_talking @@ -248,9 +248,9 @@ NSStringFormatValueTypeKey ld one - 1 people talking + 1 άτομο που μιλάει other - %ld people talking + %ld άτομα μιλούν plural.count.following @@ -264,9 +264,9 @@ NSStringFormatValueTypeKey ld one - 1 following + 1 ακολουθεί other - %ld following + %ld ακολουθούν plural.count.follower @@ -280,9 +280,9 @@ NSStringFormatValueTypeKey ld one - 1 follower + 1 ακόλουθος other - %ld followers + %ld ακόλουθοι date.year.left @@ -296,9 +296,9 @@ NSStringFormatValueTypeKey ld one - 1 year left + Απομένει 1 χρόνος other - %ld years left + Απομένουν %ld χρόνια date.month.left @@ -312,9 +312,9 @@ NSStringFormatValueTypeKey ld one - 1 months left + Απομένει 1 μήνας other - %ld months left + Απομένουν %ld μήνες date.day.left @@ -328,9 +328,9 @@ NSStringFormatValueTypeKey ld one - 1 day left + Απομένει 1 ημέρα other - %ld days left + απομένουν %ld ημέρες date.hour.left @@ -344,9 +344,9 @@ NSStringFormatValueTypeKey ld one - 1 hour left + απομένει 1 ώρα other - %ld hours left + απομένουν %ld ώρες date.minute.left @@ -360,9 +360,9 @@ NSStringFormatValueTypeKey ld one - 1 minute left + απομένει 1 λεπτό other - %ld minutes left + Απομένουν %ld λεπτά date.second.left @@ -376,9 +376,9 @@ NSStringFormatValueTypeKey ld one - 1 second left + απομένει 1 δευτερόλεπτο other - %ld seconds left + Απομένουν %ld δευτερόλεπτα date.year.ago.abbr @@ -392,9 +392,9 @@ NSStringFormatValueTypeKey ld one - 1y ago + 1χρ πριν other - %ldy ago + %ldχρ πριν date.month.ago.abbr @@ -408,9 +408,9 @@ NSStringFormatValueTypeKey ld one - 1M ago + 1μην πριν other - %ldM ago + %ldμην πριν date.day.ago.abbr @@ -424,9 +424,9 @@ NSStringFormatValueTypeKey ld one - 1d ago + %1ημ πριν other - %ldd ago + %ldημ πριν date.hour.ago.abbr @@ -440,9 +440,9 @@ NSStringFormatValueTypeKey ld one - 1h ago + 1ώ πριν other - %ldh ago + %ldώ πριν date.minute.ago.abbr @@ -456,9 +456,9 @@ NSStringFormatValueTypeKey ld one - 1m ago + 1λ πριν other - %ldm ago + %ldλ πριν date.second.ago.abbr @@ -472,9 +472,9 @@ NSStringFormatValueTypeKey ld one - 1s ago + 1δλ πριν other - %lds ago + %ldδλ πριν diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings index ca2cb11c0..7f00f1cc2 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "Please try again later."; "Common.Alerts.DeletePost.Message" = "Are you sure you want to delete this post?"; "Common.Alerts.DeletePost.Title" = "Delete Post"; -"Common.Alerts.DiscardPostContent.Message" = "Confirm to discard composed post content."; -"Common.Alerts.DiscardPostContent.Title" = "Discard Draft"; "Common.Alerts.EditProfileFailure.Message" = "Cannot edit profile. Please try again."; "Common.Alerts.EditProfileFailure.Title" = "Edit Profile Error"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "Cannot attach more than one video."; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.strings index 8ff1cbeab..69ae61e3f 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "Por favor, vuelve a intentarlo más tarde."; "Common.Alerts.DeletePost.Message" = "¿Estás seguro de que quieres borrar esta publicación?"; "Common.Alerts.DeletePost.Title" = "¿Estás seguro de que deseas eliminar esta publicación?"; -"Common.Alerts.DiscardPostContent.Message" = "Confirma para descartar el contenido de la publicación."; -"Common.Alerts.DiscardPostContent.Title" = "Descartar borrador"; "Common.Alerts.EditProfileFailure.Message" = "No se ha podido editar el perfil. Por favor, inténtalo de nuevo."; "Common.Alerts.EditProfileFailure.Title" = "Error en la Edición del Perfil"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "No puedes adjuntar más de un vídeo."; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings index ca450b298..a2bf96287 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "Mesedez beranduago saiatu."; "Common.Alerts.DeletePost.Message" = "Ziur bidalketa hau ezabatu nahi duzula?"; "Common.Alerts.DeletePost.Title" = "Ziur zaude bidalketa hau ezabatu nahi duzula?"; -"Common.Alerts.DiscardPostContent.Message" = "Berretsi idatzitako bidalketaren edukia baztertzea."; -"Common.Alerts.DiscardPostContent.Title" = "Baztertu zirriborroa"; "Common.Alerts.EditProfileFailure.Message" = "Ezin da profila editatu. Mesedez saiatu berriro."; "Common.Alerts.EditProfileFailure.Title" = "Errorea profila editatzean"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "Ezin da bideo bat baino gehiago erantsi."; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings index 7a688ff51..d2bac1841 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "Yritä uudelleen myöhemmin."; "Common.Alerts.DeletePost.Message" = "Are you sure you want to delete this post?"; "Common.Alerts.DeletePost.Title" = "Haluatko varmasti poistaa tämän julkaisun?"; -"Common.Alerts.DiscardPostContent.Message" = "Confirm to discard composed post content."; -"Common.Alerts.DiscardPostContent.Title" = "Hylkää luonnos"; "Common.Alerts.EditProfileFailure.Message" = "Profiilia ei voida muoka. Yritä uudelleen."; "Common.Alerts.EditProfileFailure.Title" = "Virhe profiilin muokkauksessa"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "Ei voi liittä yhtä videota enempää."; @@ -530,7 +528,7 @@ uploaded to Mastodon."; "Scene.Welcome.Education.Mastodon.Title" = "Tervetuloa Mastodoniin"; "Scene.Welcome.Education.Servers.Description" = "Jokainen Mastodon-tili sijaitsee jollakin palvelimella, joilla on kaikilla omat arvot, säännöt ja ylläpitäjät. Palvelinvalinnastasi riippumatta voit seurata kaikkien palvelinten käyttäjiä ja viestiä heidän kanssaan."; "Scene.Welcome.Education.Servers.Title" = "Mitä palvelimet ovat?"; -"Scene.Welcome.JoinDefaultServer" = "Join %@"; +"Scene.Welcome.JoinDefaultServer" = "Liity palvelimelle %@"; "Scene.Welcome.LearnMore" = "Lue lisää"; "Scene.Welcome.LogIn" = "Kirjaudu sisään"; "Scene.Welcome.PickServer" = "Pick another server"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.strings index a9c9b6e2a..e4d803933 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "Merci de réessayer plus tard."; "Common.Alerts.DeletePost.Message" = "Voulez-vous vraiment supprimer ce message ?"; "Common.Alerts.DeletePost.Title" = "Voulez-vous vraiment supprimer ce message ?"; -"Common.Alerts.DiscardPostContent.Message" = "Confirmez pour abandonner le contenu de votre message."; -"Common.Alerts.DiscardPostContent.Title" = "Abandonner le brouillon"; "Common.Alerts.EditProfileFailure.Message" = "Impossible de modifier le profil. Veuillez réessayer."; "Common.Alerts.EditProfileFailure.Title" = "Erreur lors de l'édition du profil"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "Impossible de joindre plus d’une vidéo."; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/gd.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/gd.lproj/Localizable.strings index 496c6965d..e7f9f86c7 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/gd.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/gd.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "Feuch ris a-rithist an ceann greis."; "Common.Alerts.DeletePost.Message" = "A bheil thu cinnteach gu bheil thu airson am post seo a sguabadh às?"; "Common.Alerts.DeletePost.Title" = "Sguab às am post"; -"Common.Alerts.DiscardPostContent.Message" = "Dearbh tilgeil air falbh susbaint a’ phuist a sgrìobh thu."; -"Common.Alerts.DiscardPostContent.Title" = "Tilg air falbh an dreachd"; "Common.Alerts.EditProfileFailure.Message" = "Cha b’ urrainn dhuinn a’ pròifil a dheasachadh. Feuch ris a-rithist."; "Common.Alerts.EditProfileFailure.Title" = "Mearachd le deasachadh na pròifil"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "Chan urrainn dhut barrachd air aon video a cheangal ris."; @@ -30,7 +28,7 @@ Thoir sùil air a’ cheangal agad ris an eadar-lìon."; "Common.Controls.Actions.Add" = "Cuir ris"; "Common.Controls.Actions.Back" = "Air ais"; "Common.Controls.Actions.BlockDomain" = "Bac %@"; -"Common.Controls.Actions.Bookmark" = "Bookmark"; +"Common.Controls.Actions.Bookmark" = "Comharra-lìn"; "Common.Controls.Actions.Cancel" = "Sguir dheth"; "Common.Controls.Actions.Compose" = "Sgrìobh"; "Common.Controls.Actions.Confirm" = "Dearbh"; @@ -42,8 +40,8 @@ Thoir sùil air a’ cheangal agad ris an eadar-lìon."; "Common.Controls.Actions.Done" = "Deiseil"; "Common.Controls.Actions.Edit" = "Deasaich"; "Common.Controls.Actions.EditPost" = "Deasaich"; -"Common.Controls.Actions.FindPeople" = "Lorg daoine a leanas tu"; -"Common.Controls.Actions.Follow" = "Follow %@"; +"Common.Controls.Actions.FindPeople" = "Lorg daoine gus an leantainn"; +"Common.Controls.Actions.Follow" = "Lean %@"; "Common.Controls.Actions.ManuallySearch" = "Lorg a làimh ’na àite"; "Common.Controls.Actions.Next" = "Air adhart"; "Common.Controls.Actions.Ok" = "Ceart ma-thà"; @@ -53,7 +51,7 @@ Thoir sùil air a’ cheangal agad ris an eadar-lìon."; "Common.Controls.Actions.Preview" = "Ro-sheall"; "Common.Controls.Actions.Previous" = "Air ais"; "Common.Controls.Actions.Remove" = "Thoir air falbh"; -"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; +"Common.Controls.Actions.RemoveBookmark" = "Thoir air falbh an comharra-lìn"; "Common.Controls.Actions.Reply" = "Freagair"; "Common.Controls.Actions.ReportUser" = "Dèan gearan mu %@"; "Common.Controls.Actions.Save" = "Sàbhail"; @@ -70,7 +68,7 @@ Thoir sùil air a’ cheangal agad ris an eadar-lìon."; "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Chan eil fhios"; "Common.Controls.Actions.TryAgain" = "Feuch ris a-rithist"; "Common.Controls.Actions.UnblockDomain" = "Dì-bhac %@"; -"Common.Controls.Actions.Unfollow" = "Unfollow %@"; +"Common.Controls.Actions.Unfollow" = "Na lean %@ tuilleadh"; "Common.Controls.Friendship.Block" = "Bac"; "Common.Controls.Friendship.BlockDomain" = "Bac %@"; "Common.Controls.Friendship.BlockUser" = "Bac %@"; @@ -412,7 +410,7 @@ a luchdadh suas gu Mastodon."; "Scene.Report.StepOne.IDontLikeIt" = "Cha toigh leam e"; "Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "Chan eil thu airson seo fhaicinn"; "Scene.Report.StepOne.ItViolatesServerRules" = "Tha e a’ briseadh riaghailtean an fhrithealaiche"; -"Scene.Report.StepOne.ItsSomethingElse" = "’S rud eile a tha ann"; +"Scene.Report.StepOne.ItsSomethingElse" = "’S e rud eile a tha ann"; "Scene.Report.StepOne.ItsSpam" = "’S e spama a th’ ann"; "Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Ceanglaichean droch-rùnach, conaltradh fuadain no an dearbh fhreagairt a-rithist ’s a-rithist"; "Scene.Report.StepOne.SelectTheBestMatch" = "Tagh a’ mhaids as fheàrr"; @@ -530,7 +528,7 @@ a luchdadh suas gu Mastodon."; "Scene.Welcome.Education.Mastodon.Title" = "Fàilte gu Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Tha gach cunntas Mastodon ’ga òstadh air frithealaiche – tha luachan, riaghailtean ⁊ rianairean sònraichte aig gach fear. Ge b’ e dè am frithealaiche a thaghas tu, ’s urrainn dhut daoine air frithealaiche sam bith a leantainn is bruidhinn riutha."; "Scene.Welcome.Education.Servers.Title" = "Dè th’ anns na frithealaichean?"; -"Scene.Welcome.JoinDefaultServer" = "Join %@"; +"Scene.Welcome.JoinDefaultServer" = "Faigh ballrachd aig %@"; "Scene.Welcome.LearnMore" = "Barrachd fiosrachaidh"; "Scene.Welcome.LogIn" = "Clàraich a-steach"; "Scene.Welcome.PickServer" = "Tagh frithealaiche eile"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.strings index bd9ca1bf2..f1cba68cd 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "Inténtao de novo máis tarde."; "Common.Alerts.DeletePost.Message" = "Tes a certeza de querer eliminar esta publicación?"; "Common.Alerts.DeletePost.Title" = "Eliminar publicación"; -"Common.Alerts.DiscardPostContent.Message" = "Confirma que queres descartar o contido do borrador."; -"Common.Alerts.DiscardPostContent.Title" = "Descartar Borrador"; "Common.Alerts.EditProfileFailure.Message" = "Non se editou o perfil. Inténtao máis tarde."; "Common.Alerts.EditProfileFailure.Title" = "Erro ao editar o perfil"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "Non podes anexar máis de un vídeo."; @@ -530,7 +528,7 @@ ser subido a Mastodon."; "Scene.Welcome.Education.Mastodon.Title" = "Benvida a Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Cada conta Mastodon está hospedada nun servidor — cada unha coas súas regras, valores e admins. Non importa cal elixas, podes seguir e interactuar con persoas de outros servidores."; "Scene.Welcome.Education.Servers.Title" = "Que son os servidores?"; -"Scene.Welcome.JoinDefaultServer" = "Join %@"; +"Scene.Welcome.JoinDefaultServer" = "Únete a %@"; "Scene.Welcome.LearnMore" = "Saber máis"; "Scene.Welcome.LogIn" = "Acceder"; "Scene.Welcome.PickServer" = "Elixe outro servidor"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.strings index 7fbd9f886..1eb26fa5a 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "Per favore, riprova più tardi."; "Common.Alerts.DeletePost.Message" = "Vuoi veramente eliminare questo post?"; "Common.Alerts.DeletePost.Title" = "Cancella il post"; -"Common.Alerts.DiscardPostContent.Message" = "Confermare di scartare il contenuto del post composto."; -"Common.Alerts.DiscardPostContent.Title" = "Elimina bozza"; "Common.Alerts.EditProfileFailure.Message" = "Impossibile modificare il profilo. Per favore, riprova."; "Common.Alerts.EditProfileFailure.Title" = "Errore nella modifica del profilo"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "Impossibile allegare più di un filmato."; @@ -530,7 +528,7 @@ caricato su Mastodon."; "Scene.Welcome.Education.Mastodon.Title" = "Benvenuto/a su Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Ogni account Mastodon è ospitato su un server — ognuno con i propri valori, regole, e amministratori. Non importa quale scegliere, è possibile seguire e interagire con persone su altri server."; "Scene.Welcome.Education.Servers.Title" = "Cosa sono i server?"; -"Scene.Welcome.JoinDefaultServer" = "Join %@"; +"Scene.Welcome.JoinDefaultServer" = "Unisciti a %@"; "Scene.Welcome.LearnMore" = "Scopri di più"; "Scene.Welcome.LogIn" = "Accedi"; "Scene.Welcome.PickServer" = "Scegli un altro server"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.strings index 309a3b7d5..4255ed496 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "後でもう一度お試しください。"; "Common.Alerts.DeletePost.Message" = "本当にこの投稿を削除しますか?"; "Common.Alerts.DeletePost.Title" = "投稿を削除"; -"Common.Alerts.DiscardPostContent.Message" = "この操作は取り消しできません。下書きは失われます。"; -"Common.Alerts.DiscardPostContent.Title" = "投稿を破棄しますか?"; "Common.Alerts.EditProfileFailure.Message" = "プロフィールを編集できません。もう一度お試しください。"; "Common.Alerts.EditProfileFailure.Title" = "プロフィールを編集できませんでした"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "複数の動画を添付することはできません。"; @@ -525,7 +523,7 @@ "Scene.Welcome.Education.Mastodon.Title" = "Mastodon とは"; "Scene.Welcome.Education.Servers.Description" = "Mastodon のアカウントはいずれかのサーバーに所属します。それぞれのサーバーは異なる価値観やルールをもち、それらを管理する管理者がいます。どのサーバーにいても、ほかのあらゆるサーバーのユーザーをフォローして、かかわりをもつことができるでしょう。"; "Scene.Welcome.Education.Servers.Title" = "サーバーとは"; -"Scene.Welcome.JoinDefaultServer" = "Join %@"; +"Scene.Welcome.JoinDefaultServer" = "%@ に登録"; "Scene.Welcome.LearnMore" = "詳しく学ぶ"; "Scene.Welcome.LogIn" = "ログイン"; "Scene.Welcome.PickServer" = "ほかのサーバーをさがす"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.strings index eb7f7da71..04157c456 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "Ttxil εreḍ tikelt-nniḍen ticki."; "Common.Alerts.DeletePost.Message" = "Tebɣiḍ s tidet ad tekkseḍ tasuffeɣt-agi?"; "Common.Alerts.DeletePost.Title" = "Tebɣiḍ s tidet ad tekkseḍ tasuffeɣt-agi?"; -"Common.Alerts.DiscardPostContent.Message" = "Sentem i wakken ad yettusefsax ugbur n tsuffeɣt."; -"Common.Alerts.DiscardPostContent.Title" = "Kkes arewway"; "Common.Alerts.EditProfileFailure.Message" = "Yegguma ad yettwaẓreg umaɣnu. Ɛreḍ tikkelt-nniḍen."; "Common.Alerts.EditProfileFailure.Title" = "Ẓreg tuccḍa n umaɣnu"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "Ur tezmireḍ ara ad ugar n tvidyut."; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.strings index 03e0faaa5..9350f13fe 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "Ji kerema xwe paşê dîsa biceribîne."; "Common.Alerts.DeletePost.Message" = "Ma tu dixwazî vê şandiyê jê bibî?"; "Common.Alerts.DeletePost.Title" = "Şandiyê jê bibe"; -"Common.Alerts.DiscardPostContent.Message" = "Bipejrîne ku naveroka şandiyê ya hatiye nivîsandin paşguh bikî."; -"Common.Alerts.DiscardPostContent.Title" = "Reşnivîsê paşguh bike"; "Common.Alerts.EditProfileFailure.Message" = "Nikare profîlê serrast bike. Jkx dîsa biceribîne."; "Common.Alerts.EditProfileFailure.Title" = "Di serrastkirina profîlê çewtî"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "Nikare ji bêtirî yek vîdyoyekê tevlî şandiyê bike."; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings index ae5c1feb5..a9a095ece 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "Probeer het later nog eens."; "Common.Alerts.DeletePost.Message" = "Weet je zeker dat je dit bericht wilt verwijderen?"; "Common.Alerts.DeletePost.Title" = "Bericht verwijderen"; -"Common.Alerts.DiscardPostContent.Message" = "Bevestig het verwijderen van het conceptbericht."; -"Common.Alerts.DiscardPostContent.Title" = "Verwijder concept"; "Common.Alerts.EditProfileFailure.Message" = "Je profiel kan niet bewerkt worden. Probeer het opnieuw."; "Common.Alerts.EditProfileFailure.Title" = "Profiel bewerken mislukt"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "Kan niet meer dan één video toevoegen."; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings index 43764bab6..27d902a05 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "Пожалуйста, попробуйте позже."; "Common.Alerts.DeletePost.Message" = "Вы уверены, что хотите удалить этот пост?"; "Common.Alerts.DeletePost.Title" = "Вы уверены, что хотите удалить этот пост?"; -"Common.Alerts.DiscardPostContent.Message" = "Вы действительно хотите удалить набранное содержимое поста?"; -"Common.Alerts.DiscardPostContent.Title" = "Удалить черновик"; "Common.Alerts.EditProfileFailure.Message" = "Не удаётся изменить профиль. Пожалуйста, попробуйте ещё раз."; "Common.Alerts.EditProfileFailure.Title" = "Ошибка изменения профиля"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "Невозможно прикрепить более одного видео."; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/sl.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/sl.lproj/Localizable.strings index 862e0b119..6787f8bc4 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/sl.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/sl.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "Poskusite znova pozneje."; "Common.Alerts.DeletePost.Message" = "Ali ste prepričani, da želite izbrisati to objavo?"; "Common.Alerts.DeletePost.Title" = "Izbriši objavo"; -"Common.Alerts.DiscardPostContent.Message" = "Potrdite za opustitev sestavljene vsebine objave."; -"Common.Alerts.DiscardPostContent.Title" = "Zavrzi osnutek"; "Common.Alerts.EditProfileFailure.Message" = "Profila ni mogoče urejati. Poskusite znova."; "Common.Alerts.EditProfileFailure.Title" = "Napaka urejanja profila"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "Ni možno priložiti več kot enega videoposnetka."; @@ -530,7 +528,7 @@ možno naložiti v Mastodon."; "Scene.Welcome.Education.Mastodon.Title" = "Dobrodošli na Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Vsak račun Mastodon gostuje na strežniku — vsak strežnik ima svoje vrednote, pravila in skbrnike. Vseeno je, katerega izberete - sledite in komunicirate lahko z osebbami na poljubnem strežniku."; "Scene.Welcome.Education.Servers.Title" = "Kaj so strežniki?"; -"Scene.Welcome.JoinDefaultServer" = "Join %@"; +"Scene.Welcome.JoinDefaultServer" = "Pridruži se %@"; "Scene.Welcome.LearnMore" = "Več o tem"; "Scene.Welcome.LogIn" = "Prijava"; "Scene.Welcome.PickServer" = "Izberi drug strežnik"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.strings index cdd014501..66250f6f9 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "Var god försök igen senare."; "Common.Alerts.DeletePost.Message" = "Är du säker på att du vill radera detta inlägg?"; "Common.Alerts.DeletePost.Title" = "Radera inlägg"; -"Common.Alerts.DiscardPostContent.Message" = "Bekräfta för att slänga inläggsutkast."; -"Common.Alerts.DiscardPostContent.Title" = "Släng utkast"; "Common.Alerts.EditProfileFailure.Message" = "Kan inte redigera profil. Var god försök igen."; "Common.Alerts.EditProfileFailure.Title" = "Kunde inte redigera profil"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "Det går inte att bifoga mer än en video."; @@ -30,7 +28,7 @@ Kontrollera din internetanslutning."; "Common.Controls.Actions.Add" = "Lägg till"; "Common.Controls.Actions.Back" = "Tillbaka"; "Common.Controls.Actions.BlockDomain" = "Blockera %@"; -"Common.Controls.Actions.Bookmark" = "Bookmark"; +"Common.Controls.Actions.Bookmark" = "Bokmärk"; "Common.Controls.Actions.Cancel" = "Avbryt"; "Common.Controls.Actions.Compose" = "Skriv"; "Common.Controls.Actions.Confirm" = "Bekräfta"; @@ -43,7 +41,7 @@ Kontrollera din internetanslutning."; "Common.Controls.Actions.Edit" = "Redigera"; "Common.Controls.Actions.EditPost" = "Redigera"; "Common.Controls.Actions.FindPeople" = "Hitta personer att följa"; -"Common.Controls.Actions.Follow" = "Follow %@"; +"Common.Controls.Actions.Follow" = "Följ %@"; "Common.Controls.Actions.ManuallySearch" = "Sök manuellt istället"; "Common.Controls.Actions.Next" = "Nästa"; "Common.Controls.Actions.Ok" = "OK"; @@ -53,7 +51,7 @@ Kontrollera din internetanslutning."; "Common.Controls.Actions.Preview" = "Förhandsvisa"; "Common.Controls.Actions.Previous" = "Föregående"; "Common.Controls.Actions.Remove" = "Radera"; -"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; +"Common.Controls.Actions.RemoveBookmark" = "Ta bort bokmärke"; "Common.Controls.Actions.Reply" = "Svara"; "Common.Controls.Actions.ReportUser" = "Rapportera %@"; "Common.Controls.Actions.Save" = "Spara"; @@ -70,7 +68,7 @@ Kontrollera din internetanslutning."; "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Okänt"; "Common.Controls.Actions.TryAgain" = "Försök igen"; "Common.Controls.Actions.UnblockDomain" = "Avblockera %@"; -"Common.Controls.Actions.Unfollow" = "Unfollow %@"; +"Common.Controls.Actions.Unfollow" = "Avfölj %@"; "Common.Controls.Friendship.Block" = "Blockera"; "Common.Controls.Friendship.BlockDomain" = "Blockera %@"; "Common.Controls.Friendship.BlockUser" = "Blockera %@"; @@ -151,7 +149,7 @@ Kontrollera din internetanslutning."; "Common.Controls.Status.Tag.Mention" = "Omnämn"; "Common.Controls.Status.Tag.Url" = "URL"; "Common.Controls.Status.TapToReveal" = "Tryck för att visa"; -"Common.Controls.Status.Translation.ShowOriginal" = "Show Original"; +"Common.Controls.Status.Translation.ShowOriginal" = "Visa original"; "Common.Controls.Status.Translation.TranslatedFrom" = "Översatt från %@ med %@"; "Common.Controls.Status.Translation.UnknownLanguage" = "Okänt"; "Common.Controls.Status.Translation.UnknownProvider" = "Okänd"; @@ -226,11 +224,11 @@ laddas upp till Mastodon."; "Scene.Compose.Language.Other" = "Andra språk…"; "Scene.Compose.Language.Recent" = "Senaste"; "Scene.Compose.Language.Suggested" = "Suggested"; -"Scene.Compose.Language.Title" = "Post Language"; +"Scene.Compose.Language.Title" = "Inläggsspråk"; "Scene.Compose.MediaSelection.Browse" = "Bläddra"; "Scene.Compose.MediaSelection.Camera" = "Ta foto"; "Scene.Compose.MediaSelection.PhotoLibrary" = "Fotobibliotek"; -"Scene.Compose.Poll.AddOption" = "Add Option"; +"Scene.Compose.Poll.AddOption" = "Lägg till alternativ"; "Scene.Compose.Poll.DurationTime" = "Längd: %@"; "Scene.Compose.Poll.MoveDown" = "Flytta ned"; "Scene.Compose.Poll.MoveUp" = "Flytta upp"; @@ -317,7 +315,7 @@ laddas upp till Mastodon."; "Scene.Privacy.Description" = "Även om Mastodon-appen inte samlar in någon data kan servern du registrerar dig genom ha en annan policy. Ta en stund till att granska och godkänna Mastodon-appens sekretesspolicy och din servers sekretesspolicy."; "Scene.Privacy.Policy.Ios" = "Integritetspolicy - Mastodon för iOS"; "Scene.Privacy.Policy.Server" = "Integritetspolicy - %@"; -"Scene.Privacy.Title" = "Privacy"; +"Scene.Privacy.Title" = "Integritet"; "Scene.Profile.Accessibility.DoubleTapToOpenTheList" = "Dubbeltryck för att öppna listan"; "Scene.Profile.Accessibility.EditAvatarImage" = "Redigera profilbild"; "Scene.Profile.Accessibility.ShowAvatarImage" = "Visa profilbild"; @@ -477,7 +475,7 @@ laddas upp till Mastodon."; "Scene.ServerPicker.Language.All" = "All"; "Scene.ServerPicker.NoServerSelectedHint" = "Vi kommer att välja en server baserat på ditt språk om du fortsätter utan att göra ett val."; "Scene.ServerPicker.Search.Placeholder" = "Sök namn eller URL"; -"Scene.ServerPicker.SignupSpeed.All" = "All"; +"Scene.ServerPicker.SignupSpeed.All" = "Allt"; "Scene.ServerPicker.SignupSpeed.Instant" = "Instant Sign-up"; "Scene.ServerPicker.SignupSpeed.ManuallyReviewed" = "Manuell granskning"; "Scene.ServerPicker.Title" = "Välj server"; @@ -530,7 +528,7 @@ laddas upp till Mastodon."; "Scene.Welcome.Education.Mastodon.Title" = "Välkommen till Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Varje Mastodon-konto finns på en server — var och en med sina värderingar, regler och administratörer. Oavsett vilken du väljer kan du följa och interagera med människor på vilken server som helst."; "Scene.Welcome.Education.Servers.Title" = "Vad är servrar?"; -"Scene.Welcome.JoinDefaultServer" = "Join %@"; +"Scene.Welcome.JoinDefaultServer" = "Gå med %@"; "Scene.Welcome.LearnMore" = "Läs mer"; "Scene.Welcome.LogIn" = "Logga in"; "Scene.Welcome.PickServer" = "Hitta en annan server"; @@ -545,13 +543,13 @@ laddas upp till Mastodon."; "Widget.Hashtag.Configuration.DisplayName" = "Hashtag"; "Widget.Hashtag.NotFound.Account" = "@johnMastodon@no-such.account"; "Widget.Hashtag.NotFound.AccountName" = "John Mastodon"; -"Widget.Hashtag.NotFound.Content" = "Sorry, we couldn’t find any posts with the hashtag #%@. Please try a #DifferentHashtag or check the widget settings."; +"Widget.Hashtag.NotFound.Content" = "Ledsen, vi kunde inte hitta några inlägg med hashtaggen #%@. Prova en #AnnanHashtagg eller kontrollera widgetinställningarna."; "Widget.Hashtag.Placeholder.Account" = "@johnMastodon@no-such.account"; "Widget.Hashtag.Placeholder.AccountName" = "John Mastodon"; "Widget.Hashtag.Placeholder.Content" = "This is how a post with a #hashtag would look. Pick whichever #hashtag you want in the widget settings."; "Widget.LatestFollowers.ConfigurationDescription" = "Show latest followers."; "Widget.LatestFollowers.ConfigurationDisplayName" = "Latest followers"; -"Widget.LatestFollowers.LastUpdate" = "Last update: %@"; +"Widget.LatestFollowers.LastUpdate" = "Senaste uppdatering: %@"; "Widget.LatestFollowers.Title" = "Latest followers"; "Widget.MultipleFollowers.ConfigurationDescription" = "Show number of followers for multiple accounts."; "Widget.MultipleFollowers.ConfigurationDisplayName" = "Multiple followers"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.strings index 9de86d444..c32884677 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "โปรดลองอีกครั้งในภายหลัง"; "Common.Alerts.DeletePost.Message" = "คุณแน่ใจหรือไม่ว่าต้องการลบโพสต์นี้?"; "Common.Alerts.DeletePost.Title" = "ลบโพสต์"; -"Common.Alerts.DiscardPostContent.Message" = "ยืนยันเพื่อละทิ้งเนื้อหาโพสต์ที่เขียน"; -"Common.Alerts.DiscardPostContent.Title" = "ละทิ้งแบบร่าง"; "Common.Alerts.EditProfileFailure.Message" = "ไม่สามารถแก้ไขโปรไฟล์ โปรดลองอีกครั้ง"; "Common.Alerts.EditProfileFailure.Title" = "ข้อผิดพลาดการแก้ไขโปรไฟล์"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "ไม่สามารถแนบมากกว่าหนึ่งวิดีโอ"; @@ -278,7 +276,7 @@ "Scene.FavoritedBy.Title" = "ชื่นชอบโดย"; "Scene.FollowedTags.Actions.Follow" = "ติดตาม"; "Scene.FollowedTags.Actions.Unfollow" = "เลิกติดตาม"; -"Scene.FollowedTags.Header.Participants" = "ผู้เข้าร่วม"; +"Scene.FollowedTags.Header.Participants" = "ผู้มีส่วนร่วม"; "Scene.FollowedTags.Header.Posts" = "โพสต์"; "Scene.FollowedTags.Header.PostsToday" = "โพสต์วันนี้"; "Scene.FollowedTags.Title" = "แท็กที่ติดตาม"; @@ -530,7 +528,7 @@ "Scene.Welcome.Education.Mastodon.Title" = "ยินดีต้อนรับสู่ Mastodon"; "Scene.Welcome.Education.Servers.Description" = "ทุกบัญชี Mastodon ได้รับการโฮสต์ในเซิร์ฟเวอร์ — แต่ละแห่งมีค่า, กฎ และผู้ดูแลของเซิร์ฟเวอร์เอง ไม่ว่าคุณจะเลือกเซิร์ฟเวอร์ใด คุณสามารถติดตามและโต้ตอบกับผู้คนในเซิร์ฟเวอร์ใด ๆ"; "Scene.Welcome.Education.Servers.Title" = "เซิร์ฟเวอร์คืออะไร?"; -"Scene.Welcome.JoinDefaultServer" = "Join %@"; +"Scene.Welcome.JoinDefaultServer" = "เข้าร่วม %@"; "Scene.Welcome.LearnMore" = "เรียนรู้เพิ่มเติม"; "Scene.Welcome.LogIn" = "เข้าสู่ระบบ"; "Scene.Welcome.PickServer" = "เลือกเซิร์ฟเวอร์อื่น"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.strings index 974cb1568..267075070 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "Lütfen daha sonra tekrar deneyin."; "Common.Alerts.DeletePost.Message" = "Bu gönderiyi silmek istediğinize emin misiniz?"; "Common.Alerts.DeletePost.Title" = "Gönderiyi Sil"; -"Common.Alerts.DiscardPostContent.Message" = "Yazdığın gönderiyi paylaşmadan silmek istiyor musun?"; -"Common.Alerts.DiscardPostContent.Title" = "Taslağı Sil"; "Common.Alerts.EditProfileFailure.Message" = "Profil düzenlenemedi. Lütfen tekrar deneyin."; "Common.Alerts.EditProfileFailure.Title" = "Profil Düzenleme Hatası"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "Gönderiye birden fazla video eklenemez."; @@ -21,7 +19,7 @@ "Common.Alerts.SignOut.Message" = "Oturumu kapatmak istediğinize emin misiniz?"; "Common.Alerts.SignOut.Title" = "Oturumu Kapat"; "Common.Alerts.SignUpFailure.Title" = "Kaydolma Başarısız"; -"Common.Alerts.TranslationFailed.Button" = "OK"; +"Common.Alerts.TranslationFailed.Button" = "Tamam"; "Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported."; "Common.Alerts.TranslationFailed.Title" = "Note"; "Common.Alerts.VoteFailure.PollEnded" = "Anket bitti"; @@ -29,20 +27,20 @@ "Common.Controls.Actions.Add" = "Ekle"; "Common.Controls.Actions.Back" = "Geri"; "Common.Controls.Actions.BlockDomain" = "%@ kişisini engelle"; -"Common.Controls.Actions.Bookmark" = "Bookmark"; +"Common.Controls.Actions.Bookmark" = "Yer işareti"; "Common.Controls.Actions.Cancel" = "İptal et"; "Common.Controls.Actions.Compose" = "Yaz"; "Common.Controls.Actions.Confirm" = "Onayla"; "Common.Controls.Actions.Continue" = "Devam et"; -"Common.Controls.Actions.Copy" = "Copy"; +"Common.Controls.Actions.Copy" = "Kopyala"; "Common.Controls.Actions.CopyPhoto" = "Fotoğrafı Kopyala"; "Common.Controls.Actions.Delete" = "Sil"; "Common.Controls.Actions.Discard" = "Vazgeç"; "Common.Controls.Actions.Done" = "Kapat"; "Common.Controls.Actions.Edit" = "Düzenle"; -"Common.Controls.Actions.EditPost" = "Edit"; +"Common.Controls.Actions.EditPost" = "Düzenle"; "Common.Controls.Actions.FindPeople" = "Takip etmek için birkaç kişi bul"; -"Common.Controls.Actions.Follow" = "Follow %@"; +"Common.Controls.Actions.Follow" = "%@ takip et"; "Common.Controls.Actions.ManuallySearch" = "Onun yerine manuel olarak ara"; "Common.Controls.Actions.Next" = "İleri"; "Common.Controls.Actions.Ok" = "Tamam"; @@ -52,7 +50,7 @@ "Common.Controls.Actions.Preview" = "Önizleme"; "Common.Controls.Actions.Previous" = "Önceki"; "Common.Controls.Actions.Remove" = "Kaldır"; -"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; +"Common.Controls.Actions.RemoveBookmark" = "Yer işaretini kaldır"; "Common.Controls.Actions.Reply" = "Yanıtla"; "Common.Controls.Actions.ReportUser" = "%@ kişisini bildir"; "Common.Controls.Actions.Save" = "Kaydet"; @@ -65,8 +63,8 @@ "Common.Controls.Actions.SignIn" = "Giriş Yap"; "Common.Controls.Actions.Skip" = "Atla"; "Common.Controls.Actions.TakePhoto" = "Fotoğraf Çek"; -"Common.Controls.Actions.TranslatePost.Title" = "Translate from %@"; -"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Unknown"; +"Common.Controls.Actions.TranslatePost.Title" = "%@ dilinden çevrildi"; +"Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Bilinmeyen"; "Common.Controls.Actions.TryAgain" = "Tekrar Deneyin"; "Common.Controls.Actions.UnblockDomain" = "%@ kişisinin engelini kaldır"; "Common.Controls.Actions.Unfollow" = "Unfollow %@"; @@ -104,27 +102,27 @@ "Common.Controls.Keyboard.Timeline.ToggleContentWarning" = "İçerik Uyarısı durumunu değiştir"; "Common.Controls.Keyboard.Timeline.ToggleFavorite" = "Gönderiyi favorileme durumunu değiştir"; "Common.Controls.Keyboard.Timeline.ToggleReblog" = "Gönderiyi yeniden paylaşma durumunu değiştir"; -"Common.Controls.Status.Actions.A11YLabels.Reblog" = "Re-blog"; -"Common.Controls.Status.Actions.A11YLabels.Unreblog" = "Undo re-blog"; +"Common.Controls.Status.Actions.A11YLabels.Reblog" = "Yeniden paylaş"; +"Common.Controls.Status.Actions.A11YLabels.Unreblog" = "Yeniden paylaşımı geri al"; "Common.Controls.Status.Actions.Favorite" = "Favorile"; "Common.Controls.Status.Actions.Hide" = "Gizle"; "Common.Controls.Status.Actions.Menu" = "Menü"; "Common.Controls.Status.Actions.Reblog" = "Yeniden paylaş"; "Common.Controls.Status.Actions.Reply" = "Yanıtla"; -"Common.Controls.Status.Actions.ShareLinkInPost" = "Share Link in Post"; +"Common.Controls.Status.Actions.ShareLinkInPost" = "Bağlantıyı Gönderide Paylaş"; "Common.Controls.Status.Actions.ShowGif" = "GIF'i göster"; "Common.Controls.Status.Actions.ShowImage" = "Görüntüyü göster"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "Video oynatıcıyı göster"; "Common.Controls.Status.Actions.TapThenHoldToShowMenu" = "Menüyü göstermek için dokunun ve basılı tutun"; "Common.Controls.Status.Actions.Unfavorite" = "Favorilerden Çıkar"; "Common.Controls.Status.Actions.Unreblog" = "Yeniden paylaşımı geri al"; -"Common.Controls.Status.Buttons.EditHistoryDetail" = "Last edit %@"; -"Common.Controls.Status.Buttons.EditHistoryTitle" = "Edit History"; -"Common.Controls.Status.Buttons.FavoritesTitle" = "Favorites"; +"Common.Controls.Status.Buttons.EditHistoryDetail" = "Son güncelleme: %@"; +"Common.Controls.Status.Buttons.EditHistoryTitle" = "Düzenleme Geçmişi"; +"Common.Controls.Status.Buttons.FavoritesTitle" = "Favoriler"; "Common.Controls.Status.Buttons.ReblogsTitle" = "Reblogs"; "Common.Controls.Status.ContentWarning" = "İçerik Uyarısı"; "Common.Controls.Status.EditHistory.OriginalPost" = "Original Post · %@"; -"Common.Controls.Status.EditHistory.Title" = "Edit History"; +"Common.Controls.Status.EditHistory.Title" = "Düzenleme Geçmişi"; "Common.Controls.Status.EditedAtTimestampPrefix" = "Edited %@"; "Common.Controls.Status.LinkViaUser" = "%@ via %@"; "Common.Controls.Status.LoadEmbed" = "Load Embed"; @@ -150,18 +148,18 @@ "Common.Controls.Status.Tag.Mention" = "Bahset"; "Common.Controls.Status.Tag.Url" = "Bağlantı"; "Common.Controls.Status.TapToReveal" = "Göstermek için basın"; -"Common.Controls.Status.Translation.ShowOriginal" = "Show Original"; +"Common.Controls.Status.Translation.ShowOriginal" = "Orijinali Göster"; "Common.Controls.Status.Translation.TranslatedFrom" = "Translated from %@ using %@"; -"Common.Controls.Status.Translation.UnknownLanguage" = "Unknown"; -"Common.Controls.Status.Translation.UnknownProvider" = "Unknown"; +"Common.Controls.Status.Translation.UnknownLanguage" = "Bilinmeyen"; +"Common.Controls.Status.Translation.UnknownProvider" = "Bilinmeyen"; "Common.Controls.Status.UserReblogged" = "%@ yeniden paylaştı"; "Common.Controls.Status.UserRepliedTo" = "%@ kullanıcısına yanıt verdi"; "Common.Controls.Status.Visibility.Direct" = "Sadece bahsedilen kullanıcı bu gönderiyi görebilir."; "Common.Controls.Status.Visibility.Private" = "Sadece gönderi sahibinin takipçileri bu gönderiyi görebilir."; "Common.Controls.Status.Visibility.PrivateFromMe" = "Sadece benim takipçilerim bu gönderiyi görebilir."; "Common.Controls.Status.Visibility.Unlisted" = "Bu gönderiyi herkes görebilir, fakat herkese açık zaman tünelinde gösterilmez."; -"Common.Controls.Tabs.A11Y.Explore" = "Explore"; -"Common.Controls.Tabs.A11Y.Search" = "Search"; +"Common.Controls.Tabs.A11Y.Explore" = "Keşfet"; +"Common.Controls.Tabs.A11Y.Search" = "Ara"; "Common.Controls.Tabs.Home" = "Ana Sayfa"; "Common.Controls.Tabs.Notifications" = "Bildirimler"; "Common.Controls.Tabs.Profile" = "Profil"; @@ -185,7 +183,7 @@ Bu kişiye göre profiliniz böyle gözüküyor."; "Common.Controls.Timeline.Loader.ShowMoreReplies" = "Daha fazla yanıt görüntüe"; "Common.Controls.Timeline.Timestamp.Now" = "Şimdi"; "Common.UserList.FollowersCount" = "%@ followers"; -"Common.UserList.NoVerifiedLink" = "No verified link"; +"Common.UserList.NoVerifiedLink" = "Doğrulanmamış bağlantı"; "Extension.OpenIn.InvalidLinkError" = "This doesn't seem to be a valid Mastodon link."; "Scene.AccountList.AddAccount" = "Hesap Ekle"; "Scene.AccountList.DismissAccountSwitcher" = "Hesap Değiştiriciyi Kapat"; @@ -224,28 +222,28 @@ yüklenemiyor."; "Scene.Compose.Keyboard.TogglePoll" = "Anketi Aç/Kapat"; "Scene.Compose.Language.Other" = "Other Language…"; "Scene.Compose.Language.Recent" = "Recent"; -"Scene.Compose.Language.Suggested" = "Suggested"; -"Scene.Compose.Language.Title" = "Post Language"; +"Scene.Compose.Language.Suggested" = "Önerilen"; +"Scene.Compose.Language.Title" = "Gönderi dili"; "Scene.Compose.MediaSelection.Browse" = "Göz at"; "Scene.Compose.MediaSelection.Camera" = "Fotoğraf Çek"; "Scene.Compose.MediaSelection.PhotoLibrary" = "Fotoğraf Albümü"; -"Scene.Compose.Poll.AddOption" = "Add Option"; +"Scene.Compose.Poll.AddOption" = "Seçenek Ekle"; "Scene.Compose.Poll.DurationTime" = "Süre: %@"; "Scene.Compose.Poll.MoveDown" = "Move Down"; "Scene.Compose.Poll.MoveUp" = "Move Up"; "Scene.Compose.Poll.OneDay" = "1 Gün"; "Scene.Compose.Poll.OneHour" = "1 Saat"; "Scene.Compose.Poll.OptionNumber" = "Seçenek %ld"; -"Scene.Compose.Poll.RemoveOption" = "Remove Option"; +"Scene.Compose.Poll.RemoveOption" = "Seçeneği Kaldır"; "Scene.Compose.Poll.SevenDays" = "7 Gün"; "Scene.Compose.Poll.SixHours" = "6 Saat"; "Scene.Compose.Poll.ThePollHasEmptyOption" = "The poll has empty option"; "Scene.Compose.Poll.ThePollIsInvalid" = "Anket geçersiz"; "Scene.Compose.Poll.ThirtyMinutes" = "30 dakika"; "Scene.Compose.Poll.ThreeDays" = "3 Gün"; -"Scene.Compose.Poll.Title" = "Poll"; +"Scene.Compose.Poll.Title" = "Anket"; "Scene.Compose.ReplyingToUser" = "yanıtlanıyor: %@"; -"Scene.Compose.Title.EditPost" = "Edit Post"; +"Scene.Compose.Title.EditPost" = "Gönderiyi Düzenle"; "Scene.Compose.Title.NewPost" = "Yeni Gönderi"; "Scene.Compose.Title.NewReply" = "Yeni Yanıt"; "Scene.Compose.Visibility.Direct" = "Sadece bahsettiğim insanlar"; @@ -253,18 +251,18 @@ yüklenemiyor."; "Scene.Compose.Visibility.Public" = "Herkese açık"; "Scene.Compose.Visibility.Unlisted" = "Listelenmemiş"; "Scene.ConfirmEmail.Button.Resend" = "Yeniden gönder"; -"Scene.ConfirmEmail.DidntGetLink.Prefix" = "Didn’t get a link?"; +"Scene.ConfirmEmail.DidntGetLink.Prefix" = "Bağlantı gelmedi mi?"; "Scene.ConfirmEmail.DidntGetLink.ResendIn" = "Resend (%@)"; -"Scene.ConfirmEmail.DidntGetLink.ResendNow" = "Resend now."; +"Scene.ConfirmEmail.DidntGetLink.ResendNow" = "Yeniden gönder."; "Scene.ConfirmEmail.DontReceiveEmail.Description" = "E-posta adresinizin doğru olup olmadığını ve doğru ise gereksiz klasörünüzü kontrol edin."; "Scene.ConfirmEmail.DontReceiveEmail.ResendEmail" = "E-postayı Yeniden Gönder"; -"Scene.ConfirmEmail.DontReceiveEmail.Title" = "Check your Email"; +"Scene.ConfirmEmail.DontReceiveEmail.Title" = "E-postanızı kontrol edin"; "Scene.ConfirmEmail.OpenEmailApp.Description" = "Size bir e-posta gönderdik. Eğer e-postayı almadıysanız, gereksiz klasörünü kontrol edin."; "Scene.ConfirmEmail.OpenEmailApp.Mail" = "Posta"; "Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "E-posta İstemcisini Aç"; -"Scene.ConfirmEmail.OpenEmailApp.Title" = "Check your Inbox."; +"Scene.ConfirmEmail.OpenEmailApp.Title" = "Gelen kutunuzu kontrol edin."; "Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Tap the link we sent you to verify %@. We’ll wait right here."; -"Scene.ConfirmEmail.Title" = "Check Your Inbox"; +"Scene.ConfirmEmail.Title" = "Gelen kutunuzu kontrol edin"; "Scene.Discovery.Intro" = "Bunlar, Mastodon'un köşesinde ilgi çeken gönderilerdir."; "Scene.Discovery.Tabs.Community" = "Topluluk"; "Scene.Discovery.Tabs.ForYou" = "Senin İçin"; @@ -273,7 +271,7 @@ yüklenemiyor."; "Scene.Discovery.Tabs.Posts" = "Gönderiler"; "Scene.Familiarfollowers.FollowedByNames" = "%@ tarafından takip ediliyor"; "Scene.Familiarfollowers.Title" = "Tanıyor olabileceğin takipçiler"; -"Scene.Favorite.Title" = "Favorites"; +"Scene.Favorite.Title" = "Favoriler"; "Scene.FavoritedBy.Title" = "Favorited By"; "Scene.FollowedTags.Actions.Follow" = "Takip et"; "Scene.FollowedTags.Actions.Unfollow" = "Takibi bırak"; @@ -294,7 +292,7 @@ yüklenemiyor."; "Scene.HomeTimeline.Title" = "Ana Sayfa"; "Scene.Login.ServerSearchField.Placeholder" = "Bir URL girin ya da sunucunuzu arayın"; "Scene.Login.Subtitle" = "Hesabını oluşturduğun sunucuya giriş yap."; -"Scene.Login.Title" = "Welcome back"; +"Scene.Login.Title" = "Tekrar hoş geldiniz"; "Scene.Notification.FollowRequest.Accept" = "Kabul Et"; "Scene.Notification.FollowRequest.Accepted" = "Kabul Edildi"; "Scene.Notification.FollowRequest.Reject" = "Reddet"; @@ -312,22 +310,22 @@ yüklenemiyor."; "Scene.Preview.Keyboard.ClosePreview" = "Önizlemeyi Kapat"; "Scene.Preview.Keyboard.ShowNext" = "Sonrakini Göster"; "Scene.Preview.Keyboard.ShowPrevious" = "Öncekini Göster"; -"Scene.Privacy.Button.Confirm" = "I Agree"; +"Scene.Privacy.Button.Confirm" = "Kabul Ediyorum"; "Scene.Privacy.Description" = "Although the Mastodon app does not collect any data, the server you sign up through may have a different policy. Take a minute to review and agree to the Mastodon app privacy policy and your server’s privacy policy."; -"Scene.Privacy.Policy.Ios" = "Privacy Policy - Mastodon for iOS"; -"Scene.Privacy.Policy.Server" = "Privacy Policy - %@"; -"Scene.Privacy.Title" = "Privacy"; +"Scene.Privacy.Policy.Ios" = "Gizlilik Politikası - iOS için Mastodon"; +"Scene.Privacy.Policy.Server" = "Gizlilik Politikası - %@"; +"Scene.Privacy.Title" = "Gizlilik"; "Scene.Profile.Accessibility.DoubleTapToOpenTheList" = "Listeyi açmak için çift tıklayın"; "Scene.Profile.Accessibility.EditAvatarImage" = "Profil fotoğrafını düzenle"; "Scene.Profile.Accessibility.ShowAvatarImage" = "Profil resmini göster"; "Scene.Profile.Accessibility.ShowBannerImage" = "Kapak fotoğrafını göster"; "Scene.Profile.Dashboard.FamiliarFollowers" = "mutuals"; -"Scene.Profile.Dashboard.MyFollowers" = "followers"; -"Scene.Profile.Dashboard.MyFollowing" = "following"; -"Scene.Profile.Dashboard.MyPosts" = "posts"; +"Scene.Profile.Dashboard.MyFollowers" = "takipçiler"; +"Scene.Profile.Dashboard.MyFollowing" = "takip ediliyor"; +"Scene.Profile.Dashboard.MyPosts" = "gönderiler"; "Scene.Profile.Dashboard.OtherFollowers" = "followers"; "Scene.Profile.Dashboard.OtherFollowing" = "following"; -"Scene.Profile.Dashboard.OtherPosts" = "posts"; +"Scene.Profile.Dashboard.OtherPosts" = "gönderiler"; "Scene.Profile.Fields.AddRow" = "Satır Ekle"; "Scene.Profile.Fields.Joined" = "Joined"; "Scene.Profile.Fields.Placeholder.Content" = "İçerik"; @@ -365,7 +363,7 @@ yüklenemiyor."; "Scene.Register.Error.Reason.Inclusion" = "%@ desteklenen bir değer değil"; "Scene.Register.Error.Reason.Invalid" = "%@ geçersiz"; "Scene.Register.Error.Reason.Reserved" = "%@ rezerve edilen bir kelime"; -"Scene.Register.Error.Reason.Taken" = "%@ is already taken. How about:"; +"Scene.Register.Error.Reason.Taken" = "%@ zaten alınmış. Buna ne dersiniz:"; "Scene.Register.Error.Reason.TooLong" = "%@ çok uzun"; "Scene.Register.Error.Reason.TooShort" = "%@ çok kısa"; "Scene.Register.Error.Reason.Unreachable" = "%@ mevcut değil"; @@ -380,14 +378,14 @@ yüklenemiyor."; "Scene.Register.Input.Password.Accessibility.Checked" = "işaretli"; "Scene.Register.Input.Password.Accessibility.Unchecked" = "işaretsiz"; "Scene.Register.Input.Password.CharacterLimit" = "8 karakter"; -"Scene.Register.Input.Password.ConfirmationPlaceholder" = "Confirm Password"; +"Scene.Register.Input.Password.ConfirmationPlaceholder" = "Parolanızı Doğrulayın"; "Scene.Register.Input.Password.Hint" = "Parolanız en az sekiz karakter içermelidir"; "Scene.Register.Input.Password.Placeholder" = "parola"; "Scene.Register.Input.Password.Require" = "Parolanızda en azından şunlar olmalı:"; "Scene.Register.Input.Username.DuplicatePrompt" = "Bu kullanıcı adı alınmış."; "Scene.Register.Input.Username.Placeholder" = "kullanıcı adı"; "Scene.Register.Input.Username.Suggestion" = "amazing_%@"; -"Scene.Register.Title" = "Create Account"; +"Scene.Register.Title" = "Hesap Oluştur"; "Scene.Report.Content1" = "Bu rapora eklemek istediğiniz başka gönderiler var mı?"; "Scene.Report.Content2" = "Bu rapor hakkında moderatörlerin bilmesi gerektiği bir şey var mı?"; "Scene.Report.ReportSentTitle" = "Rapor için teşekkürler, bununla ilgileneceğiz."; @@ -462,7 +460,7 @@ yüklenemiyor."; "Scene.ServerPicker.Button.Category.Music" = "müzik"; "Scene.ServerPicker.Button.Category.Regional" = "bölgesel"; "Scene.ServerPicker.Button.Category.Tech" = "teknoloji"; -"Scene.ServerPicker.Button.Language" = "Language"; +"Scene.ServerPicker.Button.Language" = "Dil"; "Scene.ServerPicker.Button.SeeLess" = "Daha Az Göster"; "Scene.ServerPicker.Button.SeeMore" = "Daha Fazla Gör"; "Scene.ServerPicker.Button.SignupSpeed" = "Sign-up Speed"; @@ -473,14 +471,14 @@ yüklenemiyor."; "Scene.ServerPicker.Label.Category" = "KATEGORİ"; "Scene.ServerPicker.Label.Language" = "DİL"; "Scene.ServerPicker.Label.Users" = "KULLANICILAR"; -"Scene.ServerPicker.Language.All" = "All"; +"Scene.ServerPicker.Language.All" = "Hepsi"; "Scene.ServerPicker.NoServerSelectedHint" = "We’ll pick a server based on your language if you continue without making a selection."; -"Scene.ServerPicker.Search.Placeholder" = "Search name or URL"; -"Scene.ServerPicker.SignupSpeed.All" = "All"; +"Scene.ServerPicker.Search.Placeholder" = "İsim ya da bağlantı arayın"; +"Scene.ServerPicker.SignupSpeed.All" = "Hepsi"; "Scene.ServerPicker.SignupSpeed.Instant" = "Instant Sign-up"; "Scene.ServerPicker.SignupSpeed.ManuallyReviewed" = "Manual Review"; -"Scene.ServerPicker.Title" = "Pick Server"; -"Scene.ServerRules.Button.Confirm" = "I Agree"; +"Scene.ServerPicker.Title" = "Sunucu Seç"; +"Scene.ServerRules.Button.Confirm" = "Kabul Ediyorum"; "Scene.ServerRules.PrivacyPolicy" = "gizlilik politikası"; "Scene.ServerRules.Prompt" = "Devam ederek, %@ için kullanım şartlarını ve gizlilik politikasını kabul etmiş olursunuz."; "Scene.ServerRules.Subtitle" = "Bunlar, %@ moderatörleri tarafından ayarlanmış ve uygulanmıştır."; @@ -520,38 +518,38 @@ yüklenemiyor."; "Scene.Settings.Section.SpicyZone.Signout" = "Oturumu Kapat"; "Scene.Settings.Section.SpicyZone.Title" = "Tehlikeli bölge"; "Scene.Settings.Title" = "Ayarlar"; -"Scene.SuggestionAccount.FollowAll" = "Follow all"; -"Scene.SuggestionAccount.Title" = "Popular on Mastodon"; +"Scene.SuggestionAccount.FollowAll" = "Hepsini takip et"; +"Scene.SuggestionAccount.Title" = "Mastodon'da popüler"; "Scene.Thread.BackTitle" = "Gönderi"; "Scene.Thread.Title" = "%@ kullanıcının gönderisi"; -"Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "What is Mastodon?"; +"Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "Mastodon nedir?"; "Scene.Welcome.Education.Mastodon.Description" = "Mastodon is a decentralized social network, meaning no single company controls it. It’s made up of many independently-run servers, all connected together."; -"Scene.Welcome.Education.Mastodon.Title" = "Welcome to Mastodon"; +"Scene.Welcome.Education.Mastodon.Title" = "Mastodon'a Hoş Geldin"; "Scene.Welcome.Education.Servers.Description" = "Every Mastodon account is hosted on a server — each with its own values, rules, & admins. No matter which one you pick, you can follow and interact with people on any server."; "Scene.Welcome.Education.Servers.Title" = "What are servers?"; -"Scene.Welcome.JoinDefaultServer" = "Join %@"; -"Scene.Welcome.LearnMore" = "Learn more"; +"Scene.Welcome.JoinDefaultServer" = "%@ katıl"; +"Scene.Welcome.LearnMore" = "Daha fazla bilgi edin"; "Scene.Welcome.LogIn" = "Oturum Aç"; -"Scene.Welcome.PickServer" = "Pick another server"; -"Scene.Welcome.Separator.Or" = "or"; +"Scene.Welcome.PickServer" = "Başka sunucu seç"; +"Scene.Welcome.Separator.Or" = "veya"; "Widget.Common.UnsupportedWidgetFamily" = "Sorry but this Widget family is unsupported."; "Widget.Common.UserNotLoggedIn" = "Please open Mastodon to log in to an Account."; "Widget.FollowersCount.ConfigurationDescription" = "Show number of followers."; -"Widget.FollowersCount.ConfigurationDisplayName" = "Followers"; +"Widget.FollowersCount.ConfigurationDisplayName" = "Takipçiler"; "Widget.FollowersCount.FollowersToday" = "%@ followers today"; -"Widget.FollowersCount.Title" = "FOLLOWERS"; +"Widget.FollowersCount.Title" = "TAKİPÇİLER"; "Widget.Hashtag.Configuration.Description" = "Shows a recent post with the selected hashtag."; -"Widget.Hashtag.Configuration.DisplayName" = "Hashtag"; +"Widget.Hashtag.Configuration.DisplayName" = "Etiket"; "Widget.Hashtag.NotFound.Account" = "@johnMastodon@no-such.account"; "Widget.Hashtag.NotFound.AccountName" = "John Mastodon"; "Widget.Hashtag.NotFound.Content" = "Sorry, we couldn’t find any posts with the hashtag #%@. Please try a #DifferentHashtag or check the widget settings."; "Widget.Hashtag.Placeholder.Account" = "@johnMastodon@no-such.account"; "Widget.Hashtag.Placeholder.AccountName" = "John Mastodon"; "Widget.Hashtag.Placeholder.Content" = "This is how a post with a #hashtag would look. Pick whichever #hashtag you want in the widget settings."; -"Widget.LatestFollowers.ConfigurationDescription" = "Show latest followers."; -"Widget.LatestFollowers.ConfigurationDisplayName" = "Latest followers"; +"Widget.LatestFollowers.ConfigurationDescription" = "Son takipçileri göster."; +"Widget.LatestFollowers.ConfigurationDisplayName" = "Son takipçiler"; "Widget.LatestFollowers.LastUpdate" = "Last update: %@"; -"Widget.LatestFollowers.Title" = "Latest followers"; +"Widget.LatestFollowers.Title" = "Son takipçiler"; "Widget.MultipleFollowers.ConfigurationDescription" = "Show number of followers for multiple accounts."; "Widget.MultipleFollowers.ConfigurationDisplayName" = "Multiple followers"; "Widget.MultipleFollowers.MockUser.AccountName" = "another@follower.social"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.stringsdict index 93c405761..ac2d102be 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.stringsdict @@ -61,7 +61,7 @@ NSStringFormatValueTypeKey ld one - 1 character left + 1 karakter kaldı other %ld characters left @@ -184,7 +184,7 @@ NSStringFormatValueTypeKey ld one - 1 re-blog + 1 yeniden paylaşım other %ld re-blogs diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.strings index 2549948f7..f967f5ef0 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "Vui lòng thử lại sau."; "Common.Alerts.DeletePost.Message" = "Bạn có chắc muốn xóa tút này không?"; "Common.Alerts.DeletePost.Title" = "Xóa tút"; -"Common.Alerts.DiscardPostContent.Message" = "Xác nhận bỏ qua nội dung tút đã viết."; -"Common.Alerts.DiscardPostContent.Title" = "Bỏ bản nháp"; "Common.Alerts.EditProfileFailure.Message" = "Không thể chỉnh sửa hồ sơ. Vui lòng thử lại."; "Common.Alerts.EditProfileFailure.Title" = "Lỗi chỉnh sửa hồ sơ"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "Không thể đính kèm nhiều video."; @@ -32,7 +30,7 @@ Vui lòng kiểm tra kết nối mạng."; "Common.Controls.Actions.BlockDomain" = "Chặn %@"; "Common.Controls.Actions.Bookmark" = "Lưu"; "Common.Controls.Actions.Cancel" = "Hủy bỏ"; -"Common.Controls.Actions.Compose" = "Viết tút"; +"Common.Controls.Actions.Compose" = "Soạn tút"; "Common.Controls.Actions.Confirm" = "Xác nhận"; "Common.Controls.Actions.Continue" = "Tiếp tục"; "Common.Controls.Actions.Copy" = "Chép"; @@ -89,14 +87,14 @@ Vui lòng kiểm tra kết nối mạng."; "Common.Controls.Friendship.UnblockUser" = "Bỏ chặn %@"; "Common.Controls.Friendship.Unmute" = "Bỏ ẩn"; "Common.Controls.Friendship.UnmuteUser" = "Bỏ ẩn %@"; -"Common.Controls.Keyboard.Common.ComposeNewPost" = "Viết tút mới"; +"Common.Controls.Keyboard.Common.ComposeNewPost" = "Soạn tút mới"; "Common.Controls.Keyboard.Common.OpenSettings" = "Mở cài đặt"; "Common.Controls.Keyboard.Common.ShowFavorites" = "Hiện lượt thích"; "Common.Controls.Keyboard.Common.SwitchToTab" = "Chuyển thành %@"; "Common.Controls.Keyboard.SegmentedControl.NextSection" = "Tới phần tiếp theo"; "Common.Controls.Keyboard.SegmentedControl.PreviousSection" = "Tới phần trước"; "Common.Controls.Keyboard.Timeline.NextStatus" = "Tút sau"; -"Common.Controls.Keyboard.Timeline.OpenAuthorProfile" = "Mở trang người viết tút"; +"Common.Controls.Keyboard.Timeline.OpenAuthorProfile" = "Mở trang người đăng tút"; "Common.Controls.Keyboard.Timeline.OpenRebloggerProfile" = "Mở trang người đăng lại tút"; "Common.Controls.Keyboard.Timeline.OpenStatus" = "Mở tút"; "Common.Controls.Keyboard.Timeline.PreviewImage" = "Xem trước hình ảnh"; @@ -138,7 +136,7 @@ Vui lòng kiểm tra kết nối mạng."; "Common.Controls.Status.MetaEntity.Hashtag" = "Hashtag: %@"; "Common.Controls.Status.MetaEntity.Mention" = "Hiện hồ sơ: %@"; "Common.Controls.Status.MetaEntity.Url" = "Link: %@"; -"Common.Controls.Status.Poll.Closed" = "Kết thúc"; +"Common.Controls.Status.Poll.Closed" = "Đóng"; "Common.Controls.Status.Poll.Vote" = "Bình chọn"; "Common.Controls.Status.PostedViaApplication" = "%@ qua %@"; "Common.Controls.Status.SensitiveContent" = "Nội dung nhạy cảm"; @@ -163,7 +161,7 @@ Vui lòng kiểm tra kết nối mạng."; "Common.Controls.Status.Visibility.Unlisted" = "Ai cũng thấy tút này nhưng không hiện trên bảng tin máy chủ."; "Common.Controls.Tabs.A11Y.Explore" = "Khám phá"; "Common.Controls.Tabs.A11Y.Search" = "Tìm kiếm"; -"Common.Controls.Tabs.Home" = "Bảng tin"; +"Common.Controls.Tabs.Home" = "Trang chính"; "Common.Controls.Tabs.Notifications" = "Thông báo"; "Common.Controls.Tabs.Profile" = "Trang hồ sơ"; "Common.Controls.Tabs.SearchAndExplore" = "Tìm và Khám Phá"; @@ -247,7 +245,7 @@ tải lên Mastodon."; "Scene.Compose.Poll.Title" = "Bình chọn"; "Scene.Compose.ReplyingToUser" = "trả lời %@"; "Scene.Compose.Title.EditPost" = "Sửa tút"; -"Scene.Compose.Title.NewPost" = "Viết tút"; +"Scene.Compose.Title.NewPost" = "Soạn tút"; "Scene.Compose.Title.NewReply" = "Viết trả lời"; "Scene.Compose.Visibility.Direct" = "Nhắn riêng"; "Scene.Compose.Visibility.Private" = "Chỉ người theo dõi"; @@ -292,7 +290,7 @@ tải lên Mastodon."; "Scene.HomeTimeline.NavigationBarState.Offline" = "Ngoại tuyến"; "Scene.HomeTimeline.NavigationBarState.Published" = "Đã đăng!"; "Scene.HomeTimeline.NavigationBarState.Publishing" = "Đang đăng tút..."; -"Scene.HomeTimeline.Title" = "Bảng tin"; +"Scene.HomeTimeline.Title" = "Trang chính"; "Scene.Login.ServerSearchField.Placeholder" = "Nhập URL hoặc tìm máy chủ"; "Scene.Login.Subtitle" = "Đăng nhập vào máy chủ mà bạn đã tạo tài khoản."; "Scene.Login.Title" = "Chào mừng trở lại!"; @@ -434,7 +432,7 @@ tải lên Mastodon."; "Scene.Report.TitleReport" = "Báo cáo"; "Scene.Search.Recommend.Accounts.Description" = "Bạn có thể muốn theo dõi những người này"; "Scene.Search.Recommend.Accounts.Follow" = "Theo dõi"; -"Scene.Search.Recommend.Accounts.Title" = "Những người bạn có thể thích"; +"Scene.Search.Recommend.Accounts.Title" = "Những người bạn có thể quen"; "Scene.Search.Recommend.ButtonText" = "Xem tất cả"; "Scene.Search.Recommend.HashTag.Description" = "Những hashtag đang được sử dụng nhiều nhất"; "Scene.Search.Recommend.HashTag.PeopleTalking" = "%@ người đang thảo luận"; @@ -507,7 +505,7 @@ tải lên Mastodon."; "Scene.Settings.Section.Notifications.Follows" = "Theo dõi tôi"; "Scene.Settings.Section.Notifications.Mentions" = "Nhắc đến tôi"; "Scene.Settings.Section.Notifications.Title" = "Thông báo"; -"Scene.Settings.Section.Notifications.Trigger.Anyone" = "ai đó"; +"Scene.Settings.Section.Notifications.Trigger.Anyone" = "bất cứ ai"; "Scene.Settings.Section.Notifications.Trigger.Follow" = "người tôi theo dõi"; "Scene.Settings.Section.Notifications.Trigger.Follower" = "người theo dõi tôi"; "Scene.Settings.Section.Notifications.Trigger.Noone" = "không một ai"; @@ -530,7 +528,7 @@ tải lên Mastodon."; "Scene.Welcome.Education.Mastodon.Title" = "Chào mừng đến với Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Mỗi tài khoản Mastodon được lưu trữ trên một máy chủ — với nội quy và quản trị viên riêng. Bất kể bạn chọn máy chủ nào, bạn có thể theo dõi và tương tác với mọi người trên máy chủ khác."; "Scene.Welcome.Education.Servers.Title" = "Máy chủ là gì?"; -"Scene.Welcome.JoinDefaultServer" = "Join %@"; +"Scene.Welcome.JoinDefaultServer" = "Tham gia %@"; "Scene.Welcome.LearnMore" = "Tìm hiểu thêm"; "Scene.Welcome.LogIn" = "Đăng nhập"; "Scene.Welcome.PickServer" = "Tìm máy chủ khác"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.strings index d16aae1bf..00fa499c7 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "请稍后重试。"; "Common.Alerts.DeletePost.Message" = "确定要删除这个帖子吗?"; "Common.Alerts.DeletePost.Title" = "删除帖子"; -"Common.Alerts.DiscardPostContent.Message" = "确认要丢弃正在编辑的内容"; -"Common.Alerts.DiscardPostContent.Title" = "丢弃草案"; "Common.Alerts.EditProfileFailure.Message" = "无法编辑个人资料,请重试。"; "Common.Alerts.EditProfileFailure.Title" = "编辑个人资料出现错误"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "最多添加一个视频。"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.strings index 7478109ea..44e3fb585 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.strings @@ -6,8 +6,6 @@ "Common.Alerts.Common.PleaseTryAgainLater" = "請稍候再試。"; "Common.Alerts.DeletePost.Message" = "是否確定要刪除此嘟文?"; "Common.Alerts.DeletePost.Title" = "刪除嘟文"; -"Common.Alerts.DiscardPostContent.Message" = "確認放棄編寫中的嘟文內容。"; -"Common.Alerts.DiscardPostContent.Title" = "捨棄草稿"; "Common.Alerts.EditProfileFailure.Message" = "無法編輯個人檔案。請重試。"; "Common.Alerts.EditProfileFailure.Title" = "編輯個人檔案錯誤"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "無法附加一個以上影片。"; @@ -525,7 +523,7 @@ "Scene.Welcome.Education.Mastodon.Title" = "歡迎來到 Mastodon"; "Scene.Welcome.Education.Servers.Description" = "所有的 Mastodon 帳號皆託管於一個伺服器上 — 其擁有各自之價值觀、規則、與管理者。無論您選擇何者,您皆能跟隨並與其他任何伺服器上的人們互動。"; "Scene.Welcome.Education.Servers.Title" = "伺服器是什麼?"; -"Scene.Welcome.JoinDefaultServer" = "Join %@"; +"Scene.Welcome.JoinDefaultServer" = "加入 %@"; "Scene.Welcome.LearnMore" = "了解更多"; "Scene.Welcome.LogIn" = "登入"; "Scene.Welcome.PickServer" = "挑選另一個伺服器"; From 2b7aa652c92293b473f6fa6b054d3a93783e5e83 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Thu, 14 Sep 2023 15:45:39 +0200 Subject: [PATCH 37/87] Bump version --- Mastodon.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index f8743b3da..c46ea5ec7 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -4576,7 +4576,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2023.12; + MARKETING_VERSION = 2023.13; PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -4608,7 +4608,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2023.12; + MARKETING_VERSION = 2023.13; PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -4795,7 +4795,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2023.12; + MARKETING_VERSION = 2023.13; PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -5086,7 +5086,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2023.12; + MARKETING_VERSION = 2023.13; PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; From 0fa75fc1d30c6ee3bab3a672869652da2216b197 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Thu, 14 Sep 2023 16:51:39 +0200 Subject: [PATCH 38/87] Remove some logs while figuring out how search works (IOS-141) --- ...urceProvider+StatusTableViewCellDelegate.swift | 6 ------ .../DataSourceProvider+UITableViewDelegate.swift | 3 --- .../Protocol/Provider/DataSourceProvider.swift | 1 - .../SearchDetail/SearchDetailViewModel.swift | 5 ----- ...hResultViewController+DataSourceProvider.swift | 1 - .../SearchResultViewModel+State.swift | 15 --------------- 6 files changed, 31 deletions(-) diff --git a/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift b/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift index dc6a9fda5..85718c94a 100644 --- a/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift +++ b/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift @@ -352,10 +352,7 @@ extension StatusTableViewCellDelegate where Self: DataSourceProvider & AuthConte choices: [choice], authenticationBox: authContext.mastodonAuthenticationBox ) - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): vote poll for \(choice) success") } catch { - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): vote poll fail: \(error.localizedDescription)") - // restore voting state try await managedObjectContext.performChanges { guard @@ -411,10 +408,7 @@ extension StatusTableViewCellDelegate where Self: DataSourceProvider & AuthConte choices: choices, authenticationBox: authContext.mastodonAuthenticationBox ) - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): vote poll for \(choices) success") } catch { - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): vote poll fail: \(error.localizedDescription)") - // restore voting state try await managedObjectContext.performChanges { guard let poll = poll.object(in: managedObjectContext) else { return } diff --git a/Mastodon/Protocol/Provider/DataSourceProvider+UITableViewDelegate.swift b/Mastodon/Protocol/Provider/DataSourceProvider+UITableViewDelegate.swift index 6ced42601..299951ce2 100644 --- a/Mastodon/Protocol/Provider/DataSourceProvider+UITableViewDelegate.swift +++ b/Mastodon/Protocol/Provider/DataSourceProvider+UITableViewDelegate.swift @@ -15,7 +15,6 @@ import MastodonLocalization extension UITableViewDelegate where Self: DataSourceProvider & AuthContextProvider { func aspectTableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): indexPath: \(indexPath.debugDescription)") Task { let source = DataSourceItem.Source(tableViewCell: nil, indexPath: indexPath) guard let item = await item(from: source) else { @@ -77,7 +76,6 @@ extension UITableViewDelegate where Self: DataSourceProvider & MediaPreviewableV contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint ) -> UIContextMenuConfiguration? { - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") guard let cell = tableView.cellForRow(at: indexPath) as? StatusViewContainerTableViewCell else { return nil } @@ -238,7 +236,6 @@ extension UITableViewDelegate where Self: DataSourceProvider & MediaPreviewableV willPerformPreviewActionForMenuWith configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionCommitAnimating ) { - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") guard let configuration = configuration as? TimelineTableViewCellContextMenuConfiguration else { return } guard let indexPath = configuration.indexPath, let index = configuration.index else { return } diff --git a/Mastodon/Protocol/Provider/DataSourceProvider.swift b/Mastodon/Protocol/Provider/DataSourceProvider.swift index 425e40417..d7c86f56d 100644 --- a/Mastodon/Protocol/Provider/DataSourceProvider.swift +++ b/Mastodon/Protocol/Provider/DataSourceProvider.swift @@ -45,6 +45,5 @@ extension DataSourceItem { } protocol DataSourceProvider: NeedsDependency & UIViewController { - var logger: Logger { get } func item(from source: DataSourceItem.Source) async -> DataSourceItem? } diff --git a/Mastodon/Scene/Search/SearchDetail/SearchDetailViewModel.swift b/Mastodon/Scene/Search/SearchDetail/SearchDetailViewModel.swift index 779aaa2dc..425722e37 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchDetailViewModel.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchDetailViewModel.swift @@ -32,11 +32,6 @@ final class SearchDetailViewModel { self.authContext = authContext self.searchText = CurrentValueSubject(initialSearchText) } - - deinit { - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) - } - } extension SearchDetailViewModel { diff --git a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController+DataSourceProvider.swift b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController+DataSourceProvider.swift index 71ac81ef6..a2f41aefb 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController+DataSourceProvider.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController+DataSourceProvider.swift @@ -40,7 +40,6 @@ extension SearchResultViewController: DataSourceProvider { extension SearchResultViewController { func aspectTableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): indexPath: \(indexPath.debugDescription)") Task { let source = DataSourceItem.Source(tableViewCell: nil, indexPath: indexPath) guard let item = await item(from: source) else { diff --git a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+State.swift b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+State.swift index 9b12e1af0..3fdf65436 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+State.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+State.swift @@ -14,8 +14,6 @@ import MastodonCore extension SearchResultViewModel { class State: GKState { - let logger = Logger(subsystem: "SearchResultViewModel.State", category: "StateMachine") - let id = UUID() weak var viewModel: SearchResultViewModel? @@ -24,22 +22,10 @@ extension SearchResultViewModel { self.viewModel = viewModel } - override func didEnter(from previousState: GKState?) { - super.didEnter(from: previousState) - - let from = previousState.flatMap { String(describing: $0) } ?? "nil" - let to = String(describing: self) - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): \(from) -> \(to)") - } - @MainActor func enter(state: State.Type) { stateMachine?.enter(state) } - - deinit { - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): [\(self.id.uuidString)] \(String(describing: self))") - } } } @@ -165,7 +151,6 @@ extension SearchResultViewModel.State { viewModel.hashtags = hashtags } catch { - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): search \(searchText) fail: \(error.localizedDescription)") await enter(state: Fail.self) } } // end Task From c89203409371c2b88abed7c9e294688ed83e703c Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Fri, 15 Sep 2023 10:49:32 +0200 Subject: [PATCH 39/87] More cleanup (IOS-141) --- Mastodon.xcodeproj/project.pbxproj | 4 - .../Search/SearchViewModel+Diffable.swift | 42 ------ ...ySectionHeaderCollectionReusableView.swift | 5 +- .../SearchHistoryViewController.swift | 4 - .../SearchHistoryViewModel.swift | 68 --------- .../SearchResultViewController.swift | 73 ---------- .../SearchResult/SearchResultViewModel.swift | 133 ------------------ 7 files changed, 1 insertion(+), 328 deletions(-) delete mode 100644 Mastodon/Scene/Search/Search/SearchViewModel+Diffable.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index c46ea5ec7..e8c01abdd 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -194,7 +194,6 @@ DB0FCB842796B2A2006C02E2 /* FavoriteViewController+DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB832796B2A2006C02E2 /* FavoriteViewController+DataSourceProvider.swift */; }; DB0FCB862796BDA1006C02E2 /* SearchSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB852796BDA1006C02E2 /* SearchSection.swift */; }; DB0FCB882796BDA9006C02E2 /* SearchItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB872796BDA9006C02E2 /* SearchItem.swift */; }; - DB0FCB8C2796BF8D006C02E2 /* SearchViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB8B2796BF8D006C02E2 /* SearchViewModel+Diffable.swift */; }; DB0FCB8E2796C0B7006C02E2 /* TrendCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB8D2796C0B7006C02E2 /* TrendCollectionViewCell.swift */; }; DB0FCB922796DE19006C02E2 /* TrendSectionHeaderCollectionReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB912796DE19006C02E2 /* TrendSectionHeaderCollectionReusableView.swift */; }; DB0FCB942797E2B0006C02E2 /* SearchResultViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB932797E2B0006C02E2 /* SearchResultViewModel+Diffable.swift */; }; @@ -847,7 +846,6 @@ DB0FCB832796B2A2006C02E2 /* FavoriteViewController+DataSourceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FavoriteViewController+DataSourceProvider.swift"; sourceTree = ""; }; DB0FCB852796BDA1006C02E2 /* SearchSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchSection.swift; sourceTree = ""; }; DB0FCB872796BDA9006C02E2 /* SearchItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchItem.swift; sourceTree = ""; }; - DB0FCB8B2796BF8D006C02E2 /* SearchViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SearchViewModel+Diffable.swift"; sourceTree = ""; }; DB0FCB8D2796C0B7006C02E2 /* TrendCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrendCollectionViewCell.swift; sourceTree = ""; }; DB0FCB912796DE19006C02E2 /* TrendSectionHeaderCollectionReusableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrendSectionHeaderCollectionReusableView.swift; sourceTree = ""; }; DB0FCB932797E2B0006C02E2 /* SearchResultViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SearchResultViewModel+Diffable.swift"; sourceTree = ""; }; @@ -2933,7 +2931,6 @@ 2DE0FAC62615F5D200CDF649 /* View */, DB9D6BE825E4F5340051B173 /* SearchViewController.swift */, 2D6DE3FF26141DF600A63F6A /* SearchViewModel.swift */, - DB0FCB8B2796BF8D006C02E2 /* SearchViewModel+Diffable.swift */, ); path = Search; sourceTree = ""; @@ -3593,7 +3590,6 @@ DB0FCB9C27980AB6006C02E2 /* HashtagTimelineViewController+DataSourceProvider.swift in Sources */, DB63F76F279A7D1100455B82 /* NotificationTableViewCell.swift in Sources */, 2A1BF99529F7E68400FA1BA5 /* DataSourceFacade+UserView.swift in Sources */, - DB0FCB8C2796BF8D006C02E2 /* SearchViewModel+Diffable.swift in Sources */, DBEFCD76282A143F00C0ABEA /* ReportStatusViewController.swift in Sources */, DBDFF1952805561700557A48 /* DiscoveryPostsViewModel+Diffable.swift in Sources */, DB03A795272A981400EE37C5 /* ContentSplitViewController.swift in Sources */, diff --git a/Mastodon/Scene/Search/Search/SearchViewModel+Diffable.swift b/Mastodon/Scene/Search/Search/SearchViewModel+Diffable.swift deleted file mode 100644 index 3f448289a..000000000 --- a/Mastodon/Scene/Search/Search/SearchViewModel+Diffable.swift +++ /dev/null @@ -1,42 +0,0 @@ -// -// SearchViewModel+Diffable.swift -// Mastodon -// -// Created by MainasuK on 2022-1-18. -// - -import UIKit -import MastodonSDK - -//extension SearchViewModel { -// -// func setupDiffableDataSource( -// collectionView: UICollectionView -// ) { -// diffableDataSource = SearchSection.diffableDataSource( -// collectionView: collectionView, -// context: context -// ) -// -// var snapshot = NSDiffableDataSourceSnapshot() -// snapshot.appendSections([.trend]) -// diffableDataSource?.apply(snapshot) -// -// $hashtags -// .receive(on: DispatchQueue.main) -// .sink { [weak self] hashtags in -// guard let self = self else { return } -// guard let diffableDataSource = self.diffableDataSource else { return } -// -// var snapshot = NSDiffableDataSourceSnapshot() -// snapshot.appendSections([.trend]) -// -// let trendItems = hashtags.map { SearchItem.trend($0) } -// snapshot.appendItems(trendItems, toSection: .trend) -// -// diffableDataSource.apply(snapshot) -// } -// .store(in: &disposeBag) -// } -// -//} diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistorySectionHeaderCollectionReusableView.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistorySectionHeaderCollectionReusableView.swift index b6f30f94a..170f59934 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistorySectionHeaderCollectionReusableView.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistorySectionHeaderCollectionReusableView.swift @@ -16,9 +16,7 @@ protocol SearchHistorySectionHeaderCollectionReusableViewDelegate: AnyObject, Us } final class SearchHistorySectionHeaderCollectionReusableView: UICollectionReusableView { - - let logger = Logger(subsystem: "SearchHistorySectionHeaderCollectionReusableView", category: "View") - + weak var delegate: SearchHistorySectionHeaderCollectionReusableViewDelegate? let primaryLabel: UILabel = { @@ -78,7 +76,6 @@ extension SearchHistorySectionHeaderCollectionReusableView { extension SearchHistorySectionHeaderCollectionReusableView { @objc private func clearButtonDidPressed(_ sender: UIButton) { - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") delegate?.searchHistorySectionHeaderCollectionReusableView(self, clearButtonDidPressed: sender) } } diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewController.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewController.swift index ff15b08ed..2ef2c8440 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewController.swift @@ -68,8 +68,6 @@ extension SearchHistoryViewController { extension SearchHistoryViewController: UICollectionViewDelegate { func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): select item at: \(indexPath.debugDescription)") - defer { collectionView.deselectItem(at: indexPath, animated: true) } @@ -116,8 +114,6 @@ extension SearchHistoryViewController: SearchHistorySectionHeaderCollectionReusa _ searchHistorySectionHeaderCollectionReusableView: SearchHistorySectionHeaderCollectionReusableView, clearButtonDidPressed button: UIButton ) { - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") - Task { try await DataSourceFacade.responseToDeleteSearchHistory( provider: self diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewModel.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewModel.swift index d20f2d495..5078895c0 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewModel.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewModel.swift @@ -32,71 +32,3 @@ final class SearchHistoryViewModel { } } - -//extension SearchHistoryViewModel { -// func persistSearchHistory(for item: SearchHistoryItem) { -// guard let box = context.authenticationService.activeMastodonAuthenticationBox.value else { return } -// let property = SearchHistory.Property(domain: box.domain, userID: box.userID) -// -// switch item { -// case .account(let objectID): -// let managedObjectContext = context.backgroundManagedObjectContext -// managedObjectContext.performChanges { -// guard let user = try? managedObjectContext.existingObject(with: objectID) as? MastodonUser else { return } -// if let searchHistory = user.findSearchHistory(domain: box.domain, userID: box.userID) { -// searchHistory.update(updatedAt: Date()) -// } else { -// SearchHistory.insert(into: managedObjectContext, property: property, account: user) -// } -// } -// .sink { result in -// switch result { -// case .failure(let error): -// assertionFailure(error.localizedDescription) -// case .success: -// break -// } -// } -// .store(in: &context.disposeBag) -// -// case .hashtag(let objectID): -// let managedObjectContext = context.backgroundManagedObjectContext -// managedObjectContext.performChanges { -// guard let hashtag = try? managedObjectContext.existingObject(with: objectID) as? Tag else { return } -// if let searchHistory = hashtag.findSearchHistory(domain: box.domain, userID: box.userID) { -// searchHistory.update(updatedAt: Date()) -// } else { -// _ = SearchHistory.insert(into: managedObjectContext, property: property, hashtag: hashtag) -// } -// } -// .sink { result in -// switch result { -// case .failure(let error): -// assertionFailure(error.localizedDescription) -// case .success: -// break -// } -// } -// .store(in: &context.disposeBag) -// -// case .status: -// // FIXME: -// break -// } -// } -// -// func clearSearchHistory() { -// let managedObjectContext = context.backgroundManagedObjectContext -// managedObjectContext.performChanges { -// let request = SearchHistory.sortedFetchRequest -// let searchHistories = managedObjectContext.safeFetch(request) -// for searchHistory in searchHistories { -// managedObjectContext.delete(searchHistory) -// } -// } -// .sink { result in -// // do nothing -// } -// .store(in: &context.disposeBag) -// } -//} diff --git a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController.swift b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController.swift index e94d3033a..093e0f971 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController.swift @@ -53,7 +53,6 @@ extension SearchResultViewController { tableView.pinToParent() tableView.delegate = self -// tableView.prefetchDataSource = self viewModel.setupDiffableDataSource( tableView: tableView, statusTableViewCellDelegate: self, @@ -180,81 +179,9 @@ extension SearchResultViewController: UITableViewDelegate, AutoGenerateTableView func tableView(_ tableView: UITableView, willPerformPreviewActionForMenuWith configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionCommitAnimating) { aspectTableView(tableView, willPerformPreviewActionForMenuWith: configuration, animator: animator) } - // sourcery:end - -// func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { -// aspectTableView(tableView, estimatedHeightForRowAt: indexPath) -// } -// -// func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { -// aspectTableView(tableView, willDisplay: cell, forRowAt: indexPath) -// } -// -// func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) { -// aspectTableView(tableView, didEndDisplaying: cell, forRowAt: indexPath) -// } -// -// func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { -// guard let diffableDataSource = viewModel.diffableDataSource else { return } -// guard let item = diffableDataSource.itemIdentifier(for: indexPath) else { return } -// -// viewModel.persistSearchHistory(for: item) -// -// switch item { -// case .account(let account): -// let profileViewModel = RemoteProfileViewModel(context: context, userID: account.id) -// coordinator.present(scene: .profile(viewModel: profileViewModel), from: self, transition: .show) -// case .hashtag(let hashtag): -// let hashtagViewModel = HashtagTimelineViewModel(context: context, hashtag: hashtag.name) -// coordinator.present(scene: .hashtagTimeline(viewModel: hashtagViewModel), from: self, transition: .show) -// case .status: -// aspectTableView(tableView, didSelectRowAt: indexPath) -// case .bottomLoader: -// break -// } -// } -// -// func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? { -// aspectTableView(tableView, contextMenuConfigurationForRowAt: indexPath, point: point) -// } -// -// func tableView(_ tableView: UITableView, previewForHighlightingContextMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview? { -// aspectTableView(tableView, previewForHighlightingContextMenuWithConfiguration: configuration) -// } -// -// func tableView(_ tableView: UITableView, previewForDismissingContextMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview? { -// aspectTableView(tableView, previewForDismissingContextMenuWithConfiguration: configuration) -// } -// -// func tableView(_ tableView: UITableView, willPerformPreviewActionForMenuWith configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionCommitAnimating) { -// aspectTableView(tableView, willPerformPreviewActionForMenuWith: configuration, animator: animator) -// } - } -// MARK: - UITableViewDataSourcePrefetching -//extension SearchResultViewController: UITableViewDataSourcePrefetching { -// func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) { -// aspectTableView(tableView, cancelPrefetchingForRowsAt: indexPaths) -// } -// -// func tableView(_ tableView: UITableView, cancelPrefetchingForRowsAt indexPaths: [IndexPath]) { -// aspectTableView(tableView, cancelPrefetchingForRowsAt: indexPaths) -// } -//} - -// MARK: - AVPlayerViewControllerDelegate -//extension SearchResultViewController: AVPlayerViewControllerDelegate { -// func playerViewController(_ playerViewController: AVPlayerViewController, willBeginFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator) { -// handlePlayerViewController(playerViewController, willBeginFullScreenPresentationWithAnimationCoordinator: coordinator) -// } -// -// func playerViewController(_ playerViewController: AVPlayerViewController, willEndFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator) { -// handlePlayerViewController(playerViewController, willEndFullScreenPresentationWithAnimationCoordinator: coordinator) -// } -//} - // MARK: - StatusTableViewCellDelegate extension SearchResultViewController: StatusTableViewCellDelegate { } diff --git a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel.swift b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel.swift index c4cfa0f54..cd9e866bc 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel.swift @@ -62,139 +62,6 @@ final class SearchResultViewModel { domain: authContext.mastodonAuthenticationBox.domain, additionalTweetPredicate: nil ) - -// Publishers.CombineLatest( -// items, -// statusFetchedResultsController.objectIDs.removeDuplicates() -// ) -// .receive(on: DispatchQueue.main) -// .sink { [weak self] items, statusObjectIDs in -// guard let self = self else { return } -// guard let diffableDataSource = self.diffableDataSource else { return } -// -// var snapshot = NSDiffableDataSourceSnapshot() -// snapshot.appendSections([.main]) -// -// // append account & hashtag items -// -// var items = items -// if self.searchScope == .all { -// // all search scope not paging. it's safe sort on whole dataset -// items.sort(by: { ($0.sortKey ?? "") < ($1.sortKey ?? "")}) -// } -// snapshot.appendItems(items, toSection: .main) -// -// var oldSnapshotAttributeDict: [NSManagedObjectID : Item.StatusAttribute] = [:] -// let oldSnapshot = diffableDataSource.snapshot() -// for item in oldSnapshot.itemIdentifiers { -// guard case let .status(objectID, attribute) = item else { continue } -// oldSnapshotAttributeDict[objectID] = attribute -// } -// -// // append statuses -// var statusItems: [SearchResultItem] = [] -// for objectID in statusObjectIDs { -// let attribute = oldSnapshotAttributeDict[objectID] ?? Item.StatusAttribute() -// statusItems.append(.status(statusObjectID: objectID, attribute: attribute)) -// } -// snapshot.appendItems(statusItems, toSection: .main) -// -// if let currentState = self.stateMachine.currentState { -// switch currentState { -// case is State.Loading, is State.Fail, is State.Idle: -// let attribute = SearchResultItem.BottomLoaderAttribute(isEmptyResult: false) -// snapshot.appendItems([.bottomLoader(attribute: attribute)], toSection: .main) -// case is State.Fail: -// break -// case is State.NoMore: -// if snapshot.itemIdentifiers.isEmpty { -// let attribute = SearchResultItem.BottomLoaderAttribute(isEmptyResult: true) -// snapshot.appendItems([.bottomLoader(attribute: attribute)], toSection: .main) -// } -// default: -// break -// } -// } -// -// diffableDataSource.defaultRowAnimation = .fade -// diffableDataSource.apply(snapshot, animatingDifferences: true) { [weak self] in -// guard let self = self else { return } -// self.didDataSourceUpdate.send() -// } -// -// } -// .store(in: &disposeBag) } } - -extension SearchResultViewModel { - func persistSearchHistory(for item: SearchResultItem) { - fatalError() -// guard let box = context.authenticationService.activeMastodonAuthenticationBox.value else { return } -// let property = SearchHistory.Property(domain: box.domain, userID: box.userID) -// let domain = box.domain -// -// switch item { -// case .account(let entity): -// let managedObjectContext = context.backgroundManagedObjectContext -// managedObjectContext.performChanges { -// let (user, _) = APIService.CoreData.createOrMergeMastodonUser( -// into: managedObjectContext, -// for: nil, -// in: domain, -// entity: entity, -// userCache: nil, -// networkDate: Date(), -// log: OSLog.api -// ) -// if let searchHistory = user.findSearchHistory(domain: box.domain, userID: box.userID) { -// searchHistory.update(updatedAt: Date()) -// } else { -// SearchHistory.insert(into: managedObjectContext, property: property, account: user) -// } -// } -// .sink { result in -// switch result { -// case .failure(let error): -// assertionFailure(error.localizedDescription) -// case .success: -// break -// } -// } -// .store(in: &context.disposeBag) -// -// case .hashtag(let entity): -// let managedObjectContext = context.backgroundManagedObjectContext -// var tag: Tag? -// managedObjectContext.performChanges { -// let (hashtag, _) = APIService.CoreData.createOrMergeTag( -// into: managedObjectContext, -// entity: entity -// ) -// tag = hashtag -// if let searchHistory = hashtag.findSearchHistory(domain: box.domain, userID: box.userID) { -// searchHistory.update(updatedAt: Date()) -// } else { -// _ = SearchHistory.insert(into: managedObjectContext, property: property, hashtag: hashtag) -// } -// } -// .sink { result in -// switch result { -// case .failure(let error): -// assertionFailure(error.localizedDescription) -// case .success: -// print(tag?.searchHistories) -// break -// } -// } -// .store(in: &context.disposeBag) -// -// case .status: -// // FIXME: -// break -// case .bottomLoader: -// break -// } - } -} From e8509a063de6147be6fbc4fe101b35385ffe9d44 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Fri, 15 Sep 2023 11:37:33 +0200 Subject: [PATCH 40/87] Show title instead of "x" for clear-all-button (IOS-141) Also: Move stuff around. It doesn't make sense for search-diffable-stuff to live in an enitrely different folder than the rest. --- .../input/Base.lproj/app.json | 1 + Mastodon.xcodeproj/project.pbxproj | 12 +-- .../Search/Search/SearchViewController.swift | 1 - .../SearchDetailViewController.swift | 2 - ...ySectionHeaderCollectionReusableView.swift | 10 +- ...toryUserCollectionViewCell+ViewModel.swift | 2 +- .../SearchHistory}/SearchHistoryItem.swift | 0 .../SearchHistory}/SearchHistorySection.swift | 7 +- .../SearchHistoryViewController.swift | 4 + .../View/SearchHistoryTableHeaderView.swift | 100 ------------------ .../SearchResult}/SearchResultItem.swift | 0 .../SearchResult}/SearchResultSection.swift | 0 .../StatusFetchedResultsController.swift | 2 - .../Generated/Strings.swift | 2 + .../Resources/Base.lproj/Localizable.strings | 3 +- 15 files changed, 18 insertions(+), 128 deletions(-) rename Mastodon/{Diffable/Search => Scene/Search/SearchDetail/SearchHistory}/SearchHistoryItem.swift (100%) rename Mastodon/{Diffable/Search => Scene/Search/SearchDetail/SearchHistory}/SearchHistorySection.swift (92%) delete mode 100644 Mastodon/Scene/Search/SearchDetail/SearchHistory/View/SearchHistoryTableHeaderView.swift rename Mastodon/{Diffable/Search => Scene/Search/SearchDetail/SearchResult}/SearchResultItem.swift (100%) rename Mastodon/{Diffable/Search => Scene/Search/SearchDetail/SearchResult}/SearchResultSection.swift (100%) diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index 739573267..f22ec3098 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -661,6 +661,7 @@ "no_results": "No results" }, "recent_search": "Recent searches", + "clear_all": "Clear all", "clear": "Clear" } }, diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index e8c01abdd..40a6befb6 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -252,7 +252,6 @@ DB4AA6B327BA34B6009EC082 /* CellFrameCacheContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4AA6B227BA34B6009EC082 /* CellFrameCacheContainer.swift */; }; DB4F0963269ED06300D62E92 /* SearchResultViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4F0962269ED06300D62E92 /* SearchResultViewController.swift */; }; DB4F0966269ED52200D62E92 /* SearchResultViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4F0965269ED52200D62E92 /* SearchResultViewModel.swift */; }; - DB4F0968269ED8AD00D62E92 /* SearchHistoryTableHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4F0967269ED8AD00D62E92 /* SearchHistoryTableHeaderView.swift */; }; DB4F096A269EDAD200D62E92 /* SearchResultViewModel+State.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4F0969269EDAD200D62E92 /* SearchResultViewModel+State.swift */; }; DB4F097526A037F500D62E92 /* SearchHistoryViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4F097426A037F500D62E92 /* SearchHistoryViewModel.swift */; }; DB4F097B26A039FF00D62E92 /* SearchHistorySection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4F097A26A039FF00D62E92 /* SearchHistorySection.swift */; }; @@ -927,7 +926,6 @@ DB4B779626CA50BA00B087B3 /* th */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = th; path = th.lproj/Intents.stringsdict; sourceTree = ""; }; DB4F0962269ED06300D62E92 /* SearchResultViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultViewController.swift; sourceTree = ""; }; DB4F0965269ED52200D62E92 /* SearchResultViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultViewModel.swift; sourceTree = ""; }; - DB4F0967269ED8AD00D62E92 /* SearchHistoryTableHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchHistoryTableHeaderView.swift; sourceTree = ""; }; DB4F0969269EDAD200D62E92 /* SearchResultViewModel+State.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SearchResultViewModel+State.swift"; sourceTree = ""; }; DB4F097426A037F500D62E92 /* SearchHistoryViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchHistoryViewModel.swift; sourceTree = ""; }; DB4F097A26A039FF00D62E92 /* SearchHistorySection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchHistorySection.swift; sourceTree = ""; }; @@ -2099,6 +2097,8 @@ DB4F0965269ED52200D62E92 /* SearchResultViewModel.swift */, DB0FCB932797E2B0006C02E2 /* SearchResultViewModel+Diffable.swift */, DB4F0969269EDAD200D62E92 /* SearchResultViewModel+State.swift */, + 2D198648261C0B8500F0B013 /* SearchResultSection.swift */, + 2D198642261BF09500F0B013 /* SearchResultItem.swift */, ); path = SearchResult; sourceTree = ""; @@ -2108,10 +2108,6 @@ children = ( DB0FCB852796BDA1006C02E2 /* SearchSection.swift */, DB0FCB872796BDA9006C02E2 /* SearchItem.swift */, - 2D198648261C0B8500F0B013 /* SearchResultSection.swift */, - 2D198642261BF09500F0B013 /* SearchResultItem.swift */, - DB4F097A26A039FF00D62E92 /* SearchHistorySection.swift */, - DB4F097C26A03A5B00D62E92 /* SearchHistoryItem.swift */, ); path = Search; sourceTree = ""; @@ -2137,7 +2133,6 @@ DB4F098026A0475500D62E92 /* View */ = { isa = PBXGroup; children = ( - DB4F0967269ED8AD00D62E92 /* SearchHistoryTableHeaderView.swift */, ); path = View; sourceTree = ""; @@ -2920,6 +2915,8 @@ DB63F76127996B6600455B82 /* SearchHistoryViewController+DataSourceProvider.swift */, DB4F097426A037F500D62E92 /* SearchHistoryViewModel.swift */, DB63F74E2799405600455B82 /* SearchHistoryViewModel+Diffable.swift */, + DB4F097A26A039FF00D62E92 /* SearchHistorySection.swift */, + DB4F097C26A03A5B00D62E92 /* SearchHistoryItem.swift */, ); path = SearchHistory; sourceTree = ""; @@ -3694,7 +3691,6 @@ 2D84350525FF858100EECE90 /* UIScrollView.swift in Sources */, 6213AF5A28939C8400BCADB6 /* BookmarkViewModel.swift in Sources */, 5B24BBDB262DB14800A9381B /* ReportStatusViewModel+Diffable.swift in Sources */, - DB4F0968269ED8AD00D62E92 /* SearchHistoryTableHeaderView.swift in Sources */, 5DA732CC2629CEF500A92342 /* UIView+Remove.swift in Sources */, 2A506CF4292CD85800059C37 /* FollowedTagsViewController.swift in Sources */, DB1D843026566512000346B3 /* KeyboardPreference.swift in Sources */, diff --git a/Mastodon/Scene/Search/Search/SearchViewController.swift b/Mastodon/Scene/Search/Search/SearchViewController.swift index e1505121d..41bc55ee0 100644 --- a/Mastodon/Scene/Search/Search/SearchViewController.swift +++ b/Mastodon/Scene/Search/Search/SearchViewController.swift @@ -171,7 +171,6 @@ extension SearchViewController { // MARK: - UISearchBarDelegate extension SearchViewController: UISearchBarDelegate { func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool { - os_log("%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) searchBarTapPublisher.send("") return false } diff --git a/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift b/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift index 84a0aedb2..09889fc2d 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift @@ -315,8 +315,6 @@ extension SearchDetailViewController: UISearchBarDelegate { } func searchBarCancelButtonClicked(_ searchBar: UISearchBar) { - logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") - // dismiss or pop if isModal { dismiss(animated: true, completion: nil) diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistorySectionHeaderCollectionReusableView.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistorySectionHeaderCollectionReusableView.swift index 170f59934..ecab554e1 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistorySectionHeaderCollectionReusableView.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistorySectionHeaderCollectionReusableView.swift @@ -30,8 +30,9 @@ final class SearchHistorySectionHeaderCollectionReusableView: UICollectionReusab let clearButton: UIButton = { let button = UIButton(type: .system) - button.setImage(UIImage(systemName: "xmark.circle.fill"), for: .normal) - button.tintColor = Asset.Colors.Label.secondary.color + + button.setTitle(L10n.Scene.Search.Searching.clearAll, for: .normal) + button.tintColor = Asset.Colors.Brand.blurple.color button.accessibilityLabel = L10n.Scene.Search.Searching.clear return button @@ -47,9 +48,6 @@ final class SearchHistorySectionHeaderCollectionReusableView: UICollectionReusab _init() } -} - -extension SearchHistorySectionHeaderCollectionReusableView { private func _init() { primaryLabel.translatesAutoresizingMaskIntoConstraints = false addSubview(primaryLabel) @@ -72,9 +70,7 @@ extension SearchHistorySectionHeaderCollectionReusableView { clearButton.addTarget(self, action: #selector(SearchHistorySectionHeaderCollectionReusableView.clearButtonDidPressed(_:)), for: .touchUpInside) } -} -extension SearchHistorySectionHeaderCollectionReusableView { @objc private func clearButtonDidPressed(_ sender: UIButton) { delegate?.searchHistorySectionHeaderCollectionReusableView(self, clearButtonDidPressed: sender) } diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistoryUserCollectionViewCell+ViewModel.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistoryUserCollectionViewCell+ViewModel.swift index e31f050bd..31350811d 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistoryUserCollectionViewCell+ViewModel.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistoryUserCollectionViewCell+ViewModel.swift @@ -31,7 +31,7 @@ extension SearchHistoryUserCollectionViewCell { func configure( me: MastodonUser?, viewModel: ViewModel, - delegate: UserViewDelegate? + delegate: SearchHistorySectionHeaderCollectionReusableViewDelegate? ) { let user = viewModel.value diff --git a/Mastodon/Diffable/Search/SearchHistoryItem.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryItem.swift similarity index 100% rename from Mastodon/Diffable/Search/SearchHistoryItem.swift rename to Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryItem.swift diff --git a/Mastodon/Diffable/Search/SearchHistorySection.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistorySection.swift similarity index 92% rename from Mastodon/Diffable/Search/SearchHistorySection.swift rename to Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistorySection.swift index 813c5b59a..d0cbc05ee 100644 --- a/Mastodon/Diffable/Search/SearchHistorySection.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistorySection.swift @@ -78,13 +78,8 @@ extension SearchHistorySection { } } - let trendHeaderRegister = UICollectionView.SupplementaryRegistration(elementKind: UICollectionView.elementKindSectionHeader) { [weak dataSource] supplementaryView, elementKind, indexPath in + let trendHeaderRegister = UICollectionView.SupplementaryRegistration(elementKind: UICollectionView.elementKindSectionHeader) { supplementaryView, elementKind, indexPath in supplementaryView.delegate = configuration.searchHistorySectionHeaderCollectionReusableViewDelegate - - guard let _ = dataSource else { return } - // let sections = dataSource.snapshot().sectionIdentifiers - // guard indexPath.section < sections.count else { return } - // let section = sections[indexPath.section] } dataSource.supplementaryViewProvider = { (collectionView: UICollectionView, elementKind: String, indexPath: IndexPath) in diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewController.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewController.swift index 2ef2c8440..d55259d03 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewController.swift @@ -118,6 +118,10 @@ extension SearchHistoryViewController: SearchHistorySectionHeaderCollectionReusa try await DataSourceFacade.responseToDeleteSearchHistory( provider: self ) + + await MainActor.run { + button.isEnabled = false + } } } } diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/View/SearchHistoryTableHeaderView.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/View/SearchHistoryTableHeaderView.swift deleted file mode 100644 index d827231c0..000000000 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/View/SearchHistoryTableHeaderView.swift +++ /dev/null @@ -1,100 +0,0 @@ -// -// SearchHistoryTableHeaderView.swift -// Mastodon -// -// Created by MainasuK Cirno on 2021-7-14. -// - -import os.log -import UIKit -import Combine -import MastodonAsset -import MastodonCore -import MastodonLocalization -import MastodonUI - -protocol SearchHistoryTableHeaderViewDelegate: AnyObject { - func searchHistoryTableHeaderView(_ searchHistoryTableHeaderView: SearchHistoryTableHeaderView, clearSearchHistoryButtonDidPressed button: UIButton) -} - -final class SearchHistoryTableHeaderView: UIView { - - let logger = Logger(subsystem: "SearchHistory", category: "UI") - - weak var delegate: SearchHistoryTableHeaderViewDelegate? - var disposeBag = Set() - - let recentSearchesLabel: UILabel = { - let label = UILabel() - label.font = UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 20, weight: .semibold)) - label.textColor = Asset.Colors.Label.primary.color - label.text = L10n.Scene.Search.Searching.recentSearch - return label - }() - - let clearSearchHistoryButton: HighlightDimmableButton = { - let button = HighlightDimmableButton(type: .custom) - button.expandEdgeInsets = UIEdgeInsets(top: -10, left: -10, bottom: -10, right: -10) - button.setTitleColor(Asset.Colors.Brand.blurple.color, for: .normal) - button.setTitle(L10n.Scene.Search.Searching.clear, for: .normal) - return button - }() - - override init(frame: CGRect) { - super.init(frame: frame) - _init() - } - - required init?(coder: NSCoder) { - super.init(coder: coder) - _init() - } - -} - -extension SearchHistoryTableHeaderView { - private func _init() { - preservesSuperviewLayoutMargins = true - - recentSearchesLabel.translatesAutoresizingMaskIntoConstraints = false - addSubview(recentSearchesLabel) - NSLayoutConstraint.activate([ - recentSearchesLabel.topAnchor.constraint(equalTo: topAnchor, constant: 16), - recentSearchesLabel.leadingAnchor.constraint(equalTo: readableContentGuide.leadingAnchor), - bottomAnchor.constraint(equalTo: recentSearchesLabel.bottomAnchor, constant: 16), - ]) - - clearSearchHistoryButton.translatesAutoresizingMaskIntoConstraints = false - addSubview(clearSearchHistoryButton) - NSLayoutConstraint.activate([ - clearSearchHistoryButton.centerYAnchor.constraint(equalTo: recentSearchesLabel.centerYAnchor), - clearSearchHistoryButton.leadingAnchor.constraint(equalTo: recentSearchesLabel.trailingAnchor), - clearSearchHistoryButton.trailingAnchor.constraint(equalTo: readableContentGuide.trailingAnchor), - ]) - clearSearchHistoryButton.setContentHuggingPriority(.defaultHigh + 10, for: .horizontal) - - clearSearchHistoryButton.addTarget(self, action: #selector(SearchHistoryTableHeaderView.clearSearchHistoryButtonDidPressed(_:)), for: .touchUpInside) - - setupBackgroundColor(theme: ThemeService.shared.currentTheme.value) - ThemeService.shared.currentTheme - .receive(on: RunLoop.main) - .sink { [weak self] theme in - guard let self = self else { return } - self.setupBackgroundColor(theme: theme) - } - .store(in: &disposeBag) - } -} - -extension SearchHistoryTableHeaderView { - @objc private func clearSearchHistoryButtonDidPressed(_ sender: UIButton) { - logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") - delegate?.searchHistoryTableHeaderView(self, clearSearchHistoryButtonDidPressed: sender) - } -} - -extension SearchHistoryTableHeaderView { - private func setupBackgroundColor(theme: Theme) { - backgroundColor = theme.systemGroupedBackgroundColor - } -} diff --git a/Mastodon/Diffable/Search/SearchResultItem.swift b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultItem.swift similarity index 100% rename from Mastodon/Diffable/Search/SearchResultItem.swift rename to Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultItem.swift diff --git a/Mastodon/Diffable/Search/SearchResultSection.swift b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultSection.swift similarity index 100% rename from Mastodon/Diffable/Search/SearchResultSection.swift rename to Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultSection.swift diff --git a/MastodonSDK/Sources/MastodonCore/FetchedResultsController/StatusFetchedResultsController.swift b/MastodonSDK/Sources/MastodonCore/FetchedResultsController/StatusFetchedResultsController.swift index c08673acb..bb4184bfc 100644 --- a/MastodonSDK/Sources/MastodonCore/FetchedResultsController/StatusFetchedResultsController.swift +++ b/MastodonSDK/Sources/MastodonCore/FetchedResultsController/StatusFetchedResultsController.swift @@ -90,8 +90,6 @@ extension StatusFetchedResultsController { // MARK: - NSFetchedResultsControllerDelegate extension StatusFetchedResultsController: NSFetchedResultsControllerDelegate { public func controller(_ controller: NSFetchedResultsController, didChangeContentWith snapshot: NSDiffableDataSourceSnapshotReference) { - os_log("%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) - let indexes = statusIDs let objects = fetchedResultsController.fetchedObjects ?? [] diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index 27f3c06d0..dcc6f84f1 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -1277,6 +1277,8 @@ public enum L10n { public enum Searching { /// Clear public static let clear = L10n.tr("Localizable", "Scene.Search.Searching.Clear", fallback: "Clear") + /// Clear all + public static let clearAll = L10n.tr("Localizable", "Scene.Search.Searching.ClearAll", fallback: "Clear all") /// Recent searches public static let recentSearch = L10n.tr("Localizable", "Scene.Search.Searching.RecentSearch", fallback: "Recent searches") public enum EmptyState { diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 7f00f1cc2..7269b0c4a 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -440,6 +440,7 @@ uploaded to Mastodon."; "Scene.Search.SearchBar.Cancel" = "Cancel"; "Scene.Search.SearchBar.Placeholder" = "Search hashtags and users"; "Scene.Search.Searching.Clear" = "Clear"; +"Scene.Search.Searching.ClearAll" = "Clear all"; "Scene.Search.Searching.EmptyState.NoResults" = "No results"; "Scene.Search.Searching.RecentSearch" = "Recent searches"; "Scene.Search.Searching.Segment.All" = "All"; @@ -554,4 +555,4 @@ uploaded to Mastodon."; "Widget.MultipleFollowers.ConfigurationDescription" = "Show number of followers for multiple accounts."; "Widget.MultipleFollowers.ConfigurationDisplayName" = "Multiple followers"; "Widget.MultipleFollowers.MockUser.AccountName" = "another@follower.social"; -"Widget.MultipleFollowers.MockUser.DisplayName" = "Another follower"; \ No newline at end of file +"Widget.MultipleFollowers.MockUser.DisplayName" = "Another follower"; From 2e384f3cb58895512d78d24d9d57fc38ff9f9e9b Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Fri, 15 Sep 2023 17:45:22 +0200 Subject: [PATCH 41/87] WIP: Add some search-implementation and clean stuff (IOS-141) Shame on me for such a big commit. I'm new to iOS-development, sorry :nerd: --- Mastodon.xcodeproj/project.pbxproj | 28 +++ .../HomeTimelineViewModel+Diffable.swift | 7 +- .../Search/Search/SearchViewController.swift | 60 ------ .../Scene/Search/Search/SearchViewModel.swift | 27 --- ...rchResultDefaultSectionTableViewCell.swift | 26 +++ .../SearchResultOverviewSection.swift | 71 +++++++ ...chResultsOverviewTableViewController.swift | 166 ++++++++++++++++ .../SearchDetailViewController.swift | 188 ++++-------------- .../SearchDetail/SearchDetailViewModel.swift | 34 +--- .../Cell/HashtagTableViewCell.swift | 2 + .../SearchResultViewController.swift | 2 - .../SearchResultViewModel+State.swift | 1 - .../SearchResult/SearchResultViewModel.swift | 4 +- .../TableviewCell/StatusTableViewCell.swift | 2 + .../TableviewCell/UserTableViewCell.swift | 3 +- .../UserFetchedResultsController.swift | 1 - .../Entity/Mastodon+Entity+History.swift | 2 +- .../View/Content/StatusView+ViewModel.swift | 3 - 18 files changed, 355 insertions(+), 272 deletions(-) create mode 100644 Mastodon/Scene/Search/SearchDetail/Search Results Overview/Cells/SearchResultDefaultSectionTableViewCell.swift create mode 100644 Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewSection.swift create mode 100644 Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 40a6befb6..0636ceb29 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -139,6 +139,9 @@ D8099078294BC8A30050219F /* PrivacyTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8099077294BC8A30050219F /* PrivacyTableViewController.swift */; }; D809907A294BC9390050219F /* PrivacyTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8099079294BC9390050219F /* PrivacyTableViewCell.swift */; }; D809907C294D25510050219F /* PrivacyViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D809907B294D25510050219F /* PrivacyViewModel.swift */; }; + D81A22752AB4643200905D71 /* SearchResultsOverviewTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D81A22742AB4643200905D71 /* SearchResultsOverviewTableViewController.swift */; }; + D81A22782AB4782400905D71 /* SearchResultOverviewSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = D81A22772AB4782400905D71 /* SearchResultOverviewSection.swift */; }; + D81A227B2AB47B9A00905D71 /* SearchResultDefaultSectionTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D81A227A2AB47B9A00905D71 /* SearchResultDefaultSectionTableViewCell.swift */; }; D8363B1629469CE200A74079 /* OnboardingNextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8363B1529469CE200A74079 /* OnboardingNextView.swift */; }; D87BFC8B291D5C6B00FEE264 /* MastodonLoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D87BFC8A291D5C6B00FEE264 /* MastodonLoginView.swift */; }; D87BFC8D291EB81200FEE264 /* MastodonLoginViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D87BFC8C291EB81200FEE264 /* MastodonLoginViewModel.swift */; }; @@ -774,6 +777,9 @@ D8099077294BC8A30050219F /* PrivacyTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacyTableViewController.swift; sourceTree = ""; }; D8099079294BC9390050219F /* PrivacyTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacyTableViewCell.swift; sourceTree = ""; }; D809907B294D25510050219F /* PrivacyViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacyViewModel.swift; sourceTree = ""; }; + D81A22742AB4643200905D71 /* SearchResultsOverviewTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultsOverviewTableViewController.swift; sourceTree = ""; }; + D81A22772AB4782400905D71 /* SearchResultOverviewSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultOverviewSection.swift; sourceTree = ""; }; + D81A227A2AB47B9A00905D71 /* SearchResultDefaultSectionTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultDefaultSectionTableViewCell.swift; sourceTree = ""; }; D82463522A52B47B00A3DBDD /* be */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = be; path = be.lproj/Intents.strings; sourceTree = ""; }; D82463532A52B47B00A3DBDD /* be */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = be; path = be.lproj/WidgetExtension.strings; sourceTree = ""; }; D82463542A52B47B00A3DBDD /* be */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = be; path = be.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -1791,6 +1797,24 @@ path = Privacy; sourceTree = ""; }; + D81A22732AB4641F00905D71 /* Search Results Overview */ = { + isa = PBXGroup; + children = ( + D81A22792AB47B8400905D71 /* Cells */, + D81A22742AB4643200905D71 /* SearchResultsOverviewTableViewController.swift */, + D81A22772AB4782400905D71 /* SearchResultOverviewSection.swift */, + ); + path = "Search Results Overview"; + sourceTree = ""; + }; + D81A22792AB47B8400905D71 /* Cells */ = { + isa = PBXGroup; + children = ( + D81A227A2AB47B9A00905D71 /* SearchResultDefaultSectionTableViewCell.swift */, + ); + path = Cells; + sourceTree = ""; + }; D8A6AB68291C50F3003AB663 /* Login */ = { isa = PBXGroup; children = ( @@ -2898,6 +2922,7 @@ DBF1D24F269DAF6100C1C08A /* SearchDetail */ = { isa = PBXGroup; children = ( + D81A22732AB4641F00905D71 /* Search Results Overview */, DB4F0964269ED06700D62E92 /* SearchResult */, DBF1D252269DB01700C1C08A /* SearchHistory */, DBF1D24D269DAF5D00C1C08A /* SearchDetailViewController.swift */, @@ -3538,6 +3563,7 @@ DB3E6FE02806A4ED00B035AE /* DiscoveryHashtagsViewModel.swift in Sources */, 2D38F1F725CD47AC00561493 /* HomeTimelineViewModel+LoadOldestState.swift in Sources */, DB0FCB7427956939006C02E2 /* DataSourceFacade+Status.swift in Sources */, + D81A22782AB4782400905D71 /* SearchResultOverviewSection.swift in Sources */, DBB525502611ED6D002F1F29 /* ProfileHeaderView.swift in Sources */, DB63F75A279953F200455B82 /* SearchHistoryUserCollectionViewCell+ViewModel.swift in Sources */, DB023D26279FFB0A005AC798 /* ShareActivityProvider.swift in Sources */, @@ -3692,6 +3718,7 @@ 6213AF5A28939C8400BCADB6 /* BookmarkViewModel.swift in Sources */, 5B24BBDB262DB14800A9381B /* ReportStatusViewModel+Diffable.swift in Sources */, 5DA732CC2629CEF500A92342 /* UIView+Remove.swift in Sources */, + D81A22752AB4643200905D71 /* SearchResultsOverviewTableViewController.swift in Sources */, 2A506CF4292CD85800059C37 /* FollowedTagsViewController.swift in Sources */, DB1D843026566512000346B3 /* KeyboardPreference.swift in Sources */, DB852D1926FAEB6B00FC9D81 /* SidebarViewController.swift in Sources */, @@ -3790,6 +3817,7 @@ 2DAC9E46262FC9FD0062E1A6 /* SuggestionAccountTableViewCell.swift in Sources */, DB4FFC2C269EC39600D62E92 /* SearchTransitionController.swift in Sources */, 2A3D9B7E29A8F33A00F30313 /* StatusHistoryView.swift in Sources */, + D81A227B2AB47B9A00905D71 /* SearchResultDefaultSectionTableViewCell.swift in Sources */, 6213AF5E2893A8B200BCADB6 /* DataSourceFacade+Bookmark.swift in Sources */, DBA5E7A9263BD3A4004598BB /* ContextMenuImagePreviewViewController.swift in Sources */, DBF156E22702DA6900EC00B7 /* UIStatusBarManager+HandleTapAction.m in Sources */, diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift index 24cf2258a..9feee053e 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift @@ -41,13 +41,8 @@ extension HomeTimelineViewModel { .sink { [weak self] records in guard let self = self else { return } guard let diffableDataSource = self.diffableDataSource else { return } - self.logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): incoming \(records.count) objects") + Task { @MainActor in - let start = CACurrentMediaTime() - defer { - let end = CACurrentMediaTime() - self.logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): cost \(end - start, format: .fixed(precision: 4))s to process \(records.count) feeds") - } let oldSnapshot = diffableDataSource.snapshot() var newSnapshot: NSDiffableDataSourceSnapshot = { let newItems = records.map { record in diff --git a/Mastodon/Scene/Search/Search/SearchViewController.swift b/Mastodon/Scene/Search/Search/SearchViewController.swift index 41bc55ee0..093976e63 100644 --- a/Mastodon/Scene/Search/Search/SearchViewController.swift +++ b/Mastodon/Scene/Search/Search/SearchViewController.swift @@ -21,9 +21,6 @@ final class HeightFixedSearchBar: UISearchBar { } final class SearchViewController: UIViewController, NeedsDependency { - - let logger = Logger(subsystem: "SearchViewController", category: "ViewController") - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } @@ -37,16 +34,6 @@ final class SearchViewController: UIViewController, NeedsDependency { let titleViewContainer = UIView() let searchBar = HeightFixedSearchBar() -// let collectionView: UICollectionView = { -// var configuration = UICollectionLayoutListConfiguration(appearance: .insetGrouped) -// configuration.backgroundColor = .clear -// configuration.headerMode = .supplementary -// let layout = UICollectionViewCompositionalLayout.list(using: configuration) -// let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) -// collectionView.backgroundColor = .clear -// return collectionView -// }() - // value is the initial search text to set let searchBarTapPublisher = PassthroughSubject() @@ -62,11 +49,6 @@ final class SearchViewController: UIViewController, NeedsDependency { ) return viewController }() - - deinit { - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) - } - } extension SearchViewController { @@ -85,30 +67,12 @@ extension SearchViewController { title = L10n.Scene.Search.title setupSearchBar() - -// collectionView.translatesAutoresizingMaskIntoConstraints = false -// view.addSubview(collectionView) -// NSLayoutConstraint.activate([ -// collectionView.topAnchor.constraint(equalTo: view.topAnchor), -// collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor), -// collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor), -// collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor), -// ]) -// -// collectionView.delegate = self -// viewModel.setupDiffableDataSource( -// collectionView: collectionView -// ) - guard let discoveryViewController = self.discoveryViewController else { return } addChild(discoveryViewController) discoveryViewController.view.translatesAutoresizingMaskIntoConstraints = false view.addSubview(discoveryViewController.view) discoveryViewController.view.pinToParent() - -// discoveryViewController.view.isHidden = true - } override func viewDidAppear(_ animated: Bool) { @@ -183,12 +147,8 @@ extension SearchViewController: UISearchBarDelegate { // MARK: - UISearchControllerDelegate extension SearchViewController: UISearchControllerDelegate { func willDismissSearchController(_ searchController: UISearchController) { - logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") searchController.isActive = true } - func didPresentSearchController(_ searchController: UISearchController) { - logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") - } } // MARK: - ScrollViewContainer @@ -200,23 +160,3 @@ extension SearchViewController: ScrollViewContainer { discoveryViewController?.scrollToTop(animated: animated) } } - -// MARK: - UICollectionViewDelegate -//extension SearchViewController: UICollectionViewDelegate { -// func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { -// logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): select item at: \(indexPath.debugDescription)") -// -// defer { -// collectionView.deselectItem(at: indexPath, animated: true) -// } -// -// guard let diffableDataSource = viewModel.diffableDataSource else { return } -// guard let item = diffableDataSource.itemIdentifier(for: indexPath) else { return } -// -// switch item { -// case .trend(let hashtag): -// let viewModel = HashtagTimelineViewModel(context: context, hashtag: hashtag.name) -// coordinator.present(scene: .hashtagTimeline(viewModel: viewModel), from: self, transition: .show) -// } -// } -//} diff --git a/Mastodon/Scene/Search/Search/SearchViewModel.swift b/Mastodon/Scene/Search/Search/SearchViewModel.swift index 51d614280..620099bfc 100644 --- a/Mastodon/Scene/Search/Search/SearchViewModel.swift +++ b/Mastodon/Scene/Search/Search/SearchViewModel.swift @@ -31,32 +31,5 @@ final class SearchViewModel: NSObject { self.context = context self.authContext = authContext super.init() - -// Publishers.CombineLatest( -// context.authenticationService.activeMastodonAuthenticationBox, -// viewDidAppeared -// ) -// .compactMap { authenticationBox, _ -> MastodonAuthenticationBox? in -// return authenticationBox -// } -// .throttle(for: 3, scheduler: DispatchQueue.main, latest: true) -// .asyncMap { authenticationBox in -// try await context.apiService.trendHashtags(domain: authenticationBox.domain, query: nil) -// } -// .retry(3) -// .map { response in Result, Error> { response } } -// .catch { error in Just(Result, Error> { throw error }) } -// .receive(on: DispatchQueue.main) -// .sink { [weak self] result in -// guard let self = self else { return } -// switch result { -// case .success(let response): -// self.hashtags = response.value -// case .failure: -// break -// } -// } -// .store(in: &disposeBag) } - } diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/Cells/SearchResultDefaultSectionTableViewCell.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/Cells/SearchResultDefaultSectionTableViewCell.swift new file mode 100644 index 000000000..49ba6d111 --- /dev/null +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/Cells/SearchResultDefaultSectionTableViewCell.swift @@ -0,0 +1,26 @@ +// Copyright © 2023 Mastodon gGmbH. All rights reserved. + +import UIKit +import MastodonAsset + +class SearchResultDefaultSectionTableViewCell: UITableViewCell { + static let reuseIdentifier = "SearchResultDefaultSectionTableViewCell" + + func configure(item: SearchResultOverviewItem.DefaultSectionEntry) { + var content = UIListContentConfiguration.cell() + content.image = item.icon + content.text = item.title + content.imageProperties.tintColor = Asset.Colors.Brand.blurple.color + + self.contentConfiguration = content + } + + func configure(item: SearchResultOverviewItem.SuggestionSectionEntry) { + var content = UIListContentConfiguration.cell() + content.image = item.icon + content.text = item.title + content.imageProperties.tintColor = Asset.Colors.Brand.blurple.color + + self.contentConfiguration = content + } +} diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewSection.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewSection.swift new file mode 100644 index 000000000..895f26ff1 --- /dev/null +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewSection.swift @@ -0,0 +1,71 @@ +// Copyright © 2023 Mastodon gGmbH. All rights reserved. + +import UIKit +import MastodonSDK +import CoreDataStack + +enum SearchResultOverviewSection: Hashable { + case `default` + case suggestions +} + +enum SearchResultOverviewItem: Hashable { + case `default`(DefaultSectionEntry) + case suggestion(SuggestionSectionEntry) + + enum DefaultSectionEntry: Hashable { + case posts(String) + case people(String) + case profile(String, String) + case openLink(String) + + var title: String { + switch self { + //TODO: Add localization + case .posts(let text): + return "Posts with \(text)" + case .people(let username): + return "People with \(username)" + case .profile(let username, let instanceName): + return "Go to @\(username)@\(instanceName)" + case .openLink(_): + return "Open Link" + } + } + + var icon: UIImage? { + switch self { + case .posts(_): + return UIImage(systemName: "number") + case .people(_): + return UIImage(systemName: "person.2") + case .profile(_, _): + return UIImage(systemName: "person.crop.circle") + case .openLink(_): + return UIImage(systemName: "link") + } + } + } + + enum SuggestionSectionEntry: Hashable { + //TODO: Use User instead + case hashtag(tag: Mastodon.Entity.Tag) + case profile(ManagedObjectRecord) + + var title: String? { + if case let .hashtag(tag) = self { + return tag.name + } else { + return nil + } + } + + var icon: UIImage? { + if case let .hashtag(tag) = self { + return UIImage(systemName: "number") + } else { + return nil + } + } + } +} diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift new file mode 100644 index 000000000..60adc503e --- /dev/null +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift @@ -0,0 +1,166 @@ +// Copyright © 2023 Mastodon gGmbH. All rights reserved. + +import UIKit +import MastodonCore +import MastodonSDK + +protocol SearchResultsOverviewTableViewControllerDeleagte: AnyObject { + func showPosts(_ viewController: UIViewController) + func showPeople(_ viewController: UIViewController) + func showProfile(_ viewController: UIViewController) + func openLink(_ viewController: UIViewController) +} + +// we could move lots of this stuff to a coordinator, it's too much for work a viewcontroller +class SearchResultsOverviewTableViewController: UIViewController { + // similar to the other search results view controller but without the whole statemachine bullshit + // with scope all + + let appContext: AppContext + let authContext: AuthContext + + private let tableView: UITableView + var dataSource: UITableViewDiffableDataSource? + + weak var delegate: SearchResultsOverviewTableViewControllerDeleagte? + + init(appContext: AppContext, authContext: AuthContext) { + + self.appContext = appContext + self.authContext = authContext + + tableView = UITableView(frame: .zero, style: .insetGrouped) + tableView.translatesAutoresizingMaskIntoConstraints = false + tableView.backgroundColor = .systemGroupedBackground + tableView.register(SearchResultDefaultSectionTableViewCell.self, forCellReuseIdentifier: SearchResultDefaultSectionTableViewCell.reuseIdentifier) + tableView.register(StatusTableViewCell.self, forCellReuseIdentifier: StatusTableViewCell.reuseIdentifier) + tableView.register(HashtagTableViewCell.self, forCellReuseIdentifier: HashtagTableViewCell.reuseIdentifier) + tableView.register(UserTableViewCell.self, forCellReuseIdentifier: UserTableViewCell.reuseIdentifier) + + let dataSource = UITableViewDiffableDataSource(tableView: tableView) { tableView, indexPath, itemIdentifier in + switch itemIdentifier { + + case .default(let item): + guard let cell = tableView.dequeueReusableCell(withIdentifier: SearchResultDefaultSectionTableViewCell.reuseIdentifier, for: indexPath) as? SearchResultDefaultSectionTableViewCell else { fatalError() } + + cell.configure(item: item) + + return cell + + case .suggestion(let suggestion): + switch suggestion { + + case .hashtag(let hashtag): + guard let cell = tableView.dequeueReusableCell(withIdentifier: SearchResultDefaultSectionTableViewCell.reuseIdentifier, for: indexPath) as? SearchResultDefaultSectionTableViewCell else { fatalError() } + + cell.configure(item: .hashtag(tag: hashtag)) + return cell + + case .profile(let profile): + guard let cell = tableView.dequeueReusableCell(withIdentifier: UserTableViewCell.reuseIdentifier, for: indexPath) as? UserTableViewCell else { fatalError() } + +// cell.configure(me: <#T##MastodonUser?#>, tableView: <#T##UITableView#>, viewModel: <#T##UserTableViewCell.ViewModel#>, delegate: <#T##UserTableViewCellDelegate?#>) + + return cell + } + + } + } + + super.init(nibName: nil, bundle: nil) + tableView.dataSource = dataSource + tableView.delegate = self + self.dataSource = dataSource + + + view.addSubview(tableView) + tableView.pinToParent() + } + + required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } + + func showStandardSearch(for searchText: String) { + var snapshot = NSDiffableDataSourceSnapshot() + snapshot.appendSections([.default, .suggestions]) + snapshot.appendItems([.default(.posts(searchText)), + .default(.people(searchText)), + .default(.profile(searchText, authContext.mastodonAuthenticationBox.domain))], toSection: .default) + + if URL(string: searchText) != nil { + //TODO: Check if Mastodon-URL + snapshot.appendItems([.default(.openLink(searchText))], toSection: .default) + } + dataSource?.apply(snapshot, animatingDifferences: false) + } + + func searchForSuggestions(for searchText: String) { + + let query = Mastodon.API.V2.Search.Query( + q: searchText, + type: .default, + resolve: true + ) + + Task { + do { + let searchResult = try await appContext.apiService.search( + query: query, + authenticationBox: authContext.mastodonAuthenticationBox + ).value + + let firstThreeHashtags = searchResult.hashtags.prefix(3) + let firstThreeUsers = searchResult.accounts.prefix(3) + + guard var snapshot = dataSource?.snapshot() else { return } + + snapshot.deleteItems(snapshot.itemIdentifiers(inSection: .suggestions)) + snapshot.appendItems(firstThreeHashtags.map { .suggestion(.hashtag(tag: $0)) }, toSection: .suggestions ) +// snapshot.appendItems(firstThreeUsers.map { .suggestion(.profile($0.displayName)) }, toSection: .suggestions ) + + await MainActor.run { + dataSource?.apply(snapshot, animatingDifferences: false) + } + + + + } catch { + // do nothing + } + } + } +} + +//MARK: UITableViewDelegate +extension SearchResultsOverviewTableViewController: UITableViewDelegate { + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + + //TODO: Implement properly! + guard let snapshot = dataSource?.snapshot() else { return } + let section = snapshot.sectionIdentifiers[indexPath.section] + let item = snapshot.itemIdentifiers(inSection: section)[indexPath.row] + + switch item { + case .default(let defaultSectionEntry): + switch defaultSectionEntry { + case .posts(let string): + delegate?.showPosts(self) + case .people(let string): + delegate?.showPeople(self) + case .profile(let profile, let instanceName): + delegate?.showProfile(self) + case .openLink(let string): + delegate?.openLink(self) + } + case .suggestion(let suggestionSectionEntry): + switch suggestionSectionEntry { + + case .hashtag(_): + delegate?.showPosts(self) + case .profile(_): + delegate?.showProfile(self) + } + } + + tableView.deselectRow(at: indexPath, animated: true) + } +} diff --git a/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift b/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift index 09889fc2d..3868e02dc 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift @@ -8,7 +8,6 @@ import os.log import UIKit import Combine -import Pageboy import MastodonAsset import MastodonCore import MastodonLocalization @@ -23,10 +22,7 @@ final class CustomSearchController: UISearchController { // Fake search bar not works on iPad with UISplitViewController // check device and fallback to standard UISearchController -final class SearchDetailViewController: PageboyViewController, NeedsDependency { - - let logger = Logger(subsystem: "SearchDetail", category: "UI") - +final class SearchDetailViewController: UIViewController, NeedsDependency { var disposeBag = Set() var observations = Set() @@ -38,7 +34,6 @@ final class SearchDetailViewController: PageboyViewController, NeedsDependency { }() var viewModel: SearchDetailViewModel! - var viewControllers: [SearchResultViewController]! let navigationBarVisualEffectBackgroundView = UIVisualEffectView(effect: UIBlurEffect(style: .systemMaterial)) let navigationBarBackgroundView = UIView() @@ -73,9 +68,7 @@ final class SearchDetailViewController: PageboyViewController, NeedsDependency { searchController.searchBar.setShowsScope(true, animated: false) } searchBar.placeholder = L10n.Scene.Search.SearchBar.placeholder - searchBar.scopeButtonTitles = SearchDetailViewModel.SearchScope.allCases.map { $0.segmentedControlTitle } searchBar.sizeToFit() - searchBar.scopeBarBackgroundImage = UIImage() return searchBar }() @@ -86,9 +79,11 @@ final class SearchDetailViewController: PageboyViewController, NeedsDependency { searchHistoryViewController.viewModel = SearchHistoryViewModel(context: context, authContext: viewModel.authContext) return searchHistoryViewController }() -} -extension SearchDetailViewController { + private(set) lazy var searchResultsOverviewViewController: SearchResultsOverviewTableViewController = { + let searchResultsOverviewViewController = SearchResultsOverviewTableViewController(appContext: context, authContext: viewModel.authContext) + return searchResultsOverviewViewController + }() override func viewDidLoad() { super.viewDidLoad() @@ -119,81 +114,43 @@ extension SearchDetailViewController { searchHistoryViewController.view.pinToParent() } - transition = Transition(style: .fade, duration: 0.1) - isScrollEnabled = false + searchResultsOverviewViewController.delegate = self - viewControllers = viewModel.searchScopes.map { scope in - let searchResultViewController = SearchResultViewController() - searchResultViewController.context = context - searchResultViewController.coordinator = coordinator - searchResultViewController.viewModel = SearchResultViewModel(context: context, authContext: viewModel.authContext, searchScope: scope) - - // bind searchText - viewModel.searchText - .assign(to: \.value, on: searchResultViewController.viewModel.searchText) - .store(in: &searchResultViewController.disposeBag) - - // bind navigationBarFrame - viewModel.navigationBarFrame - .receive(on: DispatchQueue.main) - .assign(to: \.value, on: searchResultViewController.viewModel.navigationBarFrame) - .store(in: &searchResultViewController.disposeBag) - return searchResultViewController + addChild(searchResultsOverviewViewController) + searchResultsOverviewViewController.view.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(searchResultsOverviewViewController.view) + searchResultsOverviewViewController.didMove(toParent: self) + if isPhoneDevice { + NSLayoutConstraint.activate([ + searchResultsOverviewViewController.view.topAnchor.constraint(equalTo: navigationBarBackgroundView.bottomAnchor), + searchResultsOverviewViewController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), + searchResultsOverviewViewController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor), + searchResultsOverviewViewController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor), + ]) + } else { + searchResultsOverviewViewController.view.pinToParent() } - // set initial items from "all" search scope for non-appeared lists - if let allSearchScopeViewController = viewControllers.first(where: { $0.viewModel.searchScope == .all }) { - allSearchScopeViewController.viewModel.$items - .receive(on: DispatchQueue.main) - .sink { [weak self] items in - guard let self = self else { return } - guard self.currentViewController === allSearchScopeViewController else { return } - for viewController in self.viewControllers where viewController != allSearchScopeViewController { - // do not change appeared list - guard !viewController.viewModel.viewDidAppear.value else { continue } - // set initial items - switch viewController.viewModel.searchScope { - case .all: - assertionFailure() - break - case .people: - viewController.viewModel.userFetchedResultsController.userIDs = allSearchScopeViewController.viewModel.userFetchedResultsController.userIDs - case .hashtags: - viewController.viewModel.hashtags = allSearchScopeViewController.viewModel.hashtags - case .posts: - viewController.viewModel.statusFetchedResultsController.statusIDs = allSearchScopeViewController.viewModel.statusFetchedResultsController.statusIDs - } - } - } - .store(in: &allSearchScopeViewController.disposeBag) - } - - dataSource = self - delegate = self - - // bind search bar scope - viewModel.selectedSearchScope + // bind search trigger + // "local" search + viewModel.searchText + .removeDuplicates() .receive(on: DispatchQueue.main) - .sink { [weak self] searchScope in - guard let self = self else { return } - if let index = self.viewModel.searchScopes.firstIndex(of: searchScope) { - self.searchBar.selectedScopeButtonIndex = index - self.scrollToPage(.at(index: index), animated: true) - } + .sink { [weak self] searchText in + guard let self else { return } + + self.searchResultsOverviewViewController.showStandardSearch(for: searchText) } .store(in: &disposeBag) - // bind search trigger + // delayed search on server viewModel.searchText .removeDuplicates() .throttle(for: 0.5, scheduler: DispatchQueue.main, latest: true) .sink { [weak self] searchText in - guard let self = self else { return } - guard let searchResultViewController = self.currentViewController as? SearchResultViewController else { - return - } - self.logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): trigger search \(searchText)") - searchResultViewController.viewModel.stateMachine.enter(SearchResultViewModel.State.Loading.self) + guard let self else { return } + + self.searchResultsOverviewViewController.searchForSuggestions(for: searchText) } .store(in: &disposeBag) @@ -203,7 +160,9 @@ extension SearchDetailViewController { .receive(on: DispatchQueue.main) .sink { [weak self] searchText in guard let self = self else { return } + self.searchHistoryViewController.view.isHidden = !searchText.isEmpty + self.searchResultsOverviewViewController.view.isHidden = searchText.isEmpty } .store(in: &disposeBag) } @@ -253,7 +212,6 @@ extension SearchDetailViewController { } } } - } extension SearchDetailViewController { @@ -292,7 +250,6 @@ extension SearchDetailViewController { searchController.searchBar.sizeToFit() } - searchBar.text = viewModel.searchText.value searchBar.delegate = self } @@ -305,12 +262,7 @@ extension SearchDetailViewController { // MARK: - UISearchBarDelegate extension SearchDetailViewController: UISearchBarDelegate { - func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) { - viewModel.selectedSearchScope.value = viewModel.searchScopes[selectedScope] - } - func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { - logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): searchTest \(searchText)") viewModel.searchText.value = searchText.trimmingCharacters(in: .whitespacesAndNewlines) } @@ -322,77 +274,23 @@ extension SearchDetailViewController: UISearchBarDelegate { navigationController?.popViewController(animated: false) } } - } -// MARK: - PageboyViewControllerDataSource -extension SearchDetailViewController: PageboyViewControllerDataSource { - - func numberOfViewControllers(in pageboyViewController: PageboyViewController) -> Int { - return viewControllers.count +//MARK: SearchResultsOverviewViewControllerDelegate +extension SearchDetailViewController: SearchResultsOverviewTableViewControllerDeleagte { + func showPosts(_ viewController: UIViewController) { + //TODO: Implement } - func viewController(for pageboyViewController: PageboyViewController, at index: PageboyViewController.PageIndex) -> UIViewController? { - guard index < viewControllers.count else { return nil } - return viewControllers[index] + func showPeople(_ viewController: UIViewController) { + //TODO: Implement } - func defaultPage(for pageboyViewController: PageboyViewController) -> PageboyViewController.Page? { - return .first + func showProfile(_ viewController: UIViewController) { + //TODO: Implement } -} - -// MARK: - PageboyViewControllerDelegate -extension SearchDetailViewController: PageboyViewControllerDelegate { - - func pageboyViewController( - _ pageboyViewController: PageboyViewController, - willScrollToPageAt index: PageboyViewController.PageIndex, - direction: PageboyViewController.NavigationDirection, - animated: Bool - ) { - // do nothing - } - - func pageboyViewController( - _ pageboyViewController: PageboyViewController, - didScrollTo position: CGPoint, - direction: PageboyViewController.NavigationDirection, - animated: Bool - ) { - // do nothing - } - - func pageboyViewController( - _ pageboyViewController: PageboyViewController, - didCancelScrollToPageAt index: PageboyViewController.PageIndex, - returnToPageAt previousIndex: PageboyViewController.PageIndex - ) { - // do nothing - } - - func pageboyViewController( - _ pageboyViewController: PageboyViewController, - didScrollToPageAt index: PageboyViewController.PageIndex, - direction: PageboyViewController.NavigationDirection, - animated: Bool - ) { - logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): index \(index)") - - let searchResultViewController = viewControllers[index] - viewModel.selectedSearchScope.value = searchResultViewController.viewModel.searchScope - - // trigger fetch - searchResultViewController.viewModel.stateMachine.enter(SearchResultViewModel.State.Loading.self) - } - - - func pageboyViewController( - _ pageboyViewController: PageboyViewController, - didReloadWith currentViewController: UIViewController, - currentPageIndex: PageboyViewController.PageIndex - ) { - // do nothing + func openLink(_ viewController: UIViewController) { + //TODO: Implement } } diff --git a/Mastodon/Scene/Search/SearchDetail/SearchDetailViewModel.swift b/Mastodon/Scene/Search/SearchDetail/SearchDetailViewModel.swift index 425722e37..04228ba5a 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchDetailViewModel.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchDetailViewModel.swift @@ -5,7 +5,6 @@ // Created by MainasuK Cirno on 2021-7-13. // -import os.log import Foundation import CoreGraphics import Combine @@ -15,48 +14,37 @@ import MastodonAsset import MastodonLocalization final class SearchDetailViewModel { - + // input let authContext: AuthContext var needsBecomeFirstResponder = false let viewDidAppear = PassthroughSubject() let navigationBarFrame = CurrentValueSubject(.zero) - + // output let searchScopes = SearchScope.allCases let selectedSearchScope = CurrentValueSubject(.all) let searchText: CurrentValueSubject let searchActionPublisher = PassthroughSubject() - + init(authContext: AuthContext, initialSearchText: String = "") { self.authContext = authContext self.searchText = CurrentValueSubject(initialSearchText) } } -extension SearchDetailViewModel { - enum SearchScope: CaseIterable { - case all - case people - case hashtags - case posts - - var segmentedControlTitle: String { - switch self { - case .all: return L10n.Scene.Search.Searching.Segment.all - case .people: return L10n.Scene.Search.Searching.Segment.people - case .hashtags: return L10n.Scene.Search.Searching.Segment.hashtags - case .posts: return L10n.Scene.Search.Searching.Segment.posts - } - } - - var searchType: Mastodon.API.V2.Search.SearchType { - switch self { +enum SearchScope: CaseIterable { + case all + case people + case hashtags + case posts + + var searchType: Mastodon.API.V2.Search.SearchType { + switch self { case .all: return .default case .people: return .accounts case .hashtags: return .hashtags case .posts: return .statuses - } } } } diff --git a/Mastodon/Scene/Search/SearchDetail/SearchResult/Cell/HashtagTableViewCell.swift b/Mastodon/Scene/Search/SearchDetail/SearchResult/Cell/HashtagTableViewCell.swift index c8938c549..ccb74e31e 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchResult/Cell/HashtagTableViewCell.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchResult/Cell/HashtagTableViewCell.swift @@ -9,6 +9,8 @@ import UIKit import MetaTextKit final class HashtagTableViewCell: UITableViewCell { + + static let reuseIdentifier = "HashtagTableViewCell" let primaryLabel = MetaLabel(style: .statusName) diff --git a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController.swift b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController.swift index 093e0f971..cf7a6a0f6 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController.swift @@ -14,8 +14,6 @@ import MastodonUI final class SearchResultViewController: UIViewController, NeedsDependency, MediaPreviewableViewController { - let logger = Logger(subsystem: "SearchResultViewController", category: "ViewController") - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } diff --git a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+State.swift b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+State.swift index 3fdf65436..47832e156 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+State.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+State.swift @@ -5,7 +5,6 @@ // Created by MainasuK Cirno on 2021-7-14. // -import os.log import Foundation import GameplayKit import MastodonSDK diff --git a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel.swift b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel.swift index cd9e866bc..0c5c5868f 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel.swift @@ -20,7 +20,7 @@ final class SearchResultViewModel { // input let context: AppContext let authContext: AuthContext - let searchScope: SearchDetailViewModel.SearchScope + let searchScope: SearchScope let searchText = CurrentValueSubject("") @Published var hashtags: [Mastodon.Entity.Tag] = [] let userFetchedResultsController: UserFetchedResultsController @@ -48,7 +48,7 @@ final class SearchResultViewModel { }() let didDataSourceUpdate = PassthroughSubject() - init(context: AppContext, authContext: AuthContext, searchScope: SearchDetailViewModel.SearchScope) { + init(context: AppContext, authContext: AuthContext, searchScope: SearchScope = .all) { self.context = context self.authContext = authContext self.searchScope = searchScope diff --git a/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCell.swift b/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCell.swift index 16285ebeb..6c8c82527 100644 --- a/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCell.swift +++ b/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCell.swift @@ -13,6 +13,8 @@ import MastodonLocalization import MastodonUI final class StatusTableViewCell: UITableViewCell { + + static let reuseIdentifier = "StatusTableViewCell" static let marginForRegularHorizontalSizeClass: CGFloat = 64 diff --git a/Mastodon/Scene/Share/View/TableviewCell/UserTableViewCell.swift b/Mastodon/Scene/Share/View/TableviewCell/UserTableViewCell.swift index a05b80e9c..0f316bad8 100644 --- a/Mastodon/Scene/Share/View/TableviewCell/UserTableViewCell.swift +++ b/Mastodon/Scene/Share/View/TableviewCell/UserTableViewCell.swift @@ -16,7 +16,8 @@ import MastodonSDK protocol UserTableViewCellDelegate: UserViewDelegate, AnyObject { } final class UserTableViewCell: UITableViewCell { - + + static let reuseIdentifier = "UserTableViewCell" weak var delegate: UserTableViewCellDelegate? let userView = UserView() diff --git a/MastodonSDK/Sources/MastodonCore/FetchedResultsController/UserFetchedResultsController.swift b/MastodonSDK/Sources/MastodonCore/FetchedResultsController/UserFetchedResultsController.swift index d95a62bbb..cf4f1fc07 100644 --- a/MastodonSDK/Sources/MastodonCore/FetchedResultsController/UserFetchedResultsController.swift +++ b/MastodonSDK/Sources/MastodonCore/FetchedResultsController/UserFetchedResultsController.swift @@ -97,7 +97,6 @@ extension UserFetchedResultsController { // MARK: - NSFetchedResultsControllerDelegate extension UserFetchedResultsController: NSFetchedResultsControllerDelegate { public func controller(_ controller: NSFetchedResultsController, didChangeContentWith snapshot: NSDiffableDataSourceSnapshotReference) { - os_log("%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) let indexes = userIDs let objects = fetchedResultsController.fetchedObjects ?? [] diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+History.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+History.swift index 5f49d80f0..1acd3e84c 100644 --- a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+History.swift +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+History.swift @@ -16,7 +16,7 @@ extension Mastodon.Entity { /// 2021/1/28 /// # Reference /// [Document](https://docs.joinmastodon.org/entities/history/) - public struct History: Codable, Sendable { + public struct History: Hashable, Codable, Sendable { /// UNIX timestamp on midnight of the given day public let day: Date public let uses: String diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index d7d2faf48..ebae0d12e 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -361,8 +361,6 @@ extension StatusView.ViewModel { statusView.statusCardControl.alpha = isContentReveal ? 1 : 0 statusView.setSpoilerOverlayViewHidden(isHidden: isContentReveal) - - self.logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): isContentReveal: \(isContentReveal)") } .store(in: &disposeBag) @@ -400,7 +398,6 @@ extension StatusView.ViewModel { $mediaViewConfigurations .sink { [weak self] configurations in guard let self = self else { return } - self.logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): configure media") statusView.mediaGridContainerView.prepareForReuse() From ed11d01267dfb59974c9c079a7b977ffbedffcce Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sat, 16 Sep 2023 17:57:29 +0200 Subject: [PATCH 42/87] Show up to three hashtags and up to three users (IOS-141) --- .../HomeTimelineViewModel+Diffable.swift | 5 -- .../SearchResultOverviewSection.swift | 33 +++++--- ...chResultsOverviewTableViewController.swift | 81 ++++++++++++++----- .../SearchDetailViewController.swift | 29 ++----- .../MastodonSDK/API/Mastodon+API.swift | 1 - 5 files changed, 87 insertions(+), 62 deletions(-) diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift index 9feee053e..6da6a60fa 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift @@ -87,11 +87,8 @@ extension HomeTimelineViewModel { let hasChanges = newSnapshot.itemIdentifiers != oldSnapshot.itemIdentifiers if !hasChanges && !self.hasPendingStatusEditReload { - self.logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): snapshot not changes") self.didLoadLatest.send() return - } else { - self.logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): snapshot has changes") } guard let difference = self.calculateReloadSnapshotDifference( @@ -101,7 +98,6 @@ extension HomeTimelineViewModel { ) else { self.updateSnapshotUsingReloadData(snapshot: newSnapshot) self.didLoadLatest.send() - self.logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): applied new snapshot") return } @@ -111,7 +107,6 @@ extension HomeTimelineViewModel { contentOffset.y = tableView.contentOffset.y - difference.sourceDistanceToTableViewTopEdge tableView.setContentOffset(contentOffset, animated: false) self.didLoadLatest.send() - self.logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): applied new snapshot") self.hasPendingStatusEditReload = false } // end Task } diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewSection.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewSection.swift index 895f26ff1..37d352b07 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewSection.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewSection.swift @@ -48,24 +48,37 @@ enum SearchResultOverviewItem: Hashable { } enum SuggestionSectionEntry: Hashable { - //TODO: Use User instead case hashtag(tag: Mastodon.Entity.Tag) - case profile(ManagedObjectRecord) + case profile(user: Mastodon.Entity.Account) var title: String? { - if case let .hashtag(tag) = self { - return tag.name - } else { - return nil + switch self { + + case .hashtag(tag: let tag): + return tag.name + case .profile(user: let user): + return "\(user.displayName) — \(user.acct)" } +// if case let .hashtag(tag) = self { +// return tag.name +// } else { +// return nil +// } } var icon: UIImage? { - if case let .hashtag(tag) = self { - return UIImage(systemName: "number") - } else { - return nil + switch self { + + case .hashtag(tag: _): + return UIImage(systemName: "number") + + case .profile(user: _): + return UIImage(systemName: "person.circle") + } +// if case let .hashtag(tag) = self { +// } else { +// } } } } diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift index 60adc503e..32078309b 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift @@ -23,6 +23,7 @@ class SearchResultsOverviewTableViewController: UIViewController { var dataSource: UITableViewDiffableDataSource? weak var delegate: SearchResultsOverviewTableViewControllerDeleagte? + var activeTask: Task? init(appContext: AppContext, authContext: AuthContext) { @@ -48,22 +49,29 @@ class SearchResultsOverviewTableViewController: UIViewController { return cell case .suggestion(let suggestion): - switch suggestion { - case .hashtag(let hashtag): - guard let cell = tableView.dequeueReusableCell(withIdentifier: SearchResultDefaultSectionTableViewCell.reuseIdentifier, for: indexPath) as? SearchResultDefaultSectionTableViewCell else { fatalError() } - cell.configure(item: .hashtag(tag: hashtag)) - return cell + guard let cell = tableView.dequeueReusableCell(withIdentifier: SearchResultDefaultSectionTableViewCell.reuseIdentifier, for: indexPath) as? SearchResultDefaultSectionTableViewCell else { fatalError() } - case .profile(let profile): - guard let cell = tableView.dequeueReusableCell(withIdentifier: UserTableViewCell.reuseIdentifier, for: indexPath) as? UserTableViewCell else { fatalError() } - -// cell.configure(me: <#T##MastodonUser?#>, tableView: <#T##UITableView#>, viewModel: <#T##UserTableViewCell.ViewModel#>, delegate: <#T##UserTableViewCellDelegate?#>) - - return cell - } + cell.configure(item: suggestion) + return cell +// switch suggestion { +// +// case .hashtag(let hashtag): +// guard let cell = tableView.dequeueReusableCell(withIdentifier: SearchResultDefaultSectionTableViewCell.reuseIdentifier, for: indexPath) as? SearchResultDefaultSectionTableViewCell else { fatalError() } +// +// cell.configure(item: .hashtag(tag: hashtag)) +// return cell +// +// case .profile(let profile): +// //TODO: Use `UserFetchedResultsController` or `Persistence.MastodonUser.fetch` ??? +// guard let cell = tableView.dequeueReusableCell(withIdentifier: UserTableViewCell.reuseIdentifier, for: indexPath) as? UserTableViewCell else { fatalError() } +// +//// cell.configure(me: <#T##MastodonUser?#>, tableView: <#T##UITableView#>, viewModel: <#T##UserTableViewCell.ViewModel#>, delegate: <#T##UserTableViewCellDelegate?#>) +// +// return cell +// } } } @@ -79,9 +87,20 @@ class SearchResultsOverviewTableViewController: UIViewController { required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } - func showStandardSearch(for searchText: String) { + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + var snapshot = NSDiffableDataSourceSnapshot() snapshot.appendSections([.default, .suggestions]) + dataSource?.apply(snapshot, animatingDifferences: false) + } + + func showStandardSearch(for searchText: String) { + + guard let dataSource else { return } + + var snapshot = dataSource.snapshot() + snapshot.deleteItems(snapshot.itemIdentifiers(inSection: .default)) snapshot.appendItems([.default(.posts(searchText)), .default(.people(searchText)), .default(.profile(searchText, authContext.mastodonAuthenticationBox.domain))], toSection: .default) @@ -90,18 +109,29 @@ class SearchResultsOverviewTableViewController: UIViewController { //TODO: Check if Mastodon-URL snapshot.appendItems([.default(.openLink(searchText))], toSection: .default) } - dataSource?.apply(snapshot, animatingDifferences: false) + + dataSource.apply(snapshot, animatingDifferences: false) } func searchForSuggestions(for searchText: String) { + activeTask?.cancel() + + guard let dataSource else { return } + + var snapshot = dataSource.snapshot() + snapshot.deleteItems(snapshot.itemIdentifiers(inSection: .suggestions)) + dataSource.apply(snapshot, animatingDifferences: false) + + guard searchText.isNotEmpty else { return } + let query = Mastodon.API.V2.Search.Query( q: searchText, type: .default, resolve: true ) - Task { + let searchTask = Task { do { let searchResult = try await appContext.apiService.search( query: query, @@ -111,22 +141,29 @@ class SearchResultsOverviewTableViewController: UIViewController { let firstThreeHashtags = searchResult.hashtags.prefix(3) let firstThreeUsers = searchResult.accounts.prefix(3) - guard var snapshot = dataSource?.snapshot() else { return } + var snapshot = dataSource.snapshot() - snapshot.deleteItems(snapshot.itemIdentifiers(inSection: .suggestions)) - snapshot.appendItems(firstThreeHashtags.map { .suggestion(.hashtag(tag: $0)) }, toSection: .suggestions ) -// snapshot.appendItems(firstThreeUsers.map { .suggestion(.profile($0.displayName)) }, toSection: .suggestions ) - - await MainActor.run { - dataSource?.apply(snapshot, animatingDifferences: false) + if firstThreeHashtags.isNotEmpty { + snapshot.appendItems(firstThreeHashtags.map { .suggestion(.hashtag(tag: $0)) }, toSection: .suggestions ) } + if firstThreeUsers.isNotEmpty { + snapshot.appendItems(firstThreeUsers.map { .suggestion(.profile(user: $0)) }, toSection: .suggestions ) + } + guard Task.isCancelled == false else { return } + + await MainActor.run { + dataSource.apply(snapshot, animatingDifferences: false) + } } catch { // do nothing + print(error.localizedDescription) } } + + activeTask = searchTask } } diff --git a/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift b/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift index 3868e02dc..4e1f7696e 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift @@ -131,29 +131,6 @@ final class SearchDetailViewController: UIViewController, NeedsDependency { searchResultsOverviewViewController.view.pinToParent() } - // bind search trigger - // "local" search - viewModel.searchText - .removeDuplicates() - .receive(on: DispatchQueue.main) - .sink { [weak self] searchText in - guard let self else { return } - - self.searchResultsOverviewViewController.showStandardSearch(for: searchText) - } - .store(in: &disposeBag) - - // delayed search on server - viewModel.searchText - .removeDuplicates() - .throttle(for: 0.5, scheduler: DispatchQueue.main, latest: true) - .sink { [weak self] searchText in - guard let self else { return } - - self.searchResultsOverviewViewController.searchForSuggestions(for: searchText) - } - .store(in: &disposeBag) - // bind search history display viewModel.searchText .removeDuplicates() @@ -263,7 +240,11 @@ extension SearchDetailViewController { extension SearchDetailViewController: UISearchBarDelegate { func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { - viewModel.searchText.value = searchText.trimmingCharacters(in: .whitespacesAndNewlines) + let trimmedSearchText = searchText.trimmingCharacters(in: .whitespacesAndNewlines) + viewModel.searchText.value = trimmedSearchText + + searchResultsOverviewViewController.showStandardSearch(for: trimmedSearchText) + searchResultsOverviewViewController.searchForSuggestions(for: trimmedSearchText) } func searchBarCancelButtonClicked(_ searchBar: UISearchBar) { diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift index 76bebe5a0..57d99dc41 100644 --- a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift @@ -208,7 +208,6 @@ extension Mastodon.API { return try Mastodon.API.decoder.decode(type, from: data) } catch let decodeError { #if DEBUG - os_log(.info, "%{public}s[%{public}ld], %{public}s: decode fail. content %s", ((#file as NSString).lastPathComponent), #line, #function, String(data: data, encoding: .utf8) ?? "") debugPrint(decodeError) #endif From 1afecc85eae8d8d6f9a67856520bb29ec382fdce Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sat, 16 Sep 2023 18:39:33 +0200 Subject: [PATCH 43/87] Show hashtag-page (IOS-141) --- Mastodon/Coordinator/NeedsDependency.swift | 1 + .../Provider/DataSourceFacade+Hashtag.swift | 2 +- ...chResultsOverviewTableViewController.swift | 56 ++++++++++++------- .../SearchDetailViewController.swift | 9 +-- .../Service/API/APIService+Account.swift | 12 ++-- .../Entity/Mastodon+Entity+Tag.swift | 7 +++ 6 files changed, 55 insertions(+), 32 deletions(-) diff --git a/Mastodon/Coordinator/NeedsDependency.swift b/Mastodon/Coordinator/NeedsDependency.swift index c035437ac..46fbcd1ff 100644 --- a/Mastodon/Coordinator/NeedsDependency.swift +++ b/Mastodon/Coordinator/NeedsDependency.swift @@ -9,6 +9,7 @@ import UIKit import MastodonCore protocol NeedsDependency: AnyObject { + //FIXME: Get rid of ! ~@zeitschlag var context: AppContext! { get set } var coordinator: SceneCoordinator! { get set } } diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Hashtag.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Hashtag.swift index 6135c904a..9b0001351 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Hashtag.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Hashtag.swift @@ -26,7 +26,7 @@ extension DataSourceFacade { @MainActor static func coordinateToHashtagScene( - provider: DataSourceProvider & AuthContextProvider, + provider: NeedsDependency & UIViewController & AuthContextProvider, tag: Mastodon.Entity.Tag ) async { let hashtagTimelineViewModel = HashtagTimelineViewModel( diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift index 32078309b..a4b8b123b 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift @@ -5,19 +5,19 @@ import MastodonCore import MastodonSDK protocol SearchResultsOverviewTableViewControllerDeleagte: AnyObject { - func showPosts(_ viewController: UIViewController) func showPeople(_ viewController: UIViewController) func showProfile(_ viewController: UIViewController) func openLink(_ viewController: UIViewController) } // we could move lots of this stuff to a coordinator, it's too much for work a viewcontroller -class SearchResultsOverviewTableViewController: UIViewController { +class SearchResultsOverviewTableViewController: UIViewController, NeedsDependency, AuthContextProvider { // similar to the other search results view controller but without the whole statemachine bullshit // with scope all - let appContext: AppContext + var context: AppContext! let authContext: AuthContext + var coordinator: SceneCoordinator! private let tableView: UITableView var dataSource: UITableViewDiffableDataSource? @@ -25,10 +25,11 @@ class SearchResultsOverviewTableViewController: UIViewController { weak var delegate: SearchResultsOverviewTableViewControllerDeleagte? var activeTask: Task? - init(appContext: AppContext, authContext: AuthContext) { + init(appContext: AppContext, authContext: AuthContext, coordinator: SceneCoordinator) { - self.appContext = appContext + self.context = appContext self.authContext = authContext + self.coordinator = coordinator tableView = UITableView(frame: .zero, style: .insetGrouped) tableView.translatesAutoresizingMaskIntoConstraints = false @@ -50,7 +51,6 @@ class SearchResultsOverviewTableViewController: UIViewController { case .suggestion(let suggestion): - guard let cell = tableView.dequeueReusableCell(withIdentifier: SearchResultDefaultSectionTableViewCell.reuseIdentifier, for: indexPath) as? SearchResultDefaultSectionTableViewCell else { fatalError() } cell.configure(item: suggestion) @@ -59,17 +59,26 @@ class SearchResultsOverviewTableViewController: UIViewController { // switch suggestion { // // case .hashtag(let hashtag): -// guard let cell = tableView.dequeueReusableCell(withIdentifier: SearchResultDefaultSectionTableViewCell.reuseIdentifier, for: indexPath) as? SearchResultDefaultSectionTableViewCell else { fatalError() } -// -// cell.configure(item: .hashtag(tag: hashtag)) -// return cell // // case .profile(let profile): // //TODO: Use `UserFetchedResultsController` or `Persistence.MastodonUser.fetch` ??? +// // guard let cell = tableView.dequeueReusableCell(withIdentifier: UserTableViewCell.reuseIdentifier, for: indexPath) as? UserTableViewCell else { fatalError() } + + // how the fuck do I get a MastodonUser??? +// try await managedObjectContext.perform { +// Persistence.MastodonUser.fetch(in: managedObjectContext, +// context: Persistence.MastodonUser.PersistContext( +// domain: domain, +// entity: profile.value, +// cache: nil, +// networkDate: profile.netwo +// )) +// } // -//// cell.configure(me: <#T##MastodonUser?#>, tableView: <#T##UITableView#>, viewModel: <#T##UserTableViewCell.ViewModel#>, delegate: <#T##UserTableViewCellDelegate?#>) -// + + // cell.configure(me: <#T##MastodonUser?#>, tableView: <#T##UITableView#>, viewModel: <#T##UserTableViewCell.ViewModel#>, delegate: <#T##UserTableViewCellDelegate?#>) + // return cell // } } @@ -87,8 +96,8 @@ class SearchResultsOverviewTableViewController: UIViewController { required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } - override func viewDidAppear(_ animated: Bool) { - super.viewDidAppear(animated) + override func viewDidLoad() { + super.viewDidLoad() var snapshot = NSDiffableDataSourceSnapshot() snapshot.appendSections([.default, .suggestions]) @@ -133,7 +142,7 @@ class SearchResultsOverviewTableViewController: UIViewController { let searchTask = Task { do { - let searchResult = try await appContext.apiService.search( + let searchResult = try await context.apiService.search( query: query, authenticationBox: authContext.mastodonAuthenticationBox ).value @@ -165,6 +174,15 @@ class SearchResultsOverviewTableViewController: UIViewController { activeTask = searchTask } + + func showPosts(tag: Mastodon.Entity.Tag) { + Task { + await DataSourceFacade.coordinateToHashtagScene( + provider: self, + tag: tag + ) + } + } } //MARK: UITableViewDelegate @@ -179,8 +197,8 @@ extension SearchResultsOverviewTableViewController: UITableViewDelegate { switch item { case .default(let defaultSectionEntry): switch defaultSectionEntry { - case .posts(let string): - delegate?.showPosts(self) + case .posts(let hashtag): + showPosts(tag: Mastodon.Entity.Tag(name: hashtag, url: authContext.mastodonAuthenticationBox.domain)) case .people(let string): delegate?.showPeople(self) case .profile(let profile, let instanceName): @@ -191,8 +209,8 @@ extension SearchResultsOverviewTableViewController: UITableViewDelegate { case .suggestion(let suggestionSectionEntry): switch suggestionSectionEntry { - case .hashtag(_): - delegate?.showPosts(self) + case .hashtag(let tag): + showPosts(tag: tag) case .profile(_): delegate?.showProfile(self) } diff --git a/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift b/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift index 4e1f7696e..25dc48e45 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift @@ -23,12 +23,13 @@ final class CustomSearchController: UISearchController { // Fake search bar not works on iPad with UISplitViewController // check device and fallback to standard UISearchController final class SearchDetailViewController: UIViewController, NeedsDependency { + var disposeBag = Set() var observations = Set() weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } - + let isPhoneDevice: Bool = { return UIDevice.current.userInterfaceIdiom == .phone }() @@ -81,7 +82,7 @@ final class SearchDetailViewController: UIViewController, NeedsDependency { }() private(set) lazy var searchResultsOverviewViewController: SearchResultsOverviewTableViewController = { - let searchResultsOverviewViewController = SearchResultsOverviewTableViewController(appContext: context, authContext: viewModel.authContext) + let searchResultsOverviewViewController = SearchResultsOverviewTableViewController(appContext: context, authContext: viewModel.authContext, coordinator: coordinator) return searchResultsOverviewViewController }() @@ -259,10 +260,6 @@ extension SearchDetailViewController: UISearchBarDelegate { //MARK: SearchResultsOverviewViewControllerDelegate extension SearchDetailViewController: SearchResultsOverviewTableViewControllerDeleagte { - func showPosts(_ viewController: UIViewController) { - //TODO: Implement - } - func showPeople(_ viewController: UIViewController) { //TODO: Implement } diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Account.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Account.swift index d68984587..812c558d8 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Account.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Account.swift @@ -230,12 +230,12 @@ extension APIService { var result: MastodonUser? try await managedObjectContext.perform { result = Persistence.MastodonUser.fetch(in: managedObjectContext, - context: Persistence.MastodonUser.PersistContext( - domain: domain, - entity: response.value, - cache: nil, - networkDate: response.networkDate - )) + context: Persistence.MastodonUser.PersistContext( + domain: domain, + entity: response.value, + cache: nil, + networkDate: response.networkDate + )) } return result } diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Tag.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Tag.swift index 8d7baa6a6..6a3516904 100644 --- a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Tag.swift +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Tag.swift @@ -25,6 +25,13 @@ extension Mastodon.Entity { public let history: [History]? public let following: Bool? + public init(name: String, url: String, history: [History]? = nil, following: Bool? = nil) { + self.name = name + self.url = url + self.history = history + self.following = following + } + enum CodingKeys: String, CodingKey { case name case url From a304fb21086eb8eb3ab4f2bfbb2ef5554c54108e Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sun, 17 Sep 2023 12:48:58 +0200 Subject: [PATCH 44/87] Show profile-page for suggested accounts in search (IOS-141) --- Mastodon/Diffable/User/UserSection.swift | 49 +++++----- .../Provider/DataSourceFacade+Profile.swift | 2 +- ...chResultsOverviewTableViewController.swift | 92 +++++++++++++------ .../SearchResult/SearchResultSection.swift | 2 +- .../UserTableViewCell+ViewModel.swift | 83 ++++++++--------- 5 files changed, 130 insertions(+), 98 deletions(-) diff --git a/Mastodon/Diffable/User/UserSection.swift b/Mastodon/Diffable/User/UserSection.swift index cbad1ff72..24f13ddc6 100644 --- a/Mastodon/Diffable/User/UserSection.swift +++ b/Mastodon/Diffable/User/UserSection.swift @@ -39,30 +39,31 @@ extension UserSection { return UITableViewDiffableDataSource(tableView: tableView) { tableView, indexPath, item -> UITableViewCell? in switch item { - case .user(let record): - let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: UserTableViewCell.self), for: indexPath) as! UserTableViewCell - context.managedObjectContext.performAndWait { - guard let user = record.object(in: context.managedObjectContext) else { return } - configure( - context: context, - authContext: authContext, - tableView: tableView, - cell: cell, - viewModel: UserTableViewCell.ViewModel(value: .user(user), - followedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$followingUserIds.eraseToAnyPublisher(), - blockedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$blockedUserIds.eraseToAnyPublisher(), - followRequestedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$followRequestedUserIDs.eraseToAnyPublisher() - ), - configuration: configuration - ) - } - - return cell - case .bottomLoader: - let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: TimelineBottomLoaderTableViewCell.self), for: indexPath) as! TimelineBottomLoaderTableViewCell - cell.startAnimating() - return cell - case .bottomHeader(let text): + case .user(let record): + let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: UserTableViewCell.self), for: indexPath) as! UserTableViewCell + context.managedObjectContext.performAndWait { + guard let user = record.object(in: context.managedObjectContext) else { return } + configure( + context: context, + authContext: authContext, + tableView: tableView, + cell: cell, + viewModel: UserTableViewCell.ViewModel( + user: user, + followedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$followingUserIds.eraseToAnyPublisher(), + blockedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$blockedUserIds.eraseToAnyPublisher(), + followRequestedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$followRequestedUserIDs.eraseToAnyPublisher() + ), + configuration: configuration + ) + } + + return cell + case .bottomLoader: + let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: TimelineBottomLoaderTableViewCell.self), for: indexPath) as! TimelineBottomLoaderTableViewCell + cell.startAnimating() + return cell + case .bottomHeader(let text): let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: TimelineFooterTableViewCell.self), for: indexPath) as! TimelineFooterTableViewCell cell.messageLabel.text = text return cell diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Profile.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Profile.swift index f434bc6ac..161e52e87 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Profile.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Profile.swift @@ -33,7 +33,7 @@ extension DataSourceFacade { @MainActor static func coordinateToProfileScene( - provider: DataSourceProvider & AuthContextProvider, + provider: NeedsDependency & UIViewController & AuthContextProvider, user: ManagedObjectRecord ) async { guard let user = user.object(in: provider.context.managedObjectContext) else { diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift index a4b8b123b..b3026e279 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift @@ -51,36 +51,52 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc case .suggestion(let suggestion): - guard let cell = tableView.dequeueReusableCell(withIdentifier: SearchResultDefaultSectionTableViewCell.reuseIdentifier, for: indexPath) as? SearchResultDefaultSectionTableViewCell else { fatalError() } + switch suggestion { - cell.configure(item: suggestion) - return cell + case .hashtag(let hashtag): -// switch suggestion { -// -// case .hashtag(let hashtag): -// -// case .profile(let profile): -// //TODO: Use `UserFetchedResultsController` or `Persistence.MastodonUser.fetch` ??? -// -// guard let cell = tableView.dequeueReusableCell(withIdentifier: UserTableViewCell.reuseIdentifier, for: indexPath) as? UserTableViewCell else { fatalError() } + + guard let cell = tableView.dequeueReusableCell(withIdentifier: SearchResultDefaultSectionTableViewCell.reuseIdentifier, for: indexPath) as? SearchResultDefaultSectionTableViewCell else { fatalError() } + + cell.configure(item: .hashtag(tag: hashtag)) + return cell + + // + case .profile(let profile): + guard let cell = tableView.dequeueReusableCell(withIdentifier: UserTableViewCell.reuseIdentifier, for: indexPath) as? UserTableViewCell else { fatalError() } // how the fuck do I get a MastodonUser??? -// try await managedObjectContext.perform { -// Persistence.MastodonUser.fetch(in: managedObjectContext, -// context: Persistence.MastodonUser.PersistContext( -// domain: domain, -// entity: profile.value, -// cache: nil, -// networkDate: profile.netwo -// )) -// } -// + let managedObjectContext = appContext.managedObjectContext + Task { + do { - // cell.configure(me: <#T##MastodonUser?#>, tableView: <#T##UITableView#>, viewModel: <#T##UserTableViewCell.ViewModel#>, delegate: <#T##UserTableViewCellDelegate?#>) + try await managedObjectContext.perform { + guard let user = Persistence.MastodonUser.fetch(in: managedObjectContext, + context: Persistence.MastodonUser.PersistContext( + domain: authContext.mastodonAuthenticationBox.domain, + entity: profile, + cache: nil, + networkDate: Date() + )) else { return } -// return cell -// } + cell.configure( + me: authContext.mastodonAuthenticationBox.authenticationRecord.object(in: managedObjectContext)?.user, + tableView: tableView, + viewModel: UserTableViewCell.ViewModel( + user: user, + followedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$followingUserIds.eraseToAnyPublisher(), + blockedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$blockedUserIds.eraseToAnyPublisher(), + followRequestedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$followRequestedUserIDs.eraseToAnyPublisher()), + delegate: nil) + } + } + catch { + // do nothing + } + } + + return cell + } } } @@ -183,6 +199,28 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc ) } } + + func showProfile(for account: Mastodon.Entity.Account) { + let managedObjectContext = context.managedObjectContext + let domain = authContext.mastodonAuthenticationBox.domain + + Task { + let user = try await managedObjectContext.perform { + return Persistence.MastodonUser.fetch(in: managedObjectContext, + context: Persistence.MastodonUser.PersistContext( + domain: domain, + entity: account, + cache: nil, + networkDate: Date() + )) + } + + if let user { + await DataSourceFacade.coordinateToProfileScene(provider:self, + user: user.asRecord) + } + } + } } //MARK: UITableViewDelegate @@ -198,8 +236,10 @@ extension SearchResultsOverviewTableViewController: UITableViewDelegate { case .default(let defaultSectionEntry): switch defaultSectionEntry { case .posts(let hashtag): + //FIXME: Show statuses instead of tag-content. Reuse SearchResultsViewController with statuses here? showPosts(tag: Mastodon.Entity.Tag(name: hashtag, url: authContext.mastodonAuthenticationBox.domain)) case .people(let string): + //FIXME: Invoke SearchResultsViewController with people-scope here delegate?.showPeople(self) case .profile(let profile, let instanceName): delegate?.showProfile(self) @@ -211,8 +251,8 @@ extension SearchResultsOverviewTableViewController: UITableViewDelegate { case .hashtag(let tag): showPosts(tag: tag) - case .profile(_): - delegate?.showProfile(self) + case .profile(let account): + showProfile(for: account) } } diff --git a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultSection.swift b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultSection.swift index 90560150e..49eeddb32 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultSection.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultSection.swift @@ -53,7 +53,7 @@ extension SearchResultSection { authContext: authContext, tableView: tableView, cell: cell, - viewModel: UserTableViewCell.ViewModel(value: .user(user), + viewModel: UserTableViewCell.ViewModel(user: user, followedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$followingUserIds.eraseToAnyPublisher(), blockedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$blockedUserIds.eraseToAnyPublisher(), followRequestedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$followRequestedUserIDs.eraseToAnyPublisher()), diff --git a/Mastodon/Scene/Share/View/TableviewCell/UserTableViewCell+ViewModel.swift b/Mastodon/Scene/Share/View/TableviewCell/UserTableViewCell+ViewModel.swift index b83b8b47d..7f2727a91 100644 --- a/Mastodon/Scene/Share/View/TableviewCell/UserTableViewCell+ViewModel.swift +++ b/Mastodon/Scene/Share/View/TableviewCell/UserTableViewCell+ViewModel.swift @@ -12,72 +12,63 @@ import Combine extension UserTableViewCell { final class ViewModel { - let value: Value + let user: MastodonUser let followedUsers: AnyPublisher<[String], Never> let blockedUsers: AnyPublisher<[String], Never> let followRequestedUsers: AnyPublisher<[String], Never> - init(value: Value, followedUsers: AnyPublisher<[String], Never>, blockedUsers: AnyPublisher<[String], Never>, followRequestedUsers: AnyPublisher<[String], Never>) { - self.value = value + init(user: MastodonUser, followedUsers: AnyPublisher<[String], Never>, blockedUsers: AnyPublisher<[String], Never>, followRequestedUsers: AnyPublisher<[String], Never>) { + self.user = user self.followedUsers = followedUsers self.followRequestedUsers = followRequestedUsers self.blockedUsers = blockedUsers } - - enum Value { - case user(MastodonUser) - // case status(Status) - } } } extension UserTableViewCell { func configure( - me: MastodonUser?, + me: MastodonUser? = nil, tableView: UITableView, viewModel: ViewModel, delegate: UserTableViewCellDelegate? ) { - switch viewModel.value { - case .user(let user): - userView.configure(user: user, delegate: delegate) - - guard let me = me else { - return userView.setButtonState(.none) - } - - if user == me { - userView.setButtonState(.none) - } else { - userView.setButtonState(.loading) - } - - Publishers.CombineLatest3( - viewModel.followedUsers, - viewModel.followRequestedUsers, - viewModel.blockedUsers - ) - .receive(on: DispatchQueue.main) - .sink { [weak self] followed, requested, blocked in - if blocked.contains(user.id) { - self?.userView.setButtonState(.blocked) - } else if followed.contains(user.id) { - self?.userView.setButtonState(.unfollow) - } else if requested.contains(user.id) { - self?.userView.setButtonState(.pending) - } else if user.locked { - self?.userView.setButtonState(.request) - } else if user != me { - self?.userView.setButtonState(.follow) - } - } - .store(in: &disposeBag) - + userView.configure(user: viewModel.user, delegate: delegate) + + guard let me = me else { + return userView.setButtonState(.none) } - - self.delegate = delegate + + if viewModel.user == me { + userView.setButtonState(.none) + } else { + userView.setButtonState(.loading) + } + + Publishers.CombineLatest3( + viewModel.followedUsers, + viewModel.followRequestedUsers, + viewModel.blockedUsers + ) + .receive(on: DispatchQueue.main) + .sink { [weak self] followed, requested, blocked in + if blocked.contains(viewModel.user.id) { + self?.userView.setButtonState(.blocked) + } else if followed.contains(viewModel.user.id) { + self?.userView.setButtonState(.unfollow) + } else if requested.contains(viewModel.user.id) { + self?.userView.setButtonState(.pending) + } else if viewModel.user.locked { + self?.userView.setButtonState(.request) + } else if viewModel.user != me { + self?.userView.setButtonState(.follow) + } + } + .store(in: &disposeBag) + + self.delegate = delegate } } From 1ad591fd8246000f8d6d6c12e6ea82e099b6241f Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sun, 17 Sep 2023 13:01:46 +0200 Subject: [PATCH 45/87] Search for people (IOS-141) --- Mastodon/Coordinator/SceneCoordinator.swift | 313 +++++++++--------- .../SearchResultOverviewSection.swift | 36 +- ...chResultsOverviewTableViewController.swift | 30 +- 3 files changed, 189 insertions(+), 190 deletions(-) diff --git a/Mastodon/Coordinator/SceneCoordinator.swift b/Mastodon/Coordinator/SceneCoordinator.swift index 4908a533a..73eda67eb 100644 --- a/Mastodon/Coordinator/SceneCoordinator.swift +++ b/Mastodon/Coordinator/SceneCoordinator.swift @@ -153,6 +153,7 @@ extension SceneCoordinator { // search case searchDetail(viewModel: SearchDetailViewModel) + case searchResult(viewModel: SearchResultViewModel) // compose case compose(viewModel: ComposeViewModel) @@ -376,159 +377,169 @@ private extension SceneCoordinator { let viewController: UIViewController? switch scene { - case .welcome: - let _viewController = WelcomeViewController() - viewController = _viewController - case .mastodonPickServer(let viewModel): - let _viewController = MastodonPickServerViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .mastodonRegister(let viewModel): - let _viewController = MastodonRegisterViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .mastodonServerRules(let viewModel): - let _viewController = MastodonServerRulesViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .mastodonConfirmEmail(let viewModel): - let _viewController = MastodonConfirmEmailViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .mastodonLogin: - let loginViewController = MastodonLoginViewController(appContext: appContext, - authenticationViewModel: AuthenticationViewModel(context: appContext, coordinator: self, isAuthenticationExist: false), - sceneCoordinator: self) - loginViewController.delegate = self + case .welcome: + let _viewController = WelcomeViewController() + viewController = _viewController + case .mastodonPickServer(let viewModel): + let _viewController = MastodonPickServerViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .mastodonRegister(let viewModel): + let _viewController = MastodonRegisterViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .mastodonServerRules(let viewModel): + let _viewController = MastodonServerRulesViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .mastodonConfirmEmail(let viewModel): + let _viewController = MastodonConfirmEmailViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .mastodonLogin: + let loginViewController = MastodonLoginViewController(appContext: appContext, + authenticationViewModel: AuthenticationViewModel(context: appContext, coordinator: self, isAuthenticationExist: false), + sceneCoordinator: self) + loginViewController.delegate = self - viewController = loginViewController - case .mastodonPrivacyPolicies(let viewModel): - let privacyViewController = PrivacyTableViewController(context: appContext, coordinator: self, viewModel: viewModel) - viewController = privacyViewController - case .mastodonResendEmail(let viewModel): - let _viewController = MastodonResendEmailViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .mastodonWebView(let viewModel): - let _viewController = WebViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .searchDetail(let viewModel): - let _viewController = SearchDetailViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .compose(let viewModel): - let _viewController = ComposeViewController(viewModel: viewModel) - viewController = _viewController - case .thread(let viewModel): - let _viewController = ThreadViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .editHistory(let viewModel): - let editHistoryViewController = StatusEditHistoryViewController(viewModel: viewModel) - viewController = editHistoryViewController - case .hashtagTimeline(let viewModel): - let _viewController = HashtagTimelineViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .accountList(let viewModel): - let _viewController = AccountListViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .profile(let viewModel): - let _viewController = ProfileViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .bookmark(let viewModel): - let _viewController = BookmarkViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .followedTags(let viewModel): - let _viewController = FollowedTagsViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .favorite(let viewModel): - let _viewController = FavoriteViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .follower(let viewModel): - let _viewController = FollowerListViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .following(let viewModel): - let _viewController = FollowingListViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .familiarFollowers(let viewModel): - let _viewController = FamiliarFollowersViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .rebloggedBy(let viewModel): - let _viewController = RebloggedByViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .favoritedBy(let viewModel): - let _viewController = FavoritedByViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .report(let viewModel): - let _viewController = ReportViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .reportServerRules(let viewModel): - let _viewController = ReportServerRulesViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .reportStatus(let viewModel): - let _viewController = ReportStatusViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .reportSupplementary(let viewModel): - let _viewController = ReportSupplementaryViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .reportResult(let viewModel): - let _viewController = ReportResultViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .suggestionAccount(let viewModel): - let _viewController = SuggestionAccountViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .mediaPreview(let viewModel): - let _viewController = MediaPreviewViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .safari(let url): - guard let scheme = url.scheme?.lowercased(), - scheme == "http" || scheme == "https" else { - return nil - } - let _viewController = SFSafariViewController(url: url) - _viewController.preferredBarTintColor = ThemeService.shared.currentTheme.value.navigationBarBackgroundColor - _viewController.preferredControlTintColor = Asset.Colors.Brand.blurple.color - viewController = _viewController + viewController = loginViewController + case .mastodonPrivacyPolicies(let viewModel): + let privacyViewController = PrivacyTableViewController(context: appContext, coordinator: self, viewModel: viewModel) + viewController = privacyViewController + case .mastodonResendEmail(let viewModel): + let _viewController = MastodonResendEmailViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .mastodonWebView(let viewModel): + let _viewController = WebViewController() + _viewController.viewModel = viewModel + viewController = _viewController - case .alertController(let alertController): - if let popoverPresentationController = alertController.popoverPresentationController { - assert( - popoverPresentationController.sourceView != nil || - popoverPresentationController.sourceRect != .zero || - popoverPresentationController.barButtonItem != nil - ) - } - viewController = alertController - case .activityViewController(let activityViewController, let sourceView, let barButtonItem): - activityViewController.popoverPresentationController?.sourceView = sourceView - activityViewController.popoverPresentationController?.barButtonItem = barButtonItem - viewController = activityViewController - case .settings(let viewModel): - let _viewController = SettingsViewController() - _viewController.viewModel = viewModel - viewController = _viewController - case .editStatus(let viewModel): - let composeViewController = ComposeViewController(viewModel: viewModel) - viewController = composeViewController + + case .searchDetail(let viewModel): + let _viewController = SearchDetailViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .searchResult(let viewModel): + let searchResultViewController = SearchResultViewController() + searchResultViewController.context = appContext + searchResultViewController.coordinator = self + searchResultViewController.viewModel = viewModel + viewController = searchResultViewController + + + case .compose(let viewModel): + let _viewController = ComposeViewController(viewModel: viewModel) + viewController = _viewController + case .thread(let viewModel): + let _viewController = ThreadViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .editHistory(let viewModel): + let editHistoryViewController = StatusEditHistoryViewController(viewModel: viewModel) + viewController = editHistoryViewController + case .hashtagTimeline(let viewModel): + let _viewController = HashtagTimelineViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .accountList(let viewModel): + let _viewController = AccountListViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .profile(let viewModel): + let _viewController = ProfileViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .bookmark(let viewModel): + let _viewController = BookmarkViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .followedTags(let viewModel): + let _viewController = FollowedTagsViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .favorite(let viewModel): + let _viewController = FavoriteViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .follower(let viewModel): + let _viewController = FollowerListViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .following(let viewModel): + let _viewController = FollowingListViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .familiarFollowers(let viewModel): + let _viewController = FamiliarFollowersViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .rebloggedBy(let viewModel): + let _viewController = RebloggedByViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .favoritedBy(let viewModel): + let _viewController = FavoritedByViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .report(let viewModel): + let _viewController = ReportViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .reportServerRules(let viewModel): + let _viewController = ReportServerRulesViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .reportStatus(let viewModel): + let _viewController = ReportStatusViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .reportSupplementary(let viewModel): + let _viewController = ReportSupplementaryViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .reportResult(let viewModel): + let _viewController = ReportResultViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .suggestionAccount(let viewModel): + let _viewController = SuggestionAccountViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .mediaPreview(let viewModel): + let _viewController = MediaPreviewViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .safari(let url): + guard let scheme = url.scheme?.lowercased(), + scheme == "http" || scheme == "https" else { + return nil + } + let _viewController = SFSafariViewController(url: url) + _viewController.preferredBarTintColor = ThemeService.shared.currentTheme.value.navigationBarBackgroundColor + _viewController.preferredControlTintColor = Asset.Colors.Brand.blurple.color + viewController = _viewController + + case .alertController(let alertController): + if let popoverPresentationController = alertController.popoverPresentationController { + assert( + popoverPresentationController.sourceView != nil || + popoverPresentationController.sourceRect != .zero || + popoverPresentationController.barButtonItem != nil + ) + } + viewController = alertController + case .activityViewController(let activityViewController, let sourceView, let barButtonItem): + activityViewController.popoverPresentationController?.sourceView = sourceView + activityViewController.popoverPresentationController?.barButtonItem = barButtonItem + viewController = activityViewController + case .settings(let viewModel): + let _viewController = SettingsViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .editStatus(let viewModel): + let composeViewController = ComposeViewController(viewModel: viewModel) + viewController = composeViewController } setupDependency(for: viewController as? NeedsDependency) diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewSection.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewSection.swift index 37d352b07..0909f5eab 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewSection.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewSection.swift @@ -46,39 +46,25 @@ enum SearchResultOverviewItem: Hashable { } } } - + enum SuggestionSectionEntry: Hashable { case hashtag(tag: Mastodon.Entity.Tag) case profile(user: Mastodon.Entity.Account) - + var title: String? { - switch self { - - case .hashtag(tag: let tag): - return tag.name - case .profile(user: let user): - return "\(user.displayName) — \(user.acct)" + if case let .hashtag(tag) = self { + return tag.name + } else { + return nil } -// if case let .hashtag(tag) = self { -// return tag.name -// } else { -// return nil -// } } - + var icon: UIImage? { - switch self { - - case .hashtag(tag: _): - return UIImage(systemName: "number") - - case .profile(user: _): - return UIImage(systemName: "person.circle") - + if case .hashtag(_) = self { + return UIImage(systemName: "number") + } else { + return nil } -// if case let .hashtag(tag) = self { -// } else { -// } } } } diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift index b3026e279..5097dd605 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift @@ -61,23 +61,21 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc cell.configure(item: .hashtag(tag: hashtag)) return cell - // case .profile(let profile): guard let cell = tableView.dequeueReusableCell(withIdentifier: UserTableViewCell.reuseIdentifier, for: indexPath) as? UserTableViewCell else { fatalError() } - // how the fuck do I get a MastodonUser??? let managedObjectContext = appContext.managedObjectContext Task { do { try await managedObjectContext.perform { guard let user = Persistence.MastodonUser.fetch(in: managedObjectContext, - context: Persistence.MastodonUser.PersistContext( - domain: authContext.mastodonAuthenticationBox.domain, - entity: profile, - cache: nil, - networkDate: Date() - )) else { return } + context: Persistence.MastodonUser.PersistContext( + domain: authContext.mastodonAuthenticationBox.domain, + entity: profile, + cache: nil, + networkDate: Date() + )) else { return } cell.configure( me: authContext.mastodonAuthenticationBox.authenticationRecord.object(in: managedObjectContext)?.user, @@ -89,8 +87,7 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc followRequestedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$followRequestedUserIDs.eraseToAnyPublisher()), delegate: nil) } - } - catch { + } catch { // do nothing } } @@ -105,7 +102,6 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc tableView.delegate = self self.dataSource = dataSource - view.addSubview(tableView) tableView.pinToParent() } @@ -221,6 +217,13 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc } } } + + func searchForPeople(withName searchText: String) { + let searchResultViewModel = SearchResultViewModel(context: context, authContext: authContext, searchScope: .people) + searchResultViewModel.searchText.value = searchText + + coordinator.present(scene: .searchResult(viewModel: searchResultViewModel), transition: .show) + } } //MARK: UITableViewDelegate @@ -238,9 +241,8 @@ extension SearchResultsOverviewTableViewController: UITableViewDelegate { case .posts(let hashtag): //FIXME: Show statuses instead of tag-content. Reuse SearchResultsViewController with statuses here? showPosts(tag: Mastodon.Entity.Tag(name: hashtag, url: authContext.mastodonAuthenticationBox.domain)) - case .people(let string): - //FIXME: Invoke SearchResultsViewController with people-scope here - delegate?.showPeople(self) + case .people(let searchText): + searchForPeople(withName: searchText) case .profile(let profile, let instanceName): delegate?.showProfile(self) case .openLink(let string): From ed56e7aebe1d0d71da7c1222743a30fa2b6ffc1b Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sun, 17 Sep 2023 13:18:29 +0200 Subject: [PATCH 46/87] Show posts with a certain keyword instead of Hashtag (IOS-141) --- .../SearchResultsOverviewTableViewController.swift | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift index 5097dd605..e818f9418 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift @@ -224,6 +224,13 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc coordinator.present(scene: .searchResult(viewModel: searchResultViewModel), transition: .show) } + + func searchForPosts(withSearchText searchText: String) { + let searchResultViewModel = SearchResultViewModel(context: context, authContext: authContext, searchScope: .posts) + searchResultViewModel.searchText.value = searchText + + coordinator.present(scene: .searchResult(viewModel: searchResultViewModel), transition: .show) + } } //MARK: UITableViewDelegate @@ -238,9 +245,8 @@ extension SearchResultsOverviewTableViewController: UITableViewDelegate { switch item { case .default(let defaultSectionEntry): switch defaultSectionEntry { - case .posts(let hashtag): - //FIXME: Show statuses instead of tag-content. Reuse SearchResultsViewController with statuses here? - showPosts(tag: Mastodon.Entity.Tag(name: hashtag, url: authContext.mastodonAuthenticationBox.domain)) + case .posts(let searchText): + searchForPosts(withSearchText: searchText) case .people(let searchText): searchForPeople(withName: searchText) case .profile(let profile, let instanceName): From 558f88e77a39d9460106fc067d1ea8f63ba8bf77 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sun, 17 Sep 2023 13:34:08 +0200 Subject: [PATCH 47/87] Sprinkle in some localization (IOS-141) --- .../input/Base.lproj/app.json | 10 ++++---- .../SearchResultOverviewSection.swift | 16 ++++++------- .../SearchResultViewController.swift | 2 ++ .../Generated/Strings.swift | 24 +++++++++++-------- .../Resources/Base.lproj/Localizable.strings | 8 +++---- 5 files changed, 32 insertions(+), 28 deletions(-) diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index f22ec3098..139f20347 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -651,12 +651,10 @@ } }, "searching": { - "segment": { - "all": "All", - "people": "People", - "hashtags": "Hashtags", - "posts": "Posts" - }, + "posts": "Posts with \"%@\"", + "people": "People with \"%@\"", + "profile": "Go to @%@@%@", + "url": "Open Link", "empty_state": { "no_results": "No results" }, diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewSection.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewSection.swift index 0909f5eab..8fcc93734 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewSection.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewSection.swift @@ -2,6 +2,7 @@ import UIKit import MastodonSDK +import MastodonLocalization import CoreDataStack enum SearchResultOverviewSection: Hashable { @@ -21,15 +22,14 @@ enum SearchResultOverviewItem: Hashable { var title: String { switch self { - //TODO: Add localization case .posts(let text): - return "Posts with \(text)" + return L10n.Scene.Search.Searching.posts(text) case .people(let username): - return "People with \(username)" + return L10n.Scene.Search.Searching.people(username) case .profile(let username, let instanceName): - return "Go to @\(username)@\(instanceName)" + return L10n.Scene.Search.Searching.profile(username, instanceName) case .openLink(_): - return "Open Link" + return L10n.Scene.Search.Searching.url } } @@ -46,11 +46,11 @@ enum SearchResultOverviewItem: Hashable { } } } - + enum SuggestionSectionEntry: Hashable { case hashtag(tag: Mastodon.Entity.Tag) case profile(user: Mastodon.Entity.Account) - + var title: String? { if case let .hashtag(tag) = self { return tag.name @@ -58,7 +58,7 @@ enum SearchResultOverviewItem: Hashable { return nil } } - + var icon: UIImage? { if case .hashtag(_) = self { return UIImage(systemName: "number") diff --git a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController.swift b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController.swift index cf7a6a0f6..731117ec6 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController.swift @@ -116,6 +116,8 @@ extension SearchResultViewController { self.tableView.verticalScrollIndicatorInsets.top = frame.height } .store(in: &disposeBag) + + title = viewModel.searchText.value } override func viewWillAppear(_ animated: Bool) { diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index dcc6f84f1..9ff595057 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -1279,22 +1279,26 @@ public enum L10n { public static let clear = L10n.tr("Localizable", "Scene.Search.Searching.Clear", fallback: "Clear") /// Clear all public static let clearAll = L10n.tr("Localizable", "Scene.Search.Searching.ClearAll", fallback: "Clear all") + /// People with "%@" + public static func people(_ p1: Any) -> String { + return L10n.tr("Localizable", "Scene.Search.Searching.People", String(describing: p1), fallback: "People with \"%@\"") + } + /// Posts with "%@" + public static func posts(_ p1: Any) -> String { + return L10n.tr("Localizable", "Scene.Search.Searching.Posts", String(describing: p1), fallback: "Posts with \"%@\"") + } + /// Go to @%@@%@ + public static func profile(_ p1: Any, _ p2: Any) -> String { + return L10n.tr("Localizable", "Scene.Search.Searching.Profile", String(describing: p1), String(describing: p2), fallback: "Go to @%@@%@") + } /// Recent searches public static let recentSearch = L10n.tr("Localizable", "Scene.Search.Searching.RecentSearch", fallback: "Recent searches") + /// Open Link + public static let url = L10n.tr("Localizable", "Scene.Search.Searching.Url", fallback: "Open Link") public enum EmptyState { /// No results public static let noResults = L10n.tr("Localizable", "Scene.Search.Searching.EmptyState.NoResults", fallback: "No results") } - public enum Segment { - /// All - public static let all = L10n.tr("Localizable", "Scene.Search.Searching.Segment.All", fallback: "All") - /// Hashtags - public static let hashtags = L10n.tr("Localizable", "Scene.Search.Searching.Segment.Hashtags", fallback: "Hashtags") - /// People - public static let people = L10n.tr("Localizable", "Scene.Search.Searching.Segment.People", fallback: "People") - /// Posts - public static let posts = L10n.tr("Localizable", "Scene.Search.Searching.Segment.Posts", fallback: "Posts") - } } } public enum ServerPicker { diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 7269b0c4a..964d7ba42 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -443,10 +443,10 @@ uploaded to Mastodon."; "Scene.Search.Searching.ClearAll" = "Clear all"; "Scene.Search.Searching.EmptyState.NoResults" = "No results"; "Scene.Search.Searching.RecentSearch" = "Recent searches"; -"Scene.Search.Searching.Segment.All" = "All"; -"Scene.Search.Searching.Segment.Hashtags" = "Hashtags"; -"Scene.Search.Searching.Segment.People" = "People"; -"Scene.Search.Searching.Segment.Posts" = "Posts"; +"Scene.Search.Searching.Posts" = "Posts with \"%@\""; +"Scene.Search.Searching.People" = "People with \"%@\""; +"Scene.Search.Searching.Profile" = "Go to @%@@%@"; +"Scene.Search.Searching.Url" = "Open Link"; "Scene.Search.Title" = "Search"; "Scene.ServerPicker.Button.Category.Academia" = "academia"; "Scene.ServerPicker.Button.Category.Activism" = "activism"; From c0f2dc5649d5592a2e8ac6afd5b2c49025346ac7 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sun, 17 Sep 2023 13:52:35 +0200 Subject: [PATCH 48/87] Add recent searches to recent searches (IOS-141) --- .../Protocol/Provider/DataSourceFacade+SearchHistory.swift | 3 ++- .../SearchResultsOverviewTableViewController.swift | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+SearchHistory.swift b/Mastodon/Protocol/Provider/DataSourceFacade+SearchHistory.swift index 18d238c02..1193bb676 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+SearchHistory.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+SearchHistory.swift @@ -8,11 +8,12 @@ import Foundation import CoreDataStack import MastodonCore +import UIKit extension DataSourceFacade { static func responseToCreateSearchHistory( - provider: DataSourceProvider & AuthContextProvider, + provider: NeedsDependency & UIViewController & AuthContextProvider, item: DataSourceItem ) async { switch item { diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift index e818f9418..229a5296f 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift @@ -193,6 +193,9 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc provider: self, tag: tag ) + + await DataSourceFacade.responseToCreateSearchHistory(provider: self, + item: .hashtag(tag: .entity(tag))) } } @@ -214,6 +217,9 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc if let user { await DataSourceFacade.coordinateToProfileScene(provider:self, user: user.asRecord) + + await DataSourceFacade.responseToCreateSearchHistory(provider: self, + item: .user(record: user.asRecord)) } } } From 15436738d54fcfecfaa379c11ef2089b3746945c Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sun, 17 Sep 2023 14:34:10 +0200 Subject: [PATCH 49/87] Go to user (IOS-141) --- .../Provider/DataSourceFacade+Profile.swift | 221 ------------------ ...chResultsOverviewTableViewController.swift | 35 ++- 2 files changed, 31 insertions(+), 225 deletions(-) diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Profile.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Profile.swift index 161e52e87..219e7ddef 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Profile.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Profile.swift @@ -127,227 +127,6 @@ extension DataSourceFacade { let barButtonItem: UIBarButtonItem? } -// @MainActor -// static func createProfileActionMenu( -// dependency: NeedsDependency, -// user: ManagedObjectRecord -// ) -> UIMenu { -// var children: [UIMenuElement] = [] -// let name = mastodonUser.displayNameWithFallback -// -// if let shareUser = shareUser { -// let shareAction = UIAction( -// title: L10n.Common.Controls.Actions.shareUser(name), -// image: UIImage(systemName: "square.and.arrow.up"), -// identifier: nil, -// discoverabilityTitle: nil, -// attributes: [], -// state: .off -// ) { [weak provider, weak sourceView, weak barButtonItem] _ in -// guard let provider = provider else { return } -// let activityViewController = createActivityViewControllerForMastodonUser(mastodonUser: shareUser, dependency: provider) -// provider.coordinator.present( -// scene: .activityViewController( -// activityViewController: activityViewController, -// sourceView: sourceView, -// barButtonItem: barButtonItem -// ), -// from: provider, -// transition: .activityViewControllerPresent(animated: true, completion: nil) -// ) -// } -// children.append(shareAction) -// } -// -// if let shareStatus = shareStatus { -// let shareAction = UIAction( -// title: L10n.Common.Controls.Actions.sharePost, -// image: UIImage(systemName: "square.and.arrow.up"), -// identifier: nil, -// discoverabilityTitle: nil, -// attributes: [], -// state: .off -// ) { [weak provider, weak sourceView, weak barButtonItem] _ in -// guard let provider = provider else { return } -// let activityViewController = createActivityViewControllerForMastodonUser(status: shareStatus, dependency: provider) -// provider.coordinator.present( -// scene: .activityViewController( -// activityViewController: activityViewController, -// sourceView: sourceView, -// barButtonItem: barButtonItem -// ), -// from: provider, -// transition: .activityViewControllerPresent(animated: true, completion: nil) -// ) -// } -// children.append(shareAction) -// } -// -// if !isMyself { -// // mute -// let muteAction = UIAction( -// title: isMuting ? L10n.Common.Controls.Friendship.unmuteUser(name) : L10n.Common.Controls.Friendship.mute, -// image: isMuting ? UIImage(systemName: "speaker") : UIImage(systemName: "speaker.slash"), -// discoverabilityTitle: isMuting ? nil : L10n.Common.Controls.Friendship.muteUser(name), -// attributes: isMuting ? [] : .destructive, -// state: .off -// ) { [weak provider, weak cell] _ in -// guard let provider = provider else { return } -// -// UserProviderFacade.toggleUserMuteRelationship( -// provider: provider, -// cell: cell -// ) -// .sink { _ in -// // do nothing -// } receiveValue: { _ in -// // do nothing -// } -// .store(in: &provider.context.disposeBag) -// } -// if isMuting { -// children.append(muteAction) -// } else { -// let muteMenu = UIMenu(title: L10n.Common.Controls.Friendship.muteUser(name), image: UIImage(systemName: "speaker.slash"), options: [], children: [muteAction]) -// children.append(muteMenu) -// } -// } -// -// if !isMyself { -// // block -// let blockAction = UIAction( -// title: isBlocking ? L10n.Common.Controls.Friendship.unblockUser(name) : L10n.Common.Controls.Friendship.block, -// image: isBlocking ? UIImage(systemName: "hand.raised.slash") : UIImage(systemName: "hand.raised"), -// discoverabilityTitle: isBlocking ? nil : L10n.Common.Controls.Friendship.blockUser(name), -// attributes: isBlocking ? [] : .destructive, -// state: .off -// ) { [weak provider, weak cell] _ in -// guard let provider = provider else { return } -// -// UserProviderFacade.toggleUserBlockRelationship( -// provider: provider, -// cell: cell -// ) -// .sink { _ in -// // do nothing -// } receiveValue: { _ in -// // do nothing -// } -// .store(in: &provider.context.disposeBag) -// } -// if isBlocking { -// children.append(blockAction) -// } else { -// let blockMenu = UIMenu(title: L10n.Common.Controls.Friendship.blockUser(name), image: UIImage(systemName: "hand.raised"), options: [], children: [blockAction]) -// children.append(blockMenu) -// } -// } -// -// if !isMyself { -// let reportAction = UIAction( -// title: L10n.Common.Controls.Actions.reportUser(name), -// image: UIImage(systemName: "flag"), -// identifier: nil, -// discoverabilityTitle: nil, -// attributes: [], -// state: .off -// ) { [weak provider] _ in -// guard let provider = provider else { return } -// guard let authenticationBox = provider.context.authenticationService.activeMastodonAuthenticationBox.value else { -// return -// } -// let viewModel = ReportViewModel( -// context: provider.context, -// domain: authenticationBox.domain, -// user: mastodonUser, -// status: nil -// ) -// provider.coordinator.present( -// scene: .report(viewModel: viewModel), -// from: provider, -// transition: .modal(animated: true, completion: nil) -// ) -// } -// children.append(reportAction) -// } -// -// if !isInSameDomain { -// if isDomainBlocking { -// let unblockDomainAction = UIAction( -// title: L10n.Common.Controls.Actions.unblockDomain(mastodonUser.domainFromAcct), -// image: UIImage(systemName: "nosign"), -// identifier: nil, -// discoverabilityTitle: nil, -// attributes: [], -// state: .off -// ) { [weak provider, weak cell] _ in -// guard let provider = provider else { return } -// provider.context.blockDomainService.unblockDomain(userProvider: provider, cell: cell) -// } -// children.append(unblockDomainAction) -// } else { -// let blockDomainAction = UIAction( -// title: L10n.Common.Controls.Actions.blockDomain(mastodonUser.domainFromAcct), -// image: UIImage(systemName: "nosign"), -// identifier: nil, -// discoverabilityTitle: nil, -// attributes: [], -// state: .off -// ) { [weak provider, weak cell] _ in -// guard let provider = provider else { return } -// -// let alertController = UIAlertController(title: L10n.Common.Alerts.BlockDomain.title(mastodonUser.domainFromAcct), message: nil, preferredStyle: .alert) -// let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .default) { _ in } -// alertController.addAction(cancelAction) -// let blockDomainAction = UIAlertAction(title: L10n.Common.Alerts.BlockDomain.blockEntireDomain, style: .destructive) { [weak provider, weak cell] _ in -// guard let provider = provider else { return } -// provider.context.blockDomainService.blockDomain(userProvider: provider, cell: cell) -// } -// alertController.addAction(blockDomainAction) -// provider.present(alertController, animated: true, completion: nil) -// } -// children.append(blockDomainAction) -// } -// } -// -// if let status = shareStatus, isMyself { -// let deleteAction = UIAction( -// title: L10n.Common.Controls.Actions.delete, -// image: UIImage(systemName: "delete.left"), -// identifier: nil, -// discoverabilityTitle: nil, -// attributes: [.destructive], -// state: .off -// ) { [weak provider] _ in -// guard let provider = provider else { return } -// -// let alertController = UIAlertController(title: L10n.Common.Alerts.DeletePost.title, message: nil, preferredStyle: .alert) -// let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .default) { _ in } -// alertController.addAction(cancelAction) -// let deleteAction = UIAlertAction(title: L10n.Common.Alerts.DeletePost.delete, style: .destructive) { [weak provider] _ in -// guard let provider = provider else { return } -// guard let activeMastodonAuthenticationBox = provider.context.authenticationService.activeMastodonAuthenticationBox.value else { return } -// provider.context.apiService.deleteStatus( -// domain: activeMastodonAuthenticationBox.domain, -// statusID: status.id, -// authorizationBox: activeMastodonAuthenticationBox -// ) -// .sink { _ in -// // do nothing -// } receiveValue: { _ in -// // do nothing -// } -// .store(in: &provider.context.disposeBag) -// } -// alertController.addAction(deleteAction) -// provider.present(alertController, animated: true, completion: nil) -// } -// children.append(deleteAction) -// } -// -// return UIMenu(title: "", options: [], children: children) -// } - static func createActivityViewController( dependency: NeedsDependency, user: ManagedObjectRecord diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift index 229a5296f..ccfd4fc73 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift @@ -195,7 +195,7 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc ) await DataSourceFacade.responseToCreateSearchHistory(provider: self, - item: .hashtag(tag: .entity(tag))) + item: .hashtag(tag: .entity(tag))) } } @@ -219,7 +219,7 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc user: user.asRecord) await DataSourceFacade.responseToCreateSearchHistory(provider: self, - item: .user(record: user.asRecord)) + item: .user(record: user.asRecord)) } } } @@ -237,6 +237,33 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc coordinator.present(scene: .searchResult(viewModel: searchResultViewModel), transition: .show) } + + func searchForPerson(username: String, domain: String) { + let acct = "\(username)@\(domain)" + let query = Mastodon.API.V2.Search.Query( + q: acct, + type: .default, + resolve: true + ) + + Task { + let searchResult = try await context.apiService.search( + query: query, + authenticationBox: authContext.mastodonAuthenticationBox + ).value + + if let account = searchResult.accounts.first(where: { $0.acctWithDomainIfMissing(domain).lowercased() == acct.lowercased() }) { + showProfile(for: account) + } else { + await MainActor.run { + let alertController = UIAlertController(title: "No User Account", message: "There's no Useraccount \"\(username)\" on \(domain)", preferredStyle: .alert) + let okAction = UIAlertAction(title: "OK", style: .default) + alertController.addAction(okAction) + coordinator.present(scene: .alertController(alertController: alertController), transition: .alertController(animated: true)) + } + } + } + } } //MARK: UITableViewDelegate @@ -255,8 +282,8 @@ extension SearchResultsOverviewTableViewController: UITableViewDelegate { searchForPosts(withSearchText: searchText) case .people(let searchText): searchForPeople(withName: searchText) - case .profile(let profile, let instanceName): - delegate?.showProfile(self) + case .profile(let username, let domain): + searchForPerson(username: username, domain: domain) case .openLink(let string): delegate?.openLink(self) } From 7abc536d01ab30e3a3b69e6a6fabef32f3535ecf Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sun, 17 Sep 2023 14:40:23 +0200 Subject: [PATCH 50/87] Add localization to "No such user"-alert (IOS-141) --- Localization/app.json | 14 ++++++++------ .../SearchResultsOverviewTableViewController.swift | 8 ++++++-- .../MastodonLocalization/Generated/Strings.swift | 8 ++++++++ .../Resources/Base.lproj/Localizable.strings | 4 ++++ 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/Localization/app.json b/Localization/app.json index 739573267..8a7817d40 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -651,15 +651,17 @@ } }, "searching": { - "segment": { - "all": "All", - "people": "People", - "hashtags": "Hashtags", - "posts": "Posts" - }, + "posts": "Posts with \"%@\"", + "people": "People with \"%@\"", + "profile": "Go to @%@@%@", + "url": "Open Link", "empty_state": { "no_results": "No results" }, + "no_user": { + "title": "No User Account Found", + "message": "There's no Useraccount \"%@\" on %@" + } "recent_search": "Recent searches", "clear": "Clear" } diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift index ccfd4fc73..a90fb747a 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift @@ -3,6 +3,7 @@ import UIKit import MastodonCore import MastodonSDK +import MastodonLocalization protocol SearchResultsOverviewTableViewControllerDeleagte: AnyObject { func showPeople(_ viewController: UIViewController) @@ -256,8 +257,11 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc showProfile(for: account) } else { await MainActor.run { - let alertController = UIAlertController(title: "No User Account", message: "There's no Useraccount \"\(username)\" on \(domain)", preferredStyle: .alert) - let okAction = UIAlertAction(title: "OK", style: .default) + let alertTitle = L10n.Scene.Search.Searching.NoUser.title + let alertMessage = L10n.Scene.Search.Searching.NoUser.message(username, domain) + + let alertController = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: .alert) + let okAction = UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default) alertController.addAction(okAction) coordinator.present(scene: .alertController(alertController: alertController), transition: .alertController(animated: true)) } diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index 9ff595057..4484b6e96 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -1299,6 +1299,14 @@ public enum L10n { /// No results public static let noResults = L10n.tr("Localizable", "Scene.Search.Searching.EmptyState.NoResults", fallback: "No results") } + public enum NoUser { + /// There's no Useraccount "%@" on %@ + public static func message(_ p1: Any, _ p2: Any) -> String { + return L10n.tr("Localizable", "Scene.Search.Searching.NoUser.Message", String(describing: p1), String(describing: p2), fallback: "There's no Useraccount \"%@\" on %@") + } + /// No User Account Found + public static let title = L10n.tr("Localizable", "Scene.Search.Searching.NoUser.Title", fallback: "No User Account Found") + } } } public enum ServerPicker { diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 964d7ba42..0b5102ec0 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -447,6 +447,10 @@ uploaded to Mastodon."; "Scene.Search.Searching.People" = "People with \"%@\""; "Scene.Search.Searching.Profile" = "Go to @%@@%@"; "Scene.Search.Searching.Url" = "Open Link"; + +"Scene.Search.Searching.NoUser.Title" = "No User Account Found"; +"Scene.Search.Searching.NoUser.Message" = "There's no Useraccount \"%@\" on %@"; + "Scene.Search.Title" = "Search"; "Scene.ServerPicker.Button.Category.Academia" = "academia"; "Scene.ServerPicker.Button.Category.Activism" = "activism"; From ed5a0f3abcb747d5d7b32d0349fad036eaf2289e Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sun, 17 Sep 2023 15:16:25 +0200 Subject: [PATCH 51/87] Show max. 10 items in history (IOS-141) --- .../SearchHistory/SearchHistoryViewModel+Diffable.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewModel+Diffable.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewModel+Diffable.swift index 92b70bf99..26f8f572f 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewModel+Diffable.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewModel+Diffable.swift @@ -53,10 +53,12 @@ extension SearchHistoryViewModel { return users + hashtags } + + let mostRecentItems = Array(items.prefix(10)) var snapshot = NSDiffableDataSourceSnapshot() snapshot.appendSections([.main]) - snapshot.appendItems(items, toSection: .main) - await diffableDataSource.apply(snapshot, animatingDifferences: false) + snapshot.appendItems(mostRecentItems, toSection: .main) + await diffableDataSource.apply(snapshot, animatingDifferences: true) } catch { // do nothing } From cde28f576c6d8a030200faf5a5ff53e7f3a671f8 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sun, 17 Sep 2023 15:16:47 +0200 Subject: [PATCH 52/87] Seach-key dismisses keyboard (IOS-141) --- .../Search/SearchDetail/SearchDetailViewController.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift b/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift index 25dc48e45..e0f099bbe 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift @@ -248,6 +248,10 @@ extension SearchDetailViewController: UISearchBarDelegate { searchResultsOverviewViewController.searchForSuggestions(for: trimmedSearchText) } + func searchBarSearchButtonClicked(_ searchBar: UISearchBar) { + searchBar.resignFirstResponder() + } + func searchBarCancelButtonClicked(_ searchBar: UISearchBar) { // dismiss or pop if isModal { From 4378c1e97109d1fd2f1021affb06db35bc4549e6 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sun, 17 Sep 2023 16:57:15 +0200 Subject: [PATCH 53/87] Go to link (IOS-141) It's either a profile (then show the profile) or a status (than show the status) or a link (then open the link in safari) --- ...chResultsOverviewTableViewController.swift | 54 +++++++++++++++++-- .../Sources/MastodonSDK/Extension/URL.swift | 11 ++++ 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift index a90fb747a..173be218e 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift @@ -118,7 +118,6 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc } func showStandardSearch(for searchText: String) { - guard let dataSource else { return } var snapshot = dataSource.snapshot() @@ -127,8 +126,7 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc .default(.people(searchText)), .default(.profile(searchText, authContext.mastodonAuthenticationBox.domain))], toSection: .default) - if URL(string: searchText) != nil { - //TODO: Check if Mastodon-URL + if URL(string: searchText)?.isValidURL() ?? false { snapshot.appendItems([.default(.openLink(searchText))], toSection: .default) } @@ -188,6 +186,8 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc activeTask = searchTask } + //MARK: - Actions + func showPosts(tag: Mastodon.Entity.Tag) { Task { await DataSourceFacade.coordinateToHashtagScene( @@ -268,6 +268,50 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc } } } + + func goTo(link: String) { + + let query = Mastodon.API.V2.Search.Query( + q: link, + type: .default, + resolve: true + ) + + let authContext = self.authContext + let managedObjectContext = context.managedObjectContext + + Task { + let searchResult = try await context.apiService.search( + query: query, + authenticationBox: authContext.mastodonAuthenticationBox + ).value + + if let account = searchResult.accounts.first { + showProfile(for: account) + } else if let status = searchResult.statuses.first { + + let status = try await managedObjectContext.perform { + return Persistence.Status.fetch(in: managedObjectContext, context: Persistence.Status.PersistContext( + domain: authContext.mastodonAuthenticationBox.domain, + entity: status, + me: authContext.mastodonAuthenticationBox.authenticationRecord.object(in: managedObjectContext)?.user, + statusCache: nil, + userCache: nil, + networkDate: Date())) + } + + guard let status else { return } + + await DataSourceFacade.coordinateToStatusThreadScene( + provider: self, + target: .status, // remove reblog wrapper + status: status.asRecord + ) + } else if let url = URL(string: link) { + coordinator.present(scene: .safari(url: url), transition: .safariPresent(animated: true)) + } + } + } } //MARK: UITableViewDelegate @@ -288,8 +332,8 @@ extension SearchResultsOverviewTableViewController: UITableViewDelegate { searchForPeople(withName: searchText) case .profile(let username, let domain): searchForPerson(username: username, domain: domain) - case .openLink(let string): - delegate?.openLink(self) + case .openLink(let urlString): + goTo(link: urlString) } case .suggestion(let suggestionSectionEntry): switch suggestionSectionEntry { diff --git a/MastodonSDK/Sources/MastodonSDK/Extension/URL.swift b/MastodonSDK/Sources/MastodonSDK/Extension/URL.swift index a9345c7b3..5675fc8c5 100644 --- a/MastodonSDK/Sources/MastodonSDK/Extension/URL.swift +++ b/MastodonSDK/Sources/MastodonSDK/Extension/URL.swift @@ -11,4 +11,15 @@ extension URL { public static func httpScheme(domain: String) -> String { return domain.hasSuffix(".onion") ? "http" : "https" } + + // inspired by https://stackoverflow.com/a/49072718 + public func isValidURL() -> Bool { + if let detector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue), + let match = detector.firstMatch(in: absoluteString, options: [], range: NSRange(location: 0, length: absoluteString.utf16.count)) { + // it is a link, if the match covers the whole string + return match.range.length == absoluteString.utf16.count + } else { + return false + } + } } From cb4c5a938d8d95b72737ff0d8de80cfd76b0576c Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sun, 17 Sep 2023 17:21:53 +0200 Subject: [PATCH 54/87] Consider mastodon-domains for other instances and profiles (IOS-141) --- .../SearchResultOverviewSection.swift | 2 +- ...earchResultsOverviewTableViewController.swift | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewSection.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewSection.swift index 8fcc93734..6cc4b8942 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewSection.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewSection.swift @@ -17,7 +17,7 @@ enum SearchResultOverviewItem: Hashable { enum DefaultSectionEntry: Hashable { case posts(String) case people(String) - case profile(String, String) + case profile(username: String, domain: String) case openLink(String) var title: String { diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift index 173be218e..797bd65e6 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift @@ -123,8 +123,20 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc var snapshot = dataSource.snapshot() snapshot.deleteItems(snapshot.itemIdentifiers(inSection: .default)) snapshot.appendItems([.default(.posts(searchText)), - .default(.people(searchText)), - .default(.profile(searchText, authContext.mastodonAuthenticationBox.domain))], toSection: .default) + .default(.people(searchText))], toSection: .default) + let components = searchText.split(separator: "@") + if components.count == 2 { + let username = String(components[0]) + + let domain = String(components[1]) + if domain.split(separator: ".").count >= 2 { + snapshot.appendItems([.default(.profile(username: username, domain: domain))], toSection: .default) + } else { + snapshot.appendItems([.default(.profile(username: username, domain: authContext.mastodonAuthenticationBox.domain))], toSection: .default) + } + } else { + snapshot.appendItems([.default(.profile(username: searchText, domain: authContext.mastodonAuthenticationBox.domain))], toSection: .default) + } if URL(string: searchText)?.isValidURL() ?? false { snapshot.appendItems([.default(.openLink(searchText))], toSection: .default) From c4b31112a47e9d546dfd9c825b506818a6fb04ee Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sun, 17 Sep 2023 17:27:42 +0200 Subject: [PATCH 55/87] Fix build (IOS-141) --- Mastodon/Protocol/Provider/DataSourceFacade+Thread.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Thread.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Thread.swift index 41f5d58de..e2431fc28 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Thread.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Thread.swift @@ -5,14 +5,14 @@ // Created by MainasuK on 2022-1-17. // -import Foundation +import UIKit import CoreData import CoreDataStack import MastodonCore extension DataSourceFacade { static func coordinateToStatusThreadScene( - provider: DataSourceProvider & AuthContextProvider, + provider: NeedsDependency & UIViewController & AuthContextProvider, target: StatusTarget, status: ManagedObjectRecord ) async { @@ -40,7 +40,7 @@ extension DataSourceFacade { @MainActor static func coordinateToStatusThreadScene( - provider: DataSourceProvider & AuthContextProvider, + provider: NeedsDependency & UIViewController & AuthContextProvider, root: StatusItem.Thread ) async { let threadViewModel = ThreadViewModel( From 11863b94580c9497e4eb08cd93722f3bea75362c Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sun, 17 Sep 2023 17:44:38 +0200 Subject: [PATCH 56/87] Show magnifying glass next to hashtags (IOS-141) --- Mastodon.xcodeproj/project.pbxproj | 8 -------- .../Cells/SearchResultDefaultSectionTableViewCell.swift | 4 ++-- .../SearchDetail/SearchHistory/SearchHistorySection.swift | 3 +++ 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 0636ceb29..dc441b9e8 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -2154,13 +2154,6 @@ path = Status; sourceTree = ""; }; - DB4F098026A0475500D62E92 /* View */ = { - isa = PBXGroup; - children = ( - ); - path = View; - sourceTree = ""; - }; DB4FFC2D269EC39C00D62E92 /* Search */ = { isa = PBXGroup; children = ( @@ -2935,7 +2928,6 @@ isa = PBXGroup; children = ( DB63F7502799449300455B82 /* Cell */, - DB4F098026A0475500D62E92 /* View */, DBF1D250269DB01200C1C08A /* SearchHistoryViewController.swift */, DB63F76127996B6600455B82 /* SearchHistoryViewController+DataSourceProvider.swift */, DB4F097426A037F500D62E92 /* SearchHistoryViewModel.swift */, diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/Cells/SearchResultDefaultSectionTableViewCell.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/Cells/SearchResultDefaultSectionTableViewCell.swift index 49ba6d111..94bc48dcc 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/Cells/SearchResultDefaultSectionTableViewCell.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/Cells/SearchResultDefaultSectionTableViewCell.swift @@ -12,7 +12,7 @@ class SearchResultDefaultSectionTableViewCell: UITableViewCell { content.text = item.title content.imageProperties.tintColor = Asset.Colors.Brand.blurple.color - self.contentConfiguration = content + contentConfiguration = content } func configure(item: SearchResultOverviewItem.SuggestionSectionEntry) { @@ -21,6 +21,6 @@ class SearchResultDefaultSectionTableViewCell: UITableViewCell { content.text = item.title content.imageProperties.tintColor = Asset.Colors.Brand.blurple.color - self.contentConfiguration = content + contentConfiguration = content } } diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistorySection.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistorySection.swift index d0cbc05ee..2c0e19451 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistorySection.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistorySection.swift @@ -8,6 +8,7 @@ import UIKit import CoreDataStack import MastodonCore +import MastodonAsset enum SearchHistorySection: Hashable { case main @@ -47,6 +48,8 @@ extension SearchHistorySection { context.managedObjectContext.performAndWait { guard let hashtag = item.object(in: context.managedObjectContext) else { return } var contentConfiguration = cell.defaultContentConfiguration() + contentConfiguration.image = UIImage(systemName: "magnifyingglass") + contentConfiguration.imageProperties.tintColor = Asset.Colors.Brand.blurple.color contentConfiguration.text = "#" + hashtag.name cell.contentConfiguration = contentConfiguration } From b74f17c6b6ce14955c2d258e90def8eec5e51fbd Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Sun, 17 Sep 2023 18:14:42 +0200 Subject: [PATCH 57/87] Don't show follow-button for me (IOS-141) --- ...archResultsOverviewTableViewController.swift | 11 ----------- .../SearchDetailViewController.swift | 17 ----------------- ...istoryUserCollectionViewCell+ViewModel.swift | 5 +++-- .../UserTableViewCell+ViewModel.swift | 4 +++- .../View/Content/UserView+ViewModel.swift | 5 +---- .../MastodonUI/View/Content/UserView.swift | 7 +++++++ 6 files changed, 14 insertions(+), 35 deletions(-) diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift index 797bd65e6..c6d6175c7 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift @@ -5,17 +5,8 @@ import MastodonCore import MastodonSDK import MastodonLocalization -protocol SearchResultsOverviewTableViewControllerDeleagte: AnyObject { - func showPeople(_ viewController: UIViewController) - func showProfile(_ viewController: UIViewController) - func openLink(_ viewController: UIViewController) -} - // we could move lots of this stuff to a coordinator, it's too much for work a viewcontroller class SearchResultsOverviewTableViewController: UIViewController, NeedsDependency, AuthContextProvider { - // similar to the other search results view controller but without the whole statemachine bullshit - // with scope all - var context: AppContext! let authContext: AuthContext var coordinator: SceneCoordinator! @@ -23,7 +14,6 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc private let tableView: UITableView var dataSource: UITableViewDiffableDataSource? - weak var delegate: SearchResultsOverviewTableViewControllerDeleagte? var activeTask: Task? init(appContext: AppContext, authContext: AuthContext, coordinator: SceneCoordinator) { @@ -330,7 +320,6 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc extension SearchResultsOverviewTableViewController: UITableViewDelegate { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - //TODO: Implement properly! guard let snapshot = dataSource?.snapshot() else { return } let section = snapshot.sectionIdentifiers[indexPath.section] let item = snapshot.itemIdentifiers(inSection: section)[indexPath.row] diff --git a/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift b/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift index e0f099bbe..990dab66e 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift @@ -115,8 +115,6 @@ final class SearchDetailViewController: UIViewController, NeedsDependency { searchHistoryViewController.view.pinToParent() } - searchResultsOverviewViewController.delegate = self - addChild(searchResultsOverviewViewController) searchResultsOverviewViewController.view.translatesAutoresizingMaskIntoConstraints = false view.addSubview(searchResultsOverviewViewController.view) @@ -261,18 +259,3 @@ extension SearchDetailViewController: UISearchBarDelegate { } } } - -//MARK: SearchResultsOverviewViewControllerDelegate -extension SearchDetailViewController: SearchResultsOverviewTableViewControllerDeleagte { - func showPeople(_ viewController: UIViewController) { - //TODO: Implement - } - - func showProfile(_ viewController: UIViewController) { - //TODO: Implement - } - - func openLink(_ viewController: UIViewController) { - //TODO: Implement - } -} diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistoryUserCollectionViewCell+ViewModel.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistoryUserCollectionViewCell+ViewModel.swift index 31350811d..8e9710e9a 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistoryUserCollectionViewCell+ViewModel.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistoryUserCollectionViewCell+ViewModel.swift @@ -54,7 +54,9 @@ extension SearchHistoryUserCollectionViewCell { ) .receive(on: DispatchQueue.main) .sink { [weak self] followed, requested, blocked in - if blocked.contains(user.id) { + if user == me { + self?.userView.setButtonState(.none) + } else if blocked.contains(user.id) { self?.userView.setButtonState(.blocked) } else if followed.contains(user.id) { self?.userView.setButtonState(.unfollow) @@ -67,6 +69,5 @@ extension SearchHistoryUserCollectionViewCell { } } .store(in: &_disposeBag) - } } diff --git a/Mastodon/Scene/Share/View/TableviewCell/UserTableViewCell+ViewModel.swift b/Mastodon/Scene/Share/View/TableviewCell/UserTableViewCell+ViewModel.swift index 7f2727a91..526e74ab3 100644 --- a/Mastodon/Scene/Share/View/TableviewCell/UserTableViewCell+ViewModel.swift +++ b/Mastodon/Scene/Share/View/TableviewCell/UserTableViewCell+ViewModel.swift @@ -54,7 +54,9 @@ extension UserTableViewCell { ) .receive(on: DispatchQueue.main) .sink { [weak self] followed, requested, blocked in - if blocked.contains(viewModel.user.id) { + if viewModel.user == me { + self?.userView.setButtonState(.none) + } else if blocked.contains(viewModel.user.id) { self?.userView.setButtonState(.blocked) } else if followed.contains(viewModel.user.id) { self?.userView.setButtonState(.unfollow) diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/UserView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/UserView+ViewModel.swift index 1b9a88772..4127ed4d4 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/UserView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/UserView+ViewModel.swift @@ -6,7 +6,6 @@ // import CoreDataStack -import os.log import UIKit import Combine import MetaTextKit @@ -19,9 +18,7 @@ extension UserView { public final class ViewModel: ObservableObject { public var disposeBag = Set() public var observations = Set() - - let logger = Logger(subsystem: "StatusView", category: "ViewModel") - + @Published public var authorAvatarImage: UIImage? @Published public var authorAvatarImageURL: URL? @Published public var authorName: MetaContent? diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/UserView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/UserView.swift index 2ea1f1a1f..9221c7f90 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/UserView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/UserView.swift @@ -261,41 +261,48 @@ public extension UserView { switch state { case .loading: + followButtonWrapper.isHidden = false followButton.isHidden = false followButton.setTitle(nil, for: .normal) followButton.setBackgroundColor(Asset.Colors.Button.disabled.color, for: .normal) case .follow: + followButtonWrapper.isHidden = false followButton.isHidden = false followButton.setTitle(L10n.Common.Controls.Friendship.follow, for: .normal) followButton.setBackgroundColor(Asset.Colors.Button.userFollow.color, for: .normal) followButton.setTitleColor(.white, for: .normal) case .request: + followButtonWrapper.isHidden = false followButton.isHidden = false followButton.setTitle(L10n.Common.Controls.Friendship.request, for: .normal) followButton.setBackgroundColor(Asset.Colors.Button.userFollow.color, for: .normal) followButton.setTitleColor(.white, for: .normal) case .pending: + followButtonWrapper.isHidden = false followButton.isHidden = false followButton.setTitle(L10n.Common.Controls.Friendship.pending, for: .normal) followButton.setTitleColor(Asset.Colors.Button.userFollowingTitle.color, for: .normal) followButton.setBackgroundColor(Asset.Colors.Button.userFollowing.color, for: .normal) case .unfollow: + followButtonWrapper.isHidden = false followButton.isHidden = false followButton.setTitle(L10n.Common.Controls.Friendship.following, for: .normal) followButton.setBackgroundColor(Asset.Colors.Button.userFollowing.color, for: .normal) followButton.setTitleColor(Asset.Colors.Button.userFollowingTitle.color, for: .normal) case .blocked: + followButtonWrapper.isHidden = false followButton.isHidden = false followButton.setTitle(L10n.Common.Controls.Friendship.blocked, for: .normal) followButton.setBackgroundColor(Asset.Colors.Button.userBlocked.color, for: .normal) followButton.setTitleColor(.systemRed, for: .normal) case .none: + followButtonWrapper.isHidden = true followButton.isHidden = true followButton.setTitle(nil, for: .normal) followButton.setBackgroundColor(.clear, for: .normal) From a7bab76f9670a2d64cff553ebbbeafce74429453 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 18 Sep 2023 16:12:42 +0200 Subject: [PATCH 58/87] Add a cell for profiles in search results (IOS-141) --- Mastodon.xcodeproj/project.pbxproj | 4 + .../SearchResultsProfileTableViewCell.swift | 170 ++++++++++++++++++ ...chResultsOverviewTableViewController.swift | 47 ++--- .../Entity/Mastodon+Entity+Account.swift | 7 + .../Extension/FLAnimatedImageView.swift | 4 +- 5 files changed, 194 insertions(+), 38 deletions(-) create mode 100644 Mastodon/Scene/Search/SearchDetail/Search Results Overview/Cells/SearchResultsProfileTableViewCell.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index dc441b9e8..f4936e22f 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -151,6 +151,7 @@ D8A6AB6C291C5136003AB663 /* MastodonLoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8A6AB6B291C5136003AB663 /* MastodonLoginViewController.swift */; }; D8BE30B32A179E26006B8270 /* SuggestionAccountTableViewFooter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8BE30B22A179E26006B8270 /* SuggestionAccountTableViewFooter.swift */; }; D8BEBCB62A1B7FFD0004F475 /* SuggestionAccountTableViewCell+ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8BEBCB52A1B7FFD0004F475 /* SuggestionAccountTableViewCell+ViewModel.swift */; }; + D8D688F62AB869CB000F651A /* SearchResultsProfileTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8D688F52AB869CB000F651A /* SearchResultsProfileTableViewCell.swift */; }; D8E5C346296DAB84007E76A7 /* DataSourceFacade+Status+History.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8E5C345296DAB84007E76A7 /* DataSourceFacade+Status+History.swift */; }; D8E5C349296DB8A3007E76A7 /* StatusEditHistoryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8E5C348296DB8A3007E76A7 /* StatusEditHistoryViewController.swift */; }; D8F0372C29D232730027DE2E /* HashtagIntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8F0372B29D232730027DE2E /* HashtagIntentHandler.swift */; }; @@ -803,6 +804,7 @@ D8A6FE6629325F5900666A47 /* Localizable.stringsdict */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; path = Localizable.stringsdict; sourceTree = ""; }; D8BE30B22A179E26006B8270 /* SuggestionAccountTableViewFooter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuggestionAccountTableViewFooter.swift; sourceTree = ""; }; D8BEBCB52A1B7FFD0004F475 /* SuggestionAccountTableViewCell+ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SuggestionAccountTableViewCell+ViewModel.swift"; sourceTree = ""; }; + D8D688F52AB869CB000F651A /* SearchResultsProfileTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultsProfileTableViewCell.swift; sourceTree = ""; }; D8E5C345296DAB84007E76A7 /* DataSourceFacade+Status+History.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DataSourceFacade+Status+History.swift"; sourceTree = ""; }; D8E5C348296DB8A3007E76A7 /* StatusEditHistoryViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusEditHistoryViewController.swift; sourceTree = ""; }; D8F0372B29D232730027DE2E /* HashtagIntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashtagIntentHandler.swift; sourceTree = ""; }; @@ -1811,6 +1813,7 @@ isa = PBXGroup; children = ( D81A227A2AB47B9A00905D71 /* SearchResultDefaultSectionTableViewCell.swift */, + D8D688F52AB869CB000F651A /* SearchResultsProfileTableViewCell.swift */, ); path = Cells; sourceTree = ""; @@ -3890,6 +3893,7 @@ DBFEEC99279BDCDE004F81DD /* ProfileAboutViewModel.swift in Sources */, 2D198649261C0B8500F0B013 /* SearchResultSection.swift in Sources */, DB4F097B26A039FF00D62E92 /* SearchHistorySection.swift in Sources */, + D8D688F62AB869CB000F651A /* SearchResultsProfileTableViewCell.swift in Sources */, 2A82294F29262EE000D2A1F7 /* AppContext+NextAccount.swift in Sources */, DBB525302611EBF3002F1F29 /* ProfilePagingViewModel.swift in Sources */, DB9F58EC26EF435000E7BBE9 /* AccountViewController.swift in Sources */, diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/Cells/SearchResultsProfileTableViewCell.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/Cells/SearchResultsProfileTableViewCell.swift new file mode 100644 index 000000000..25af454b8 --- /dev/null +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/Cells/SearchResultsProfileTableViewCell.swift @@ -0,0 +1,170 @@ +// Copyright © 2023 Mastodon gGmbH. All rights reserved. + +import UIKit +import MastodonSDK +import MastodonUI +import MetaTextKit +import MastodonLocalization +import MastodonMeta +import MastodonCore +import MastodonAsset + +class SearchResultsProfileTableViewCell: UITableViewCell { + static let reuseIdentifier = "SearchResultsProfileTableViewCell" + + private static var metricFormatter = MastodonMetricFormatter() + + private let avatarImageWrapperView: UIView + let avatarImageView: AvatarImageView + + private let metaInformationStackView: UIStackView + + private let upperLineStackView: UIStackView + let displayNameLabel: MetaLabel + let acctLabel: UILabel + + private let lowerLineStackView: UIStackView + let followersLabel: UILabel + let verifiedLinkImageView: UIImageView + let verifiedLinkLabel: MetaLabel + + private let contentStackView: UIStackView + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + + avatarImageView = AvatarImageView() + avatarImageView.cornerConfiguration = AvatarImageView.CornerConfiguration(corner: .fixed(radius: 8)) + avatarImageView.translatesAutoresizingMaskIntoConstraints = false + + avatarImageWrapperView = UIView() + avatarImageWrapperView.translatesAutoresizingMaskIntoConstraints = false + avatarImageWrapperView.addSubview(avatarImageView) + + displayNameLabel = MetaLabel(style: .statusName) + displayNameLabel.setContentCompressionResistancePriority(.required, for: .horizontal) + displayNameLabel.setContentHuggingPriority(.required, for: .horizontal) + + acctLabel = UILabel() + acctLabel.textColor = .secondaryLabel + acctLabel.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .regular)) + acctLabel.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal) + + upperLineStackView = UIStackView(arrangedSubviews: [displayNameLabel, acctLabel]) + upperLineStackView.distribution = .fill + upperLineStackView.alignment = .center + + followersLabel = UILabel() + followersLabel.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal) + followersLabel.textColor = .secondaryLabel + followersLabel.setContentHuggingPriority(.required, for: .horizontal) + + verifiedLinkImageView = UIImageView() + verifiedLinkImageView.setContentCompressionResistancePriority(.defaultHigh - 1, for: .vertical) + verifiedLinkImageView.setContentHuggingPriority(.required, for: .horizontal) + verifiedLinkImageView.contentMode = .scaleAspectFit + + verifiedLinkLabel = MetaLabel(style: .profileFieldValue) + verifiedLinkLabel.setContentCompressionResistancePriority(.defaultHigh - 2, for: .horizontal) + verifiedLinkLabel.translatesAutoresizingMaskIntoConstraints = false + verifiedLinkLabel.textAttributes = [ + .font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .regular)), + .foregroundColor: UIColor.secondaryLabel + ] + verifiedLinkLabel.linkAttributes = [ + .font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .regular)), + .foregroundColor: Asset.Colors.Brand.blurple.color + ] + verifiedLinkLabel.isUserInteractionEnabled = false + + lowerLineStackView = UIStackView(arrangedSubviews: [followersLabel, verifiedLinkImageView, verifiedLinkLabel]) + lowerLineStackView.distribution = .fill + lowerLineStackView.alignment = .center + lowerLineStackView.spacing = 4 + lowerLineStackView.setCustomSpacing(2, after: verifiedLinkImageView) + + metaInformationStackView = UIStackView(arrangedSubviews: [upperLineStackView, lowerLineStackView]) + metaInformationStackView.axis = .vertical + metaInformationStackView.alignment = .leading + + contentStackView = UIStackView(arrangedSubviews: [avatarImageWrapperView, metaInformationStackView]) + contentStackView.translatesAutoresizingMaskIntoConstraints = false + contentStackView.axis = .horizontal + contentStackView.alignment = .center + contentStackView.spacing = 16 + + super.init(style: style, reuseIdentifier: reuseIdentifier) + + contentView.addSubview(contentStackView) + setupConstraints() + } + + required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } + + private func setupConstraints() { + let constraints = [ + contentStackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8), + contentStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16), + contentView.trailingAnchor.constraint(greaterThanOrEqualTo: contentStackView.trailingAnchor, constant: 16), + contentView.bottomAnchor.constraint(equalTo: contentStackView.bottomAnchor, constant: 8), + + upperLineStackView.trailingAnchor.constraint(greaterThanOrEqualTo: metaInformationStackView.trailingAnchor), + lowerLineStackView.trailingAnchor.constraint(greaterThanOrEqualTo: metaInformationStackView.trailingAnchor), + metaInformationStackView.trailingAnchor.constraint(greaterThanOrEqualTo: contentStackView.trailingAnchor), + + avatarImageView.widthAnchor.constraint(equalToConstant: 30), + avatarImageView.heightAnchor.constraint(equalTo: avatarImageView.widthAnchor), + avatarImageView.topAnchor.constraint(greaterThanOrEqualTo: avatarImageWrapperView.topAnchor), + avatarImageView.leadingAnchor.constraint(equalTo: avatarImageWrapperView.leadingAnchor), + avatarImageWrapperView.trailingAnchor.constraint(equalTo: avatarImageView.trailingAnchor), + avatarImageWrapperView.bottomAnchor.constraint(greaterThanOrEqualTo: avatarImageView.bottomAnchor), + avatarImageView.centerYAnchor.constraint(equalTo: avatarImageWrapperView.centerYAnchor), + ] + + NSLayoutConstraint.activate(constraints) + } + + override func prepareForReuse() { + super.prepareForReuse() + + avatarImageView.prepareForReuse() + } + + func configure(with account: Mastodon.Entity.Account) { + let displayNameMetaContent: MetaContent + do { + let content = MastodonContent(content: account.displayNameWithFallback, emojis: account.emojis?.asDictionary ?? [:]) + displayNameMetaContent = try MastodonMetaContent.convert(document: content) + } catch { + displayNameMetaContent = PlaintextMetaContent(string: account.displayNameWithFallback) + } + + displayNameLabel.configure(content: displayNameMetaContent) + acctLabel.text = account.acct + followersLabel.attributedText = NSAttributedString( + format: NSAttributedString(string: L10n.Common.UserList.followersCount("%@"), attributes: [.font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .regular))]), + args: NSAttributedString(string: Self.metricFormatter.string(from: account.followersCount) ?? account.followersCount.formatted(), attributes: [.font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .bold))]) + ) + + avatarImageView.setImage(url: account.avatarImageURL()) + + if let verifiedLink = account.verifiedLink?.value { + verifiedLinkImageView.image = UIImage(systemName: "checkmark") + verifiedLinkImageView.tintColor = Asset.Colors.Brand.blurple.color + + let verifiedLinkMetaContent: MetaContent + do { + let mastodonContent = MastodonContent(content: verifiedLink, emojis: [:]) + verifiedLinkMetaContent = try MastodonMetaContent.convert(document: mastodonContent) + } catch { + verifiedLinkMetaContent = PlaintextMetaContent(string: verifiedLink) + } + + verifiedLinkLabel.configure(content: verifiedLinkMetaContent) + } else { + verifiedLinkImageView.image = UIImage(systemName: "questionmark.circle") + verifiedLinkImageView.tintColor = .secondaryLabel + + verifiedLinkLabel.configure(content: PlaintextMetaContent(string: L10n.Common.UserList.noVerifiedLink)) + } + } +} diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift index c6d6175c7..c25bea693 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift @@ -28,11 +28,15 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc tableView.register(SearchResultDefaultSectionTableViewCell.self, forCellReuseIdentifier: SearchResultDefaultSectionTableViewCell.reuseIdentifier) tableView.register(StatusTableViewCell.self, forCellReuseIdentifier: StatusTableViewCell.reuseIdentifier) tableView.register(HashtagTableViewCell.self, forCellReuseIdentifier: HashtagTableViewCell.reuseIdentifier) - tableView.register(UserTableViewCell.self, forCellReuseIdentifier: UserTableViewCell.reuseIdentifier) + tableView.register(SearchResultsProfileTableViewCell.self, forCellReuseIdentifier: SearchResultsProfileTableViewCell.reuseIdentifier) + + super.init(nibName: nil, bundle: nil) + + let dataSource = UITableViewDiffableDataSource(tableView: tableView) { [weak self] tableView, indexPath, itemIdentifier in + + guard let self else { fatalError("Ooops, no self!?") } - let dataSource = UITableViewDiffableDataSource(tableView: tableView) { tableView, indexPath, itemIdentifier in switch itemIdentifier { - case .default(let item): guard let cell = tableView.dequeueReusableCell(withIdentifier: SearchResultDefaultSectionTableViewCell.reuseIdentifier, for: indexPath) as? SearchResultDefaultSectionTableViewCell else { fatalError() } @@ -41,54 +45,23 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc return cell case .suggestion(let suggestion): - switch suggestion { - case .hashtag(let hashtag): - - guard let cell = tableView.dequeueReusableCell(withIdentifier: SearchResultDefaultSectionTableViewCell.reuseIdentifier, for: indexPath) as? SearchResultDefaultSectionTableViewCell else { fatalError() } cell.configure(item: .hashtag(tag: hashtag)) return cell case .profile(let profile): - guard let cell = tableView.dequeueReusableCell(withIdentifier: UserTableViewCell.reuseIdentifier, for: indexPath) as? UserTableViewCell else { fatalError() } + guard let cell = tableView.dequeueReusableCell(withIdentifier: SearchResultsProfileTableViewCell.reuseIdentifier, for: indexPath) as? SearchResultsProfileTableViewCell else { fatalError() } - let managedObjectContext = appContext.managedObjectContext - Task { - do { - - try await managedObjectContext.perform { - guard let user = Persistence.MastodonUser.fetch(in: managedObjectContext, - context: Persistence.MastodonUser.PersistContext( - domain: authContext.mastodonAuthenticationBox.domain, - entity: profile, - cache: nil, - networkDate: Date() - )) else { return } - - cell.configure( - me: authContext.mastodonAuthenticationBox.authenticationRecord.object(in: managedObjectContext)?.user, - tableView: tableView, - viewModel: UserTableViewCell.ViewModel( - user: user, - followedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$followingUserIds.eraseToAnyPublisher(), - blockedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$blockedUserIds.eraseToAnyPublisher(), - followRequestedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$followRequestedUserIDs.eraseToAnyPublisher()), - delegate: nil) - } - } catch { - // do nothing - } - } + cell.configure(with: profile) return cell } } } - super.init(nibName: nil, bundle: nil) tableView.dataSource = dataSource tableView.delegate = self self.dataSource = dataSource @@ -349,3 +322,5 @@ extension SearchResultsOverviewTableViewController: UITableViewDelegate { tableView.deselectRow(at: indexPath, animated: true) } } + +extension SearchResultsOverviewTableViewController: UserTableViewCellDelegate {} diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Account.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Account.swift index 38bcf14fc..34fdad5ba 100644 --- a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Account.swift +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Account.swift @@ -92,3 +92,10 @@ extension Mastodon.Entity.Account { return acct } } + +extension Mastodon.Entity.Account { + public var verifiedLink: Mastodon.Entity.Field? { + let firstVerified = fields?.first(where: { $0.verifiedAt != nil }) + return firstVerified + } +} diff --git a/MastodonSDK/Sources/MastodonUI/Extension/FLAnimatedImageView.swift b/MastodonSDK/Sources/MastodonUI/Extension/FLAnimatedImageView.swift index 3fc92a4b5..68c7fbc95 100644 --- a/MastodonSDK/Sources/MastodonUI/Extension/FLAnimatedImageView.swift +++ b/MastodonSDK/Sources/MastodonUI/Extension/FLAnimatedImageView.swift @@ -39,8 +39,8 @@ extension FLAnimatedImageView { public func setImage( url: URL?, - placeholder: UIImage?, - scaleToSize: CGSize? + placeholder: UIImage? = nil, + scaleToSize: CGSize? = nil ) { // cancel task cancelTask() From ce37a8eb47c42cc36b2df9544cade88bf45c01f5 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 18 Sep 2023 17:05:29 +0200 Subject: [PATCH 59/87] Copy condensed version of user-view to collection-view in search-history (IOS-141) --- Mastodon.xcodeproj/project.pbxproj | 4 - ...toryUserCollectionViewCell+ViewModel.swift | 73 ------ .../SearchHistoryUserCollectionViewCell.swift | 219 +++++++++++++----- .../SearchHistory/SearchHistorySection.swift | 11 +- .../SearchHistoryViewController.swift | 2 - .../SearchResult/SearchResultSection.swift | 2 +- .../Entity/Mastodon/MastodonUser.swift | 7 + .../MastodonUI/View/Button/AvatarButton.swift | 24 -- 8 files changed, 175 insertions(+), 167 deletions(-) delete mode 100644 Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistoryUserCollectionViewCell+ViewModel.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index f4936e22f..a61ad3f16 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -300,7 +300,6 @@ DB63F74F2799405600455B82 /* SearchHistoryViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F74E2799405600455B82 /* SearchHistoryViewModel+Diffable.swift */; }; DB63F752279944AA00455B82 /* SearchHistorySectionHeaderCollectionReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F751279944AA00455B82 /* SearchHistorySectionHeaderCollectionReusableView.swift */; }; DB63F7542799491600455B82 /* DataSourceFacade+SearchHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F7532799491600455B82 /* DataSourceFacade+SearchHistory.swift */; }; - DB63F75A279953F200455B82 /* SearchHistoryUserCollectionViewCell+ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F759279953F200455B82 /* SearchHistoryUserCollectionViewCell+ViewModel.swift */; }; DB63F76227996B6600455B82 /* SearchHistoryViewController+DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F76127996B6600455B82 /* SearchHistoryViewController+DataSourceProvider.swift */; }; DB63F764279A5E3C00455B82 /* NotificationTimelineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F763279A5E3C00455B82 /* NotificationTimelineViewController.swift */; }; DB63F767279A5EB300455B82 /* NotificationTimelineViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F766279A5EB300455B82 /* NotificationTimelineViewModel.swift */; }; @@ -993,7 +992,6 @@ DB63F74E2799405600455B82 /* SearchHistoryViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SearchHistoryViewModel+Diffable.swift"; sourceTree = ""; }; DB63F751279944AA00455B82 /* SearchHistorySectionHeaderCollectionReusableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchHistorySectionHeaderCollectionReusableView.swift; sourceTree = ""; }; DB63F7532799491600455B82 /* DataSourceFacade+SearchHistory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DataSourceFacade+SearchHistory.swift"; sourceTree = ""; }; - DB63F759279953F200455B82 /* SearchHistoryUserCollectionViewCell+ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SearchHistoryUserCollectionViewCell+ViewModel.swift"; sourceTree = ""; }; DB63F76127996B6600455B82 /* SearchHistoryViewController+DataSourceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SearchHistoryViewController+DataSourceProvider.swift"; sourceTree = ""; }; DB63F763279A5E3C00455B82 /* NotificationTimelineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationTimelineViewController.swift; sourceTree = ""; }; DB63F766279A5EB300455B82 /* NotificationTimelineViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationTimelineViewModel.swift; sourceTree = ""; }; @@ -2295,7 +2293,6 @@ isa = PBXGroup; children = ( DB63F74C27993F5B00455B82 /* SearchHistoryUserCollectionViewCell.swift */, - DB63F759279953F200455B82 /* SearchHistoryUserCollectionViewCell+ViewModel.swift */, DB63F751279944AA00455B82 /* SearchHistorySectionHeaderCollectionReusableView.swift */, ); path = Cell; @@ -3560,7 +3557,6 @@ DB0FCB7427956939006C02E2 /* DataSourceFacade+Status.swift in Sources */, D81A22782AB4782400905D71 /* SearchResultOverviewSection.swift in Sources */, DBB525502611ED6D002F1F29 /* ProfileHeaderView.swift in Sources */, - DB63F75A279953F200455B82 /* SearchHistoryUserCollectionViewCell+ViewModel.swift in Sources */, DB023D26279FFB0A005AC798 /* ShareActivityProvider.swift in Sources */, 5D0393962612D266007FE196 /* WebViewModel.swift in Sources */, 5B24BBDA262DB14800A9381B /* ReportViewModel.swift in Sources */, diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistoryUserCollectionViewCell+ViewModel.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistoryUserCollectionViewCell+ViewModel.swift deleted file mode 100644 index 8e9710e9a..000000000 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistoryUserCollectionViewCell+ViewModel.swift +++ /dev/null @@ -1,73 +0,0 @@ -// -// SearchHistoryUserCollectionViewCell+ViewModel.swift -// Mastodon -// -// Created by MainasuK on 2022-1-20. -// - -import Foundation -import CoreDataStack -import MastodonUI -import Combine - -extension SearchHistoryUserCollectionViewCell { - final class ViewModel { - let value: MastodonUser - - let followedUsers: AnyPublisher<[String], Never> - let blockedUsers: AnyPublisher<[String], Never> - let followRequestedUsers: AnyPublisher<[String], Never> - - init(value: MastodonUser, followedUsers: AnyPublisher<[String], Never>, blockedUsers: AnyPublisher<[String], Never>, followRequestedUsers: AnyPublisher<[String], Never>) { - self.value = value - self.followedUsers = followedUsers - self.followRequestedUsers = followRequestedUsers - self.blockedUsers = blockedUsers - } - } -} - -extension SearchHistoryUserCollectionViewCell { - func configure( - me: MastodonUser?, - viewModel: ViewModel, - delegate: SearchHistorySectionHeaderCollectionReusableViewDelegate? - ) { - let user = viewModel.value - - userView.configure(user: user, delegate: delegate) - - guard let me = me else { - return userView.setButtonState(.none) - } - - if user == me { - userView.setButtonState(.none) - } else { - userView.setButtonState(.loading) - } - - Publishers.CombineLatest3( - viewModel.followedUsers, - viewModel.followRequestedUsers, - viewModel.blockedUsers - ) - .receive(on: DispatchQueue.main) - .sink { [weak self] followed, requested, blocked in - if user == me { - self?.userView.setButtonState(.none) - } else if blocked.contains(user.id) { - self?.userView.setButtonState(.blocked) - } else if followed.contains(user.id) { - self?.userView.setButtonState(.unfollow) - } else if requested.contains(user.id) { - self?.userView.setButtonState(.pending) - } else if user.locked { - self?.userView.setButtonState(.request) - } else if user != me { - self?.userView.setButtonState(.follow) - } - } - .store(in: &_disposeBag) - } -} diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistoryUserCollectionViewCell.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistoryUserCollectionViewCell.swift index 1da7075f2..3e655417c 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistoryUserCollectionViewCell.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistoryUserCollectionViewCell.swift @@ -1,74 +1,187 @@ -// -// SearchHistoryUserCollectionViewCell.swift -// Mastodon -// -// Created by MainasuK on 2022-1-20. -// +// Copyright © 2023 Mastodon gGmbH. All rights reserved. import UIKit -import Combine -import MastodonCore +import MastodonSDK import MastodonUI +import MetaTextKit +import MastodonLocalization +import MastodonMeta +import MastodonCore +import MastodonAsset +import CoreDataStack + +class SearchHistoryUserCollectionViewCell: UICollectionViewCell { + static let reuseIdentifier = "SearchHistoryUserCollectionViewCell" + + private static var metricFormatter = MastodonMetricFormatter() + + private let avatarImageWrapperView: UIView + let avatarImageView: AvatarImageView + + private let metaInformationStackView: UIStackView + + private let upperLineStackView: UIStackView + let displayNameLabel: MetaLabel + let acctLabel: UILabel + + private let lowerLineStackView: UIStackView + let followersLabel: UILabel + let verifiedLinkImageView: UIImageView + let verifiedLinkLabel: MetaLabel + + private let contentStackView: UIStackView + + override init(frame: CGRect) { + avatarImageView = AvatarImageView() + avatarImageView.cornerConfiguration = AvatarImageView.CornerConfiguration(corner: .fixed(radius: 8)) + avatarImageView.translatesAutoresizingMaskIntoConstraints = false + + avatarImageWrapperView = UIView() + avatarImageWrapperView.translatesAutoresizingMaskIntoConstraints = false + avatarImageWrapperView.addSubview(avatarImageView) + + displayNameLabel = MetaLabel(style: .statusName) + displayNameLabel.setContentCompressionResistancePriority(.required, for: .horizontal) + displayNameLabel.setContentHuggingPriority(.required, for: .horizontal) + + acctLabel = UILabel() + acctLabel.textColor = .secondaryLabel + acctLabel.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .regular)) + acctLabel.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal) + + upperLineStackView = UIStackView(arrangedSubviews: [displayNameLabel, acctLabel]) + upperLineStackView.distribution = .fill + upperLineStackView.alignment = .center + + followersLabel = UILabel() + followersLabel.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal) + followersLabel.textColor = .secondaryLabel + followersLabel.setContentHuggingPriority(.required, for: .horizontal) + + verifiedLinkImageView = UIImageView() + verifiedLinkImageView.setContentCompressionResistancePriority(.defaultHigh - 1, for: .vertical) + verifiedLinkImageView.setContentHuggingPriority(.required, for: .horizontal) + verifiedLinkImageView.contentMode = .scaleAspectFit + + verifiedLinkLabel = MetaLabel(style: .profileFieldValue) + verifiedLinkLabel.setContentCompressionResistancePriority(.defaultHigh - 2, for: .horizontal) + verifiedLinkLabel.translatesAutoresizingMaskIntoConstraints = false + verifiedLinkLabel.textAttributes = [ + .font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .regular)), + .foregroundColor: UIColor.secondaryLabel + ] + verifiedLinkLabel.linkAttributes = [ + .font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .regular)), + .foregroundColor: Asset.Colors.Brand.blurple.color + ] + verifiedLinkLabel.isUserInteractionEnabled = false + + lowerLineStackView = UIStackView(arrangedSubviews: [followersLabel, verifiedLinkImageView, verifiedLinkLabel]) + lowerLineStackView.distribution = .fill + lowerLineStackView.alignment = .center + lowerLineStackView.spacing = 4 + lowerLineStackView.setCustomSpacing(2, after: verifiedLinkImageView) + + metaInformationStackView = UIStackView(arrangedSubviews: [upperLineStackView, lowerLineStackView]) + metaInformationStackView.axis = .vertical + metaInformationStackView.alignment = .leading + + contentStackView = UIStackView(arrangedSubviews: [avatarImageWrapperView, metaInformationStackView]) + contentStackView.translatesAutoresizingMaskIntoConstraints = false + contentStackView.axis = .horizontal + contentStackView.alignment = .center + contentStackView.spacing = 16 + + super.init(frame: .zero) + + contentView.addSubview(contentStackView) + setupConstraints() + } + + required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } + + private func setupConstraints() { + let constraints = [ + contentStackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8), + contentStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16), + contentView.trailingAnchor.constraint(greaterThanOrEqualTo: contentStackView.trailingAnchor, constant: 16), + contentView.bottomAnchor.constraint(equalTo: contentStackView.bottomAnchor, constant: 8), + + upperLineStackView.trailingAnchor.constraint(greaterThanOrEqualTo: metaInformationStackView.trailingAnchor), + lowerLineStackView.trailingAnchor.constraint(greaterThanOrEqualTo: metaInformationStackView.trailingAnchor), + metaInformationStackView.trailingAnchor.constraint(greaterThanOrEqualTo: contentStackView.trailingAnchor), + + avatarImageView.widthAnchor.constraint(equalToConstant: 30), + avatarImageView.heightAnchor.constraint(equalTo: avatarImageView.widthAnchor), + avatarImageView.topAnchor.constraint(greaterThanOrEqualTo: avatarImageWrapperView.topAnchor), + avatarImageView.leadingAnchor.constraint(equalTo: avatarImageWrapperView.leadingAnchor), + avatarImageWrapperView.trailingAnchor.constraint(equalTo: avatarImageView.trailingAnchor), + avatarImageWrapperView.bottomAnchor.constraint(greaterThanOrEqualTo: avatarImageView.bottomAnchor), + avatarImageView.centerYAnchor.constraint(equalTo: avatarImageWrapperView.centerYAnchor), + ] + + NSLayoutConstraint.activate(constraints) + } -final class SearchHistoryUserCollectionViewCell: UICollectionViewCell { - - var _disposeBag = Set() - - let userView = UserView() - override func prepareForReuse() { super.prepareForReuse() - - userView.prepareForReuse() - } - - override init(frame: CGRect) { - super.init(frame: frame) - _init() - } - - required init?(coder: NSCoder) { - super.init(coder: coder) - _init() - } - -} -extension SearchHistoryUserCollectionViewCell { - - private func _init() { - ThemeService.shared.currentTheme - .map { $0.secondarySystemGroupedBackgroundColor } - .sink { [weak self] backgroundColor in - guard let self = self else { return } - self.backgroundColor = backgroundColor - self.setNeedsUpdateConfiguration() + avatarImageView.prepareForReuse() + } + + func configure(with user: MastodonUser) { + let displayNameMetaContent: MetaContent + do { + let content = MastodonContent(content: user.displayNameWithFallback, emojis: user.emojis.asDictionary) + displayNameMetaContent = try MastodonMetaContent.convert(document: content) + } catch { + displayNameMetaContent = PlaintextMetaContent(string: user.displayNameWithFallback) + } + + displayNameLabel.configure(content: displayNameMetaContent) + acctLabel.text = user.acct + followersLabel.attributedText = NSAttributedString( + format: NSAttributedString(string: L10n.Common.UserList.followersCount("%@"), attributes: [.font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .regular))]), + args: NSAttributedString(string: Self.metricFormatter.string(from: Int(user.followersCount)) ?? user.followersCount.formatted(), attributes: [.font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .bold))]) + ) + + avatarImageView.setImage(url: user.avatarImageURL()) + + if let verifiedLink = user.verifiedLink?.value { + verifiedLinkImageView.image = UIImage(systemName: "checkmark") + verifiedLinkImageView.tintColor = Asset.Colors.Brand.blurple.color + + let verifiedLinkMetaContent: MetaContent + do { + let mastodonContent = MastodonContent(content: verifiedLink, emojis: [:]) + verifiedLinkMetaContent = try MastodonMetaContent.convert(document: mastodonContent) + } catch { + verifiedLinkMetaContent = PlaintextMetaContent(string: verifiedLink) } - .store(in: &_disposeBag) - - userView.translatesAutoresizingMaskIntoConstraints = false - contentView.addSubview(userView) - NSLayoutConstraint.activate([ - userView.topAnchor.constraint(equalTo: contentView.topAnchor), - userView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16), - contentView.trailingAnchor.constraint(equalTo: userView.trailingAnchor, constant: 16), - userView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), - ]) - userView.accessibilityTraits.insert(.button) + verifiedLinkLabel.configure(content: verifiedLinkMetaContent) + } else { + verifiedLinkImageView.image = UIImage(systemName: "questionmark.circle") + verifiedLinkImageView.tintColor = .secondaryLabel + + verifiedLinkLabel.configure(content: PlaintextMetaContent(string: L10n.Common.UserList.noVerifiedLink)) + } } - + override func updateConfiguration(using state: UICellConfigurationState) { super.updateConfiguration(using: state) - + var backgroundConfiguration = UIBackgroundConfiguration.listGroupedCell() backgroundConfiguration.backgroundColorTransformer = .init { _ in if state.isHighlighted || state.isSelected { return ThemeService.shared.currentTheme.value.tableViewCellSelectionBackgroundColor + } else { + return ThemeService.shared.currentTheme.value.secondarySystemGroupedBackgroundColor } - return ThemeService.shared.currentTheme.value.secondarySystemGroupedBackgroundColor } + self.backgroundConfiguration = backgroundConfiguration + } - } + diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistorySection.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistorySection.swift index 2c0e19451..aa43f2467 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistorySection.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistorySection.swift @@ -31,16 +31,7 @@ extension SearchHistorySection { let userCellRegister = UICollectionView.CellRegistration> { cell, indexPath, item in context.managedObjectContext.performAndWait { guard let user = item.object(in: context.managedObjectContext) else { return } - cell.configure( - me: authContext.mastodonAuthenticationBox.authenticationRecord.object(in: context.managedObjectContext)?.user, - viewModel: SearchHistoryUserCollectionViewCell.ViewModel( - value: user, - followedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$followingUserIds.eraseToAnyPublisher(), - blockedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$blockedUserIds.eraseToAnyPublisher(), - followRequestedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$followRequestedUserIDs.eraseToAnyPublisher() - ), - delegate: configuration.searchHistorySectionHeaderCollectionReusableViewDelegate - ) + cell.configure(with: user) } } diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewController.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewController.swift index d55259d03..86340feed 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewController.swift @@ -14,8 +14,6 @@ import MastodonUI final class SearchHistoryViewController: UIViewController, NeedsDependency { - let logger = Logger(subsystem: "SearchHistoryViewController", category: "ViewController") - weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } diff --git a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultSection.swift b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultSection.swift index 49eeddb32..a7b10ae1f 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultSection.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultSection.swift @@ -45,7 +45,7 @@ extension SearchResultSection { return UITableViewDiffableDataSource(tableView: tableView) { tableView, indexPath, item -> UITableViewCell? in switch item { case .user(let record): - let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: UserTableViewCell.self), for: indexPath) as! UserTableViewCell + let cell = tableView.dequeueReusableCell(withIdentifier: UserTableViewCell.reuseIdentifier, for: indexPath) as! UserTableViewCell context.managedObjectContext.performAndWait { guard let user = record.object(in: context.managedObjectContext) else { return } configure( diff --git a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/MastodonUser.swift b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/MastodonUser.swift index fe668ccb9..6f3c5f8eb 100644 --- a/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/MastodonUser.swift +++ b/MastodonSDK/Sources/CoreDataStack/Entity/Mastodon/MastodonUser.swift @@ -548,3 +548,10 @@ extension MastodonUser: AutoUpdatableObject { } } } + +extension MastodonUser { + public var verifiedLink: MastodonField? { + let firstVerified = fields.first(where: { $0.verifiedAt != nil }) + return firstVerified + } +} diff --git a/MastodonSDK/Sources/MastodonUI/View/Button/AvatarButton.swift b/MastodonSDK/Sources/MastodonUI/View/Button/AvatarButton.swift index ab5c8a70e..6d399c1b2 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Button/AvatarButton.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Button/AvatarButton.swift @@ -5,7 +5,6 @@ // Created by MainasuK Cirno on 2021-7-21. // -import os.log import UIKit import MastodonLocalization @@ -117,26 +116,3 @@ extension AvatarButton { } } - -#if canImport(SwiftUI) && DEBUG -import SwiftUI - -struct AvatarButton_Previews: PreviewProvider { - - static var previews: some View { - UIViewPreview(width: 42) { - let avatarButton = AvatarButton() - avatarButton.translatesAutoresizingMaskIntoConstraints = false - NSLayoutConstraint.activate([ - avatarButton.widthAnchor.constraint(equalToConstant: 42), - avatarButton.heightAnchor.constraint(equalToConstant: 42), - ]) - return avatarButton - } - .previewLayout(.fixed(width: 42, height: 42)) - } - -} - -#endif - From dd569fe0acb29001c262e4936bd29bda3cf8dcf0 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 18 Sep 2023 17:21:36 +0200 Subject: [PATCH 60/87] Put CondensedUserView into their own class (IOS-141) --- .../SearchResultsProfileTableViewCell.swift | 153 +------------ ...chResultsOverviewTableViewController.swift | 2 +- .../SearchHistoryUserCollectionViewCell.swift | 156 +------------ .../SearchHistory/SearchHistorySection.swift | 2 +- .../View/Content/CondensedUserView.swift | 205 ++++++++++++++++++ 5 files changed, 220 insertions(+), 298 deletions(-) create mode 100644 MastodonSDK/Sources/MastodonUI/View/Content/CondensedUserView.swift diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/Cells/SearchResultsProfileTableViewCell.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/Cells/SearchResultsProfileTableViewCell.swift index 25af454b8..505e1fa80 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/Cells/SearchResultsProfileTableViewCell.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/Cells/SearchResultsProfileTableViewCell.swift @@ -1,170 +1,29 @@ // Copyright © 2023 Mastodon gGmbH. All rights reserved. import UIKit -import MastodonSDK import MastodonUI -import MetaTextKit -import MastodonLocalization -import MastodonMeta -import MastodonCore -import MastodonAsset class SearchResultsProfileTableViewCell: UITableViewCell { static let reuseIdentifier = "SearchResultsProfileTableViewCell" - private static var metricFormatter = MastodonMetricFormatter() - - private let avatarImageWrapperView: UIView - let avatarImageView: AvatarImageView - - private let metaInformationStackView: UIStackView - - private let upperLineStackView: UIStackView - let displayNameLabel: MetaLabel - let acctLabel: UILabel - - private let lowerLineStackView: UIStackView - let followersLabel: UILabel - let verifiedLinkImageView: UIImageView - let verifiedLinkLabel: MetaLabel - - private let contentStackView: UIStackView + let condensedUserView: CondensedUserView override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - avatarImageView = AvatarImageView() - avatarImageView.cornerConfiguration = AvatarImageView.CornerConfiguration(corner: .fixed(radius: 8)) - avatarImageView.translatesAutoresizingMaskIntoConstraints = false - - avatarImageWrapperView = UIView() - avatarImageWrapperView.translatesAutoresizingMaskIntoConstraints = false - avatarImageWrapperView.addSubview(avatarImageView) - - displayNameLabel = MetaLabel(style: .statusName) - displayNameLabel.setContentCompressionResistancePriority(.required, for: .horizontal) - displayNameLabel.setContentHuggingPriority(.required, for: .horizontal) - - acctLabel = UILabel() - acctLabel.textColor = .secondaryLabel - acctLabel.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .regular)) - acctLabel.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal) - - upperLineStackView = UIStackView(arrangedSubviews: [displayNameLabel, acctLabel]) - upperLineStackView.distribution = .fill - upperLineStackView.alignment = .center - - followersLabel = UILabel() - followersLabel.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal) - followersLabel.textColor = .secondaryLabel - followersLabel.setContentHuggingPriority(.required, for: .horizontal) - - verifiedLinkImageView = UIImageView() - verifiedLinkImageView.setContentCompressionResistancePriority(.defaultHigh - 1, for: .vertical) - verifiedLinkImageView.setContentHuggingPriority(.required, for: .horizontal) - verifiedLinkImageView.contentMode = .scaleAspectFit - - verifiedLinkLabel = MetaLabel(style: .profileFieldValue) - verifiedLinkLabel.setContentCompressionResistancePriority(.defaultHigh - 2, for: .horizontal) - verifiedLinkLabel.translatesAutoresizingMaskIntoConstraints = false - verifiedLinkLabel.textAttributes = [ - .font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .regular)), - .foregroundColor: UIColor.secondaryLabel - ] - verifiedLinkLabel.linkAttributes = [ - .font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .regular)), - .foregroundColor: Asset.Colors.Brand.blurple.color - ] - verifiedLinkLabel.isUserInteractionEnabled = false - - lowerLineStackView = UIStackView(arrangedSubviews: [followersLabel, verifiedLinkImageView, verifiedLinkLabel]) - lowerLineStackView.distribution = .fill - lowerLineStackView.alignment = .center - lowerLineStackView.spacing = 4 - lowerLineStackView.setCustomSpacing(2, after: verifiedLinkImageView) - - metaInformationStackView = UIStackView(arrangedSubviews: [upperLineStackView, lowerLineStackView]) - metaInformationStackView.axis = .vertical - metaInformationStackView.alignment = .leading - - contentStackView = UIStackView(arrangedSubviews: [avatarImageWrapperView, metaInformationStackView]) - contentStackView.translatesAutoresizingMaskIntoConstraints = false - contentStackView.axis = .horizontal - contentStackView.alignment = .center - contentStackView.spacing = 16 + condensedUserView = CondensedUserView(frame: .zero) + condensedUserView.translatesAutoresizingMaskIntoConstraints = false super.init(style: style, reuseIdentifier: reuseIdentifier) - contentView.addSubview(contentStackView) - setupConstraints() + contentView.addSubview(condensedUserView) + condensedUserView.pinToParent() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } - private func setupConstraints() { - let constraints = [ - contentStackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8), - contentStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16), - contentView.trailingAnchor.constraint(greaterThanOrEqualTo: contentStackView.trailingAnchor, constant: 16), - contentView.bottomAnchor.constraint(equalTo: contentStackView.bottomAnchor, constant: 8), - - upperLineStackView.trailingAnchor.constraint(greaterThanOrEqualTo: metaInformationStackView.trailingAnchor), - lowerLineStackView.trailingAnchor.constraint(greaterThanOrEqualTo: metaInformationStackView.trailingAnchor), - metaInformationStackView.trailingAnchor.constraint(greaterThanOrEqualTo: contentStackView.trailingAnchor), - - avatarImageView.widthAnchor.constraint(equalToConstant: 30), - avatarImageView.heightAnchor.constraint(equalTo: avatarImageView.widthAnchor), - avatarImageView.topAnchor.constraint(greaterThanOrEqualTo: avatarImageWrapperView.topAnchor), - avatarImageView.leadingAnchor.constraint(equalTo: avatarImageWrapperView.leadingAnchor), - avatarImageWrapperView.trailingAnchor.constraint(equalTo: avatarImageView.trailingAnchor), - avatarImageWrapperView.bottomAnchor.constraint(greaterThanOrEqualTo: avatarImageView.bottomAnchor), - avatarImageView.centerYAnchor.constraint(equalTo: avatarImageWrapperView.centerYAnchor), - ] - - NSLayoutConstraint.activate(constraints) - } - override func prepareForReuse() { super.prepareForReuse() - avatarImageView.prepareForReuse() - } - - func configure(with account: Mastodon.Entity.Account) { - let displayNameMetaContent: MetaContent - do { - let content = MastodonContent(content: account.displayNameWithFallback, emojis: account.emojis?.asDictionary ?? [:]) - displayNameMetaContent = try MastodonMetaContent.convert(document: content) - } catch { - displayNameMetaContent = PlaintextMetaContent(string: account.displayNameWithFallback) - } - - displayNameLabel.configure(content: displayNameMetaContent) - acctLabel.text = account.acct - followersLabel.attributedText = NSAttributedString( - format: NSAttributedString(string: L10n.Common.UserList.followersCount("%@"), attributes: [.font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .regular))]), - args: NSAttributedString(string: Self.metricFormatter.string(from: account.followersCount) ?? account.followersCount.formatted(), attributes: [.font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .bold))]) - ) - - avatarImageView.setImage(url: account.avatarImageURL()) - - if let verifiedLink = account.verifiedLink?.value { - verifiedLinkImageView.image = UIImage(systemName: "checkmark") - verifiedLinkImageView.tintColor = Asset.Colors.Brand.blurple.color - - let verifiedLinkMetaContent: MetaContent - do { - let mastodonContent = MastodonContent(content: verifiedLink, emojis: [:]) - verifiedLinkMetaContent = try MastodonMetaContent.convert(document: mastodonContent) - } catch { - verifiedLinkMetaContent = PlaintextMetaContent(string: verifiedLink) - } - - verifiedLinkLabel.configure(content: verifiedLinkMetaContent) - } else { - verifiedLinkImageView.image = UIImage(systemName: "questionmark.circle") - verifiedLinkImageView.tintColor = .secondaryLabel - - verifiedLinkLabel.configure(content: PlaintextMetaContent(string: L10n.Common.UserList.noVerifiedLink)) - } + condensedUserView.prepareForReuse() } } diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift index c25bea693..5687562bb 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift @@ -55,7 +55,7 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc case .profile(let profile): guard let cell = tableView.dequeueReusableCell(withIdentifier: SearchResultsProfileTableViewCell.reuseIdentifier, for: indexPath) as? SearchResultsProfileTableViewCell else { fatalError() } - cell.configure(with: profile) + cell.condensedUserView.configure(with: profile) return cell } diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistoryUserCollectionViewCell.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistoryUserCollectionViewCell.swift index 3e655417c..c17492b2e 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistoryUserCollectionViewCell.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistoryUserCollectionViewCell.swift @@ -1,171 +1,29 @@ // Copyright © 2023 Mastodon gGmbH. All rights reserved. import UIKit -import MastodonSDK import MastodonUI -import MetaTextKit -import MastodonLocalization -import MastodonMeta import MastodonCore -import MastodonAsset -import CoreDataStack class SearchHistoryUserCollectionViewCell: UICollectionViewCell { static let reuseIdentifier = "SearchHistoryUserCollectionViewCell" - private static var metricFormatter = MastodonMetricFormatter() - - private let avatarImageWrapperView: UIView - let avatarImageView: AvatarImageView - - private let metaInformationStackView: UIStackView - - private let upperLineStackView: UIStackView - let displayNameLabel: MetaLabel - let acctLabel: UILabel - - private let lowerLineStackView: UIStackView - let followersLabel: UILabel - let verifiedLinkImageView: UIImageView - let verifiedLinkLabel: MetaLabel - - private let contentStackView: UIStackView + let condensedUserView: CondensedUserView override init(frame: CGRect) { - avatarImageView = AvatarImageView() - avatarImageView.cornerConfiguration = AvatarImageView.CornerConfiguration(corner: .fixed(radius: 8)) - avatarImageView.translatesAutoresizingMaskIntoConstraints = false + condensedUserView = CondensedUserView(frame: .zero) + condensedUserView.translatesAutoresizingMaskIntoConstraints = false + super.init(frame: frame) - avatarImageWrapperView = UIView() - avatarImageWrapperView.translatesAutoresizingMaskIntoConstraints = false - avatarImageWrapperView.addSubview(avatarImageView) - - displayNameLabel = MetaLabel(style: .statusName) - displayNameLabel.setContentCompressionResistancePriority(.required, for: .horizontal) - displayNameLabel.setContentHuggingPriority(.required, for: .horizontal) - - acctLabel = UILabel() - acctLabel.textColor = .secondaryLabel - acctLabel.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .regular)) - acctLabel.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal) - - upperLineStackView = UIStackView(arrangedSubviews: [displayNameLabel, acctLabel]) - upperLineStackView.distribution = .fill - upperLineStackView.alignment = .center - - followersLabel = UILabel() - followersLabel.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal) - followersLabel.textColor = .secondaryLabel - followersLabel.setContentHuggingPriority(.required, for: .horizontal) - - verifiedLinkImageView = UIImageView() - verifiedLinkImageView.setContentCompressionResistancePriority(.defaultHigh - 1, for: .vertical) - verifiedLinkImageView.setContentHuggingPriority(.required, for: .horizontal) - verifiedLinkImageView.contentMode = .scaleAspectFit - - verifiedLinkLabel = MetaLabel(style: .profileFieldValue) - verifiedLinkLabel.setContentCompressionResistancePriority(.defaultHigh - 2, for: .horizontal) - verifiedLinkLabel.translatesAutoresizingMaskIntoConstraints = false - verifiedLinkLabel.textAttributes = [ - .font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .regular)), - .foregroundColor: UIColor.secondaryLabel - ] - verifiedLinkLabel.linkAttributes = [ - .font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .regular)), - .foregroundColor: Asset.Colors.Brand.blurple.color - ] - verifiedLinkLabel.isUserInteractionEnabled = false - - lowerLineStackView = UIStackView(arrangedSubviews: [followersLabel, verifiedLinkImageView, verifiedLinkLabel]) - lowerLineStackView.distribution = .fill - lowerLineStackView.alignment = .center - lowerLineStackView.spacing = 4 - lowerLineStackView.setCustomSpacing(2, after: verifiedLinkImageView) - - metaInformationStackView = UIStackView(arrangedSubviews: [upperLineStackView, lowerLineStackView]) - metaInformationStackView.axis = .vertical - metaInformationStackView.alignment = .leading - - contentStackView = UIStackView(arrangedSubviews: [avatarImageWrapperView, metaInformationStackView]) - contentStackView.translatesAutoresizingMaskIntoConstraints = false - contentStackView.axis = .horizontal - contentStackView.alignment = .center - contentStackView.spacing = 16 - - super.init(frame: .zero) - - contentView.addSubview(contentStackView) - setupConstraints() + contentView.addSubview(condensedUserView) + condensedUserView.pinToParent() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } - private func setupConstraints() { - let constraints = [ - contentStackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8), - contentStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16), - contentView.trailingAnchor.constraint(greaterThanOrEqualTo: contentStackView.trailingAnchor, constant: 16), - contentView.bottomAnchor.constraint(equalTo: contentStackView.bottomAnchor, constant: 8), - - upperLineStackView.trailingAnchor.constraint(greaterThanOrEqualTo: metaInformationStackView.trailingAnchor), - lowerLineStackView.trailingAnchor.constraint(greaterThanOrEqualTo: metaInformationStackView.trailingAnchor), - metaInformationStackView.trailingAnchor.constraint(greaterThanOrEqualTo: contentStackView.trailingAnchor), - - avatarImageView.widthAnchor.constraint(equalToConstant: 30), - avatarImageView.heightAnchor.constraint(equalTo: avatarImageView.widthAnchor), - avatarImageView.topAnchor.constraint(greaterThanOrEqualTo: avatarImageWrapperView.topAnchor), - avatarImageView.leadingAnchor.constraint(equalTo: avatarImageWrapperView.leadingAnchor), - avatarImageWrapperView.trailingAnchor.constraint(equalTo: avatarImageView.trailingAnchor), - avatarImageWrapperView.bottomAnchor.constraint(greaterThanOrEqualTo: avatarImageView.bottomAnchor), - avatarImageView.centerYAnchor.constraint(equalTo: avatarImageWrapperView.centerYAnchor), - ] - - NSLayoutConstraint.activate(constraints) - } - override func prepareForReuse() { super.prepareForReuse() - avatarImageView.prepareForReuse() - } - - func configure(with user: MastodonUser) { - let displayNameMetaContent: MetaContent - do { - let content = MastodonContent(content: user.displayNameWithFallback, emojis: user.emojis.asDictionary) - displayNameMetaContent = try MastodonMetaContent.convert(document: content) - } catch { - displayNameMetaContent = PlaintextMetaContent(string: user.displayNameWithFallback) - } - - displayNameLabel.configure(content: displayNameMetaContent) - acctLabel.text = user.acct - followersLabel.attributedText = NSAttributedString( - format: NSAttributedString(string: L10n.Common.UserList.followersCount("%@"), attributes: [.font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .regular))]), - args: NSAttributedString(string: Self.metricFormatter.string(from: Int(user.followersCount)) ?? user.followersCount.formatted(), attributes: [.font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .bold))]) - ) - - avatarImageView.setImage(url: user.avatarImageURL()) - - if let verifiedLink = user.verifiedLink?.value { - verifiedLinkImageView.image = UIImage(systemName: "checkmark") - verifiedLinkImageView.tintColor = Asset.Colors.Brand.blurple.color - - let verifiedLinkMetaContent: MetaContent - do { - let mastodonContent = MastodonContent(content: verifiedLink, emojis: [:]) - verifiedLinkMetaContent = try MastodonMetaContent.convert(document: mastodonContent) - } catch { - verifiedLinkMetaContent = PlaintextMetaContent(string: verifiedLink) - } - - verifiedLinkLabel.configure(content: verifiedLinkMetaContent) - } else { - verifiedLinkImageView.image = UIImage(systemName: "questionmark.circle") - verifiedLinkImageView.tintColor = .secondaryLabel - - verifiedLinkLabel.configure(content: PlaintextMetaContent(string: L10n.Common.UserList.noVerifiedLink)) - } + condensedUserView.prepareForReuse() } override func updateConfiguration(using state: UICellConfigurationState) { diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistorySection.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistorySection.swift index aa43f2467..082e1224f 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistorySection.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistorySection.swift @@ -31,7 +31,7 @@ extension SearchHistorySection { let userCellRegister = UICollectionView.CellRegistration> { cell, indexPath, item in context.managedObjectContext.performAndWait { guard let user = item.object(in: context.managedObjectContext) else { return } - cell.configure(with: user) + cell.condensedUserView.configure(with: user) } } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/CondensedUserView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/CondensedUserView.swift new file mode 100644 index 000000000..be766f5e6 --- /dev/null +++ b/MastodonSDK/Sources/MastodonUI/View/Content/CondensedUserView.swift @@ -0,0 +1,205 @@ +// Copyright © 2023 Mastodon gGmbH. All rights reserved. + +import UIKit +import CoreDataStack +import MetaTextKit +import MastodonAsset +import MastodonLocalization +import MastodonMeta +import MastodonCore +import MastodonSDK + +public class CondensedUserView: UIView { + private static var metricFormatter = MastodonMetricFormatter() + + private let avatarImageWrapperView: UIView + let avatarImageView: AvatarImageView + + private let metaInformationStackView: UIStackView + + private let upperLineStackView: UIStackView + let displayNameLabel: MetaLabel + let acctLabel: UILabel + + private let lowerLineStackView: UIStackView + let followersLabel: UILabel + let verifiedLinkImageView: UIImageView + let verifiedLinkLabel: MetaLabel + + private let contentStackView: UIStackView + + public override init(frame: CGRect) { + avatarImageView = AvatarImageView() + avatarImageView.cornerConfiguration = AvatarImageView.CornerConfiguration(corner: .fixed(radius: 8)) + avatarImageView.translatesAutoresizingMaskIntoConstraints = false + + avatarImageWrapperView = UIView() + avatarImageWrapperView.translatesAutoresizingMaskIntoConstraints = false + avatarImageWrapperView.addSubview(avatarImageView) + + displayNameLabel = MetaLabel(style: .statusName) + displayNameLabel.setContentCompressionResistancePriority(.required, for: .horizontal) + displayNameLabel.setContentHuggingPriority(.required, for: .horizontal) + + acctLabel = UILabel() + acctLabel.textColor = .secondaryLabel + acctLabel.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .regular)) + acctLabel.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal) + + upperLineStackView = UIStackView(arrangedSubviews: [displayNameLabel, acctLabel]) + upperLineStackView.distribution = .fill + upperLineStackView.alignment = .center + + followersLabel = UILabel() + followersLabel.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal) + followersLabel.textColor = .secondaryLabel + followersLabel.setContentHuggingPriority(.required, for: .horizontal) + + verifiedLinkImageView = UIImageView() + verifiedLinkImageView.setContentCompressionResistancePriority(.defaultHigh - 1, for: .vertical) + verifiedLinkImageView.setContentHuggingPriority(.required, for: .horizontal) + verifiedLinkImageView.contentMode = .scaleAspectFit + + verifiedLinkLabel = MetaLabel(style: .profileFieldValue) + verifiedLinkLabel.setContentCompressionResistancePriority(.defaultHigh - 2, for: .horizontal) + verifiedLinkLabel.translatesAutoresizingMaskIntoConstraints = false + verifiedLinkLabel.textAttributes = [ + .font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .regular)), + .foregroundColor: UIColor.secondaryLabel + ] + verifiedLinkLabel.linkAttributes = [ + .font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .regular)), + .foregroundColor: Asset.Colors.Brand.blurple.color + ] + verifiedLinkLabel.isUserInteractionEnabled = false + + lowerLineStackView = UIStackView(arrangedSubviews: [followersLabel, verifiedLinkImageView, verifiedLinkLabel]) + lowerLineStackView.distribution = .fill + lowerLineStackView.alignment = .center + lowerLineStackView.spacing = 4 + lowerLineStackView.setCustomSpacing(2, after: verifiedLinkImageView) + + metaInformationStackView = UIStackView(arrangedSubviews: [upperLineStackView, lowerLineStackView]) + metaInformationStackView.axis = .vertical + metaInformationStackView.alignment = .leading + + contentStackView = UIStackView(arrangedSubviews: [avatarImageWrapperView, metaInformationStackView]) + contentStackView.translatesAutoresizingMaskIntoConstraints = false + contentStackView.axis = .horizontal + contentStackView.alignment = .center + contentStackView.spacing = 16 + + super.init(frame: .zero) + + addSubview(contentStackView) + setupConstraints() + } + + required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } + + private func setupConstraints() { + let constraints = [ + contentStackView.topAnchor.constraint(equalTo: topAnchor, constant: 8), + contentStackView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16), + trailingAnchor.constraint(greaterThanOrEqualTo: contentStackView.trailingAnchor, constant: 16), + bottomAnchor.constraint(equalTo: contentStackView.bottomAnchor, constant: 8), + + upperLineStackView.trailingAnchor.constraint(greaterThanOrEqualTo: metaInformationStackView.trailingAnchor), + lowerLineStackView.trailingAnchor.constraint(greaterThanOrEqualTo: metaInformationStackView.trailingAnchor), + metaInformationStackView.trailingAnchor.constraint(greaterThanOrEqualTo: contentStackView.trailingAnchor), + + avatarImageView.widthAnchor.constraint(equalToConstant: 30), + avatarImageView.heightAnchor.constraint(equalTo: avatarImageView.widthAnchor), + avatarImageView.topAnchor.constraint(greaterThanOrEqualTo: avatarImageWrapperView.topAnchor), + avatarImageView.leadingAnchor.constraint(equalTo: avatarImageWrapperView.leadingAnchor), + avatarImageWrapperView.trailingAnchor.constraint(equalTo: avatarImageView.trailingAnchor), + avatarImageWrapperView.bottomAnchor.constraint(greaterThanOrEqualTo: avatarImageView.bottomAnchor), + avatarImageView.centerYAnchor.constraint(equalTo: avatarImageWrapperView.centerYAnchor), + ] + + NSLayoutConstraint.activate(constraints) + } + + public func prepareForReuse() { + avatarImageView.prepareForReuse() + } + + public func configure(with user: MastodonUser) { + let displayNameMetaContent: MetaContent + do { + let content = MastodonContent(content: user.displayNameWithFallback, emojis: user.emojis.asDictionary) + displayNameMetaContent = try MastodonMetaContent.convert(document: content) + } catch { + displayNameMetaContent = PlaintextMetaContent(string: user.displayNameWithFallback) + } + + displayNameLabel.configure(content: displayNameMetaContent) + acctLabel.text = user.acct + followersLabel.attributedText = NSAttributedString( + format: NSAttributedString(string: L10n.Common.UserList.followersCount("%@"), attributes: [.font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .regular))]), + args: NSAttributedString(string: Self.metricFormatter.string(from: Int(user.followersCount)) ?? user.followersCount.formatted(), attributes: [.font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .bold))]) + ) + + avatarImageView.setImage(url: user.avatarImageURL()) + + if let verifiedLink = user.verifiedLink?.value { + verifiedLinkImageView.image = UIImage(systemName: "checkmark") + verifiedLinkImageView.tintColor = Asset.Colors.Brand.blurple.color + + let verifiedLinkMetaContent: MetaContent + do { + let mastodonContent = MastodonContent(content: verifiedLink, emojis: [:]) + verifiedLinkMetaContent = try MastodonMetaContent.convert(document: mastodonContent) + } catch { + verifiedLinkMetaContent = PlaintextMetaContent(string: verifiedLink) + } + + verifiedLinkLabel.configure(content: verifiedLinkMetaContent) + } else { + verifiedLinkImageView.image = UIImage(systemName: "questionmark.circle") + verifiedLinkImageView.tintColor = .secondaryLabel + + verifiedLinkLabel.configure(content: PlaintextMetaContent(string: L10n.Common.UserList.noVerifiedLink)) + } + } + + public func configure(with account: Mastodon.Entity.Account) { + let displayNameMetaContent: MetaContent + do { + let content = MastodonContent(content: account.displayNameWithFallback, emojis: account.emojis?.asDictionary ?? [:]) + displayNameMetaContent = try MastodonMetaContent.convert(document: content) + } catch { + displayNameMetaContent = PlaintextMetaContent(string: account.displayNameWithFallback) + } + + displayNameLabel.configure(content: displayNameMetaContent) + acctLabel.text = account.acct + followersLabel.attributedText = NSAttributedString( + format: NSAttributedString(string: L10n.Common.UserList.followersCount("%@"), attributes: [.font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .regular))]), + args: NSAttributedString(string: Self.metricFormatter.string(from: account.followersCount) ?? account.followersCount.formatted(), attributes: [.font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .bold))]) + ) + + avatarImageView.setImage(url: account.avatarImageURL()) + + if let verifiedLink = account.verifiedLink?.value { + verifiedLinkImageView.image = UIImage(systemName: "checkmark") + verifiedLinkImageView.tintColor = Asset.Colors.Brand.blurple.color + + let verifiedLinkMetaContent: MetaContent + do { + let mastodonContent = MastodonContent(content: verifiedLink, emojis: [:]) + verifiedLinkMetaContent = try MastodonMetaContent.convert(document: mastodonContent) + } catch { + verifiedLinkMetaContent = PlaintextMetaContent(string: verifiedLink) + } + + verifiedLinkLabel.configure(content: verifiedLinkMetaContent) + } else { + verifiedLinkImageView.image = UIImage(systemName: "questionmark.circle") + verifiedLinkImageView.tintColor = .secondaryLabel + + verifiedLinkLabel.configure(content: PlaintextMetaContent(string: L10n.Common.UserList.noVerifiedLink)) + } + } + +} From 3ce8e29244681116e5ebc7a132f04c4ce73b99b9 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 18 Sep 2023 17:32:01 +0200 Subject: [PATCH 61/87] Don't prioritize hashtags or users (IOS-141) --- .../SearchHistoryViewModel+Diffable.swift | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewModel+Diffable.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewModel+Diffable.swift index 26f8f572f..a8af8e845 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewModel+Diffable.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewModel+Diffable.swift @@ -37,21 +37,18 @@ extension SearchHistoryViewModel { do { let managedObjectContext = self.context.managedObjectContext let items: [SearchHistoryItem] = try await managedObjectContext.perform { - var users: [SearchHistoryItem] = [] - var hashtags: [SearchHistoryItem] = [] - + var items: [SearchHistoryItem] = [] + for record in records { guard let searchHistory = record.object(in: managedObjectContext) else { continue } if let user = searchHistory.account { - users.append(.user(.init(objectID: user.objectID))) + items.append(.user(.init(objectID: user.objectID))) } else if let hashtag = searchHistory.hashtag { - hashtags.append(.hashtag(.init(objectID: hashtag.objectID))) - } else { - continue + items.append(.hashtag(.init(objectID: hashtag.objectID))) } } - return users + hashtags + return items } let mostRecentItems = Array(items.prefix(10)) From ee472c5920feea0ec902b780a2889da0991f624f Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 18 Sep 2023 17:45:02 +0200 Subject: [PATCH 62/87] Fix separator-inset (IOS-141) --- .../SearchResultsOverviewTableViewController.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift index 5687562bb..70ae8899b 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift @@ -25,16 +25,16 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc tableView = UITableView(frame: .zero, style: .insetGrouped) tableView.translatesAutoresizingMaskIntoConstraints = false tableView.backgroundColor = .systemGroupedBackground + tableView.separatorInset.left = 62 tableView.register(SearchResultDefaultSectionTableViewCell.self, forCellReuseIdentifier: SearchResultDefaultSectionTableViewCell.reuseIdentifier) tableView.register(StatusTableViewCell.self, forCellReuseIdentifier: StatusTableViewCell.reuseIdentifier) tableView.register(HashtagTableViewCell.self, forCellReuseIdentifier: HashtagTableViewCell.reuseIdentifier) tableView.register(SearchResultsProfileTableViewCell.self, forCellReuseIdentifier: SearchResultsProfileTableViewCell.reuseIdentifier) + super.init(nibName: nil, bundle: nil) - let dataSource = UITableViewDiffableDataSource(tableView: tableView) { [weak self] tableView, indexPath, itemIdentifier in - - guard let self else { fatalError("Ooops, no self!?") } + let dataSource = UITableViewDiffableDataSource(tableView: tableView) { tableView, indexPath, itemIdentifier in switch itemIdentifier { case .default(let item): From 5cb1280088d4c1a1ffae5aa0ae8a90cf33c38857 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 18 Sep 2023 17:48:26 +0200 Subject: [PATCH 63/87] Fix separator-inset on search-history (IOS-141) --- .../SearchHistory/SearchHistoryViewController.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewController.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewController.swift index 86340feed..91d51d1c7 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewController.swift @@ -22,6 +22,8 @@ final class SearchHistoryViewController: UIViewController, NeedsDependency { let collectionView: UICollectionView = { var configuration = UICollectionLayoutListConfiguration(appearance: .insetGrouped) + configuration.separatorConfiguration.bottomSeparatorInsets.leading = 62 + configuration.separatorConfiguration.topSeparatorInsets.leading = 62 configuration.backgroundColor = .clear configuration.headerMode = .supplementary let layout = UICollectionViewCompositionalLayout.list(using: configuration) From fa6b3fed246995786c8d06d0b3509fb122a9097d Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 18 Sep 2023 17:58:17 +0200 Subject: [PATCH 64/87] Add https if there's no prefix (IOS-141) --- ...earchResultsOverviewTableViewController.swift | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift index 70ae8899b..89b8e2e7e 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift @@ -282,8 +282,20 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc target: .status, // remove reblog wrapper status: status.asRecord ) - } else if let url = URL(string: link) { - coordinator.present(scene: .safari(url: url), transition: .safariPresent(animated: true)) + } else if var url = URL(string: link) { + let prefixedURL: URL? + if var components = URLComponents(url: url, resolvingAgainstBaseURL: false) { + if components.scheme == nil { + components.scheme = "https" + } + prefixedURL = components.url + } else { + prefixedURL = url + } + + guard let prefixedURL else { return } + + coordinator.present(scene: .safari(url: prefixedURL), transition: .safariPresent(animated: true)) } } } From c1b80a73c248310e30d69bf6ed1b3baeb628f56c Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 18 Sep 2023 21:17:39 +0200 Subject: [PATCH 65/87] Refactor navigation-logic into a coordinator (IOS-141) --- Mastodon.xcodeproj/project.pbxproj | 4 + Mastodon/Coordinator/SceneCoordinator.swift | 2 +- .../SearchResultOverviewCoordinator.swift | 173 ++++++++++++++++++ ...chResultsOverviewTableViewController.swift | 171 +++-------------- .../SearchDetailViewController.swift | 22 ++- ...ySectionHeaderCollectionReusableView.swift | 2 +- .../SearchHistoryViewController.swift | 2 - 7 files changed, 220 insertions(+), 156 deletions(-) create mode 100644 Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewCoordinator.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index a61ad3f16..20af38cce 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -152,6 +152,7 @@ D8BE30B32A179E26006B8270 /* SuggestionAccountTableViewFooter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8BE30B22A179E26006B8270 /* SuggestionAccountTableViewFooter.swift */; }; D8BEBCB62A1B7FFD0004F475 /* SuggestionAccountTableViewCell+ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8BEBCB52A1B7FFD0004F475 /* SuggestionAccountTableViewCell+ViewModel.swift */; }; D8D688F62AB869CB000F651A /* SearchResultsProfileTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8D688F52AB869CB000F651A /* SearchResultsProfileTableViewCell.swift */; }; + D8D688F92AB8B970000F651A /* SearchResultOverviewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8D688F82AB8B970000F651A /* SearchResultOverviewCoordinator.swift */; }; D8E5C346296DAB84007E76A7 /* DataSourceFacade+Status+History.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8E5C345296DAB84007E76A7 /* DataSourceFacade+Status+History.swift */; }; D8E5C349296DB8A3007E76A7 /* StatusEditHistoryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8E5C348296DB8A3007E76A7 /* StatusEditHistoryViewController.swift */; }; D8F0372C29D232730027DE2E /* HashtagIntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8F0372B29D232730027DE2E /* HashtagIntentHandler.swift */; }; @@ -804,6 +805,7 @@ D8BE30B22A179E26006B8270 /* SuggestionAccountTableViewFooter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuggestionAccountTableViewFooter.swift; sourceTree = ""; }; D8BEBCB52A1B7FFD0004F475 /* SuggestionAccountTableViewCell+ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SuggestionAccountTableViewCell+ViewModel.swift"; sourceTree = ""; }; D8D688F52AB869CB000F651A /* SearchResultsProfileTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultsProfileTableViewCell.swift; sourceTree = ""; }; + D8D688F82AB8B970000F651A /* SearchResultOverviewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultOverviewCoordinator.swift; sourceTree = ""; }; D8E5C345296DAB84007E76A7 /* DataSourceFacade+Status+History.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DataSourceFacade+Status+History.swift"; sourceTree = ""; }; D8E5C348296DB8A3007E76A7 /* StatusEditHistoryViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusEditHistoryViewController.swift; sourceTree = ""; }; D8F0372B29D232730027DE2E /* HashtagIntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashtagIntentHandler.swift; sourceTree = ""; }; @@ -1803,6 +1805,7 @@ D81A22792AB47B8400905D71 /* Cells */, D81A22742AB4643200905D71 /* SearchResultsOverviewTableViewController.swift */, D81A22772AB4782400905D71 /* SearchResultOverviewSection.swift */, + D8D688F82AB8B970000F651A /* SearchResultOverviewCoordinator.swift */, ); path = "Search Results Overview"; sourceTree = ""; @@ -3806,6 +3809,7 @@ DB63F77B279ACAE500455B82 /* DataSourceFacade+Favorite.swift in Sources */, DB9D6BF825E4F5690051B173 /* NotificationViewController.swift in Sources */, 2DAC9E46262FC9FD0062E1A6 /* SuggestionAccountTableViewCell.swift in Sources */, + D8D688F92AB8B970000F651A /* SearchResultOverviewCoordinator.swift in Sources */, DB4FFC2C269EC39600D62E92 /* SearchTransitionController.swift in Sources */, 2A3D9B7E29A8F33A00F30313 /* StatusHistoryView.swift in Sources */, D81A227B2AB47B9A00905D71 /* SearchResultDefaultSectionTableViewCell.swift in Sources */, diff --git a/Mastodon/Coordinator/SceneCoordinator.swift b/Mastodon/Coordinator/SceneCoordinator.swift index 73eda67eb..4455e46d2 100644 --- a/Mastodon/Coordinator/SceneCoordinator.swift +++ b/Mastodon/Coordinator/SceneCoordinator.swift @@ -417,7 +417,7 @@ private extension SceneCoordinator { case .searchDetail(let viewModel): - let _viewController = SearchDetailViewController() + let _viewController = SearchDetailViewController(appContext: appContext, sceneCoordinator: self, authContext: viewModel.authContext) _viewController.viewModel = viewModel viewController = _viewController case .searchResult(let viewModel): diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewCoordinator.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewCoordinator.swift new file mode 100644 index 000000000..758b01684 --- /dev/null +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewCoordinator.swift @@ -0,0 +1,173 @@ +// Copyright © 2023 Mastodon gGmbH. All rights reserved. + +import UIKit +import MastodonCore +import MastodonSDK +import MastodonLocalization + +protocol Coordinator { + func start() +} + +class SearchResultOverviewCoordinator: Coordinator { + + let overviewViewController: SearchResultsOverviewTableViewController + let sceneCoordinator: SceneCoordinator + let context: AppContext + let authContext: AuthContext + + var activeTask: Task? + + init(appContext: AppContext, authContext: AuthContext, sceneCoordinator: SceneCoordinator) { + self.sceneCoordinator = sceneCoordinator + self.context = appContext + self.authContext = authContext + + overviewViewController = SearchResultsOverviewTableViewController(appContext: appContext, authContext: authContext, sceneCoordinator: sceneCoordinator) + } + + func start() { + overviewViewController.delegate = self + } +} + +extension SearchResultOverviewCoordinator: SearchResultsOverviewTableViewControllerDelegate { + @MainActor + func searchForPosts(_ viewController: SearchResultsOverviewTableViewController, withSearchText searchText: String) { + let searchResultViewModel = SearchResultViewModel(context: context, authContext: authContext, searchScope: .posts) + searchResultViewModel.searchText.value = searchText + + sceneCoordinator.present(scene: .searchResult(viewModel: searchResultViewModel), transition: .show) + } + + func showPosts(_ viewController: SearchResultsOverviewTableViewController, tag: Mastodon.Entity.Tag) { + Task { + await DataSourceFacade.coordinateToHashtagScene( + provider: viewController, + tag: tag + ) + + await DataSourceFacade.responseToCreateSearchHistory(provider: viewController, + item: .hashtag(tag: .entity(tag))) + } + } + + @MainActor + func searchForPeople(_ viewController: SearchResultsOverviewTableViewController, withName searchText: String) { + let searchResultViewModel = SearchResultViewModel(context: context, authContext: authContext, searchScope: .people) + searchResultViewModel.searchText.value = searchText + + sceneCoordinator.present(scene: .searchResult(viewModel: searchResultViewModel), transition: .show) + } + + func goTo(_ viewController: SearchResultsOverviewTableViewController, urlString: String) { + + let query = Mastodon.API.V2.Search.Query( + q: urlString, + type: .default, + resolve: true + ) + + let authContext = self.authContext + let managedObjectContext = context.managedObjectContext + + Task { + let searchResult = try await context.apiService.search( + query: query, + authenticationBox: authContext.mastodonAuthenticationBox + ).value + + if let account = searchResult.accounts.first { + showProfile(viewController, for: account) + } else if let status = searchResult.statuses.first { + + let status = try await managedObjectContext.perform { + return Persistence.Status.fetch(in: managedObjectContext, context: Persistence.Status.PersistContext( + domain: authContext.mastodonAuthenticationBox.domain, + entity: status, + me: authContext.mastodonAuthenticationBox.authenticationRecord.object(in: managedObjectContext)?.user, + statusCache: nil, + userCache: nil, + networkDate: Date())) + } + + guard let status else { return } + + await DataSourceFacade.coordinateToStatusThreadScene( + provider: viewController, + target: .status, // remove reblog wrapper + status: status.asRecord + ) + } else if let url = URL(string: urlString) { + let prefixedURL: URL? + if var components = URLComponents(url: url, resolvingAgainstBaseURL: false) { + if components.scheme == nil { + components.scheme = "https" + } + prefixedURL = components.url + } else { + prefixedURL = url + } + + guard let prefixedURL else { return } + + await sceneCoordinator.present(scene: .safari(url: prefixedURL), transition: .safariPresent(animated: true)) + } + } + } + + func showProfile(_ viewController: SearchResultsOverviewTableViewController, for account: Mastodon.Entity.Account) { + let managedObjectContext = context.managedObjectContext + let domain = authContext.mastodonAuthenticationBox.domain + + Task { + let user = try await managedObjectContext.perform { + return Persistence.MastodonUser.fetch(in: managedObjectContext, + context: Persistence.MastodonUser.PersistContext( + domain: domain, + entity: account, + cache: nil, + networkDate: Date() + )) + } + + if let user { + await DataSourceFacade.coordinateToProfileScene(provider: viewController, + user: user.asRecord) + + await DataSourceFacade.responseToCreateSearchHistory(provider: viewController, + item: .user(record: user.asRecord)) + } + } + } + + func searchForPerson(_ viewController: SearchResultsOverviewTableViewController, username: String, domain: String) { + let acct = "\(username)@\(domain)" + let query = Mastodon.API.V2.Search.Query( + q: acct, + type: .default, + resolve: true + ) + + Task { + let searchResult = try await context.apiService.search( + query: query, + authenticationBox: authContext.mastodonAuthenticationBox + ).value + + if let account = searchResult.accounts.first(where: { $0.acctWithDomainIfMissing(domain).lowercased() == acct.lowercased() }) { + showProfile(viewController, for: account) + } else { + await MainActor.run { + let alertTitle = L10n.Scene.Search.Searching.NoUser.title + let alertMessage = L10n.Scene.Search.Searching.NoUser.message(username, domain) + + let alertController = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: .alert) + let okAction = UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default) + alertController.addAction(okAction) + sceneCoordinator.present(scene: .alertController(alertController: alertController), transition: .alertController(animated: true)) + } + } + } + } +} diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift index 89b8e2e7e..726a19b2b 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift @@ -5,22 +5,32 @@ import MastodonCore import MastodonSDK import MastodonLocalization -// we could move lots of this stuff to a coordinator, it's too much for work a viewcontroller +protocol SearchResultsOverviewTableViewControllerDelegate: AnyObject { + func goTo(_ viewController: SearchResultsOverviewTableViewController, urlString: String) + func showPosts(_ viewController: SearchResultsOverviewTableViewController, tag: Mastodon.Entity.Tag) + func searchForPosts(_ viewController: SearchResultsOverviewTableViewController, withSearchText searchText: String) + func searchForPeople(_ viewController: SearchResultsOverviewTableViewController, withName searchText: String) + func showProfile(_ viewController: SearchResultsOverviewTableViewController, for account: Mastodon.Entity.Account) + func searchForPerson(_ viewController: SearchResultsOverviewTableViewController, username: String, domain: String) +} + class SearchResultsOverviewTableViewController: UIViewController, NeedsDependency, AuthContextProvider { - var context: AppContext! let authContext: AuthContext + var context: AppContext! var coordinator: SceneCoordinator! private let tableView: UITableView var dataSource: UITableViewDiffableDataSource? + weak var delegate: SearchResultsOverviewTableViewControllerDelegate? + var activeTask: Task? - init(appContext: AppContext, authContext: AuthContext, coordinator: SceneCoordinator) { + init(appContext: AppContext, authContext: AuthContext, sceneCoordinator: SceneCoordinator) { - self.context = appContext self.authContext = authContext - self.coordinator = coordinator + self.context = appContext + self.coordinator = sceneCoordinator tableView = UITableView(frame: .zero, style: .insetGrouped) tableView.translatesAutoresizingMaskIntoConstraints = false @@ -160,145 +170,6 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc activeTask = searchTask } - - //MARK: - Actions - - func showPosts(tag: Mastodon.Entity.Tag) { - Task { - await DataSourceFacade.coordinateToHashtagScene( - provider: self, - tag: tag - ) - - await DataSourceFacade.responseToCreateSearchHistory(provider: self, - item: .hashtag(tag: .entity(tag))) - } - } - - func showProfile(for account: Mastodon.Entity.Account) { - let managedObjectContext = context.managedObjectContext - let domain = authContext.mastodonAuthenticationBox.domain - - Task { - let user = try await managedObjectContext.perform { - return Persistence.MastodonUser.fetch(in: managedObjectContext, - context: Persistence.MastodonUser.PersistContext( - domain: domain, - entity: account, - cache: nil, - networkDate: Date() - )) - } - - if let user { - await DataSourceFacade.coordinateToProfileScene(provider:self, - user: user.asRecord) - - await DataSourceFacade.responseToCreateSearchHistory(provider: self, - item: .user(record: user.asRecord)) - } - } - } - - func searchForPeople(withName searchText: String) { - let searchResultViewModel = SearchResultViewModel(context: context, authContext: authContext, searchScope: .people) - searchResultViewModel.searchText.value = searchText - - coordinator.present(scene: .searchResult(viewModel: searchResultViewModel), transition: .show) - } - - func searchForPosts(withSearchText searchText: String) { - let searchResultViewModel = SearchResultViewModel(context: context, authContext: authContext, searchScope: .posts) - searchResultViewModel.searchText.value = searchText - - coordinator.present(scene: .searchResult(viewModel: searchResultViewModel), transition: .show) - } - - func searchForPerson(username: String, domain: String) { - let acct = "\(username)@\(domain)" - let query = Mastodon.API.V2.Search.Query( - q: acct, - type: .default, - resolve: true - ) - - Task { - let searchResult = try await context.apiService.search( - query: query, - authenticationBox: authContext.mastodonAuthenticationBox - ).value - - if let account = searchResult.accounts.first(where: { $0.acctWithDomainIfMissing(domain).lowercased() == acct.lowercased() }) { - showProfile(for: account) - } else { - await MainActor.run { - let alertTitle = L10n.Scene.Search.Searching.NoUser.title - let alertMessage = L10n.Scene.Search.Searching.NoUser.message(username, domain) - - let alertController = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: .alert) - let okAction = UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default) - alertController.addAction(okAction) - coordinator.present(scene: .alertController(alertController: alertController), transition: .alertController(animated: true)) - } - } - } - } - - func goTo(link: String) { - - let query = Mastodon.API.V2.Search.Query( - q: link, - type: .default, - resolve: true - ) - - let authContext = self.authContext - let managedObjectContext = context.managedObjectContext - - Task { - let searchResult = try await context.apiService.search( - query: query, - authenticationBox: authContext.mastodonAuthenticationBox - ).value - - if let account = searchResult.accounts.first { - showProfile(for: account) - } else if let status = searchResult.statuses.first { - - let status = try await managedObjectContext.perform { - return Persistence.Status.fetch(in: managedObjectContext, context: Persistence.Status.PersistContext( - domain: authContext.mastodonAuthenticationBox.domain, - entity: status, - me: authContext.mastodonAuthenticationBox.authenticationRecord.object(in: managedObjectContext)?.user, - statusCache: nil, - userCache: nil, - networkDate: Date())) - } - - guard let status else { return } - - await DataSourceFacade.coordinateToStatusThreadScene( - provider: self, - target: .status, // remove reblog wrapper - status: status.asRecord - ) - } else if var url = URL(string: link) { - let prefixedURL: URL? - if var components = URLComponents(url: url, resolvingAgainstBaseURL: false) { - if components.scheme == nil { - components.scheme = "https" - } - prefixedURL = components.url - } else { - prefixedURL = url - } - - guard let prefixedURL else { return } - - coordinator.present(scene: .safari(url: prefixedURL), transition: .safariPresent(animated: true)) - } - } - } } //MARK: UITableViewDelegate @@ -313,21 +184,21 @@ extension SearchResultsOverviewTableViewController: UITableViewDelegate { case .default(let defaultSectionEntry): switch defaultSectionEntry { case .posts(let searchText): - searchForPosts(withSearchText: searchText) + delegate?.searchForPosts(self, withSearchText: searchText) case .people(let searchText): - searchForPeople(withName: searchText) + delegate?.searchForPeople(self, withName: searchText) case .profile(let username, let domain): - searchForPerson(username: username, domain: domain) + delegate?.searchForPerson(self, username: username, domain: domain) case .openLink(let urlString): - goTo(link: urlString) + delegate?.goTo(self, urlString: urlString) } case .suggestion(let suggestionSectionEntry): switch suggestionSectionEntry { case .hashtag(let tag): - showPosts(tag: tag) + delegate?.showPosts(self, tag: tag) case .profile(let account): - showProfile(for: account) + delegate?.showProfile(self, for: account) } } diff --git a/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift b/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift index 990dab66e..82cb9795f 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift @@ -26,6 +26,7 @@ final class SearchDetailViewController: UIViewController, NeedsDependency { var disposeBag = Set() var observations = Set() + let searchResultOverviewCoordinator: SearchResultOverviewCoordinator weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } @@ -82,11 +83,28 @@ final class SearchDetailViewController: UIViewController, NeedsDependency { }() private(set) lazy var searchResultsOverviewViewController: SearchResultsOverviewTableViewController = { - let searchResultsOverviewViewController = SearchResultsOverviewTableViewController(appContext: context, authContext: viewModel.authContext, coordinator: coordinator) - return searchResultsOverviewViewController + return searchResultOverviewCoordinator.overviewViewController }() + //MARK: - init + + init(appContext: AppContext, sceneCoordinator: SceneCoordinator, authContext: AuthContext) { + self.context = appContext + self.coordinator = sceneCoordinator + + self.searchResultOverviewCoordinator = SearchResultOverviewCoordinator(appContext: appContext, authContext: authContext, sceneCoordinator: sceneCoordinator) + + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } + + //MARK: - UIViewController + override func viewDidLoad() { + + searchResultOverviewCoordinator.start() + super.viewDidLoad() setupBackgroundColor(theme: ThemeService.shared.currentTheme.value) diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistorySectionHeaderCollectionReusableView.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistorySectionHeaderCollectionReusableView.swift index ecab554e1..6375f5d29 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistorySectionHeaderCollectionReusableView.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistorySectionHeaderCollectionReusableView.swift @@ -11,7 +11,7 @@ import MastodonAsset import MastodonLocalization import MastodonUI -protocol SearchHistorySectionHeaderCollectionReusableViewDelegate: AnyObject, UserViewDelegate { +protocol SearchHistorySectionHeaderCollectionReusableViewDelegate: AnyObject { func searchHistorySectionHeaderCollectionReusableView(_ searchHistorySectionHeaderCollectionReusableView: SearchHistorySectionHeaderCollectionReusableView, clearButtonDidPressed button: UIButton) } diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewController.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewController.swift index 91d51d1c7..8645da5ac 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistoryViewController.swift @@ -125,5 +125,3 @@ extension SearchHistoryViewController: SearchHistorySectionHeaderCollectionReusa } } } - -extension SearchHistoryViewController: UserTableViewCellDelegate {} From 68dc99004c1cc47fa5d7047741683ef968cf76da Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 18 Sep 2023 23:10:59 +0200 Subject: [PATCH 66/87] Fix background-color (IOS-141) --- .../Cells/SearchResultDefaultSectionTableViewCell.swift | 8 ++++++++ .../Cells/SearchResultsProfileTableViewCell.swift | 1 + .../Cell/SearchHistoryUserCollectionViewCell.swift | 2 +- .../SearchDetail/SearchHistory/SearchHistorySection.swift | 4 ++-- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/Cells/SearchResultDefaultSectionTableViewCell.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/Cells/SearchResultDefaultSectionTableViewCell.swift index 94bc48dcc..e6cd2b902 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/Cells/SearchResultDefaultSectionTableViewCell.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/Cells/SearchResultDefaultSectionTableViewCell.swift @@ -6,6 +6,14 @@ import MastodonAsset class SearchResultDefaultSectionTableViewCell: UITableViewCell { static let reuseIdentifier = "SearchResultDefaultSectionTableViewCell" + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + + backgroundColor = .secondarySystemGroupedBackground + } + + required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } + func configure(item: SearchResultOverviewItem.DefaultSectionEntry) { var content = UIListContentConfiguration.cell() content.image = item.icon diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/Cells/SearchResultsProfileTableViewCell.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/Cells/SearchResultsProfileTableViewCell.swift index 505e1fa80..303c20aa8 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/Cells/SearchResultsProfileTableViewCell.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/Cells/SearchResultsProfileTableViewCell.swift @@ -17,6 +17,7 @@ class SearchResultsProfileTableViewCell: UITableViewCell { contentView.addSubview(condensedUserView) condensedUserView.pinToParent() + backgroundColor = .secondarySystemGroupedBackground } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistoryUserCollectionViewCell.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistoryUserCollectionViewCell.swift index c17492b2e..db315b1d1 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistoryUserCollectionViewCell.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchHistory/Cell/SearchHistoryUserCollectionViewCell.swift @@ -34,7 +34,7 @@ class SearchHistoryUserCollectionViewCell: UICollectionViewCell { if state.isHighlighted || state.isSelected { return ThemeService.shared.currentTheme.value.tableViewCellSelectionBackgroundColor } else { - return ThemeService.shared.currentTheme.value.secondarySystemGroupedBackgroundColor + return .secondarySystemGroupedBackground } } diff --git a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistorySection.swift b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistorySection.swift index 082e1224f..4269cdda7 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistorySection.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchHistory/SearchHistorySection.swift @@ -48,13 +48,13 @@ extension SearchHistorySection { var backgroundConfiguration = UIBackgroundConfiguration.listGroupedCell() backgroundConfiguration.backgroundColorTransformer = .init { [weak cell] _ in guard let state = cell?.configurationState else { - return ThemeService.shared.currentTheme.value.secondarySystemGroupedBackgroundColor + return .secondarySystemGroupedBackground } if state.isHighlighted || state.isSelected { return ThemeService.shared.currentTheme.value.tableViewCellSelectionBackgroundColor } - return ThemeService.shared.currentTheme.value.secondarySystemGroupedBackgroundColor + return .secondarySystemGroupedBackground } cell.backgroundConfiguration = backgroundConfiguration } From 0c5b3a64cf3c034a75b39bed16e9be3842e7307a Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 20 Sep 2023 16:03:46 +0200 Subject: [PATCH 67/87] Adopt search to follow mastodon-logic (IOS-141) as defined here: https://github.com/mastodon/mastodon/blob/main/app/javascript/mastodon/features/compose/components/search.jsx#L280-L310 --- Localization/app.json | 5 +- .../SearchResultOverviewSection.swift | 17 ++++--- ...chResultsOverviewTableViewController.swift | 48 +++++++++++++------ .../Generated/Strings.swift | 18 ++++--- .../Resources/Base.lproj/Localizable.strings | 7 +-- .../ComposeContent/Helper/MastodonRegex.swift | 5 ++ 6 files changed, 67 insertions(+), 33 deletions(-) diff --git a/Localization/app.json b/Localization/app.json index 8a7817d40..b82bcb151 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -651,8 +651,9 @@ } }, "searching": { - "posts": "Posts with \"%@\"", - "people": "People with \"%@\"", + "posts": "Posts matching \"%@\"", + "people": "People matching \"%@\"", + "hashtag": "Go to #%@", "profile": "Go to @%@@%@", "url": "Open Link", "empty_state": { diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewSection.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewSection.swift index 6cc4b8942..a9a1438c9 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewSection.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewSection.swift @@ -15,9 +15,10 @@ enum SearchResultOverviewItem: Hashable { case suggestion(SuggestionSectionEntry) enum DefaultSectionEntry: Hashable { - case posts(String) - case people(String) - case profile(username: String, domain: String) + case showHashtag(hashtag: String) + case posts(matching: String) + case people(matching: String) + case showProfile(username: String, domain: String) case openLink(String) var title: String { @@ -26,23 +27,27 @@ enum SearchResultOverviewItem: Hashable { return L10n.Scene.Search.Searching.posts(text) case .people(let username): return L10n.Scene.Search.Searching.people(username) - case .profile(let username, let instanceName): + case .showProfile(let username, let instanceName): return L10n.Scene.Search.Searching.profile(username, instanceName) case .openLink(_): return L10n.Scene.Search.Searching.url + case .showHashtag(let hashtag): + return L10n.Scene.Search.Searching.hashtag(hashtag) } } var icon: UIImage? { switch self { case .posts(_): - return UIImage(systemName: "number") + return UIImage(systemName: "magnifyingglass") case .people(_): return UIImage(systemName: "person.2") - case .profile(_, _): + case .showProfile(_, _): return UIImage(systemName: "person.crop.circle") case .openLink(_): return UIImage(systemName: "link") + case .showHashtag(_): + return UIImage(systemName: "number") } } } diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift index 726a19b2b..2d4d61cef 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift @@ -4,6 +4,7 @@ import UIKit import MastodonCore import MastodonSDK import MastodonLocalization +import MastodonUI protocol SearchResultsOverviewTableViewControllerDelegate: AnyObject { func goTo(_ viewController: SearchResultsOverviewTableViewController, urlString: String) @@ -95,26 +96,40 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc var snapshot = dataSource.snapshot() snapshot.deleteItems(snapshot.itemIdentifiers(inSection: .default)) - snapshot.appendItems([.default(.posts(searchText)), - .default(.people(searchText))], toSection: .default) - let components = searchText.split(separator: "@") - if components.count == 2 { - let username = String(components[0]) - let domain = String(components[1]) - if domain.split(separator: ".").count >= 2 { - snapshot.appendItems([.default(.profile(username: username, domain: domain))], toSection: .default) - } else { - snapshot.appendItems([.default(.profile(username: username, domain: authContext.mastodonAuthenticationBox.domain))], toSection: .default) + if searchText.lowercased().starts(with: "https://") && (searchText.contains(" ") == false) { + if URL(string: searchText)?.isValidURL() ?? false { + snapshot.appendItems([.default(.openLink(searchText))], toSection: .default) } - } else { - snapshot.appendItems([.default(.profile(username: searchText, domain: authContext.mastodonAuthenticationBox.domain))], toSection: .default) } - if URL(string: searchText)?.isValidURL() ?? false { - snapshot.appendItems([.default(.openLink(searchText))], toSection: .default) + //TODO: Check for Hashtag-Regex! + if searchText.starts(with: "#") && searchText.length > 1 { + snapshot.appendItems([.default(.showHashtag(hashtag: searchText.replacingOccurrences(of: "#", with: "")))], + toSection: .default) } + if searchText.length > 1, + let usernameRegex = try? NSRegularExpression(pattern: MastodonRegex.Search.username, options: .caseInsensitive), + usernameRegex.firstMatch(in: searchText, range: NSRange(location: 0, length: searchText.length-1)) != nil { + let components = searchText.split(separator: "@") + if components.count == 2 { + let username = String(components[0]).replacingOccurrences(of: "@", with: "") + + let domain = String(components[1]) + if domain.split(separator: ".").count >= 2 { + snapshot.appendItems([.default(.showProfile(username: username, domain: domain))], toSection: .default) + } else { + snapshot.appendItems([.default(.showProfile(username: username, domain: authContext.mastodonAuthenticationBox.domain))], toSection: .default) + } + } else { + snapshot.appendItems([.default(.showProfile(username: searchText, domain: authContext.mastodonAuthenticationBox.domain))], toSection: .default) + } + } + + snapshot.appendItems([.default(.posts(matching: searchText)), + .default(.people(matching: searchText))], toSection: .default) + dataSource.apply(snapshot, animatingDifferences: false) } @@ -187,10 +202,13 @@ extension SearchResultsOverviewTableViewController: UITableViewDelegate { delegate?.searchForPosts(self, withSearchText: searchText) case .people(let searchText): delegate?.searchForPeople(self, withName: searchText) - case .profile(let username, let domain): + case .showProfile(let username, let domain): delegate?.searchForPerson(self, username: username, domain: domain) case .openLink(let urlString): delegate?.goTo(self, urlString: urlString) + case .showHashtag(let hashtagText): + let tag = Mastodon.Entity.Tag(name: hashtagText, url: "") + delegate?.showPosts(self, tag: tag) } case .suggestion(let suggestionSectionEntry): switch suggestionSectionEntry { diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index 4484b6e96..3367b4805 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -1279,13 +1279,17 @@ public enum L10n { public static let clear = L10n.tr("Localizable", "Scene.Search.Searching.Clear", fallback: "Clear") /// Clear all public static let clearAll = L10n.tr("Localizable", "Scene.Search.Searching.ClearAll", fallback: "Clear all") - /// People with "%@" - public static func people(_ p1: Any) -> String { - return L10n.tr("Localizable", "Scene.Search.Searching.People", String(describing: p1), fallback: "People with \"%@\"") + /// Go to #%@ + public static func hashtag(_ p1: Any) -> String { + return L10n.tr("Localizable", "Scene.Search.Searching.Hashtag", String(describing: p1), fallback: "Go to #%@") } - /// Posts with "%@" + /// People matching "%@" + public static func people(_ p1: Any) -> String { + return L10n.tr("Localizable", "Scene.Search.Searching.People", String(describing: p1), fallback: "People matching \"%@\"") + } + /// Posts matching "%@" public static func posts(_ p1: Any) -> String { - return L10n.tr("Localizable", "Scene.Search.Searching.Posts", String(describing: p1), fallback: "Posts with \"%@\"") + return L10n.tr("Localizable", "Scene.Search.Searching.Posts", String(describing: p1), fallback: "Posts matching \"%@\"") } /// Go to @%@@%@ public static func profile(_ p1: Any, _ p2: Any) -> String { @@ -1293,8 +1297,8 @@ public enum L10n { } /// Recent searches public static let recentSearch = L10n.tr("Localizable", "Scene.Search.Searching.RecentSearch", fallback: "Recent searches") - /// Open Link - public static let url = L10n.tr("Localizable", "Scene.Search.Searching.Url", fallback: "Open Link") + /// Open URL in Mastodon + public static let url = L10n.tr("Localizable", "Scene.Search.Searching.Url", fallback: "Open URL in Mastodon") public enum EmptyState { /// No results public static let noResults = L10n.tr("Localizable", "Scene.Search.Searching.EmptyState.NoResults", fallback: "No results") diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 0b5102ec0..9ef23c951 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -443,10 +443,11 @@ uploaded to Mastodon."; "Scene.Search.Searching.ClearAll" = "Clear all"; "Scene.Search.Searching.EmptyState.NoResults" = "No results"; "Scene.Search.Searching.RecentSearch" = "Recent searches"; -"Scene.Search.Searching.Posts" = "Posts with \"%@\""; -"Scene.Search.Searching.People" = "People with \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.People" = "People matching \"%@\""; "Scene.Search.Searching.Profile" = "Go to @%@@%@"; -"Scene.Search.Searching.Url" = "Open Link"; +"Scene.Search.Searching.Hashtag" = "Go to #%@"; +"Scene.Search.Searching.Url" = "Open URL in Mastodon"; "Scene.Search.Searching.NoUser.Title" = "No User Account Found"; "Scene.Search.Searching.NoUser.Message" = "There's no Useraccount \"%@\" on %@"; diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Helper/MastodonRegex.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Helper/MastodonRegex.swift index c8c3f498b..0cc925f6d 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Helper/MastodonRegex.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Helper/MastodonRegex.swift @@ -22,4 +22,9 @@ public enum MastodonRegex { /// #… /// :… public static let autoCompletePattern = "(?:@([a-zA-Z0-9_]+)(@[a-zA-Z0-9_.-]+)?|#([^\\s.]+))|(^\\B:|\\s:)([a-zA-Z0-9_]+)" + + public enum Search { + public static let username = "^@?[a-z0-9_-]+(@[\\S]+)?$" + } } + From d9243c25ce90f92ddb6fdd1aabcb373966782615 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 20 Sep 2023 16:04:23 +0200 Subject: [PATCH 68/87] Only search for accounts when searching for a person (IOS-141) --- .../SearchResultOverviewCoordinator.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewCoordinator.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewCoordinator.swift index 758b01684..4dc337b9a 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewCoordinator.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewCoordinator.swift @@ -145,7 +145,7 @@ extension SearchResultOverviewCoordinator: SearchResultsOverviewTableViewControl let acct = "\(username)@\(domain)" let query = Mastodon.API.V2.Search.Query( q: acct, - type: .default, + type: .accounts, resolve: true ) From e041a7e086324e1e6dd965ddeea7a5e91896d63e Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 20 Sep 2023 16:29:30 +0200 Subject: [PATCH 69/87] Add Hashtag-Regex (IOS-141) --- .../SearchResultsOverviewTableViewController.swift | 4 +++- .../Scene/ComposeContent/Helper/MastodonRegex.swift | 9 +++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift index 2d4d61cef..db38027bc 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift @@ -103,10 +103,12 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc } } - //TODO: Check for Hashtag-Regex! if searchText.starts(with: "#") && searchText.length > 1 { snapshot.appendItems([.default(.showHashtag(hashtag: searchText.replacingOccurrences(of: "#", with: "")))], toSection: .default) + } else if searchText.length > 1, let hashtagRegex = try? NSRegularExpression(pattern: MastodonRegex.Search.hashtag, options: .caseInsensitive), hashtagRegex.firstMatch(in: searchText, range: NSRange(location: 0, length: searchText.length-1)) != nil { + snapshot.appendItems([.default(.showHashtag(hashtag: searchText.replacingOccurrences(of: "#", with: "")))], + toSection: .default) } if searchText.length > 1, diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Helper/MastodonRegex.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Helper/MastodonRegex.swift index 0cc925f6d..76df54124 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Helper/MastodonRegex.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Helper/MastodonRegex.swift @@ -25,6 +25,15 @@ public enum MastodonRegex { public enum Search { public static let username = "^@?[a-z0-9_-]+(@[\\S]+)?$" + + /// See: https://github.com/mastodon/mastodon/blob/main/app/javascript/mastodon/utils/hashtags.ts + public static var hashtag: String { + let word = "\\p{L}\\p{M}\\p{N}\\p{Pc}" + let alpha = "\\p{L}\\p{M}" + let hashtag_separators = "_\\u00b7\\u200c" + + return "^(([\(word)_][\(word)\(hashtag_separators)]*[\(alpha)\(hashtag_separators)][\(word)\(hashtag_separators)]*[\(word)_])|([\(word)_]*[\(alpha)][\(word)_]*))$" + } } } From a0f7454a3d4ccde89d10cbbe27eeed9e0a1a1eea Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 20 Sep 2023 18:47:35 +0200 Subject: [PATCH 70/87] Show loading-indicator (IOS-141) aaaaand simplify things as we don't need a super-dynamic search-result-screen anymore. --- .../SearchResultOverviewCoordinator.swift | 6 +- .../SearchResult/SearchResultSection.swift | 2 - ...ultViewController+DataSourceProvider.swift | 2 + .../SearchResultViewController.swift | 85 +------------------ .../SearchResultViewModel+Diffable.swift | 6 +- .../SearchResultViewModel+State.swift | 35 ++++---- .../SearchResult/SearchResultViewModel.swift | 9 +- 7 files changed, 31 insertions(+), 114 deletions(-) diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewCoordinator.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewCoordinator.swift index 4dc337b9a..a2d6c8e24 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewCoordinator.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultOverviewCoordinator.swift @@ -34,8 +34,7 @@ class SearchResultOverviewCoordinator: Coordinator { extension SearchResultOverviewCoordinator: SearchResultsOverviewTableViewControllerDelegate { @MainActor func searchForPosts(_ viewController: SearchResultsOverviewTableViewController, withSearchText searchText: String) { - let searchResultViewModel = SearchResultViewModel(context: context, authContext: authContext, searchScope: .posts) - searchResultViewModel.searchText.value = searchText + let searchResultViewModel = SearchResultViewModel(context: context, authContext: authContext, searchScope: .posts, searchText: searchText) sceneCoordinator.present(scene: .searchResult(viewModel: searchResultViewModel), transition: .show) } @@ -54,8 +53,7 @@ extension SearchResultOverviewCoordinator: SearchResultsOverviewTableViewControl @MainActor func searchForPeople(_ viewController: SearchResultsOverviewTableViewController, withName searchText: String) { - let searchResultViewModel = SearchResultViewModel(context: context, authContext: authContext, searchScope: .people) - searchResultViewModel.searchText.value = searchText + let searchResultViewModel = SearchResultViewModel(context: context, authContext: authContext, searchScope: .people, searchText: searchText) sceneCoordinator.present(scene: .searchResult(viewModel: searchResultViewModel), transition: .show) } diff --git a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultSection.swift b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultSection.swift index a7b10ae1f..dbede1795 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultSection.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultSection.swift @@ -23,8 +23,6 @@ enum SearchResultSection: Hashable { extension SearchResultSection { - static let logger = Logger(subsystem: "SearchResultSection", category: "logic") - struct Configuration { let authContext: AuthContext weak var statusViewTableViewCellDelegate: StatusTableViewCellDelegate? diff --git a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController+DataSourceProvider.swift b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController+DataSourceProvider.swift index a2f41aefb..f2e8c7c6e 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController+DataSourceProvider.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController+DataSourceProvider.swift @@ -71,6 +71,8 @@ extension SearchResultViewController { case .notification: assertionFailure() } // end switch + + tableView.deselectRow(at: indexPath, animated: true) } // end Task } // end func } diff --git a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController.swift b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController.swift index 731117ec6..fa8b844a6 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewController.swift @@ -11,6 +11,7 @@ import Combine import CoreDataStack import MastodonCore import MastodonUI +import MastodonAsset final class SearchResultViewController: UIViewController, NeedsDependency, MediaPreviewableViewController { @@ -37,14 +38,7 @@ extension SearchResultViewController { override func viewDidLoad() { super.viewDidLoad() - setupBackgroundColor(theme: ThemeService.shared.currentTheme.value) - ThemeService.shared.currentTheme - .receive(on: DispatchQueue.main) - .sink { [weak self] theme in - guard let self = self else { return } - self.setupBackgroundColor(theme: theme) - } - .store(in: &disposeBag) + view.backgroundColor = Asset.Theme.System.systemGroupedBackground.color tableView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(tableView) @@ -68,85 +62,14 @@ extension SearchResultViewController { } .store(in: &disposeBag) - // listen keyboard events and set content inset - let keyboardEventPublishers = Publishers.CombineLatest3( - KeyboardResponderService.shared.isShow, - KeyboardResponderService.shared.state, - KeyboardResponderService.shared.endFrame - ) - Publishers.CombineLatest3( - keyboardEventPublishers, - viewModel.viewDidAppear, - viewModel.didDataSourceUpdate - ) - .sink(receiveValue: { [weak self] keyboardEvents, _, _ in - guard let self = self else { return } - let (isShow, state, endFrame) = keyboardEvents - - // update keyboard background color - guard isShow, state == .dock else { - self.tableView.contentInset.bottom = 0 - self.tableView.verticalScrollIndicatorInsets.bottom = 0 - return - } - // isShow AND dock state - - // adjust inset for tableView - let contentFrame = self.view.convert(self.tableView.frame, to: nil) - let padding = contentFrame.maxY - endFrame.minY - guard padding > 0 else { - self.tableView.contentInset.bottom = self.view.safeAreaInsets.bottom - self.tableView.verticalScrollIndicatorInsets.bottom = self.view.safeAreaInsets.bottom - return - } - - self.tableView.contentInset.bottom = padding - self.view.safeAreaInsets.bottom - self.tableView.verticalScrollIndicatorInsets.bottom = padding - self.view.safeAreaInsets.bottom - }) - .store(in: &disposeBag) -// - // works for already onscreen page - viewModel.navigationBarFrame - .removeDuplicates() - .receive(on: DispatchQueue.main) - .sink { [weak self] frame in - guard let self = self else { return } - guard self.viewModel.viewDidAppear.value else { return } - self.tableView.contentInset.top = frame.height - self.tableView.verticalScrollIndicatorInsets.top = frame.height - } - .store(in: &disposeBag) - - title = viewModel.searchText.value - } - - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - - // works for appearing page - if !viewModel.viewDidAppear.value { - tableView.contentInset.top = viewModel.navigationBarFrame.value.height - tableView.contentOffset.y = -viewModel.navigationBarFrame.value.height - } - - tableView.deselectRow(with: transitionCoordinator, animated: animated) + title = viewModel.searchText } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) - viewModel.viewDidAppear.value = true + viewModel.stateMachine.enter(SearchResultViewModel.State.Initial.self) } - -} - -extension SearchResultViewController { - private func setupBackgroundColor(theme: Theme) { - view.backgroundColor = theme.systemGroupedBackgroundColor -// tableView.backgroundColor = theme.systemBackgroundColor -// searchHeader.backgroundColor = theme.systemGroupedBackgroundColor - } - } // MARK: - StatusTableViewCellDelegate diff --git a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+Diffable.swift b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+Diffable.swift index 225f79b02..5b74ba8aa 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+Diffable.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+Diffable.swift @@ -65,8 +65,7 @@ extension SearchResultViewModel { if let currentState = self.stateMachine.currentState { switch currentState { case is State.Loading, - is State.Fail, - is State.Idle: + is State.Fail: let attribute = SearchResultItem.BottomLoaderAttribute(isEmptyResult: false) snapshot.appendItems([.bottomLoader(attribute: attribute)], toSection: .main) case is State.NoMore: @@ -74,6 +73,9 @@ extension SearchResultViewModel { let attribute = SearchResultItem.BottomLoaderAttribute(isEmptyResult: true) snapshot.appendItems([.bottomLoader(attribute: attribute)], toSection: .main) } + case is State.Idle: + // do nothing + break default: break } diff --git a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+State.swift b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+State.swift index 47832e156..4858f0d2d 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+State.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+State.swift @@ -22,7 +22,7 @@ extension SearchResultViewModel { } @MainActor - func enter(state: State.Type) { + public func enter(state: State.Type) { stateMachine?.enter(state) } } @@ -31,24 +31,27 @@ extension SearchResultViewModel { extension SearchResultViewModel.State { class Initial: SearchResultViewModel.State { override func isValidNextState(_ stateClass: AnyClass) -> Bool { - guard let viewModel = viewModel else { return false } - return stateClass == Loading.self && !viewModel.searchText.value.isEmpty + return stateClass == Loading.self + } + + override func didEnter(from previousState: GKState?) { + super.didEnter(from: previousState) + + guard let viewModel else { return } + + viewModel.items = [.bottomLoader(attribute: .init(isEmptyResult: false))] } } class Loading: SearchResultViewModel.State { - var previousSearchText = "" var offset: Int? = nil var latestLoadingToken = UUID() override func isValidNextState(_ stateClass: AnyClass) -> Bool { - guard let viewModel = self.viewModel else { return false } switch stateClass { case is Fail.Type, is Idle.Type, is NoMore.Type: return true - case is Loading.Type: - return viewModel.searchText.value != previousSearchText default: return false } @@ -56,12 +59,11 @@ extension SearchResultViewModel.State { override func didEnter(from previousState: GKState?) { super.didEnter(from: previousState) - guard let viewModel = viewModel, let stateMachine = stateMachine else { return } + guard let viewModel, let stateMachine = stateMachine else { return } - let searchText = viewModel.searchText.value let searchType = viewModel.searchScope.searchType - if previousState is NoMore && previousSearchText == searchText { + if previousState is NoMore { // same searchText from NoMore // break the loading and resume NoMore state stateMachine.enter(NoMore.self) @@ -71,17 +73,12 @@ extension SearchResultViewModel.State { // viewModel.items.value = viewModel.items.value } - guard !searchText.isEmpty else { + guard viewModel.searchText.isEmpty == false else { stateMachine.enter(Fail.self) return } - if searchText != previousSearchText { - previousSearchText = searchText - offset = nil - } else { - offset = viewModel.items.count - } + offset = viewModel.items.count // not set offset for all case // and assert other cases the items are all the same type elements @@ -93,7 +90,7 @@ extension SearchResultViewModel.State { }() let query = Mastodon.API.V2.Search.Query( - q: searchText, + q: viewModel.searchText, type: searchType, accountID: nil, maxID: nil, @@ -115,8 +112,6 @@ extension SearchResultViewModel.State { authenticationBox: viewModel.authContext.mastodonAuthenticationBox ) - // discard result when search text is outdated - guard searchText == self.previousSearchText else { return } // discard result when request not the latest one guard id == self.latestLoadingToken else { return } // discard result when state is not Loading diff --git a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel.swift b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel.swift index 0c5c5868f..f66921535 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel.swift @@ -21,13 +21,12 @@ final class SearchResultViewModel { let context: AppContext let authContext: AuthContext let searchScope: SearchScope - let searchText = CurrentValueSubject("") + let searchText: String @Published var hashtags: [Mastodon.Entity.Tag] = [] let userFetchedResultsController: UserFetchedResultsController let statusFetchedResultsController: StatusFetchedResultsController let listBatchFetchViewModel = ListBatchFetchViewModel() - let viewDidAppear = CurrentValueSubject(false) var cellFrameCache = NSCache() var navigationBarFrame = CurrentValueSubject(.zero) @@ -43,15 +42,16 @@ final class SearchResultViewModel { State.Idle(viewModel: self), State.NoMore(viewModel: self), ]) - stateMachine.enter(State.Initial.self) return stateMachine }() let didDataSourceUpdate = PassthroughSubject() - init(context: AppContext, authContext: AuthContext, searchScope: SearchScope = .all) { + init(context: AppContext, authContext: AuthContext, searchScope: SearchScope = .all, searchText: String) { self.context = context self.authContext = authContext self.searchScope = searchScope + self.searchText = searchText + self.userFetchedResultsController = UserFetchedResultsController( managedObjectContext: context.managedObjectContext, domain: authContext.mastodonAuthenticationBox.domain, @@ -63,5 +63,4 @@ final class SearchResultViewModel { additionalTweetPredicate: nil ) } - } From a7a387dad5cf4c939990fafacd5d1e626dd1cabe Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 20 Sep 2023 18:56:34 +0200 Subject: [PATCH 71/87] Add a typealias for `NeedsDependency & UIViewController` (IOS-141) Well, okay, `ViewControllerWithDependencies` not super creative. --- Mastodon/Coordinator/NeedsDependency.swift | 2 ++ Mastodon/Protocol/Provider/DataSourceFacade+Hashtag.swift | 2 +- Mastodon/Protocol/Provider/DataSourceFacade+Profile.swift | 2 +- .../Protocol/Provider/DataSourceFacade+SearchHistory.swift | 2 +- Mastodon/Protocol/Provider/DataSourceFacade+Thread.swift | 4 ++-- Mastodon/Protocol/Provider/DataSourceProvider.swift | 2 +- 6 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Mastodon/Coordinator/NeedsDependency.swift b/Mastodon/Coordinator/NeedsDependency.swift index 46fbcd1ff..be22fc8cd 100644 --- a/Mastodon/Coordinator/NeedsDependency.swift +++ b/Mastodon/Coordinator/NeedsDependency.swift @@ -14,6 +14,8 @@ protocol NeedsDependency: AnyObject { var coordinator: SceneCoordinator! { get set } } +typealias ViewControllerWithDependencies = NeedsDependency & UIViewController + extension UISceneSession { private struct AssociatedKeys { static var sceneCoordinator = "SceneCoordinator" diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Hashtag.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Hashtag.swift index 9b0001351..2422adf6c 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Hashtag.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Hashtag.swift @@ -26,7 +26,7 @@ extension DataSourceFacade { @MainActor static func coordinateToHashtagScene( - provider: NeedsDependency & UIViewController & AuthContextProvider, + provider: ViewControllerWithDependencies & AuthContextProvider, tag: Mastodon.Entity.Tag ) async { let hashtagTimelineViewModel = HashtagTimelineViewModel( diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Profile.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Profile.swift index 219e7ddef..8f77a1888 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Profile.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Profile.swift @@ -33,7 +33,7 @@ extension DataSourceFacade { @MainActor static func coordinateToProfileScene( - provider: NeedsDependency & UIViewController & AuthContextProvider, + provider: ViewControllerWithDependencies & AuthContextProvider, user: ManagedObjectRecord ) async { guard let user = user.object(in: provider.context.managedObjectContext) else { diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+SearchHistory.swift b/Mastodon/Protocol/Provider/DataSourceFacade+SearchHistory.swift index 1193bb676..48d6b7f03 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+SearchHistory.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+SearchHistory.swift @@ -13,7 +13,7 @@ import UIKit extension DataSourceFacade { static func responseToCreateSearchHistory( - provider: NeedsDependency & UIViewController & AuthContextProvider, + provider: ViewControllerWithDependencies & AuthContextProvider, item: DataSourceItem ) async { switch item { diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Thread.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Thread.swift index e2431fc28..ad8d0e671 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Thread.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Thread.swift @@ -12,7 +12,7 @@ import MastodonCore extension DataSourceFacade { static func coordinateToStatusThreadScene( - provider: NeedsDependency & UIViewController & AuthContextProvider, + provider: ViewControllerWithDependencies & AuthContextProvider, target: StatusTarget, status: ManagedObjectRecord ) async { @@ -40,7 +40,7 @@ extension DataSourceFacade { @MainActor static func coordinateToStatusThreadScene( - provider: NeedsDependency & UIViewController & AuthContextProvider, + provider: ViewControllerWithDependencies & AuthContextProvider, root: StatusItem.Thread ) async { let threadViewModel = ThreadViewModel( diff --git a/Mastodon/Protocol/Provider/DataSourceProvider.swift b/Mastodon/Protocol/Provider/DataSourceProvider.swift index d7c86f56d..e4287b6b9 100644 --- a/Mastodon/Protocol/Provider/DataSourceProvider.swift +++ b/Mastodon/Protocol/Provider/DataSourceProvider.swift @@ -44,6 +44,6 @@ extension DataSourceItem { } } -protocol DataSourceProvider: NeedsDependency & UIViewController { +protocol DataSourceProvider: ViewControllerWithDependencies { func item(from source: DataSourceItem.Source) async -> DataSourceItem? } From 5a7ee4c9e64600344985ce165ed7a175c37235d9 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 20 Sep 2023 19:39:09 +0200 Subject: [PATCH 72/87] Add missing keys to the right app.json --- Localization/app.json | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/Localization/app.json b/Localization/app.json index b82bcb151..139f20347 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -651,19 +651,15 @@ } }, "searching": { - "posts": "Posts matching \"%@\"", - "people": "People matching \"%@\"", - "hashtag": "Go to #%@", + "posts": "Posts with \"%@\"", + "people": "People with \"%@\"", "profile": "Go to @%@@%@", "url": "Open Link", "empty_state": { "no_results": "No results" }, - "no_user": { - "title": "No User Account Found", - "message": "There's no Useraccount \"%@\" on %@" - } "recent_search": "Recent searches", + "clear_all": "Clear all", "clear": "Clear" } }, From 5370d005049ca4382c90c47d2b449161b7a0dcbf Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 20 Sep 2023 19:51:10 +0200 Subject: [PATCH 73/87] Fix app.json --- Localization/app.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Localization/app.json b/Localization/app.json index 139f20347..f54da1964 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -651,9 +651,9 @@ } }, "searching": { - "posts": "Posts with \"%@\"", - "people": "People with \"%@\"", - "profile": "Go to @%@@%@", + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", "url": "Open Link", "empty_state": { "no_results": "No results" From 5c71b7ef45f2f1b4a0daa74bdad5c5f3f93f1f18 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 20 Sep 2023 19:59:46 +0200 Subject: [PATCH 74/87] Search for everything when user taps "search" on keyboard (IOS-141) --- .../SearchResultsOverviewTableViewController.swift | 1 + .../Search/SearchDetail/SearchDetailViewController.swift | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift index db38027bc..ff6c8c621 100644 --- a/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/Search Results Overview/SearchResultsOverviewTableViewController.swift @@ -34,6 +34,7 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc self.coordinator = sceneCoordinator tableView = UITableView(frame: .zero, style: .insetGrouped) + tableView.keyboardDismissMode = .onDrag tableView.translatesAutoresizingMaskIntoConstraints = false tableView.backgroundColor = .systemGroupedBackground tableView.separatorInset.left = 62 diff --git a/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift b/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift index 82cb9795f..f61b47265 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchDetailViewController.swift @@ -265,7 +265,12 @@ extension SearchDetailViewController: UISearchBarDelegate { } func searchBarSearchButtonClicked(_ searchBar: UISearchBar) { + guard let searchText = searchBar.text, searchText.isNotEmpty else { return } + searchBar.resignFirstResponder() + + let searchResultViewModel = SearchResultViewModel(context: context, authContext: viewModel.authContext, searchScope: .all, searchText: searchText) + coordinator.present(scene: .searchResult(viewModel: searchResultViewModel), transition: .show) } func searchBarCancelButtonClicked(_ searchBar: UISearchBar) { From a2990d54e204fea2f4a2c7b2daff2b9827050cf3 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 20 Sep 2023 20:09:42 +0200 Subject: [PATCH 75/87] Calculate offset without loader-cell (IOS-141) Sorry, Stephen Fry! It wasn't anything personal --- .../SearchResult/SearchResultViewModel+State.swift | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+State.swift b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+State.swift index 4858f0d2d..e332b13d9 100644 --- a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+State.swift +++ b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+State.swift @@ -78,7 +78,13 @@ extension SearchResultViewModel.State { return } - offset = viewModel.items.count + offset = viewModel.items.filter({ item in + if case .bottomLoader(_) = item { + return false + } else { + return true + } + }).count // not set offset for all case // and assert other cases the items are all the same type elements From 92ca2a006c974e55f64ff15711cd6656230c3509 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 20 Sep 2023 21:04:49 +0200 Subject: [PATCH 76/87] Fix colors for hashtag-follow-button --- Mastodon.xcodeproj/project.pbxproj | 4 -- .../HashtagTimelineHeaderView.swift | 29 +++++++----- ...ashtagTimelineHeaderViewActionButton.swift | 47 ------------------- 3 files changed, 18 insertions(+), 62 deletions(-) delete mode 100644 Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderViewActionButton.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 20af38cce..26b20f229 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -44,7 +44,6 @@ 2A72812E297EA9D8004138C5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2A72812D297EA9D8004138C5 /* Assets.xcassets */; }; 2A728134297EA9D8004138C5 /* WidgetExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 2A728120297EA9D7004138C5 /* WidgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 2A72813F297EC762004138C5 /* WidgetExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A72813E297EC762004138C5 /* WidgetExtension.swift */; }; - 2A76F75C2930D94700B3388D /* HashtagTimelineHeaderViewActionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A76F75B2930D94700B3388D /* HashtagTimelineHeaderViewActionButton.swift */; }; 2A82294F29262EE000D2A1F7 /* AppContext+NextAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A82294E29262EE000D2A1F7 /* AppContext+NextAccount.swift */; }; 2A86A14629892944007F1062 /* MultiFollowersCountIntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A86A14529892944007F1062 /* MultiFollowersCountIntentHandler.swift */; }; 2A86A14929892B3A007F1062 /* MultiFollowersCountWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A86A14829892B3A007F1062 /* MultiFollowersCountWidget.swift */; }; @@ -639,7 +638,6 @@ 2A72812D297EA9D8004138C5 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 2A72812F297EA9D8004138C5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 2A72813E297EC762004138C5 /* WidgetExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetExtension.swift; sourceTree = ""; }; - 2A76F75B2930D94700B3388D /* HashtagTimelineHeaderViewActionButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashtagTimelineHeaderViewActionButton.swift; sourceTree = ""; }; 2A82294E29262EE000D2A1F7 /* AppContext+NextAccount.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppContext+NextAccount.swift"; sourceTree = ""; }; 2A86A14529892944007F1062 /* MultiFollowersCountIntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiFollowersCountIntentHandler.swift; sourceTree = ""; }; 2A86A14829892B3A007F1062 /* MultiFollowersCountWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiFollowersCountWidget.swift; sourceTree = ""; }; @@ -1323,7 +1321,6 @@ 0F20220626134DA4000C64BF /* HashtagTimelineViewModel+Diffable.swift */, 0F20222C261457EE000C64BF /* HashtagTimelineViewModel+State.swift */, 2A506CF5292D040100059C37 /* HashtagTimelineHeaderView.swift */, - 2A76F75B2930D94700B3388D /* HashtagTimelineHeaderViewActionButton.swift */, ); path = HashtagTimeline; sourceTree = ""; @@ -3881,7 +3878,6 @@ DBCC3B30261440A50045B23D /* UITabBarController.swift in Sources */, DB3E6FE42806A5B800B035AE /* DiscoverySection.swift in Sources */, DB8190C62601FF0400020C08 /* AttachmentContainerView.swift in Sources */, - 2A76F75C2930D94700B3388D /* HashtagTimelineHeaderViewActionButton.swift in Sources */, DB697DDB278F4DE3004EF2F7 /* DataSourceProvider+StatusTableViewCellDelegate.swift in Sources */, DB87D4512609CF1E00D12C0D /* ComposeStatusPollOptionAppendEntryCollectionViewCell.swift in Sources */, DBB45B5627B39FC9002DC5A7 /* MediaPreviewVideoViewController.swift in Sources */, diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift index 3af2cf07b..96bc4ed13 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderView.swift @@ -69,10 +69,13 @@ final class HashtagTimelineHeaderView: UIView { var onButtonTapped: (() -> Void)? let followButton: UIButton = { - let button = HashtagTimelineHeaderViewActionButton() - button.cornerRadius = 10 - button.contentEdgeInsets = UIEdgeInsets(top: 6, left: 16, bottom: 5, right: 16) // set 28pt height - button.titleLabel?.font = .systemFont(ofSize: 14, weight: .bold) + let button = UIButton(configuration: .tinted()) + button.configuration?.background.cornerRadius = 10 + button.configuration?.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer({ incoming in + var outgoing = incoming + outgoing.font = UIFontMetrics(forTextStyle: .subheadline).scaledFont(for: .boldSystemFont(ofSize: 15)) + return outgoing + }) return button }() @@ -153,14 +156,18 @@ private extension HashtagTimelineHeaderView { extension HashtagTimelineHeaderView { func update(_ entity: HashtagTimelineHeaderView.Data) { titleLabel.text = "#\(entity.name)" - followButton.setTitle(entity.following == true ? L10n.Scene.FollowedTags.Actions.unfollow : L10n.Scene.FollowedTags.Actions.follow, for: .normal) - followButton.backgroundColor = entity.following == true ? Asset.Colors.Button.tagUnfollow.color : Asset.Colors.Button.tagFollow.color - - followButton.setTitleColor( - entity.following == true ? Asset.Colors.Button.tagFollow.color : Asset.Colors.Button.tagUnfollow.color, - for: .normal - ) + if entity.following { + followButton.configuration?.background.backgroundColor = Asset.Colors.Button.userFollowing.color + followButton.configuration?.baseForegroundColor = Asset.Colors.Button.userFollowingTitle.color + followButton.configuration?.title = L10n.Scene.FollowedTags.Actions.unfollow + } else { + followButton.configuration?.background.backgroundColor = Asset.Colors.Button.userFollow.color + followButton.configuration?.baseForegroundColor = .white + followButton.configuration?.title = L10n.Scene.FollowedTags.Actions.follow + } + + followButton.configuration?.contentInsets = NSDirectionalEdgeInsets(top: 6, leading: 16, bottom: 5, trailing: 16) postCountLabel.text = String(entity.postCount) participantsLabel.text = String(entity.participantsCount) diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderViewActionButton.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderViewActionButton.swift deleted file mode 100644 index 7efeb15d0..000000000 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineHeaderViewActionButton.swift +++ /dev/null @@ -1,47 +0,0 @@ -// -// HashtagTimelineHeaderViewActionButton.swift -// Mastodon -// -// Created by Marcus Kida on 25.11.22. -// - -import UIKit -import MastodonUI -import MastodonAsset - -class HashtagTimelineHeaderViewActionButton: RoundedEdgesButton { - - init() { - super.init(frame: .zero) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - public override func layoutSubviews() { - super.layoutSubviews() - - let shadowColor: UIColor = { - switch traitCollection.userInterfaceStyle { - case .dark: - return .darkGray - default: - return .lightGray - } - }() - - layer.setupShadow( - color: shadowColor, - alpha: 1, - x: 0, - y: 1, - blur: 2, - spread: 0, - roundedRect: bounds, - byRoundingCorners: .allCorners, - cornerRadii: CGSize(width: cornerRadius, height: cornerRadius) - ) - } -} - From 08e71fbcda54f3e7b065be86be6854775c5160e2 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 20 Sep 2023 22:00:23 +0200 Subject: [PATCH 77/87] Fix app.jsons (again) --- Localization/StringsConvertor/input/Base.lproj/app.json | 9 +++++---- Localization/app.json | 3 ++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index 139f20347..d50363d05 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -651,10 +651,11 @@ } }, "searching": { - "posts": "Posts with \"%@\"", - "people": "People with \"%@\"", - "profile": "Go to @%@@%@", - "url": "Open Link", + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "No results" }, diff --git a/Localization/app.json b/Localization/app.json index f54da1964..d50363d05 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -654,7 +654,8 @@ "posts": "Posts with \"%s\"", "people": "People with \"%s\"", "profile": "Go to @%s@%s", - "url": "Open Link", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "No results" }, From 3d1634dcfbdb0c8fe7bc7f9b92abe4b64b37f7be Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 20 Sep 2023 22:48:22 +0200 Subject: [PATCH 78/87] New Crowdin updates (#1114) --- .../Intents/input/ar.lproj/Intents.strings | 4 +- .../StringsConvertor/input/an.lproj/app.json | 12 +- .../StringsConvertor/input/ar.lproj/app.json | 190 +++++++++--------- .../StringsConvertor/input/be.lproj/app.json | 12 +- .../StringsConvertor/input/ca.lproj/app.json | 26 +-- .../StringsConvertor/input/ckb.lproj/app.json | 12 +- .../StringsConvertor/input/cs.lproj/app.json | 12 +- .../StringsConvertor/input/cy.lproj/app.json | 12 +- .../StringsConvertor/input/da.lproj/app.json | 12 +- .../StringsConvertor/input/de.lproj/app.json | 12 +- .../StringsConvertor/input/el.lproj/app.json | 12 +- .../input/en-US.lproj/app.json | 12 +- .../StringsConvertor/input/en.lproj/app.json | 12 +- .../input/es-AR.lproj/app.json | 12 +- .../StringsConvertor/input/es.lproj/app.json | 12 +- .../StringsConvertor/input/eu.lproj/app.json | 12 +- .../StringsConvertor/input/fi.lproj/app.json | 12 +- .../input/fr.lproj/Localizable.stringsdict | 2 +- .../StringsConvertor/input/fr.lproj/app.json | 60 +++--- .../StringsConvertor/input/gd.lproj/app.json | 12 +- .../StringsConvertor/input/gl.lproj/app.json | 12 +- .../StringsConvertor/input/he.lproj/app.json | 12 +- .../StringsConvertor/input/hi.lproj/app.json | 12 +- .../StringsConvertor/input/id.lproj/app.json | 12 +- .../StringsConvertor/input/is.lproj/app.json | 12 +- .../StringsConvertor/input/it.lproj/app.json | 12 +- .../StringsConvertor/input/ja.lproj/app.json | 12 +- .../StringsConvertor/input/kab.lproj/app.json | 12 +- .../StringsConvertor/input/kmr.lproj/app.json | 12 +- .../StringsConvertor/input/ko.lproj/app.json | 12 +- .../StringsConvertor/input/lv.lproj/app.json | 12 +- .../StringsConvertor/input/my.lproj/app.json | 12 +- .../StringsConvertor/input/nl.lproj/app.json | 12 +- .../StringsConvertor/input/pl.lproj/app.json | 12 +- .../input/pt-BR.lproj/app.json | 12 +- .../StringsConvertor/input/pt.lproj/app.json | 12 +- .../StringsConvertor/input/ro.lproj/app.json | 12 +- .../StringsConvertor/input/ru.lproj/app.json | 12 +- .../StringsConvertor/input/si.lproj/app.json | 12 +- .../StringsConvertor/input/sl.lproj/app.json | 12 +- .../input/sv.lproj/Localizable.stringsdict | 4 +- .../StringsConvertor/input/sv.lproj/app.json | 16 +- .../StringsConvertor/input/th.lproj/app.json | 12 +- .../StringsConvertor/input/tr.lproj/app.json | 18 +- .../StringsConvertor/input/uk.lproj/app.json | 12 +- .../StringsConvertor/input/vi.lproj/app.json | 12 +- .../input/zh-Hans.lproj/app.json | 28 +-- .../input/zh-Hant.lproj/app.json | 12 +- 48 files changed, 408 insertions(+), 408 deletions(-) diff --git a/Localization/StringsConvertor/Intents/input/ar.lproj/Intents.strings b/Localization/StringsConvertor/Intents/input/ar.lproj/Intents.strings index 49183a431..2a1a604c7 100644 --- a/Localization/StringsConvertor/Intents/input/ar.lproj/Intents.strings +++ b/Localization/StringsConvertor/Intents/input/ar.lproj/Intents.strings @@ -1,4 +1,4 @@ -"16wxgf" = "النَّشرُ عَلَى مَاستودُون"; +"16wxgf" = "النَّشرُ عَلَى ماستدون"; "751xkl" = "محتوى نصي"; @@ -32,7 +32,7 @@ "ayoYEb-ehFLjY" = "${content}، المُتابِعُون فقط"; -"dUyuGg" = "النَّشرُ عَلَى مَاستودُون"; +"dUyuGg" = "النَّشرُ عَلَى ماستدون"; "dYQ5NN" = "لِلعَامَّة"; diff --git a/Localization/StringsConvertor/input/an.lproj/app.json b/Localization/StringsConvertor/input/an.lproj/app.json index 91d7d7631..b5177e4ca 100644 --- a/Localization/StringsConvertor/input/an.lproj/app.json +++ b/Localization/StringsConvertor/input/an.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Tot", - "people": "Chent", - "hashtags": "Etiquetas", - "posts": "Publicacions" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "Sin resultaus" }, "recent_search": "Busquedas recients", + "clear_all": "Clear all", "clear": "Borrar" } }, diff --git a/Localization/StringsConvertor/input/ar.lproj/app.json b/Localization/StringsConvertor/input/ar.lproj/app.json index a5992d018..c2ca137fc 100644 --- a/Localization/StringsConvertor/input/ar.lproj/app.json +++ b/Localization/StringsConvertor/input/ar.lproj/app.json @@ -50,7 +50,7 @@ }, "translation_failed": { "title": "مُلاحظة", - "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "message": "فشلت الترجمة. ربما لم يتمكن مدير الخادم من تفعيل الترجمات على هذا الخادم أو هذا الخادم يقوم بتشغيل نسخة قديمة من ماستدون حيث الترجمات غير مدعومة بعد.", "button": "حسنًا" } }, @@ -97,11 +97,11 @@ "title": "الترجَمَة مِن %s", "unknown_language": "غير مَعرُوفة" }, - "edit_post": "Edit", - "bookmark": "Bookmark", - "remove_bookmark": "Remove Bookmark", - "follow": "Follow %s", - "unfollow": "Unfollow %s" + "edit_post": "تعديل", + "bookmark": "إضافة إلى الفواصل المرجعية", + "remove_bookmark": "إزالة الفاصلة المرجعية", + "follow": "متابعة %s", + "unfollow": "ألغِ متابعة %s" }, "tabs": { "home": "الرَّئِيسَة", @@ -109,8 +109,8 @@ "notifications": "الإشعارات", "profile": "المِلَفُّ التَّعريفِيّ", "a11y": { - "search": "Search", - "explore": "Explore" + "search": "البحث", + "explore": "استكشف" } }, "keyboard": { @@ -147,7 +147,7 @@ "media_content_warning": "اُنقُر لِلكَشف", "tap_to_reveal": "اُنقُر لِلكَشف", "load_embed": "تحميل المُضمَن", - "link_via_user": "%s via %s", + "link_via_user": "%s عبر %s", "poll": { "vote": "صَوِّت", "closed": "انتهى" @@ -172,8 +172,8 @@ "share_link_in_post": "مُشارَكَة الرابِط فِي مَنشور", "tap_then_hold_to_show_menu": "اُنقُر مُطَوَّلًا لِإظْهَارِ القائِمَة", "a11y_labels": { - "reblog": "Re-blog", - "unreblog": "Undo re-blog" + "reblog": "إعادة التدوين", + "unreblog": "التراجع عن إعادة التدوين" } }, "tag": { @@ -194,25 +194,25 @@ "translated_from": "الترجَمَة مِن %s بِاستِخدَام %s", "unknown_language": "غير مَعرُوفة", "unknown_provider": "غير مَعرُوف", - "show_original": "Show Original" + "show_original": "إظهار الأصل" }, "media": { - "accessibility_label": "%s, attachment %d of %d", + "accessibility_label": "%s، مرفق %d من %d", "expand_image_hint": "Expands the image. Double-tap and hold to show actions", "expand_gif_hint": "Expands the GIF. Double-tap and hold to show actions", "expand_video_hint": "Shows the video player. Double-tap and hold to show actions" }, - "posted_via_application": "%s via %s", + "posted_via_application": "%s عبر %s", "buttons": { - "reblogs_title": "Reblogs", - "favorites_title": "Favorites", - "edit_history_title": "Edit History", - "edit_history_detail": "Last edit %s" + "reblogs_title": "المعاد تدوينها", + "favorites_title": "المفضلة", + "edit_history_title": "سِجِلّ التعديلات", + "edit_history_detail": "آخر تعديل %s" }, - "edited_at_timestamp_prefix": "Edited %s", + "edited_at_timestamp_prefix": "عُدّل في %s", "edit_history": { - "title": "Edit History", - "original_post": "Original Post · %s" + "title": "سِجِلّ التعديلات", + "original_post": "المنشور الأصلي · %s" } }, "friendship": { @@ -257,47 +257,47 @@ } }, "user_list": { - "no_verified_link": "No verified link", - "followers_count": "%@ followers" + "no_verified_link": "رابط غير متحقق منه", + "followers_count": "%@ متابعين" } }, "scene": { "welcome": { "log_in": "تسجيلُ الدخول", - "learn_more": "Learn more", - "join_default_server": "Join %@", - "pick_server": "Pick another server", + "learn_more": "تعلم المزيد", + "join_default_server": "انضم إلى %@", + "pick_server": "اختر خادمًا آخر", "separator": { - "or": "or" + "or": "أو" }, "education": { "mastodon": { - "title": "Welcome to Mastodon", - "description": "Mastodon is a decentralized social network, meaning no single company controls it. It’s made up of many independently-run servers, all connected together." + "title": "أهلًا بك على ماستدون", + "description": "ماستدون شبكة اجتماعية لامركزية، بمعنى أنه ليس هناك شركة واحدة تتحكم فيها. وهي تتألف من العديد من الخوادم التي تدار بشكل مستقل، وجميعها متصلة معا." }, "servers": { - "title": "What are servers?", - "description": "Every Mastodon account is hosted on a server — each with its own values, rules, & admins. No matter which one you pick, you can follow and interact with people on any server." + "title": "ما هي الخوادم؟", + "description": "تتم استضافة كل حساب ماستدون على خادم - ولكل منها قيمه وقواعده ومسؤوليه الخاصين. بغض النظر عن الشخص الذي تختاره ، يمكنك متابعة الأشخاص والتفاعل معهم على أي خادم." }, "a11y": { "what_is_mastodon": { - "title": "What is Mastodon?" + "title": "ما هو ماستدون؟" } } } }, "login": { - "title": "Welcome back", + "title": "مرحباً بك مجددًا", "subtitle": "سَجِّل دُخولَكَ إلى الخادِم الَّذي أنشأتَ حِسابَكَ فيه.", "server_search_field": { "placeholder": "أدخِل عُنوانَ URL أو اِبحَث عَنِ الخادِمِ الخاصّ بِك" } }, "server_picker": { - "title": "Pick Server", + "title": "اختر خادمًا", "button": { - "language": "Language", - "signup_speed": "Sign-up Speed", + "language": "اللغة", + "signup_speed": "سرعة التسجيل", "category": { "all": "الكُل", "all_accessiblity_description": "الفِئَة: الكُل", @@ -331,31 +331,31 @@ "no_results": "لا توجد نتائج" }, "signup_speed": { - "all": "All", - "instant": "Instant Sign-up", - "manually_reviewed": "Manual Review" + "all": "الكل", + "instant": "تسجيل فوري", + "manually_reviewed": "مراجعة يدوية" }, "language": { - "all": "All" + "all": "الكل" }, "search": { - "placeholder": "Search name or URL" + "placeholder": "البحث عن اسم أو رابط تشعّبي URL" }, - "no_server_selected_hint": "We’ll pick a server based on your language if you continue without making a selection." + "no_server_selected_hint": "سوف نختار خادماً بناءً على لغتك إذا قمت بالمتابعة دون إجراء إختيار." }, "privacy": { - "title": "Privacy", - "description": "Although the Mastodon app does not collect any data, the server you sign up through may have a different policy. Take a minute to review and agree to the Mastodon app privacy policy and your server’s privacy policy.", + "title": "الخصوصية", + "description": "على الرغم من أن تطبيق ماستدون لا يجمع أي بيانات، فإن الخادم الذي قمت بالتسجيل من خلاله قد تكون له سياسة مختلفة. خذ دقيقة للمراجعة والموافقة على سياسة خصوصية تطبيق ماستدون وسياسة الخصوصية الخاصة بخادمك.", "policy": { - "ios": "Privacy Policy - Mastodon for iOS", - "server": "Privacy Policy - %s" + "ios": "سياسة الخصوصية - ماستدون لنظام التشغيل iOS", + "server": "سياسة الخصوصية - %s" }, "button": { - "confirm": "I Agree" + "confirm": "أوافق" } }, "register": { - "title": "Create Account", + "title": "إنشاء حساب", "input": { "avatar": { "delete": "حذف" @@ -363,7 +363,7 @@ "username": { "placeholder": "اِسمُ مُستَخدِم", "duplicate_prompt": "اِسم المُستَخدِم هذا مأخوذٌ بالفعل.", - "suggestion": "amazing_%@" + "suggestion": "مذهل_%@" }, "display_name": { "placeholder": "اِسمُ عَرض" @@ -373,7 +373,7 @@ }, "password": { "placeholder": "رمز سري", - "confirmation_placeholder": "Confirm Password", + "confirmation_placeholder": "أكّد كلمة السر", "require": "رمز المرور الخاص بك يجب أن يحتوي على الأقل:", "character_limit": "ثمانيةُ خانات", "accessibility": { @@ -398,7 +398,7 @@ "reason": { "blocked": "يحتوي %s على موفِّر خدمة بريد إلكتروني غير مسموح به", "unreachable": "يبدوا أنَّ %s غير موجود", - "taken": "%s is already taken. How about:", + "taken": "%s مأخوذ بالفعل. ماذا عن:", "reserved": "إنَّ %s عبارة عن كلمة مفتاحيَّة محجوزة", "accepted": "يجب أن يُقبل %s", "blank": "%s مَطلوب", @@ -422,30 +422,30 @@ "terms_of_service": "شُرُوط الخِدمَة", "privacy_policy": "سِياسَة الخُصُوصيَّة", "button": { - "confirm": "I Agree" + "confirm": "أوافق" } }, "confirm_email": { - "title": "Check Your Inbox", - "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we sent you to verify %@. We’ll wait right here.", + "title": "تحقَّق من بريدك الوارِد", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "اضغط على الرابط الذي أرسلناه إليك للتحقق من %@. سننتظر هنا.", "button": { "resend": "إعادَةُ الإرسال" }, "dont_receive_email": { - "title": "Check your Email", + "title": "تحقق من بريدك الإلكتروني", "description": "تحقق ممَّ إذا كان عنوان بريدك الإلكتروني صحيحًا، وكذلك تأكد مِن مجلد البريد غير الهام إذا لم تكن قد فعلت ذلك.", "resend_email": "إعادة إرسال البريد الإلكتروني" }, "open_email_app": { - "title": "Check your Inbox.", + "title": "تحقَّق من بريدك الوارِد.", "description": "لقد أرسلنا لك بريدًا إلكترونيًا للتو. تحقق من مجلد البريد غير الهام الخاص بك إذا لم تكن قد فعلت ذلك.", "mail": "البريد", "open_email_client": "فتح عميل البريد الإلكتروني" }, "didnt_get_link": { - "prefix": "Didn’t get a link?", - "resend_in": "Resend (%@)", - "resend_now": "Resend now." + "prefix": "ألم تحصل على رابط؟", + "resend_in": "إعادة إرسال (%@)", + "resend_now": "أعد الإرسال الآن." } }, "home_timeline": { @@ -456,20 +456,20 @@ "published": "تمَّ النَّشر!", "Publishing": "يَجري نَشر المُشارَكَة...", "accessibility": { - "logo_label": "Mastodon", + "logo_label": "ماستدون", "logo_hint": "اُنقُر لِلتمريرِ لأعلى واُنقُر مَرّةً أُخرَى لِلذَّهابِ إلَى المَوقِعِ السَّابِق" } } }, "suggestion_account": { - "title": "Popular on Mastodon", - "follow_all": "Follow all" + "title": "رائج على ماستدون", + "follow_all": "اتبع الكل" }, "compose": { "title": { "new_post": "مَنشُورٌ جَديد", "new_reply": "رَدٌّ جديد", - "edit_post": "Edit Post" + "edit_post": "تعديل المنشور" }, "media_selection": { "camera": "اِلتِقاطُ صُورَة", @@ -493,7 +493,7 @@ "server_processing_state": "مُعالجة الخادم جارِيَة..." }, "poll": { - "title": "Poll", + "title": "استطلاع رأي", "duration_time": "المُدَّة: %s", "thirty_minutes": "ثلاثون دقيقة", "one_hour": "ساعةٌ واحدة", @@ -504,10 +504,10 @@ "option_number": "الخيار %ld", "the_poll_is_invalid": "الاِستِطلاعُ غيرُ صالِح", "the_poll_has_empty_option": "يوجَدُ خِيارٌ فارِغٌ فِي الاِستِطلاع", - "add_option": "Add Option", - "remove_option": "Remove Option", - "move_up": "Move Up", - "move_down": "Move Down" + "add_option": "إضافة خيار", + "remove_option": "إزالة الخيار", + "move_up": "أنقله إلى أعلى", + "move_down": "أنقله إلى أسفل" }, "content_warning": { "placeholder": "اكتب تَحذيرًا دَقيقًا هُنا..." @@ -541,10 +541,10 @@ "select_visibility_entry": "اختر مدى الظهور - %s" }, "language": { - "title": "Post Language", - "suggested": "Suggested", - "recent": "Recent", - "other": "Other Language…" + "title": "لغة النشر", + "suggested": "المقترحَة", + "recent": "الأخيرة", + "other": "لغات أخرى…" } }, "profile": { @@ -558,10 +558,10 @@ "other_posts": "مَنشورات", "other_following": "مُتابَعُون", "other_followers": "مُتابِعُون", - "familiar_followers": "mutuals" + "familiar_followers": "متابعة متبادلة" }, "fields": { - "joined": "Joined", + "joined": "انضم في", "add_row": "إضافة صف", "placeholder": { "label": "التسمية", @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "الكُل", - "people": "أشخاص", - "hashtags": "وُسُوم", - "posts": "مَنشُورات" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "لا تُوجَدُ نتائِج" }, "recent_search": "عَمَليَّاُت البَحثِ الأخيرَة", + "clear_all": "Clear all", "clear": "مَحو" } }, @@ -674,7 +674,7 @@ "intro": "هَذِهِ هِيَ المَنشُوراتُ الَّتي تَكْتَسِبُ شَعبِيَّةً فِي الرُّكنِ الخاصِّ بِكَ مِن مَاستُودون." }, "favorite": { - "title": "Favorites" + "title": "المفضلة" }, "notification": { "title": { @@ -739,7 +739,7 @@ "disable_avatar_animation": "تَعطيلُ الصوَرِ الرمزيَّةِ المُتحرِّكَة", "disable_emoji_animation": "تَعطيلُ الرُموزِ التَّعبيريَّةِ المُتحرِّكَة", "using_default_browser": "اِستِخدامُ المُتصفِّحِ الاِفتراضي لِفتحِ الرَّوابِط", - "open_links_in_mastodon": "فَتحُ الرَّوابِطِ فِي مَاستودُون" + "open_links_in_mastodon": "فَتحُ الرَّوابِطِ فِي مَاستدون" }, "boring_zone": { "title": "المنطِقَةُ المُملَّة", @@ -845,37 +845,37 @@ }, "extension": { "open_in": { - "invalid_link_error": "This doesn't seem to be a valid Mastodon link." + "invalid_link_error": "لا يبدو أن هذا رابط ماستدون صالح." } }, "widget": { "common": { "unsupported_widget_family": "Sorry but this Widget family is unsupported.", - "user_not_logged_in": "Please open Mastodon to log in to an Account." + "user_not_logged_in": "الرجاء فتح ماستدون لتسجيل الدخول إلى حساب." }, "followers_count": { - "configuration_display_name": "Followers", - "configuration_description": "Show number of followers.", - "title": "FOLLOWERS", + "configuration_display_name": "المتابِعون", + "configuration_description": "إظهار عدد المتابعين.", + "title": "المتابِعون", "followers_today": "%s followers today" }, "multiple_followers": { - "configuration_display_name": "Multiple followers", - "configuration_description": "Show number of followers for multiple accounts.", + "configuration_display_name": "متابعين متعددين", + "configuration_description": "إظهار عدد المتابعين لحسابات متعددة.", "mock_user": { - "display_name": "Another follower", + "display_name": "متابع آخر", "account_name": "another@follower.social" } }, "latest_followers": { - "configuration_display_name": "Latest followers", - "configuration_description": "Show latest followers.", - "title": "Latest followers", - "last_update": "Last update: %s" + "configuration_display_name": "أحدث المتابعين", + "configuration_description": "إظهار أحدث المتابِعين.", + "title": "أحدث المتابعين", + "last_update": "آخر تحديث: %s" }, "hashtag": { "configuration": { - "display_name": "Hashtag", + "display_name": "وسم", "description": "Shows a recent post with the selected hashtag." }, "not_found": { diff --git a/Localization/StringsConvertor/input/be.lproj/app.json b/Localization/StringsConvertor/input/be.lproj/app.json index 54e80198d..8a026fd8d 100644 --- a/Localization/StringsConvertor/input/be.lproj/app.json +++ b/Localization/StringsConvertor/input/be.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Усе", - "people": "Людзі", - "hashtags": "Хэштэгі", - "posts": "Допісы" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "Няма вынікаў" }, "recent_search": "Нядаўнія запыты", + "clear_all": "Clear all", "clear": "Ачысціць" } }, diff --git a/Localization/StringsConvertor/input/ca.lproj/app.json b/Localization/StringsConvertor/input/ca.lproj/app.json index d63c685f3..fa3a2e54a 100644 --- a/Localization/StringsConvertor/input/ca.lproj/app.json +++ b/Localization/StringsConvertor/input/ca.lproj/app.json @@ -45,8 +45,8 @@ "message": "Segur que vols eliminar aquesta publicació?" }, "clean_cache": { - "title": "Neteja la memòria cau", - "message": "S'ha netejat correctament la memòria cau de %s." + "title": "Esborra la memòria cau", + "message": "S'han esborrat %s de memòria cau." }, "translation_failed": { "title": "Nota", @@ -85,21 +85,21 @@ "open_in_safari": "Obrir a Safari", "open_in_browser": "Obre al navegador", "find_people": "Busca persones a seguir", - "manually_search": "Cerca manualment a canvi", + "manually_search": "Millor cerca manualment", "skip": "Omet", "reply": "Respon", - "report_user": "Informa sobre %s", - "block_domain": "Bloqueja %s", + "report_user": "Denuncia %s", + "block_domain": "Bloca %s", "unblock_domain": "Desbloca %s", "settings": "Configuració", "delete": "Suprimeix", "translate_post": { - "title": "Traduït del %s", + "title": "Tradueix del: %s", "unknown_language": "Desconegut" }, "edit_post": "Edita", "bookmark": "Marcador", - "remove_bookmark": "Suprimeix el marcador", + "remove_bookmark": "Elimina el marcador", "follow": "Segueix a %s", "unfollow": "Deixa de seguir %s" }, @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Tots", - "people": "Gent", - "hashtags": "Etiquetes", - "posts": "Tuts" - }, + "posts": "Tuts amb \"%s\"", + "people": "Gent amb \"%s\"", + "profile": "Ves a @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "No hi ha resultats" }, "recent_search": "Cerques recents", + "clear_all": "Esborra-ho tot", "clear": "Neteja" } }, diff --git a/Localization/StringsConvertor/input/ckb.lproj/app.json b/Localization/StringsConvertor/input/ckb.lproj/app.json index c670a81e8..1105dd153 100644 --- a/Localization/StringsConvertor/input/ckb.lproj/app.json +++ b/Localization/StringsConvertor/input/ckb.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "هەمووی", - "people": "خەڵک", - "hashtags": "هاشتاگ", - "posts": "پۆست" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "هیچ ئەنجامێک نەدۆزرایەوە" }, "recent_search": "گەڕانەکانی پێشترت", + "clear_all": "Clear all", "clear": "بیانسڕەوە" } }, diff --git a/Localization/StringsConvertor/input/cs.lproj/app.json b/Localization/StringsConvertor/input/cs.lproj/app.json index 9e806ef3b..093d3767d 100644 --- a/Localization/StringsConvertor/input/cs.lproj/app.json +++ b/Localization/StringsConvertor/input/cs.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Vše", - "people": "Lidé", - "hashtags": "Hashtagy", - "posts": "Příspěvky" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "Žádné výsledky" }, "recent_search": "Nedávná hledání", + "clear_all": "Clear all", "clear": "Vymazat" } }, diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json index 1de450cd3..cf0360326 100644 --- a/Localization/StringsConvertor/input/cy.lproj/app.json +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Popeth", - "people": "Pobl", - "hashtags": "Hashnodau", - "posts": "Postiadau" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "Dim canlyniadau" }, "recent_search": "Chwiliadau diweddar", + "clear_all": "Clear all", "clear": "Clirio" } }, diff --git a/Localization/StringsConvertor/input/da.lproj/app.json b/Localization/StringsConvertor/input/da.lproj/app.json index 486b96b5e..afe820815 100644 --- a/Localization/StringsConvertor/input/da.lproj/app.json +++ b/Localization/StringsConvertor/input/da.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "All", - "people": "People", - "hashtags": "Hashtags", - "posts": "Posts" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "No results" }, "recent_search": "Recent searches", + "clear_all": "Clear all", "clear": "Clear" } }, diff --git a/Localization/StringsConvertor/input/de.lproj/app.json b/Localization/StringsConvertor/input/de.lproj/app.json index 89f071571..2d182fcf5 100644 --- a/Localization/StringsConvertor/input/de.lproj/app.json +++ b/Localization/StringsConvertor/input/de.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Alles", - "people": "Personen", - "hashtags": "Hashtags", - "posts": "Beiträge" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "Keine Ergebnisse" }, "recent_search": "Zuletzt gesucht", + "clear_all": "Clear all", "clear": "Zurücksetzen" } }, diff --git a/Localization/StringsConvertor/input/el.lproj/app.json b/Localization/StringsConvertor/input/el.lproj/app.json index f87dbec4c..5936d46d8 100644 --- a/Localization/StringsConvertor/input/el.lproj/app.json +++ b/Localization/StringsConvertor/input/el.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Όλα", - "people": "Άτομα", - "hashtags": "Ετικέτες", - "posts": "Αναρτήσεις" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "Κανένα αποτέλεσμα" }, "recent_search": "Πρόσφατες αναζητήσεις", + "clear_all": "Clear all", "clear": "Εκκαθάριση" } }, diff --git a/Localization/StringsConvertor/input/en-US.lproj/app.json b/Localization/StringsConvertor/input/en-US.lproj/app.json index 74eaa7634..7f371067b 100644 --- a/Localization/StringsConvertor/input/en-US.lproj/app.json +++ b/Localization/StringsConvertor/input/en-US.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "All", - "people": "People", - "hashtags": "Hashtags", - "posts": "Posts" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "No results" }, "recent_search": "Recent searches", + "clear_all": "Clear all", "clear": "Clear" } }, diff --git a/Localization/StringsConvertor/input/en.lproj/app.json b/Localization/StringsConvertor/input/en.lproj/app.json index 74eaa7634..7f371067b 100644 --- a/Localization/StringsConvertor/input/en.lproj/app.json +++ b/Localization/StringsConvertor/input/en.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "All", - "people": "People", - "hashtags": "Hashtags", - "posts": "Posts" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "No results" }, "recent_search": "Recent searches", + "clear_all": "Clear all", "clear": "Clear" } }, diff --git a/Localization/StringsConvertor/input/es-AR.lproj/app.json b/Localization/StringsConvertor/input/es-AR.lproj/app.json index 5c443f275..9a9b1999f 100644 --- a/Localization/StringsConvertor/input/es-AR.lproj/app.json +++ b/Localization/StringsConvertor/input/es-AR.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Todo", - "people": "Cuentas", - "hashtags": "Etiquetas", - "posts": "Mensajes" - }, + "posts": "Mensajes con \"%s\"", + "people": "Personas con “%s\"", + "profile": "Ir a @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "No hay resultados" }, "recent_search": "Búsquedas recientes", + "clear_all": "Limpiar todo", "clear": "Limpiar" } }, diff --git a/Localization/StringsConvertor/input/es.lproj/app.json b/Localization/StringsConvertor/input/es.lproj/app.json index 7dbd1af30..3e2e5cfd5 100644 --- a/Localization/StringsConvertor/input/es.lproj/app.json +++ b/Localization/StringsConvertor/input/es.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Todo", - "people": "Gente", - "hashtags": "Etiquetas", - "posts": "Publicaciones" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "Sin resultados" }, "recent_search": "Búsquedas recientes", + "clear_all": "Clear all", "clear": "Borrar" } }, diff --git a/Localization/StringsConvertor/input/eu.lproj/app.json b/Localization/StringsConvertor/input/eu.lproj/app.json index 1a9bdeb64..015f72e92 100644 --- a/Localization/StringsConvertor/input/eu.lproj/app.json +++ b/Localization/StringsConvertor/input/eu.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Guztiak", - "people": "Jendea", - "hashtags": "Traolak", - "posts": "Bidalketak" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "Emaitzarik ez" }, "recent_search": "Azken bilaketak", + "clear_all": "Clear all", "clear": "Garbitu" } }, diff --git a/Localization/StringsConvertor/input/fi.lproj/app.json b/Localization/StringsConvertor/input/fi.lproj/app.json index f6befb35c..63989e829 100644 --- a/Localization/StringsConvertor/input/fi.lproj/app.json +++ b/Localization/StringsConvertor/input/fi.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Kaikki", - "people": "Tilit", - "hashtags": "Hashtagit", - "posts": "Julkaisut" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "Ei hakutuloksia" }, "recent_search": "Viimeaikaiset", + "clear_all": "Clear all", "clear": "Tyhjennä" } }, diff --git a/Localization/StringsConvertor/input/fr.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/fr.lproj/Localizable.stringsdict index 59bbf904e..2f33fd97b 100644 --- a/Localization/StringsConvertor/input/fr.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/fr.lproj/Localizable.stringsdict @@ -186,7 +186,7 @@ one 1 reblog other - %ld re-blogs + %ld reblogs plural.count.reply diff --git a/Localization/StringsConvertor/input/fr.lproj/app.json b/Localization/StringsConvertor/input/fr.lproj/app.json index 21568bc8b..967999561 100644 --- a/Localization/StringsConvertor/input/fr.lproj/app.json +++ b/Localization/StringsConvertor/input/fr.lproj/app.json @@ -98,10 +98,10 @@ "unknown_language": "Inconnu" }, "edit_post": "Éditer", - "bookmark": "Bookmark", - "remove_bookmark": "Remove Bookmark", - "follow": "Follow %s", - "unfollow": "Unfollow %s" + "bookmark": "Ajouter aux signets", + "remove_bookmark": "Supprimer le signet", + "follow": "S’abonner à %s", + "unfollow": "Se désabonner de %s" }, "tabs": { "home": "Accueil", @@ -206,12 +206,12 @@ "buttons": { "reblogs_title": "Reblogs", "favorites_title": "Favoris", - "edit_history_title": "Modifier l'historique", + "edit_history_title": "Historique des modifications", "edit_history_detail": "Dernière modification %s" }, "edited_at_timestamp_prefix": "Édité %s", "edit_history": { - "title": "Modifier l'historique", + "title": "Historique des modifications", "original_post": "Message original · %s" } }, @@ -258,14 +258,14 @@ }, "user_list": { "no_verified_link": "Lien non vérifié", - "followers_count": "%@ abonnés" + "followers_count": "%@ abonné·e·s" } }, "scene": { "welcome": { "log_in": "Se connecter", "learn_more": "En savoir plus", - "join_default_server": "Join %@", + "join_default_server": "Rejoindre %@", "pick_server": "Trouver un autre serveur", "separator": { "or": "ou" @@ -344,7 +344,7 @@ "no_server_selected_hint": "Nous choisirons un serveur basé sur votre langue si vous continuez sans en choisir un." }, "privacy": { - "title": "Confidentialité", + "title": "Vie privée", "description": "Bien que l’application Mastodon ne collecte aucune donnée, le serveur auquel vous vous inscrivez peut avoir une politique différente. Prenez une minute pour examiner et accepter la politique de confidentialité de l’application Mastodon ainsi que celle de votre serveur.", "policy": { "ios": "Politique de confidentialité - Mastodon pour iOS", @@ -462,8 +462,8 @@ } }, "suggestion_account": { - "title": "Popular on Mastodon", - "follow_all": "Follow all" + "title": "Populaire sur Mastodon", + "follow_all": "Tout suivre" }, "compose": { "title": { @@ -515,7 +515,7 @@ "visibility": { "public": "Public", "unlisted": "Non listé", - "private": "Abonnés seulement", + "private": "Abonné·e·s seulement", "direct": "Seulement les personnes que je mentionne" }, "auto_complete": { @@ -553,11 +553,11 @@ }, "dashboard": { "my_posts": "messages", - "my_following": "abonnement", - "my_followers": "abonnés", + "my_following": "abonnements", + "my_followers": "abonné·e·s", "other_posts": "publications", "other_following": "abonnement", - "other_followers": "abonnés", + "other_followers": "abonné·e·s", "familiar_followers": "mutuel" }, "fields": { @@ -617,7 +617,7 @@ "footer": "Les abonné·e·s issus des autres serveurs ne sont pas affiché·e·s." }, "following": { - "title": "abonnement", + "title": "abonnements", "footer": "Les abonnés issus des autres serveurs ne sont pas affichés." }, "familiarFollowers": { @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Tout", - "people": "Personnes", - "hashtags": "Hashtags", - "posts": "Publications" - }, + "posts": "Publications ayant « %s »", + "people": "Personnes ayant « %s »", + "profile": "Aller à @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "Aucun résultat" }, "recent_search": "Recherches récentes", + "clear_all": "Effacer tout", "clear": "Effacer" } }, @@ -682,7 +682,7 @@ "Mentions": "Mentions" }, "notification_description": { - "followed_you": "s’est abonné à vous", + "followed_you": "s’est abonné·e à vous", "favorited_your_post": "a ajouté votre message à ses favoris", "reblogged_your_post": "a partagé votre message", "mentioned_you": "vous a mentionné", @@ -728,7 +728,7 @@ "mentions": "Me mentionne", "trigger": { "anyone": "n’importe qui", - "follower": "un abonné", + "follower": "un·e abonné·e", "follow": "toute personne que je suis", "noone": "personne", "title": "Me notifier lorsque" @@ -856,21 +856,21 @@ "followers_count": { "configuration_display_name": "Abonné·e·s", "configuration_description": "Afficher le nombre d'abonnés.", - "title": "ABONNES", - "followers_today": "%s abonnés aujourd'hui" + "title": "ABONNÉ·E·S", + "followers_today": "%s abonné·e·s aujourd'hui" }, "multiple_followers": { - "configuration_display_name": "Abonnés multiples", + "configuration_display_name": "Abonné·e·s multiples", "configuration_description": "Afficher le nombre d'abonnés pour plusieurs comptes.", "mock_user": { - "display_name": "Autres abonnés", + "display_name": "Autres abonné·e·s", "account_name": "another@follower.social" } }, "latest_followers": { - "configuration_display_name": "Derniers abonnés", + "configuration_display_name": "Derniers abonné·e·s", "configuration_description": "Afficher les derniers abonnés.", - "title": "Derniers abonnés", + "title": "Derniers abonné·e·s", "last_update": "Dernière mise à jour: %s" }, "hashtag": { diff --git a/Localization/StringsConvertor/input/gd.lproj/app.json b/Localization/StringsConvertor/input/gd.lproj/app.json index 06cb72576..394301771 100644 --- a/Localization/StringsConvertor/input/gd.lproj/app.json +++ b/Localization/StringsConvertor/input/gd.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Na h-uile", - "people": "Daoine", - "hashtags": "Tagaichean hais", - "posts": "Postaichean" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "Gun toradh" }, "recent_search": "Na lorg thu o chionn goirid", + "clear_all": "Clear all", "clear": "Falamhaich" } }, diff --git a/Localization/StringsConvertor/input/gl.lproj/app.json b/Localization/StringsConvertor/input/gl.lproj/app.json index d0c97ceec..926641357 100644 --- a/Localization/StringsConvertor/input/gl.lproj/app.json +++ b/Localization/StringsConvertor/input/gl.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Todo", - "people": "Persoas", - "hashtags": "Cancelos", - "posts": "Publicacións" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "Sen resultados" }, "recent_search": "Buscas recentes", + "clear_all": "Clear all", "clear": "Limpar" } }, diff --git a/Localization/StringsConvertor/input/he.lproj/app.json b/Localization/StringsConvertor/input/he.lproj/app.json index ea7d88e7f..819010617 100644 --- a/Localization/StringsConvertor/input/he.lproj/app.json +++ b/Localization/StringsConvertor/input/he.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "All", - "people": "People", - "hashtags": "Hashtags", - "posts": "Posts" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "No results" }, "recent_search": "Recent searches", + "clear_all": "Clear all", "clear": "Clear" } }, diff --git a/Localization/StringsConvertor/input/hi.lproj/app.json b/Localization/StringsConvertor/input/hi.lproj/app.json index 334b9918f..ae022215a 100644 --- a/Localization/StringsConvertor/input/hi.lproj/app.json +++ b/Localization/StringsConvertor/input/hi.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "All", - "people": "People", - "hashtags": "Hashtags", - "posts": "Posts" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "No results" }, "recent_search": "Recent searches", + "clear_all": "Clear all", "clear": "Clear" } }, diff --git a/Localization/StringsConvertor/input/id.lproj/app.json b/Localization/StringsConvertor/input/id.lproj/app.json index 51579bc8a..a72fe5ca9 100644 --- a/Localization/StringsConvertor/input/id.lproj/app.json +++ b/Localization/StringsConvertor/input/id.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Semua", - "people": "Orang", - "hashtags": "Tagar", - "posts": "Postingan" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "Tidak ada hasil" }, "recent_search": "Pencarian terbaru", + "clear_all": "Clear all", "clear": "Hapus" } }, diff --git a/Localization/StringsConvertor/input/is.lproj/app.json b/Localization/StringsConvertor/input/is.lproj/app.json index 624101cd9..40241f6e2 100644 --- a/Localization/StringsConvertor/input/is.lproj/app.json +++ b/Localization/StringsConvertor/input/is.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Allt", - "people": "Fólk", - "hashtags": "Myllumerki", - "posts": "Færslur" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "Engar niðurstöður" }, "recent_search": "Nýlegar leitir", + "clear_all": "Hreinsa allt", "clear": "Hreinsa" } }, diff --git a/Localization/StringsConvertor/input/it.lproj/app.json b/Localization/StringsConvertor/input/it.lproj/app.json index e7099d929..37dd4cdf1 100644 --- a/Localization/StringsConvertor/input/it.lproj/app.json +++ b/Localization/StringsConvertor/input/it.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Tutto", - "people": "Persone", - "hashtags": "Hashtags", - "posts": "Post" - }, + "posts": "Post con \"%s\"", + "people": "Persone con \"%s\"", + "profile": "Vai a @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "Nessun risultato" }, "recent_search": "Ricerche recenti", + "clear_all": "Cancella tutto", "clear": "Cancella" } }, diff --git a/Localization/StringsConvertor/input/ja.lproj/app.json b/Localization/StringsConvertor/input/ja.lproj/app.json index 480274380..21c041e37 100644 --- a/Localization/StringsConvertor/input/ja.lproj/app.json +++ b/Localization/StringsConvertor/input/ja.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "すべて", - "people": "人々", - "hashtags": "ハッシュタグ", - "posts": "投稿" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "なし" }, "recent_search": "最近の検索", + "clear_all": "Clear all", "clear": "クリア" } }, diff --git a/Localization/StringsConvertor/input/kab.lproj/app.json b/Localization/StringsConvertor/input/kab.lproj/app.json index 654371983..f504ee86b 100644 --- a/Localization/StringsConvertor/input/kab.lproj/app.json +++ b/Localization/StringsConvertor/input/kab.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Akk", - "people": "Imdanen", - "hashtags": "Ihacṭagen", - "posts": "Tisuffaɣ" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "Ulac igemmaḍ" }, "recent_search": "Inadiyen imaynuten", + "clear_all": "Clear all", "clear": "Sfeḍ" } }, diff --git a/Localization/StringsConvertor/input/kmr.lproj/app.json b/Localization/StringsConvertor/input/kmr.lproj/app.json index 3e71dfe28..bf1a849bf 100644 --- a/Localization/StringsConvertor/input/kmr.lproj/app.json +++ b/Localization/StringsConvertor/input/kmr.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Hemû", - "people": "Mirov", - "hashtags": "Hashtag", - "posts": "Şandî" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "Encam tune" }, "recent_search": "Lêgerînên dawî", + "clear_all": "Clear all", "clear": "Pak bike" } }, diff --git a/Localization/StringsConvertor/input/ko.lproj/app.json b/Localization/StringsConvertor/input/ko.lproj/app.json index 813bf12b8..3bafe0d9a 100644 --- a/Localization/StringsConvertor/input/ko.lproj/app.json +++ b/Localization/StringsConvertor/input/ko.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "전부", - "people": "사람", - "hashtags": "해시태그", - "posts": "게시물" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "결과가 없습니다" }, "recent_search": "최근 검색", + "clear_all": "Clear all", "clear": "모두 지우기" } }, diff --git a/Localization/StringsConvertor/input/lv.lproj/app.json b/Localization/StringsConvertor/input/lv.lproj/app.json index 1ce04a728..d2b025bc1 100644 --- a/Localization/StringsConvertor/input/lv.lproj/app.json +++ b/Localization/StringsConvertor/input/lv.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Visi", - "people": "Cilvēki", - "hashtags": "Tēmturi", - "posts": "Ziņas" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "Nav rezultātu" }, "recent_search": "Nesen meklētais", + "clear_all": "Clear all", "clear": "Notīrīt" } }, diff --git a/Localization/StringsConvertor/input/my.lproj/app.json b/Localization/StringsConvertor/input/my.lproj/app.json index a75334beb..1aa80ef7f 100644 --- a/Localization/StringsConvertor/input/my.lproj/app.json +++ b/Localization/StringsConvertor/input/my.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "All", - "people": "People", - "hashtags": "Hashtags", - "posts": "Posts" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "No results" }, "recent_search": "Recent searches", + "clear_all": "Clear all", "clear": "Clear" } }, diff --git a/Localization/StringsConvertor/input/nl.lproj/app.json b/Localization/StringsConvertor/input/nl.lproj/app.json index c6fdeb239..0f7832035 100644 --- a/Localization/StringsConvertor/input/nl.lproj/app.json +++ b/Localization/StringsConvertor/input/nl.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Alles", - "people": "Gebruikers", - "hashtags": "Hashtags", - "posts": "Berichten" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "Geen resultaten" }, "recent_search": "Recente zoekopdrachten", + "clear_all": "Clear all", "clear": "Wissen" } }, diff --git a/Localization/StringsConvertor/input/pl.lproj/app.json b/Localization/StringsConvertor/input/pl.lproj/app.json index fddd23aaf..47e848b55 100644 --- a/Localization/StringsConvertor/input/pl.lproj/app.json +++ b/Localization/StringsConvertor/input/pl.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "All", - "people": "People", - "hashtags": "Hashtags", - "posts": "Posts" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "No results" }, "recent_search": "Recent searches", + "clear_all": "Clear all", "clear": "Clear" } }, diff --git a/Localization/StringsConvertor/input/pt-BR.lproj/app.json b/Localization/StringsConvertor/input/pt-BR.lproj/app.json index 357478885..588688317 100644 --- a/Localization/StringsConvertor/input/pt-BR.lproj/app.json +++ b/Localization/StringsConvertor/input/pt-BR.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Todos", - "people": "Pessoas", - "hashtags": "Hashtags", - "posts": "Toots" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "Sem resultados" }, "recent_search": "Pesquisas recentes", + "clear_all": "Clear all", "clear": "Limpar" } }, diff --git a/Localization/StringsConvertor/input/pt.lproj/app.json b/Localization/StringsConvertor/input/pt.lproj/app.json index 045f054af..18ca2de22 100644 --- a/Localization/StringsConvertor/input/pt.lproj/app.json +++ b/Localization/StringsConvertor/input/pt.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "All", - "people": "People", - "hashtags": "Etiquetas", - "posts": "Publicações" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "No results" }, "recent_search": "Recent searches", + "clear_all": "Clear all", "clear": "Clear" } }, diff --git a/Localization/StringsConvertor/input/ro.lproj/app.json b/Localization/StringsConvertor/input/ro.lproj/app.json index 80d5b8333..f9f1b567e 100644 --- a/Localization/StringsConvertor/input/ro.lproj/app.json +++ b/Localization/StringsConvertor/input/ro.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "All", - "people": "People", - "hashtags": "Hashtags", - "posts": "Posts" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "No results" }, "recent_search": "Recent searches", + "clear_all": "Clear all", "clear": "Clear" } }, diff --git a/Localization/StringsConvertor/input/ru.lproj/app.json b/Localization/StringsConvertor/input/ru.lproj/app.json index 381256cef..25137ad65 100644 --- a/Localization/StringsConvertor/input/ru.lproj/app.json +++ b/Localization/StringsConvertor/input/ru.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Всё", - "people": "Люди", - "hashtags": "Хэштеги", - "posts": "Посты" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "Нет результатов" }, "recent_search": "Последние запросы", + "clear_all": "Clear all", "clear": "Очистить" } }, diff --git a/Localization/StringsConvertor/input/si.lproj/app.json b/Localization/StringsConvertor/input/si.lproj/app.json index abd257761..45715a316 100644 --- a/Localization/StringsConvertor/input/si.lproj/app.json +++ b/Localization/StringsConvertor/input/si.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "සියල්ල", - "people": "මිනිසුන්", - "hashtags": "Hashtags", - "posts": "Posts" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "ප්‍රතිඵල නැත" }, "recent_search": "Recent searches", + "clear_all": "Clear all", "clear": "මකන්න" } }, diff --git a/Localization/StringsConvertor/input/sl.lproj/app.json b/Localization/StringsConvertor/input/sl.lproj/app.json index dfd2f83de..3f308a133 100644 --- a/Localization/StringsConvertor/input/sl.lproj/app.json +++ b/Localization/StringsConvertor/input/sl.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Vse", - "people": "Ljudje", - "hashtags": "Ključniki", - "posts": "Objave" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "Ni rezultatov" }, "recent_search": "Nedavna iskanja", + "clear_all": "Clear all", "clear": "Počisti" } }, diff --git a/Localization/StringsConvertor/input/sv.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/sv.lproj/Localizable.stringsdict index 2dd03d1e3..44132e62d 100644 --- a/Localization/StringsConvertor/input/sv.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/sv.lproj/Localizable.stringsdict @@ -344,7 +344,7 @@ NSStringFormatValueTypeKey ld one - %ld timme kvar + 1 timme kvar other %ld timmar kvar @@ -360,7 +360,7 @@ NSStringFormatValueTypeKey ld one - %ld minut kvar + 1 minut kvar other %ld minuter kvar diff --git a/Localization/StringsConvertor/input/sv.lproj/app.json b/Localization/StringsConvertor/input/sv.lproj/app.json index 24ea32a25..583d47ab6 100644 --- a/Localization/StringsConvertor/input/sv.lproj/app.json +++ b/Localization/StringsConvertor/input/sv.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Allt", - "people": "Personer", - "hashtags": "Hashtaggar", - "posts": "Inlägg" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "Inga resultat" }, "recent_search": "Senaste sökningarna", + "clear_all": "Rensa alla", "clear": "Rensa" } }, @@ -851,11 +851,11 @@ "widget": { "common": { "unsupported_widget_family": "Sorry but this Widget family is unsupported.", - "user_not_logged_in": "Please open Mastodon to log in to an Account." + "user_not_logged_in": "Öppna Mastodon för att logga in på ett konto." }, "followers_count": { "configuration_display_name": "Följare", - "configuration_description": "Show number of followers.", + "configuration_description": "Visa antal följare.", "title": "FÖLJARE", "followers_today": "%s följare idag" }, diff --git a/Localization/StringsConvertor/input/th.lproj/app.json b/Localization/StringsConvertor/input/th.lproj/app.json index 3532dc69d..1379310fe 100644 --- a/Localization/StringsConvertor/input/th.lproj/app.json +++ b/Localization/StringsConvertor/input/th.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "ทั้งหมด", - "people": "ผู้คน", - "hashtags": "แฮชแท็ก", - "posts": "โพสต์" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "ไม่มีผลลัพธ์" }, "recent_search": "การค้นหาล่าสุด", + "clear_all": "Clear all", "clear": "ล้าง" } }, diff --git a/Localization/StringsConvertor/input/tr.lproj/app.json b/Localization/StringsConvertor/input/tr.lproj/app.json index cf974de11..11e2940a6 100644 --- a/Localization/StringsConvertor/input/tr.lproj/app.json +++ b/Localization/StringsConvertor/input/tr.lproj/app.json @@ -506,8 +506,8 @@ "the_poll_has_empty_option": "The poll has empty option", "add_option": "Seçenek Ekle", "remove_option": "Seçeneği Kaldır", - "move_up": "Move Up", - "move_down": "Move Down" + "move_up": "Yukarı Taşı", + "move_down": "Aşağı Taşı" }, "content_warning": { "placeholder": "Buraya kesin bir uyarı yazın..." @@ -543,7 +543,7 @@ "language": { "title": "Gönderi dili", "suggested": "Önerilen", - "recent": "Recent", + "recent": "En Son", "other": "Other Language…" } }, @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Tümü", - "people": "İnsanlar", - "hashtags": "Etiketler", - "posts": "Gönderiler" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "Sonuç yok" }, "recent_search": "Son aramalar", + "clear_all": "Clear all", "clear": "Temizle" } }, diff --git a/Localization/StringsConvertor/input/uk.lproj/app.json b/Localization/StringsConvertor/input/uk.lproj/app.json index 652674b9e..0d4ac81cf 100644 --- a/Localization/StringsConvertor/input/uk.lproj/app.json +++ b/Localization/StringsConvertor/input/uk.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Всі", - "people": "Громада", - "hashtags": "Гештеги", - "posts": "Дописи" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "Жодних результатів" }, "recent_search": "Нещодавні запити", + "clear_all": "Clear all", "clear": "Очистити" } }, diff --git a/Localization/StringsConvertor/input/vi.lproj/app.json b/Localization/StringsConvertor/input/vi.lproj/app.json index 50ffc44e2..9f782be15 100644 --- a/Localization/StringsConvertor/input/vi.lproj/app.json +++ b/Localization/StringsConvertor/input/vi.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "Tất cả", - "people": "Mọi người", - "hashtags": "Hashtag", - "posts": "Tút" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "Không có kết quả" }, "recent_search": "Tìm kiếm gần đây", + "clear_all": "Clear all", "clear": "Xóa" } }, diff --git a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json index 0f9726942..5773faeec 100644 --- a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json @@ -98,10 +98,10 @@ "unknown_language": "未知的" }, "edit_post": "编辑", - "bookmark": "Bookmark", - "remove_bookmark": "Remove Bookmark", - "follow": "Follow %s", - "unfollow": "Unfollow %s" + "bookmark": "添加书签", + "remove_bookmark": "移除书签", + "follow": "关注 %s", + "unfollow": "不再关注 %s" }, "tabs": { "home": "主页", @@ -205,7 +205,7 @@ "posted_via_application": "%s 通过 %s 发布", "buttons": { "reblogs_title": "转发", - "favorites_title": "收藏", + "favorites_title": "喜欢", "edit_history_title": "编辑历史", "edit_history_detail": "编辑于:%s" }, @@ -265,7 +265,7 @@ "welcome": { "log_in": "登录", "learn_more": "了解详情", - "join_default_server": "Join %@", + "join_default_server": "加入 %@", "pick_server": "选择另一个服务器", "separator": { "or": "或" @@ -625,7 +625,7 @@ "followed_by_names": "%s 关注了这个账号" }, "favorited_by": { - "title": "收藏者" + "title": "喜欢者" }, "reblogged_by": { "title": "转发者" @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "全部", - "people": "用户", - "hashtags": "标签", - "posts": "帖子" - }, + "posts": "Posts with \"%s\"", + "people": "People with \"%s\"", + "profile": "Go to @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "无结果" }, "recent_search": "最近搜索", + "clear_all": "Clear all", "clear": "清除" } }, @@ -674,7 +674,7 @@ "intro": "这些嘟文在你的长毛象小宇宙中备受关注。" }, "favorite": { - "title": "收藏" + "title": "喜欢" }, "notification": { "title": { diff --git a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json index 3c9bdb150..c608034f3 100644 --- a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json @@ -650,16 +650,16 @@ } }, "searching": { - "segment": { - "all": "全部", - "people": "使用者", - "hashtags": "主題標籤", - "posts": "嘟文" - }, + "posts": "包含「%s」之嘟文", + "people": "包含「%s」之帳號", + "profile": "前往 @%s@%s", + "url": "Open URL in Mastodon", + "hashtag": "Go to #%s", "empty_state": { "no_results": "沒有任何結果" }, "recent_search": "最近的搜尋", + "clear_all": "清除全部", "clear": "清除" } }, From fe9ed96615c53fcbcb0dab2b7c15ae03cd265fa6 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 20 Sep 2023 23:04:52 +0200 Subject: [PATCH 79/87] Teach Localization-parser how to espace " --- .../StringsConvertor/Sources/StringsConvertor/Parser.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Localization/StringsConvertor/Sources/StringsConvertor/Parser.swift b/Localization/StringsConvertor/Sources/StringsConvertor/Parser.swift index ba9750cd4..0225baf3d 100644 --- a/Localization/StringsConvertor/Sources/StringsConvertor/Parser.swift +++ b/Localization/StringsConvertor/Sources/StringsConvertor/Parser.swift @@ -53,7 +53,7 @@ extension Parser { ].joined() let value = [ "\"", - pair.value.replacingOccurrences(of: "%s", with: "%@"), + pair.value.replacingOccurrences(of: "%s", with: "%@").replacingOccurrences(of: "\"", with: "\\\""), "\"" ].joined() let line = [ From 4e42505dee0f351f9fc0bb4bdd5358c9025f32de Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 20 Sep 2023 23:07:19 +0200 Subject: [PATCH 80/87] Fix wording in app.json --- .../StringsConvertor/input/Base.lproj/app.json | 11 +++++------ Localization/StringsConvertor/input/en.lproj/app.json | 4 ++-- Localization/app.json | 11 +++++------ 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index d50363d05..4a7792b8b 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -214,7 +214,6 @@ "title": "Edit History", "original_post": "Original Post · %s" } - }, "friendship": { "follow": "Follow", @@ -282,9 +281,9 @@ }, "a11y": { "what_is_mastodon": { - "title": "What is Mastodon?" - } - } + "title": "What is Mastodon?" + } + } } }, "login": { @@ -651,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/en.lproj/app.json b/Localization/StringsConvertor/input/en.lproj/app.json index 7f371067b..4a7792b8b 100644 --- a/Localization/StringsConvertor/input/en.lproj/app.json +++ b/Localization/StringsConvertor/input/en.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/app.json b/Localization/app.json index d50363d05..4a7792b8b 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -214,7 +214,6 @@ "title": "Edit History", "original_post": "Original Post · %s" } - }, "friendship": { "follow": "Follow", @@ -282,9 +281,9 @@ }, "a11y": { "what_is_mastodon": { - "title": "What is Mastodon?" - } - } + "title": "What is Mastodon?" + } + } } }, "login": { @@ -651,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", From fc7ce4969b6d063232fac491f950b06fef6e6860 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 20 Sep 2023 23:19:08 +0200 Subject: [PATCH 81/87] New Crowdin updates (#1117) --- .../StringsConvertor/input/an.lproj/app.json | 4 +-- .../StringsConvertor/input/ar.lproj/app.json | 4 +-- .../StringsConvertor/input/be.lproj/app.json | 4 +-- .../StringsConvertor/input/ca.lproj/app.json | 10 +++--- .../StringsConvertor/input/ckb.lproj/app.json | 4 +-- .../StringsConvertor/input/cs.lproj/app.json | 4 +-- .../StringsConvertor/input/cy.lproj/app.json | 4 +-- .../StringsConvertor/input/da.lproj/app.json | 4 +-- .../StringsConvertor/input/de.lproj/app.json | 4 +-- .../StringsConvertor/input/el.lproj/app.json | 4 +-- .../input/en-US.lproj/app.json | 4 +-- .../input/es-AR.lproj/app.json | 8 ++--- .../StringsConvertor/input/es.lproj/app.json | 4 +-- .../StringsConvertor/input/eu.lproj/app.json | 4 +-- .../StringsConvertor/input/fi.lproj/app.json | 34 +++++++++---------- .../StringsConvertor/input/fr.lproj/app.json | 4 +-- .../StringsConvertor/input/gd.lproj/app.json | 4 +-- .../StringsConvertor/input/gl.lproj/app.json | 4 +-- .../StringsConvertor/input/he.lproj/app.json | 4 +-- .../StringsConvertor/input/hi.lproj/app.json | 4 +-- .../StringsConvertor/input/id.lproj/app.json | 4 +-- .../StringsConvertor/input/is.lproj/app.json | 4 +-- .../StringsConvertor/input/it.lproj/app.json | 8 ++--- .../StringsConvertor/input/ja.lproj/app.json | 4 +-- .../StringsConvertor/input/kab.lproj/app.json | 4 +-- .../StringsConvertor/input/kmr.lproj/app.json | 4 +-- .../StringsConvertor/input/ko.lproj/app.json | 4 +-- .../StringsConvertor/input/lv.lproj/app.json | 4 +-- .../StringsConvertor/input/my.lproj/app.json | 4 +-- .../StringsConvertor/input/nl.lproj/app.json | 4 +-- .../StringsConvertor/input/pl.lproj/app.json | 4 +-- .../input/pt-BR.lproj/app.json | 4 +-- .../StringsConvertor/input/pt.lproj/app.json | 4 +-- .../StringsConvertor/input/ro.lproj/app.json | 4 +-- .../StringsConvertor/input/ru.lproj/app.json | 4 +-- .../StringsConvertor/input/si.lproj/app.json | 4 +-- .../StringsConvertor/input/sl.lproj/app.json | 4 +-- .../StringsConvertor/input/sv.lproj/app.json | 4 +-- .../StringsConvertor/input/th.lproj/app.json | 4 +-- .../StringsConvertor/input/tr.lproj/app.json | 4 +-- .../StringsConvertor/input/uk.lproj/app.json | 4 +-- .../StringsConvertor/input/vi.lproj/app.json | 4 +-- .../input/zh-Hans.lproj/app.json | 4 +-- .../input/zh-Hant.lproj/app.json | 8 ++--- 44 files changed, 112 insertions(+), 112 deletions(-) diff --git a/Localization/StringsConvertor/input/an.lproj/app.json b/Localization/StringsConvertor/input/an.lproj/app.json index b5177e4ca..36fd36bb9 100644 --- a/Localization/StringsConvertor/input/an.lproj/app.json +++ b/Localization/StringsConvertor/input/an.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/ar.lproj/app.json b/Localization/StringsConvertor/input/ar.lproj/app.json index c2ca137fc..b81a1e681 100644 --- a/Localization/StringsConvertor/input/ar.lproj/app.json +++ b/Localization/StringsConvertor/input/ar.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/be.lproj/app.json b/Localization/StringsConvertor/input/be.lproj/app.json index 8a026fd8d..e69f18d60 100644 --- a/Localization/StringsConvertor/input/be.lproj/app.json +++ b/Localization/StringsConvertor/input/be.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/ca.lproj/app.json b/Localization/StringsConvertor/input/ca.lproj/app.json index fa3a2e54a..f5dc76b88 100644 --- a/Localization/StringsConvertor/input/ca.lproj/app.json +++ b/Localization/StringsConvertor/input/ca.lproj/app.json @@ -650,11 +650,11 @@ } }, "searching": { - "posts": "Tuts amb \"%s\"", - "people": "Gent amb \"%s\"", - "profile": "Ves a @%s@%s", - "url": "Open URL in Mastodon", - "hashtag": "Go to #%s", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", + "profile": "Vés a @%s@%s", + "url": "Obre l'enllaç a Mastodon", + "hashtag": "Vés a #%s", "empty_state": { "no_results": "No hi ha resultats" }, diff --git a/Localization/StringsConvertor/input/ckb.lproj/app.json b/Localization/StringsConvertor/input/ckb.lproj/app.json index 1105dd153..cd8381b80 100644 --- a/Localization/StringsConvertor/input/ckb.lproj/app.json +++ b/Localization/StringsConvertor/input/ckb.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/cs.lproj/app.json b/Localization/StringsConvertor/input/cs.lproj/app.json index 093d3767d..b6ecac398 100644 --- a/Localization/StringsConvertor/input/cs.lproj/app.json +++ b/Localization/StringsConvertor/input/cs.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json index cf0360326..829db3a53 100644 --- a/Localization/StringsConvertor/input/cy.lproj/app.json +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/da.lproj/app.json b/Localization/StringsConvertor/input/da.lproj/app.json index afe820815..7f7a6217c 100644 --- a/Localization/StringsConvertor/input/da.lproj/app.json +++ b/Localization/StringsConvertor/input/da.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/de.lproj/app.json b/Localization/StringsConvertor/input/de.lproj/app.json index 2d182fcf5..6f09e3d74 100644 --- a/Localization/StringsConvertor/input/de.lproj/app.json +++ b/Localization/StringsConvertor/input/de.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/el.lproj/app.json b/Localization/StringsConvertor/input/el.lproj/app.json index 5936d46d8..3023b7f3f 100644 --- a/Localization/StringsConvertor/input/el.lproj/app.json +++ b/Localization/StringsConvertor/input/el.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/en-US.lproj/app.json b/Localization/StringsConvertor/input/en-US.lproj/app.json index 7f371067b..4a7792b8b 100644 --- a/Localization/StringsConvertor/input/en-US.lproj/app.json +++ b/Localization/StringsConvertor/input/en-US.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/es-AR.lproj/app.json b/Localization/StringsConvertor/input/es-AR.lproj/app.json index 9a9b1999f..83faebb28 100644 --- a/Localization/StringsConvertor/input/es-AR.lproj/app.json +++ b/Localization/StringsConvertor/input/es-AR.lproj/app.json @@ -650,11 +650,11 @@ } }, "searching": { - "posts": "Mensajes con \"%s\"", - "people": "Personas con “%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Ir a @%s@%s", - "url": "Open URL in Mastodon", - "hashtag": "Go to #%s", + "url": "Abrir dirección web en Mastodon", + "hashtag": "Ir a %s", "empty_state": { "no_results": "No hay resultados" }, diff --git a/Localization/StringsConvertor/input/es.lproj/app.json b/Localization/StringsConvertor/input/es.lproj/app.json index 3e2e5cfd5..b47fed426 100644 --- a/Localization/StringsConvertor/input/es.lproj/app.json +++ b/Localization/StringsConvertor/input/es.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/eu.lproj/app.json b/Localization/StringsConvertor/input/eu.lproj/app.json index 015f72e92..91074523d 100644 --- a/Localization/StringsConvertor/input/eu.lproj/app.json +++ b/Localization/StringsConvertor/input/eu.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/fi.lproj/app.json b/Localization/StringsConvertor/input/fi.lproj/app.json index 63989e829..aac581c2f 100644 --- a/Localization/StringsConvertor/input/fi.lproj/app.json +++ b/Localization/StringsConvertor/input/fi.lproj/app.json @@ -12,14 +12,14 @@ "title": "Palvelinvirhe" }, "vote_failure": { - "title": "Vote Failure", + "title": "Äänestys epäonnistui", "poll_ended": "Kysely on päättynyt" }, "publish_post_failure": { "title": "Julkaiseminen epäonnistui", "message": "Julkaisun julkaiseminen epäonnistui.\nTarkista internet-yhteytesi.", "attachments_message": { - "video_attach_with_photo": "Cannot attach a video to a post that already contains images.", + "video_attach_with_photo": "Videota ei voi liittää tilapäivitykseen, joka sisältää jo kuvia.", "more_than_one_video": "Ei voi liittä yhtä videota enempää." } }, @@ -33,24 +33,24 @@ "confirm": "Kirjaudu ulos" }, "block_domain": { - "title": "Are you really, really sure you want to block the entire %s? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain and any of your followers from that domain will be removed.", + "title": "Haluatko aivan varmasti estää palvelun %s täysin? Useimmiten muutama kohdistettu esto tai mykistys on riittävä ja suositeltava toimenpide. Et näe kyseisen palvelun sisältöä julkisilla aikajanoilla tai ilmoituksissa. Tälle palvelulle kuuluvat seuraajasi poistetaan.", "block_entire_domain": "Estä verkkotunnus" }, "save_photo_failure": { "title": "Kuvan tallentaminen epäonnistui", - "message": "Please enable the photo library access permission to save the photo." + "message": "Myönnä kuvakirjaston käyttöoikeus tallentaaksesi kuvan." }, "delete_post": { "title": "Haluatko varmasti poistaa tämän julkaisun?", - "message": "Are you sure you want to delete this post?" + "message": "Haluatko varmasti poistaa julkaisun?" }, "clean_cache": { "title": "Puhdista välimuisti", "message": "%s välimuisti tyhjennetty onnistuneesti." }, "translation_failed": { - "title": "Note", - "message": "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported.", + "title": "Huomautus", + "message": "Käännös epäonnistui. Ehkä palvelimen ylläpito ei ole ottanut käännösominaisuutta käyttöön tai se käyttää Mastodonin vanhempaa versiota, joka ei vielä tue käännöksiä.", "button": "OK" } }, @@ -98,10 +98,10 @@ "unknown_language": "Tuntematon" }, "edit_post": "Muokkaa", - "bookmark": "Bookmark", - "remove_bookmark": "Remove Bookmark", - "follow": "Follow %s", - "unfollow": "Unfollow %s" + "bookmark": "Kirjanmerkki", + "remove_bookmark": "Poista kirjanmerkki", + "follow": "Seuraa käyttäjää %s", + "unfollow": "Lopeta käyttäjän %s seuraaminen" }, "tabs": { "home": "Koti", @@ -650,16 +650,16 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", - "profile": "Go to @%s@%s", - "url": "Open URL in Mastodon", - "hashtag": "Go to #%s", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", + "profile": "Avaa profiilii @%s@%s", + "url": "Avaa URL Mastodonissa", + "hashtag": "Siirry #%s", "empty_state": { "no_results": "Ei hakutuloksia" }, "recent_search": "Viimeaikaiset", - "clear_all": "Clear all", + "clear_all": "Tyhjennä kaikki", "clear": "Tyhjennä" } }, diff --git a/Localization/StringsConvertor/input/fr.lproj/app.json b/Localization/StringsConvertor/input/fr.lproj/app.json index 967999561..acac6ff6e 100644 --- a/Localization/StringsConvertor/input/fr.lproj/app.json +++ b/Localization/StringsConvertor/input/fr.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Publications ayant « %s »", - "people": "Personnes ayant « %s »", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Aller à @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/gd.lproj/app.json b/Localization/StringsConvertor/input/gd.lproj/app.json index 394301771..23a9a39ce 100644 --- a/Localization/StringsConvertor/input/gd.lproj/app.json +++ b/Localization/StringsConvertor/input/gd.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/gl.lproj/app.json b/Localization/StringsConvertor/input/gl.lproj/app.json index 926641357..41ea3b506 100644 --- a/Localization/StringsConvertor/input/gl.lproj/app.json +++ b/Localization/StringsConvertor/input/gl.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/he.lproj/app.json b/Localization/StringsConvertor/input/he.lproj/app.json index 819010617..7c215374c 100644 --- a/Localization/StringsConvertor/input/he.lproj/app.json +++ b/Localization/StringsConvertor/input/he.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/hi.lproj/app.json b/Localization/StringsConvertor/input/hi.lproj/app.json index ae022215a..824164de2 100644 --- a/Localization/StringsConvertor/input/hi.lproj/app.json +++ b/Localization/StringsConvertor/input/hi.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/id.lproj/app.json b/Localization/StringsConvertor/input/id.lproj/app.json index a72fe5ca9..3623c4882 100644 --- a/Localization/StringsConvertor/input/id.lproj/app.json +++ b/Localization/StringsConvertor/input/id.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/is.lproj/app.json b/Localization/StringsConvertor/input/is.lproj/app.json index 40241f6e2..5446db812 100644 --- a/Localization/StringsConvertor/input/is.lproj/app.json +++ b/Localization/StringsConvertor/input/is.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/it.lproj/app.json b/Localization/StringsConvertor/input/it.lproj/app.json index 37dd4cdf1..fa518a9b6 100644 --- a/Localization/StringsConvertor/input/it.lproj/app.json +++ b/Localization/StringsConvertor/input/it.lproj/app.json @@ -650,11 +650,11 @@ } }, "searching": { - "posts": "Post con \"%s\"", - "people": "Persone con \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Vai a @%s@%s", - "url": "Open URL in Mastodon", - "hashtag": "Go to #%s", + "url": "Apri l'URL su Mastodon", + "hashtag": "Vai a #%s", "empty_state": { "no_results": "Nessun risultato" }, diff --git a/Localization/StringsConvertor/input/ja.lproj/app.json b/Localization/StringsConvertor/input/ja.lproj/app.json index 21c041e37..fd1852502 100644 --- a/Localization/StringsConvertor/input/ja.lproj/app.json +++ b/Localization/StringsConvertor/input/ja.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/kab.lproj/app.json b/Localization/StringsConvertor/input/kab.lproj/app.json index f504ee86b..e676171f7 100644 --- a/Localization/StringsConvertor/input/kab.lproj/app.json +++ b/Localization/StringsConvertor/input/kab.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/kmr.lproj/app.json b/Localization/StringsConvertor/input/kmr.lproj/app.json index bf1a849bf..2806f61e9 100644 --- a/Localization/StringsConvertor/input/kmr.lproj/app.json +++ b/Localization/StringsConvertor/input/kmr.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/ko.lproj/app.json b/Localization/StringsConvertor/input/ko.lproj/app.json index 3bafe0d9a..7ebf3aa2d 100644 --- a/Localization/StringsConvertor/input/ko.lproj/app.json +++ b/Localization/StringsConvertor/input/ko.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/lv.lproj/app.json b/Localization/StringsConvertor/input/lv.lproj/app.json index d2b025bc1..f047ff188 100644 --- a/Localization/StringsConvertor/input/lv.lproj/app.json +++ b/Localization/StringsConvertor/input/lv.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/my.lproj/app.json b/Localization/StringsConvertor/input/my.lproj/app.json index 1aa80ef7f..24a859de8 100644 --- a/Localization/StringsConvertor/input/my.lproj/app.json +++ b/Localization/StringsConvertor/input/my.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/nl.lproj/app.json b/Localization/StringsConvertor/input/nl.lproj/app.json index 0f7832035..8e496f432 100644 --- a/Localization/StringsConvertor/input/nl.lproj/app.json +++ b/Localization/StringsConvertor/input/nl.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/pl.lproj/app.json b/Localization/StringsConvertor/input/pl.lproj/app.json index 47e848b55..2ba4da5b1 100644 --- a/Localization/StringsConvertor/input/pl.lproj/app.json +++ b/Localization/StringsConvertor/input/pl.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/pt-BR.lproj/app.json b/Localization/StringsConvertor/input/pt-BR.lproj/app.json index 588688317..5df62b124 100644 --- a/Localization/StringsConvertor/input/pt-BR.lproj/app.json +++ b/Localization/StringsConvertor/input/pt-BR.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/pt.lproj/app.json b/Localization/StringsConvertor/input/pt.lproj/app.json index 18ca2de22..6b247e2c2 100644 --- a/Localization/StringsConvertor/input/pt.lproj/app.json +++ b/Localization/StringsConvertor/input/pt.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/ro.lproj/app.json b/Localization/StringsConvertor/input/ro.lproj/app.json index f9f1b567e..e8f204572 100644 --- a/Localization/StringsConvertor/input/ro.lproj/app.json +++ b/Localization/StringsConvertor/input/ro.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/ru.lproj/app.json b/Localization/StringsConvertor/input/ru.lproj/app.json index 25137ad65..a4e011040 100644 --- a/Localization/StringsConvertor/input/ru.lproj/app.json +++ b/Localization/StringsConvertor/input/ru.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/si.lproj/app.json b/Localization/StringsConvertor/input/si.lproj/app.json index 45715a316..040e86e0c 100644 --- a/Localization/StringsConvertor/input/si.lproj/app.json +++ b/Localization/StringsConvertor/input/si.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/sl.lproj/app.json b/Localization/StringsConvertor/input/sl.lproj/app.json index 3f308a133..e0374ddc0 100644 --- a/Localization/StringsConvertor/input/sl.lproj/app.json +++ b/Localization/StringsConvertor/input/sl.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/sv.lproj/app.json b/Localization/StringsConvertor/input/sv.lproj/app.json index 583d47ab6..8790dc9b7 100644 --- a/Localization/StringsConvertor/input/sv.lproj/app.json +++ b/Localization/StringsConvertor/input/sv.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/th.lproj/app.json b/Localization/StringsConvertor/input/th.lproj/app.json index 1379310fe..0d4008795 100644 --- a/Localization/StringsConvertor/input/th.lproj/app.json +++ b/Localization/StringsConvertor/input/th.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/tr.lproj/app.json b/Localization/StringsConvertor/input/tr.lproj/app.json index 11e2940a6..f0eed9f64 100644 --- a/Localization/StringsConvertor/input/tr.lproj/app.json +++ b/Localization/StringsConvertor/input/tr.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/uk.lproj/app.json b/Localization/StringsConvertor/input/uk.lproj/app.json index 0d4ac81cf..360e5a4c5 100644 --- a/Localization/StringsConvertor/input/uk.lproj/app.json +++ b/Localization/StringsConvertor/input/uk.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/vi.lproj/app.json b/Localization/StringsConvertor/input/vi.lproj/app.json index 9f782be15..c551d7982 100644 --- a/Localization/StringsConvertor/input/vi.lproj/app.json +++ b/Localization/StringsConvertor/input/vi.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json index 5773faeec..d15db21ea 100644 --- a/Localization/StringsConvertor/input/zh-Hans.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts with \"%s\"", - "people": "People with \"%s\"", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", diff --git a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json index c608034f3..b2aafa7b2 100644 --- a/Localization/StringsConvertor/input/zh-Hant.lproj/app.json +++ b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json @@ -650,11 +650,11 @@ } }, "searching": { - "posts": "包含「%s」之嘟文", - "people": "包含「%s」之帳號", + "posts": "Posts matching \"%s\"", + "people": "People matching \"%s\"", "profile": "前往 @%s@%s", - "url": "Open URL in Mastodon", - "hashtag": "Go to #%s", + "url": "於 Mastodon 中開啟連結", + "hashtag": "前往 #%s", "empty_state": { "no_results": "沒有任何結果" }, From a4ff32ef8c52277939c091bfb942947cb27db18a Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 20 Sep 2023 23:21:13 +0200 Subject: [PATCH 82/87] Update localizations --- MastodonIntent/ar.lproj/Intents.strings | 4 +- .../Generated/Strings.swift | 8 - .../Resources/Base.lproj/Localizable.strings | 14 +- .../Resources/ar.lproj/Localizable.strings | 188 +++++++++--------- .../Resources/be.lproj/Localizable.strings | 10 +- .../Resources/ca.lproj/Localizable.strings | 24 ++- .../Resources/ckb.lproj/Localizable.strings | 10 +- .../Resources/cs.lproj/Localizable.strings | 10 +- .../Resources/de.lproj/Localizable.strings | 10 +- .../Resources/el.lproj/Localizable.strings | 12 +- .../Resources/en.lproj/Localizable.strings | 10 +- .../Resources/es.lproj/Localizable.strings | 10 +- .../Resources/eu.lproj/Localizable.strings | 10 +- .../Resources/fi.lproj/Localizable.strings | 32 +-- .../Resources/fr.lproj/Localizable.strings | 58 +++--- .../fr.lproj/Localizable.stringsdict | 2 +- .../Resources/gd.lproj/Localizable.strings | 10 +- .../Resources/gl.lproj/Localizable.strings | 10 +- .../Resources/it.lproj/Localizable.strings | 10 +- .../Resources/ja.lproj/Localizable.strings | 10 +- .../Resources/kab.lproj/Localizable.strings | 10 +- .../Resources/ku.lproj/Localizable.strings | 10 +- .../Resources/nl.lproj/Localizable.strings | 10 +- .../Resources/ru.lproj/Localizable.strings | 10 +- .../Resources/sl.lproj/Localizable.strings | 10 +- .../Resources/sv.lproj/Localizable.strings | 14 +- .../sv.lproj/Localizable.stringsdict | 4 +- .../Resources/th.lproj/Localizable.strings | 10 +- .../Resources/tr.lproj/Localizable.strings | 16 +- .../Resources/vi.lproj/Localizable.strings | 10 +- .../zh-Hans.lproj/Localizable.strings | 26 +-- .../zh-Hant.lproj/Localizable.strings | 10 +- 32 files changed, 317 insertions(+), 275 deletions(-) diff --git a/MastodonIntent/ar.lproj/Intents.strings b/MastodonIntent/ar.lproj/Intents.strings index 49183a431..2a1a604c7 100644 --- a/MastodonIntent/ar.lproj/Intents.strings +++ b/MastodonIntent/ar.lproj/Intents.strings @@ -1,4 +1,4 @@ -"16wxgf" = "النَّشرُ عَلَى مَاستودُون"; +"16wxgf" = "النَّشرُ عَلَى ماستدون"; "751xkl" = "محتوى نصي"; @@ -32,7 +32,7 @@ "ayoYEb-ehFLjY" = "${content}، المُتابِعُون فقط"; -"dUyuGg" = "النَّشرُ عَلَى مَاستودُون"; +"dUyuGg" = "النَّشرُ عَلَى ماستدون"; "dYQ5NN" = "لِلعَامَّة"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index 3367b4805..dd45d6963 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -1303,14 +1303,6 @@ public enum L10n { /// No results public static let noResults = L10n.tr("Localizable", "Scene.Search.Searching.EmptyState.NoResults", fallback: "No results") } - public enum NoUser { - /// There's no Useraccount "%@" on %@ - public static func message(_ p1: Any, _ p2: Any) -> String { - return L10n.tr("Localizable", "Scene.Search.Searching.NoUser.Message", String(describing: p1), String(describing: p2), fallback: "There's no Useraccount \"%@\" on %@") - } - /// No User Account Found - public static let title = L10n.tr("Localizable", "Scene.Search.Searching.NoUser.Title", fallback: "No User Account Found") - } } } public enum ServerPicker { diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 9ef23c951..e5cb95e4d 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -442,16 +442,12 @@ uploaded to Mastodon."; "Scene.Search.Searching.Clear" = "Clear"; "Scene.Search.Searching.ClearAll" = "Clear all"; "Scene.Search.Searching.EmptyState.NoResults" = "No results"; -"Scene.Search.Searching.RecentSearch" = "Recent searches"; -"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; -"Scene.Search.Searching.People" = "People matching \"%@\""; -"Scene.Search.Searching.Profile" = "Go to @%@@%@"; "Scene.Search.Searching.Hashtag" = "Go to #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Go to @%@@%@"; +"Scene.Search.Searching.RecentSearch" = "Recent searches"; "Scene.Search.Searching.Url" = "Open URL in Mastodon"; - -"Scene.Search.Searching.NoUser.Title" = "No User Account Found"; -"Scene.Search.Searching.NoUser.Message" = "There's no Useraccount \"%@\" on %@"; - "Scene.Search.Title" = "Search"; "Scene.ServerPicker.Button.Category.Academia" = "academia"; "Scene.ServerPicker.Button.Category.Activism" = "activism"; @@ -560,4 +556,4 @@ uploaded to Mastodon."; "Widget.MultipleFollowers.ConfigurationDescription" = "Show number of followers for multiple accounts."; "Widget.MultipleFollowers.ConfigurationDisplayName" = "Multiple followers"; "Widget.MultipleFollowers.MockUser.AccountName" = "another@follower.social"; -"Widget.MultipleFollowers.MockUser.DisplayName" = "Another follower"; +"Widget.MultipleFollowers.MockUser.DisplayName" = "Another follower"; \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.strings index caa5f4d9f..666c56c2d 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.strings @@ -21,14 +21,14 @@ "Common.Alerts.SignOut.Title" = "تَسجيلُ الخُروج"; "Common.Alerts.SignUpFailure.Title" = "إخفاقٌ فِي التَّسجيل"; "Common.Alerts.TranslationFailed.Button" = "حسنًا"; -"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported."; +"Common.Alerts.TranslationFailed.Message" = "فشلت الترجمة. ربما لم يتمكن مدير الخادم من تفعيل الترجمات على هذا الخادم أو هذا الخادم يقوم بتشغيل نسخة قديمة من ماستدون حيث الترجمات غير مدعومة بعد."; "Common.Alerts.TranslationFailed.Title" = "مُلاحظة"; "Common.Alerts.VoteFailure.PollEnded" = "اِنتَهَى اِستِطلاعُ الرَّأي"; "Common.Alerts.VoteFailure.Title" = "إخفاقٌ فِي التَّصويت"; "Common.Controls.Actions.Add" = "إضافة"; "Common.Controls.Actions.Back" = "العودة"; "Common.Controls.Actions.BlockDomain" = "حظر %@"; -"Common.Controls.Actions.Bookmark" = "Bookmark"; +"Common.Controls.Actions.Bookmark" = "إضافة إلى الفواصل المرجعية"; "Common.Controls.Actions.Cancel" = "إلغاء"; "Common.Controls.Actions.Compose" = "تأليف"; "Common.Controls.Actions.Confirm" = "تأكيد"; @@ -39,9 +39,9 @@ "Common.Controls.Actions.Discard" = "تجاهُل"; "Common.Controls.Actions.Done" = "تمّ"; "Common.Controls.Actions.Edit" = "تَحرير"; -"Common.Controls.Actions.EditPost" = "Edit"; +"Common.Controls.Actions.EditPost" = "تعديل"; "Common.Controls.Actions.FindPeople" = "ابحث عن أشخاص لِمُتابعتهم"; -"Common.Controls.Actions.Follow" = "Follow %@"; +"Common.Controls.Actions.Follow" = "متابعة %@"; "Common.Controls.Actions.ManuallySearch" = "البحث يدويًا بدلًا من ذلك"; "Common.Controls.Actions.Next" = "التالي"; "Common.Controls.Actions.Ok" = "حسنًا"; @@ -51,7 +51,7 @@ "Common.Controls.Actions.Preview" = "مُعاينة"; "Common.Controls.Actions.Previous" = "السابق"; "Common.Controls.Actions.Remove" = "حذف"; -"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; +"Common.Controls.Actions.RemoveBookmark" = "إزالة الفاصلة المرجعية"; "Common.Controls.Actions.Reply" = "الرَّد"; "Common.Controls.Actions.ReportUser" = "الإبلاغُ عَن %@"; "Common.Controls.Actions.Save" = "حفظ"; @@ -68,7 +68,7 @@ "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "غير مَعرُوفة"; "Common.Controls.Actions.TryAgain" = "المُحاولة مرة أُخرى"; "Common.Controls.Actions.UnblockDomain" = "رفع الحظر عن %@"; -"Common.Controls.Actions.Unfollow" = "Unfollow %@"; +"Common.Controls.Actions.Unfollow" = "ألغِ متابعة %@"; "Common.Controls.Friendship.Block" = "حظر"; "Common.Controls.Friendship.BlockDomain" = "حظر %@"; "Common.Controls.Friendship.BlockUser" = "حَظرُ %@"; @@ -103,8 +103,8 @@ "Common.Controls.Keyboard.Timeline.ToggleContentWarning" = "تبديل تحذير المُحتَوى"; "Common.Controls.Keyboard.Timeline.ToggleFavorite" = "تبديل المفضلة لِمنشور"; "Common.Controls.Keyboard.Timeline.ToggleReblog" = "تبديل إعادة تدوين مَنشور"; -"Common.Controls.Status.Actions.A11YLabels.Reblog" = "Re-blog"; -"Common.Controls.Status.Actions.A11YLabels.Unreblog" = "Undo re-blog"; +"Common.Controls.Status.Actions.A11YLabels.Reblog" = "إعادة التدوين"; +"Common.Controls.Status.Actions.A11YLabels.Unreblog" = "التراجع عن إعادة التدوين"; "Common.Controls.Status.Actions.Favorite" = "التفضيل"; "Common.Controls.Status.Actions.Hide" = "إخفاء"; "Common.Controls.Status.Actions.Menu" = "القائمة"; @@ -117,17 +117,17 @@ "Common.Controls.Status.Actions.TapThenHoldToShowMenu" = "اُنقُر مُطَوَّلًا لِإظْهَارِ القائِمَة"; "Common.Controls.Status.Actions.Unfavorite" = "إزالة التفضيل"; "Common.Controls.Status.Actions.Unreblog" = "التراجُع عن إعادة النشر"; -"Common.Controls.Status.Buttons.EditHistoryDetail" = "Last edit %@"; -"Common.Controls.Status.Buttons.EditHistoryTitle" = "Edit History"; -"Common.Controls.Status.Buttons.FavoritesTitle" = "Favorites"; -"Common.Controls.Status.Buttons.ReblogsTitle" = "Reblogs"; +"Common.Controls.Status.Buttons.EditHistoryDetail" = "آخر تعديل %@"; +"Common.Controls.Status.Buttons.EditHistoryTitle" = "سِجِلّ التعديلات"; +"Common.Controls.Status.Buttons.FavoritesTitle" = "المفضلة"; +"Common.Controls.Status.Buttons.ReblogsTitle" = "المعاد تدوينها"; "Common.Controls.Status.ContentWarning" = "تحذير المُحتوى"; -"Common.Controls.Status.EditHistory.OriginalPost" = "Original Post · %@"; -"Common.Controls.Status.EditHistory.Title" = "Edit History"; -"Common.Controls.Status.EditedAtTimestampPrefix" = "Edited %@"; -"Common.Controls.Status.LinkViaUser" = "%@ via %@"; +"Common.Controls.Status.EditHistory.OriginalPost" = "المنشور الأصلي · %@"; +"Common.Controls.Status.EditHistory.Title" = "سِجِلّ التعديلات"; +"Common.Controls.Status.EditedAtTimestampPrefix" = "عُدّل في %@"; +"Common.Controls.Status.LinkViaUser" = "%@ عبر %@"; "Common.Controls.Status.LoadEmbed" = "تحميل المُضمَن"; -"Common.Controls.Status.Media.AccessibilityLabel" = "%@, attachment %d of %d"; +"Common.Controls.Status.Media.AccessibilityLabel" = "%@، مرفق %d من %d"; "Common.Controls.Status.Media.ExpandGifHint" = "Expands the GIF. Double-tap and hold to show actions"; "Common.Controls.Status.Media.ExpandImageHint" = "Expands the image. Double-tap and hold to show actions"; "Common.Controls.Status.Media.ExpandVideoHint" = "Shows the video player. Double-tap and hold to show actions"; @@ -138,7 +138,7 @@ "Common.Controls.Status.MetaEntity.Url" = "رابِط: %@"; "Common.Controls.Status.Poll.Closed" = "انتهى"; "Common.Controls.Status.Poll.Vote" = "صَوِّت"; -"Common.Controls.Status.PostedViaApplication" = "%@ via %@"; +"Common.Controls.Status.PostedViaApplication" = "%@ عبر %@"; "Common.Controls.Status.SensitiveContent" = "مُحتَوى حَسَّاس"; "Common.Controls.Status.ShowPost" = "أظْهِر مَنشور"; "Common.Controls.Status.ShowUserProfile" = "أظْهِر المِلَفَّ التَّعريفِيَّ لِلمُستَخدِم"; @@ -149,7 +149,7 @@ "Common.Controls.Status.Tag.Mention" = "إشارة"; "Common.Controls.Status.Tag.Url" = "عنوان URL"; "Common.Controls.Status.TapToReveal" = "اُنقُر لِلكَشف"; -"Common.Controls.Status.Translation.ShowOriginal" = "Show Original"; +"Common.Controls.Status.Translation.ShowOriginal" = "إظهار الأصل"; "Common.Controls.Status.Translation.TranslatedFrom" = "الترجَمَة مِن %@ بِاستِخدَام %@"; "Common.Controls.Status.Translation.UnknownLanguage" = "غير مَعرُوفة"; "Common.Controls.Status.Translation.UnknownProvider" = "غير مَعرُوف"; @@ -159,8 +159,8 @@ "Common.Controls.Status.Visibility.Private" = "فَقَطْ مُتابِعينَهُم مَن يُمكِنُهُم رُؤيَةُ هَذَا المَنشُور."; "Common.Controls.Status.Visibility.PrivateFromMe" = "فَقَطْ مُتابِعيني أنَا مَن يُمكِنُهُم رُؤيَةُ هَذَا المَنشُور."; "Common.Controls.Status.Visibility.Unlisted" = "يُمكِنُ لِلجَميعِ رُؤيَةُ هَذَا المَنشورِ وَلكِنَّهُ لَا يُعرَضُ فِي الخَطِّ الزَمنيّ العام."; -"Common.Controls.Tabs.A11Y.Explore" = "Explore"; -"Common.Controls.Tabs.A11Y.Search" = "Search"; +"Common.Controls.Tabs.A11Y.Explore" = "استكشف"; +"Common.Controls.Tabs.A11Y.Search" = "البحث"; "Common.Controls.Tabs.Home" = "الرَّئِيسَة"; "Common.Controls.Tabs.Notifications" = "الإشعارات"; "Common.Controls.Tabs.Profile" = "المِلَفُّ التَّعريفِيّ"; @@ -183,9 +183,9 @@ "Common.Controls.Timeline.Loader.LoadingMissingPosts" = "يَجري تحميل المَنشورات المَفقودَة..."; "Common.Controls.Timeline.Loader.ShowMoreReplies" = "أظْهِر مَزيدًا مِنَ الرُّدود"; "Common.Controls.Timeline.Timestamp.Now" = "الآن"; -"Common.UserList.FollowersCount" = "%@ followers"; -"Common.UserList.NoVerifiedLink" = "No verified link"; -"Extension.OpenIn.InvalidLinkError" = "This doesn't seem to be a valid Mastodon link."; +"Common.UserList.FollowersCount" = "%@ متابعين"; +"Common.UserList.NoVerifiedLink" = "رابط غير متحقق منه"; +"Extension.OpenIn.InvalidLinkError" = "لا يبدو أن هذا رابط ماستدون صالح."; "Scene.AccountList.AddAccount" = "إضافَةُ حِساب"; "Scene.AccountList.DismissAccountSwitcher" = "تجاهُل مبدِّل الحِساب"; "Scene.AccountList.TabBarHint" = "المِلَفُّ المُحدَّدُ حالِيًّا: %@. اُنقُر نَقرًا مُزدَوَجًا مَعَ الاِستِمرارِ لِإظهارِ مُبدِّلِ الحِساب"; @@ -221,30 +221,30 @@ "Scene.Compose.Keyboard.SelectVisibilityEntry" = "اختر مدى الظهور - %@"; "Scene.Compose.Keyboard.ToggleContentWarning" = "تبديل تحذير المُحتَوى"; "Scene.Compose.Keyboard.TogglePoll" = "تبديل الاستطلاع"; -"Scene.Compose.Language.Other" = "Other Language…"; -"Scene.Compose.Language.Recent" = "Recent"; -"Scene.Compose.Language.Suggested" = "Suggested"; -"Scene.Compose.Language.Title" = "Post Language"; +"Scene.Compose.Language.Other" = "لغات أخرى…"; +"Scene.Compose.Language.Recent" = "الأخيرة"; +"Scene.Compose.Language.Suggested" = "المقترحَة"; +"Scene.Compose.Language.Title" = "لغة النشر"; "Scene.Compose.MediaSelection.Browse" = "تَصَفَّح"; "Scene.Compose.MediaSelection.Camera" = "اِلتِقاطُ صُورَة"; "Scene.Compose.MediaSelection.PhotoLibrary" = "مَكتَبَةُ الصُّوَر"; -"Scene.Compose.Poll.AddOption" = "Add Option"; +"Scene.Compose.Poll.AddOption" = "إضافة خيار"; "Scene.Compose.Poll.DurationTime" = "المُدَّة: %@"; -"Scene.Compose.Poll.MoveDown" = "Move Down"; -"Scene.Compose.Poll.MoveUp" = "Move Up"; +"Scene.Compose.Poll.MoveDown" = "أنقله إلى أسفل"; +"Scene.Compose.Poll.MoveUp" = "أنقله إلى أعلى"; "Scene.Compose.Poll.OneDay" = "يومٌ واحِد"; "Scene.Compose.Poll.OneHour" = "ساعةٌ واحدة"; "Scene.Compose.Poll.OptionNumber" = "الخيار %ld"; -"Scene.Compose.Poll.RemoveOption" = "Remove Option"; +"Scene.Compose.Poll.RemoveOption" = "إزالة الخيار"; "Scene.Compose.Poll.SevenDays" = "سبعةُ أيام"; "Scene.Compose.Poll.SixHours" = "سِتُّ ساعات"; "Scene.Compose.Poll.ThePollHasEmptyOption" = "يوجَدُ خِيارٌ فارِغٌ فِي الاِستِطلاع"; "Scene.Compose.Poll.ThePollIsInvalid" = "الاِستِطلاعُ غيرُ صالِح"; "Scene.Compose.Poll.ThirtyMinutes" = "ثلاثون دقيقة"; "Scene.Compose.Poll.ThreeDays" = "ثلاثةُ أيام"; -"Scene.Compose.Poll.Title" = "Poll"; +"Scene.Compose.Poll.Title" = "استطلاع رأي"; "Scene.Compose.ReplyingToUser" = "رَدًا على %@"; -"Scene.Compose.Title.EditPost" = "Edit Post"; +"Scene.Compose.Title.EditPost" = "تعديل المنشور"; "Scene.Compose.Title.NewPost" = "مَنشُورٌ جَديد"; "Scene.Compose.Title.NewReply" = "رَدٌّ جديد"; "Scene.Compose.Visibility.Direct" = "لِمَن أشرتُ إليهِم فَقَط"; @@ -252,18 +252,18 @@ "Scene.Compose.Visibility.Public" = "لِلعَامَّة"; "Scene.Compose.Visibility.Unlisted" = "غير مُدرَج"; "Scene.ConfirmEmail.Button.Resend" = "إعادَةُ الإرسال"; -"Scene.ConfirmEmail.DidntGetLink.Prefix" = "Didn’t get a link?"; -"Scene.ConfirmEmail.DidntGetLink.ResendIn" = "Resend (%@)"; -"Scene.ConfirmEmail.DidntGetLink.ResendNow" = "Resend now."; +"Scene.ConfirmEmail.DidntGetLink.Prefix" = "ألم تحصل على رابط؟"; +"Scene.ConfirmEmail.DidntGetLink.ResendIn" = "إعادة إرسال (%@)"; +"Scene.ConfirmEmail.DidntGetLink.ResendNow" = "أعد الإرسال الآن."; "Scene.ConfirmEmail.DontReceiveEmail.Description" = "تحقق ممَّ إذا كان عنوان بريدك الإلكتروني صحيحًا، وكذلك تأكد مِن مجلد البريد غير الهام إذا لم تكن قد فعلت ذلك."; "Scene.ConfirmEmail.DontReceiveEmail.ResendEmail" = "إعادة إرسال البريد الإلكتروني"; -"Scene.ConfirmEmail.DontReceiveEmail.Title" = "Check your Email"; +"Scene.ConfirmEmail.DontReceiveEmail.Title" = "تحقق من بريدك الإلكتروني"; "Scene.ConfirmEmail.OpenEmailApp.Description" = "لقد أرسلنا لك بريدًا إلكترونيًا للتو. تحقق من مجلد البريد غير الهام الخاص بك إذا لم تكن قد فعلت ذلك."; "Scene.ConfirmEmail.OpenEmailApp.Mail" = "البريد"; "Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "فتح عميل البريد الإلكتروني"; -"Scene.ConfirmEmail.OpenEmailApp.Title" = "Check your Inbox."; -"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Tap the link we sent you to verify %@. We’ll wait right here."; -"Scene.ConfirmEmail.Title" = "Check Your Inbox"; +"Scene.ConfirmEmail.OpenEmailApp.Title" = "تحقَّق من بريدك الوارِد."; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "اضغط على الرابط الذي أرسلناه إليك للتحقق من %@. سننتظر هنا."; +"Scene.ConfirmEmail.Title" = "تحقَّق من بريدك الوارِد"; "Scene.Discovery.Intro" = "هَذِهِ هِيَ المَنشُوراتُ الَّتي تَكْتَسِبُ شَعبِيَّةً فِي الرُّكنِ الخاصِّ بِكَ مِن مَاستُودون."; "Scene.Discovery.Tabs.Community" = "المُجتَمَع"; "Scene.Discovery.Tabs.ForYou" = "لَك"; @@ -272,7 +272,7 @@ "Scene.Discovery.Tabs.Posts" = "مَنشُورات"; "Scene.Familiarfollowers.FollowedByNames" = "مُتابَعٌ مِن قِبَلِ %@"; "Scene.Familiarfollowers.Title" = "مُتابِعُونَ مَألُوفُونَ بِالنِّسبَةِ لَك"; -"Scene.Favorite.Title" = "Favorites"; +"Scene.Favorite.Title" = "المفضلة"; "Scene.FavoritedBy.Title" = "مُفَضَّلٌ مِن قِبَلِ"; "Scene.FollowedTags.Actions.Follow" = "مُتابَعَة"; "Scene.FollowedTags.Actions.Unfollow" = "إلغاءُ المُتابَعَة"; @@ -285,7 +285,7 @@ "Scene.Following.Footer" = "لا يُمكِن عَرض المُتابَعات مِنَ الخوادم الأُخرى."; "Scene.Following.Title" = "مُتابَعُون"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "اُنقُر لِلتمريرِ لأعلى واُنقُر مَرّةً أُخرَى لِلذَّهابِ إلَى المَوقِعِ السَّابِق"; -"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "ماستدون"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "إظهار منشورات جديدة"; "Scene.HomeTimeline.NavigationBarState.Offline" = "غَير مُتَّصِل"; "Scene.HomeTimeline.NavigationBarState.Published" = "تمَّ النَّشر!"; @@ -293,7 +293,7 @@ "Scene.HomeTimeline.Title" = "الرَّئِيسَة"; "Scene.Login.ServerSearchField.Placeholder" = "أدخِل عُنوانَ URL أو اِبحَث عَنِ الخادِمِ الخاصّ بِك"; "Scene.Login.Subtitle" = "سَجِّل دُخولَكَ إلى الخادِم الَّذي أنشأتَ حِسابَكَ فيه."; -"Scene.Login.Title" = "Welcome back"; +"Scene.Login.Title" = "مرحباً بك مجددًا"; "Scene.Notification.FollowRequest.Accept" = "قَبُول"; "Scene.Notification.FollowRequest.Accepted" = "مَقبُول"; "Scene.Notification.FollowRequest.Reject" = "رَفض"; @@ -311,16 +311,16 @@ "Scene.Preview.Keyboard.ClosePreview" = "إغلاق المُعايَنَة"; "Scene.Preview.Keyboard.ShowNext" = "أظْهِر التَّالي"; "Scene.Preview.Keyboard.ShowPrevious" = "أظْهِر السَّابِق"; -"Scene.Privacy.Button.Confirm" = "I Agree"; -"Scene.Privacy.Description" = "Although the Mastodon app does not collect any data, the server you sign up through may have a different policy. Take a minute to review and agree to the Mastodon app privacy policy and your server’s privacy policy."; -"Scene.Privacy.Policy.Ios" = "Privacy Policy - Mastodon for iOS"; -"Scene.Privacy.Policy.Server" = "Privacy Policy - %@"; -"Scene.Privacy.Title" = "Privacy"; +"Scene.Privacy.Button.Confirm" = "أوافق"; +"Scene.Privacy.Description" = "على الرغم من أن تطبيق ماستدون لا يجمع أي بيانات، فإن الخادم الذي قمت بالتسجيل من خلاله قد تكون له سياسة مختلفة. خذ دقيقة للمراجعة والموافقة على سياسة خصوصية تطبيق ماستدون وسياسة الخصوصية الخاصة بخادمك."; +"Scene.Privacy.Policy.Ios" = "سياسة الخصوصية - ماستدون لنظام التشغيل iOS"; +"Scene.Privacy.Policy.Server" = "سياسة الخصوصية - %@"; +"Scene.Privacy.Title" = "الخصوصية"; "Scene.Profile.Accessibility.DoubleTapToOpenTheList" = "اُنقُر نَقرًا مُزدَوَجًا لِفَتحِ القائِمَة"; "Scene.Profile.Accessibility.EditAvatarImage" = "تَحريرُ الصُّورَةِ الرَّمزِيَّة"; "Scene.Profile.Accessibility.ShowAvatarImage" = "أظْهِر الصُّورَةَ الرَّمزِيَّة"; "Scene.Profile.Accessibility.ShowBannerImage" = "أظْهِر صُورَةَ الرَّايَة"; -"Scene.Profile.Dashboard.FamiliarFollowers" = "mutuals"; +"Scene.Profile.Dashboard.FamiliarFollowers" = "متابعة متبادلة"; "Scene.Profile.Dashboard.MyFollowers" = "مُتابِعُون"; "Scene.Profile.Dashboard.MyFollowing" = "مُتابَعُون"; "Scene.Profile.Dashboard.MyPosts" = "مَنشورات"; @@ -328,7 +328,7 @@ "Scene.Profile.Dashboard.OtherFollowing" = "مُتابَعُون"; "Scene.Profile.Dashboard.OtherPosts" = "مَنشورات"; "Scene.Profile.Fields.AddRow" = "إضافة صف"; -"Scene.Profile.Fields.Joined" = "Joined"; +"Scene.Profile.Fields.Joined" = "انضم في"; "Scene.Profile.Fields.Placeholder.Content" = "المُحتَوى"; "Scene.Profile.Fields.Placeholder.Label" = "التسمية"; "Scene.Profile.Fields.Verified.Long" = "تمَّ التَّحقق مِن مِلكية هذا الرابِطِ بِتاريخ %@"; @@ -364,7 +364,7 @@ "Scene.Register.Error.Reason.Inclusion" = "إنَّ %@ قيمة غير مدعومة"; "Scene.Register.Error.Reason.Invalid" = "%@ غير صالح"; "Scene.Register.Error.Reason.Reserved" = "إنَّ %@ عبارة عن كلمة مفتاحيَّة محجوزة"; -"Scene.Register.Error.Reason.Taken" = "%@ is already taken. How about:"; +"Scene.Register.Error.Reason.Taken" = "%@ مأخوذ بالفعل. ماذا عن:"; "Scene.Register.Error.Reason.TooLong" = "%@ طَويلٌ جِدًّا"; "Scene.Register.Error.Reason.TooShort" = "%@ قَصِيرٌ جِدًا"; "Scene.Register.Error.Reason.Unreachable" = "يبدوا أنَّ %@ غير موجود"; @@ -379,14 +379,14 @@ "Scene.Register.Input.Password.Accessibility.Checked" = "مُتَحَققٌ مِنه"; "Scene.Register.Input.Password.Accessibility.Unchecked" = "غيرُ مُتَحَققٍ مِنه"; "Scene.Register.Input.Password.CharacterLimit" = "ثمانيةُ خانات"; -"Scene.Register.Input.Password.ConfirmationPlaceholder" = "Confirm Password"; +"Scene.Register.Input.Password.ConfirmationPlaceholder" = "أكّد كلمة السر"; "Scene.Register.Input.Password.Hint" = "يَجِبُ أن يَحتَوي رَمزُكَ السِرِّيَ علَى ثَمانِ خاناتٍ أقلًا"; "Scene.Register.Input.Password.Placeholder" = "رمز سري"; "Scene.Register.Input.Password.Require" = "رمز المرور الخاص بك يجب أن يحتوي على الأقل:"; "Scene.Register.Input.Username.DuplicatePrompt" = "اِسم المُستَخدِم هذا مأخوذٌ بالفعل."; "Scene.Register.Input.Username.Placeholder" = "اِسمُ مُستَخدِم"; -"Scene.Register.Input.Username.Suggestion" = "amazing_%@"; -"Scene.Register.Title" = "Create Account"; +"Scene.Register.Input.Username.Suggestion" = "مذهل_%@"; +"Scene.Register.Title" = "إنشاء حساب"; "Scene.Report.Content1" = "هل ترغب في إضافة أي منشورات أُخرى إلى البلاغ؟"; "Scene.Report.Content2" = "هل هناك أي شيء يجب أن يعرفه المُراقبين حول هذا البلاغ؟"; "Scene.Report.ReportSentTitle" = "شُكرًا لَكَ على الإبلاغ، سَوفَ نَنظُرُ فِي هَذَا الأمر."; @@ -440,12 +440,14 @@ "Scene.Search.SearchBar.Cancel" = "إلغاء"; "Scene.Search.SearchBar.Placeholder" = "اِبحَث عَن وُسُومٍ أو مُستَخدِمين"; "Scene.Search.Searching.Clear" = "مَحو"; +"Scene.Search.Searching.ClearAll" = "Clear all"; "Scene.Search.Searching.EmptyState.NoResults" = "لا تُوجَدُ نتائِج"; +"Scene.Search.Searching.Hashtag" = "Go to #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Go to @%@@%@"; "Scene.Search.Searching.RecentSearch" = "عَمَليَّاُت البَحثِ الأخيرَة"; -"Scene.Search.Searching.Segment.All" = "الكُل"; -"Scene.Search.Searching.Segment.Hashtags" = "وُسُوم"; -"Scene.Search.Searching.Segment.People" = "أشخاص"; -"Scene.Search.Searching.Segment.Posts" = "مَنشُورات"; +"Scene.Search.Searching.Url" = "Open URL in Mastodon"; "Scene.Search.Title" = "البَحث"; "Scene.ServerPicker.Button.Category.Academia" = "أكاديمي"; "Scene.ServerPicker.Button.Category.Activism" = "نُشَطاء"; @@ -461,10 +463,10 @@ "Scene.ServerPicker.Button.Category.Music" = "مُوسيقى"; "Scene.ServerPicker.Button.Category.Regional" = "إقليمي"; "Scene.ServerPicker.Button.Category.Tech" = "تَقنِيَة"; -"Scene.ServerPicker.Button.Language" = "Language"; +"Scene.ServerPicker.Button.Language" = "اللغة"; "Scene.ServerPicker.Button.SeeLess" = "عَرضُ عَناصِرٍ أقَل"; "Scene.ServerPicker.Button.SeeMore" = "عَرضُ عَناصِرٍ أكثَر"; -"Scene.ServerPicker.Button.SignupSpeed" = "Sign-up Speed"; +"Scene.ServerPicker.Button.SignupSpeed" = "سرعة التسجيل"; "Scene.ServerPicker.EmptyState.BadNetwork" = "حدث خطأٌ ما أثناء تحميل البيانات. تحقَّق من اتصالك بالإنترنت."; "Scene.ServerPicker.EmptyState.FindingServers" = "يجري إيجاد خوادم متوفِّرَة..."; "Scene.ServerPicker.EmptyState.NoResults" = "لا توجد نتائج"; @@ -472,14 +474,14 @@ "Scene.ServerPicker.Label.Category" = "الفئة"; "Scene.ServerPicker.Label.Language" = "اللُّغَة"; "Scene.ServerPicker.Label.Users" = "مُستَخدِم"; -"Scene.ServerPicker.Language.All" = "All"; -"Scene.ServerPicker.NoServerSelectedHint" = "We’ll pick a server based on your language if you continue without making a selection."; -"Scene.ServerPicker.Search.Placeholder" = "Search name or URL"; -"Scene.ServerPicker.SignupSpeed.All" = "All"; -"Scene.ServerPicker.SignupSpeed.Instant" = "Instant Sign-up"; -"Scene.ServerPicker.SignupSpeed.ManuallyReviewed" = "Manual Review"; -"Scene.ServerPicker.Title" = "Pick Server"; -"Scene.ServerRules.Button.Confirm" = "I Agree"; +"Scene.ServerPicker.Language.All" = "الكل"; +"Scene.ServerPicker.NoServerSelectedHint" = "سوف نختار خادماً بناءً على لغتك إذا قمت بالمتابعة دون إجراء إختيار."; +"Scene.ServerPicker.Search.Placeholder" = "البحث عن اسم أو رابط تشعّبي URL"; +"Scene.ServerPicker.SignupSpeed.All" = "الكل"; +"Scene.ServerPicker.SignupSpeed.Instant" = "تسجيل فوري"; +"Scene.ServerPicker.SignupSpeed.ManuallyReviewed" = "مراجعة يدوية"; +"Scene.ServerPicker.Title" = "اختر خادمًا"; +"Scene.ServerRules.Button.Confirm" = "أوافق"; "Scene.ServerRules.PrivacyPolicy" = "سِياسَة الخُصُوصيَّة"; "Scene.ServerRules.Prompt" = "في حال إختيارك للمواصلة، أنت تخضع لشروط الخدمة وسياسة الخصوصية لِـ%@."; "Scene.ServerRules.Subtitle" = "سُنَّت هذه القواعد من قِبل مشرفي %@."; @@ -512,46 +514,46 @@ "Scene.Settings.Section.Notifications.Trigger.Title" = "أشعِرني عِندما يَقومُ"; "Scene.Settings.Section.Preference.DisableAvatarAnimation" = "تَعطيلُ الصوَرِ الرمزيَّةِ المُتحرِّكَة"; "Scene.Settings.Section.Preference.DisableEmojiAnimation" = "تَعطيلُ الرُموزِ التَّعبيريَّةِ المُتحرِّكَة"; -"Scene.Settings.Section.Preference.OpenLinksInMastodon" = "فَتحُ الرَّوابِطِ فِي مَاستودُون"; +"Scene.Settings.Section.Preference.OpenLinksInMastodon" = "فَتحُ الرَّوابِطِ فِي مَاستدون"; "Scene.Settings.Section.Preference.Title" = "التَّفضيلات"; "Scene.Settings.Section.Preference.UsingDefaultBrowser" = "اِستِخدامُ المُتصفِّحِ الاِفتراضي لِفتحِ الرَّوابِط"; "Scene.Settings.Section.SpicyZone.Clear" = "مَحوُ ذاكِرَةِ التَّخزينِ المُؤقَّتِ لِلوسائِط"; "Scene.Settings.Section.SpicyZone.Signout" = "تَسجيلُ الخُروج"; "Scene.Settings.Section.SpicyZone.Title" = "المنطِقَةُ اللَّاذِعَة"; "Scene.Settings.Title" = "الإعدادات"; -"Scene.SuggestionAccount.FollowAll" = "Follow all"; -"Scene.SuggestionAccount.Title" = "Popular on Mastodon"; +"Scene.SuggestionAccount.FollowAll" = "اتبع الكل"; +"Scene.SuggestionAccount.Title" = "رائج على ماستدون"; "Scene.Thread.BackTitle" = "منشور"; "Scene.Thread.Title" = "مَنشور مِن %@"; -"Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "What is Mastodon?"; -"Scene.Welcome.Education.Mastodon.Description" = "Mastodon is a decentralized social network, meaning no single company controls it. It’s made up of many independently-run servers, all connected together."; -"Scene.Welcome.Education.Mastodon.Title" = "Welcome to Mastodon"; -"Scene.Welcome.Education.Servers.Description" = "Every Mastodon account is hosted on a server — each with its own values, rules, & admins. No matter which one you pick, you can follow and interact with people on any server."; -"Scene.Welcome.Education.Servers.Title" = "What are servers?"; -"Scene.Welcome.JoinDefaultServer" = "Join %@"; -"Scene.Welcome.LearnMore" = "Learn more"; +"Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "ما هو ماستدون؟"; +"Scene.Welcome.Education.Mastodon.Description" = "ماستدون شبكة اجتماعية لامركزية، بمعنى أنه ليس هناك شركة واحدة تتحكم فيها. وهي تتألف من العديد من الخوادم التي تدار بشكل مستقل، وجميعها متصلة معا."; +"Scene.Welcome.Education.Mastodon.Title" = "أهلًا بك على ماستدون"; +"Scene.Welcome.Education.Servers.Description" = "تتم استضافة كل حساب ماستدون على خادم - ولكل منها قيمه وقواعده ومسؤوليه الخاصين. بغض النظر عن الشخص الذي تختاره ، يمكنك متابعة الأشخاص والتفاعل معهم على أي خادم."; +"Scene.Welcome.Education.Servers.Title" = "ما هي الخوادم؟"; +"Scene.Welcome.JoinDefaultServer" = "انضم إلى %@"; +"Scene.Welcome.LearnMore" = "تعلم المزيد"; "Scene.Welcome.LogIn" = "تسجيلُ الدخول"; -"Scene.Welcome.PickServer" = "Pick another server"; -"Scene.Welcome.Separator.Or" = "or"; +"Scene.Welcome.PickServer" = "اختر خادمًا آخر"; +"Scene.Welcome.Separator.Or" = "أو"; "Widget.Common.UnsupportedWidgetFamily" = "Sorry but this Widget family is unsupported."; -"Widget.Common.UserNotLoggedIn" = "Please open Mastodon to log in to an Account."; -"Widget.FollowersCount.ConfigurationDescription" = "Show number of followers."; -"Widget.FollowersCount.ConfigurationDisplayName" = "Followers"; +"Widget.Common.UserNotLoggedIn" = "الرجاء فتح ماستدون لتسجيل الدخول إلى حساب."; +"Widget.FollowersCount.ConfigurationDescription" = "إظهار عدد المتابعين."; +"Widget.FollowersCount.ConfigurationDisplayName" = "المتابِعون"; "Widget.FollowersCount.FollowersToday" = "%@ followers today"; -"Widget.FollowersCount.Title" = "FOLLOWERS"; +"Widget.FollowersCount.Title" = "المتابِعون"; "Widget.Hashtag.Configuration.Description" = "Shows a recent post with the selected hashtag."; -"Widget.Hashtag.Configuration.DisplayName" = "Hashtag"; +"Widget.Hashtag.Configuration.DisplayName" = "وسم"; "Widget.Hashtag.NotFound.Account" = "@johnMastodon@no-such.account"; "Widget.Hashtag.NotFound.AccountName" = "John Mastodon"; "Widget.Hashtag.NotFound.Content" = "Sorry, we couldn’t find any posts with the hashtag #%@. Please try a #DifferentHashtag or check the widget settings."; "Widget.Hashtag.Placeholder.Account" = "@johnMastodon@no-such.account"; "Widget.Hashtag.Placeholder.AccountName" = "John Mastodon"; "Widget.Hashtag.Placeholder.Content" = "This is how a post with a #hashtag would look. Pick whichever #hashtag you want in the widget settings."; -"Widget.LatestFollowers.ConfigurationDescription" = "Show latest followers."; -"Widget.LatestFollowers.ConfigurationDisplayName" = "Latest followers"; -"Widget.LatestFollowers.LastUpdate" = "Last update: %@"; -"Widget.LatestFollowers.Title" = "Latest followers"; -"Widget.MultipleFollowers.ConfigurationDescription" = "Show number of followers for multiple accounts."; -"Widget.MultipleFollowers.ConfigurationDisplayName" = "Multiple followers"; +"Widget.LatestFollowers.ConfigurationDescription" = "إظهار أحدث المتابِعين."; +"Widget.LatestFollowers.ConfigurationDisplayName" = "أحدث المتابعين"; +"Widget.LatestFollowers.LastUpdate" = "آخر تحديث: %@"; +"Widget.LatestFollowers.Title" = "أحدث المتابعين"; +"Widget.MultipleFollowers.ConfigurationDescription" = "إظهار عدد المتابعين لحسابات متعددة."; +"Widget.MultipleFollowers.ConfigurationDisplayName" = "متابعين متعددين"; "Widget.MultipleFollowers.MockUser.AccountName" = "another@follower.social"; -"Widget.MultipleFollowers.MockUser.DisplayName" = "Another follower"; \ No newline at end of file +"Widget.MultipleFollowers.MockUser.DisplayName" = "متابع آخر"; \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/be.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/be.lproj/Localizable.strings index 4d8f7d218..a92e4a131 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/be.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/be.lproj/Localizable.strings @@ -440,12 +440,14 @@ "Scene.Search.SearchBar.Cancel" = "Скасаваць"; "Scene.Search.SearchBar.Placeholder" = "Пошук хэштэгаў і карыстальнікаў"; "Scene.Search.Searching.Clear" = "Ачысціць"; +"Scene.Search.Searching.ClearAll" = "Clear all"; "Scene.Search.Searching.EmptyState.NoResults" = "Няма вынікаў"; +"Scene.Search.Searching.Hashtag" = "Go to #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Go to @%@@%@"; "Scene.Search.Searching.RecentSearch" = "Нядаўнія запыты"; -"Scene.Search.Searching.Segment.All" = "Усе"; -"Scene.Search.Searching.Segment.Hashtags" = "Хэштэгі"; -"Scene.Search.Searching.Segment.People" = "Людзі"; -"Scene.Search.Searching.Segment.Posts" = "Допісы"; +"Scene.Search.Searching.Url" = "Open URL in Mastodon"; "Scene.Search.Title" = "Пошук"; "Scene.ServerPicker.Button.Category.Academia" = "акадэмія"; "Scene.ServerPicker.Button.Category.Activism" = "актывізм"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.strings index 4c93afc67..d8ad0c93e 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.strings @@ -1,7 +1,7 @@ "Common.Alerts.BlockDomain.BlockEntireDomain" = "Bloca el domini"; "Common.Alerts.BlockDomain.Title" = "Estàs totalment segur que vols bloquejar per complet %@? En la majoria dels casos bloquejar o silenciar uns pocs objectius és suficient i preferible. No veureu contingut d’aquest domini i se suprimirà qualsevol dels vostres seguidors d’aquest domini."; -"Common.Alerts.CleanCache.Message" = "S'ha netejat correctament la memòria cau de %@."; -"Common.Alerts.CleanCache.Title" = "Neteja la memòria cau"; +"Common.Alerts.CleanCache.Message" = "S'han esborrat %@ de memòria cau."; +"Common.Alerts.CleanCache.Title" = "Esborra la memòria cau"; "Common.Alerts.Common.PleaseTryAgain" = "Torna-ho a provar."; "Common.Alerts.Common.PleaseTryAgainLater" = "Prova-ho més tard."; "Common.Alerts.DeletePost.Message" = "Segur que vols eliminar aquesta publicació?"; @@ -27,7 +27,7 @@ Comprova la connexió a Internet."; "Common.Alerts.VoteFailure.Title" = "Error en votar"; "Common.Controls.Actions.Add" = "Afegeix"; "Common.Controls.Actions.Back" = "Enrere"; -"Common.Controls.Actions.BlockDomain" = "Bloqueja %@"; +"Common.Controls.Actions.BlockDomain" = "Bloca %@"; "Common.Controls.Actions.Bookmark" = "Marcador"; "Common.Controls.Actions.Cancel" = "Cancel·la"; "Common.Controls.Actions.Compose" = "Redacta"; @@ -42,7 +42,7 @@ Comprova la connexió a Internet."; "Common.Controls.Actions.EditPost" = "Edita"; "Common.Controls.Actions.FindPeople" = "Busca persones a seguir"; "Common.Controls.Actions.Follow" = "Segueix a %@"; -"Common.Controls.Actions.ManuallySearch" = "Cerca manualment a canvi"; +"Common.Controls.Actions.ManuallySearch" = "Millor cerca manualment"; "Common.Controls.Actions.Next" = "Següent"; "Common.Controls.Actions.Ok" = "D'acord"; "Common.Controls.Actions.Open" = "Obre"; @@ -51,9 +51,9 @@ Comprova la connexió a Internet."; "Common.Controls.Actions.Preview" = "Vista prèvia"; "Common.Controls.Actions.Previous" = "Anterior"; "Common.Controls.Actions.Remove" = "Elimina"; -"Common.Controls.Actions.RemoveBookmark" = "Suprimeix el marcador"; +"Common.Controls.Actions.RemoveBookmark" = "Elimina el marcador"; "Common.Controls.Actions.Reply" = "Respon"; -"Common.Controls.Actions.ReportUser" = "Informa sobre %@"; +"Common.Controls.Actions.ReportUser" = "Denuncia %@"; "Common.Controls.Actions.Save" = "Desa"; "Common.Controls.Actions.SavePhoto" = "Desa la foto"; "Common.Controls.Actions.SeeMore" = "Mostra'n més"; @@ -64,7 +64,7 @@ Comprova la connexió a Internet."; "Common.Controls.Actions.SignIn" = "Inicia sessió"; "Common.Controls.Actions.Skip" = "Omet"; "Common.Controls.Actions.TakePhoto" = "Fes una foto"; -"Common.Controls.Actions.TranslatePost.Title" = "Traduït del %@"; +"Common.Controls.Actions.TranslatePost.Title" = "Tradueix del: %@"; "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Desconegut"; "Common.Controls.Actions.TryAgain" = "Torna a provar"; "Common.Controls.Actions.UnblockDomain" = "Desbloca %@"; @@ -440,12 +440,14 @@ carregat a Mastodon."; "Scene.Search.SearchBar.Cancel" = "Cancel·la"; "Scene.Search.SearchBar.Placeholder" = "Cerca etiquetes i usuaris"; "Scene.Search.Searching.Clear" = "Neteja"; +"Scene.Search.Searching.ClearAll" = "Esborra-ho tot"; "Scene.Search.Searching.EmptyState.NoResults" = "No hi ha resultats"; +"Scene.Search.Searching.Hashtag" = "Vés a #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Vés a @%@@%@"; "Scene.Search.Searching.RecentSearch" = "Cerques recents"; -"Scene.Search.Searching.Segment.All" = "Tots"; -"Scene.Search.Searching.Segment.Hashtags" = "Etiquetes"; -"Scene.Search.Searching.Segment.People" = "Gent"; -"Scene.Search.Searching.Segment.Posts" = "Tuts"; +"Scene.Search.Searching.Url" = "Obre l'enllaç a Mastodon"; "Scene.Search.Title" = "Cerca"; "Scene.ServerPicker.Button.Category.Academia" = "acadèmia"; "Scene.ServerPicker.Button.Category.Activism" = "activisme"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings index d7d009c0a..24df73232 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings @@ -439,12 +439,14 @@ "Scene.Search.SearchBar.Cancel" = "بگەڕێوە"; "Scene.Search.SearchBar.Placeholder" = "بۆ هاشتاگ و بەکارهێنەر بگەڕێ"; "Scene.Search.Searching.Clear" = "بیانسڕەوە"; +"Scene.Search.Searching.ClearAll" = "Clear all"; "Scene.Search.Searching.EmptyState.NoResults" = "هیچ ئەنجامێک نەدۆزرایەوە"; +"Scene.Search.Searching.Hashtag" = "Go to #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Go to @%@@%@"; "Scene.Search.Searching.RecentSearch" = "گەڕانەکانی پێشترت"; -"Scene.Search.Searching.Segment.All" = "هەمووی"; -"Scene.Search.Searching.Segment.Hashtags" = "هاشتاگ"; -"Scene.Search.Searching.Segment.People" = "خەڵک"; -"Scene.Search.Searching.Segment.Posts" = "پۆست"; +"Scene.Search.Searching.Url" = "Open URL in Mastodon"; "Scene.Search.Title" = "بگەڕێ"; "Scene.ServerPicker.Button.Category.Academia" = "ئەکادیمیا"; "Scene.ServerPicker.Button.Category.Activism" = "چالاکی"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/cs.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/cs.lproj/Localizable.strings index 136c4f9e4..dd04a01b8 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/cs.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/cs.lproj/Localizable.strings @@ -436,12 +436,14 @@ nahrán do Mastodonu."; "Scene.Search.SearchBar.Cancel" = "Zrušit"; "Scene.Search.SearchBar.Placeholder" = "Hledat hashtagy a uživatele"; "Scene.Search.Searching.Clear" = "Vymazat"; +"Scene.Search.Searching.ClearAll" = "Clear all"; "Scene.Search.Searching.EmptyState.NoResults" = "Žádné výsledky"; +"Scene.Search.Searching.Hashtag" = "Go to #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Go to @%@@%@"; "Scene.Search.Searching.RecentSearch" = "Nedávná hledání"; -"Scene.Search.Searching.Segment.All" = "Vše"; -"Scene.Search.Searching.Segment.Hashtags" = "Hashtagy"; -"Scene.Search.Searching.Segment.People" = "Lidé"; -"Scene.Search.Searching.Segment.Posts" = "Příspěvky"; +"Scene.Search.Searching.Url" = "Open URL in Mastodon"; "Scene.Search.Title" = "Hledat"; "Scene.ServerPicker.Button.Category.Academia" = "akademická sféra"; "Scene.ServerPicker.Button.Category.Activism" = "aktivismus"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.strings index 8013f1b61..e869f6b1a 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.strings @@ -440,12 +440,14 @@ kann nicht auf Mastodon hochgeladen werden."; "Scene.Search.SearchBar.Cancel" = "Abbrechen"; "Scene.Search.SearchBar.Placeholder" = "Hashtags und Benutzer suchen"; "Scene.Search.Searching.Clear" = "Zurücksetzen"; +"Scene.Search.Searching.ClearAll" = "Clear all"; "Scene.Search.Searching.EmptyState.NoResults" = "Keine Ergebnisse"; +"Scene.Search.Searching.Hashtag" = "Go to #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Go to @%@@%@"; "Scene.Search.Searching.RecentSearch" = "Zuletzt gesucht"; -"Scene.Search.Searching.Segment.All" = "Alles"; -"Scene.Search.Searching.Segment.Hashtags" = "Hashtags"; -"Scene.Search.Searching.Segment.People" = "Personen"; -"Scene.Search.Searching.Segment.Posts" = "Beiträge"; +"Scene.Search.Searching.Url" = "Open URL in Mastodon"; "Scene.Search.Title" = "Suche"; "Scene.ServerPicker.Button.Category.Academia" = "Wissenschaft"; "Scene.ServerPicker.Button.Category.Activism" = "Aktivismus"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/el.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/el.lproj/Localizable.strings index f46391a81..b28fc79bb 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/el.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/el.lproj/Localizable.strings @@ -211,7 +211,7 @@ "Scene.Compose.Attachment.ServerProcessingState" = "Επεξεργασία Διακομιστή..."; "Scene.Compose.Attachment.UploadFailed" = "Η Μεταφόρτωση Απέτυχε"; "Scene.Compose.Attachment.Video" = "βίντεο"; -"Scene.Compose.AutoComplete.SpaceToAdd" = ""Διάστημα" για προσθήκη"; +"Scene.Compose.AutoComplete.SpaceToAdd" = "\"Διάστημα\" για προσθήκη"; "Scene.Compose.ComposeAction" = "Δημοσίευση"; "Scene.Compose.ContentInputPlaceholder" = "Πληκτρολόγησε ή επικόλλησε τί έχεις στο μυαλό σου"; "Scene.Compose.ContentWarning.Placeholder" = "Γράψε εδώ μια ακριβή προειδοποίηση..."; @@ -440,12 +440,14 @@ "Scene.Search.SearchBar.Cancel" = "Άκυρο"; "Scene.Search.SearchBar.Placeholder" = "Αναζήτησε ετικέτες και χρήστες"; "Scene.Search.Searching.Clear" = "Εκκαθάριση"; +"Scene.Search.Searching.ClearAll" = "Clear all"; "Scene.Search.Searching.EmptyState.NoResults" = "Κανένα αποτέλεσμα"; +"Scene.Search.Searching.Hashtag" = "Go to #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Go to @%@@%@"; "Scene.Search.Searching.RecentSearch" = "Πρόσφατες αναζητήσεις"; -"Scene.Search.Searching.Segment.All" = "Όλα"; -"Scene.Search.Searching.Segment.Hashtags" = "Ετικέτες"; -"Scene.Search.Searching.Segment.People" = "Άτομα"; -"Scene.Search.Searching.Segment.Posts" = "Αναρτήσεις"; +"Scene.Search.Searching.Url" = "Open URL in Mastodon"; "Scene.Search.Title" = "Αναζήτηση"; "Scene.ServerPicker.Button.Category.Academia" = "ακαδημαϊκά"; "Scene.ServerPicker.Button.Category.Activism" = "ακτιβισμός"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings index 7f00f1cc2..e5cb95e4d 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings @@ -440,12 +440,14 @@ uploaded to Mastodon."; "Scene.Search.SearchBar.Cancel" = "Cancel"; "Scene.Search.SearchBar.Placeholder" = "Search hashtags and users"; "Scene.Search.Searching.Clear" = "Clear"; +"Scene.Search.Searching.ClearAll" = "Clear all"; "Scene.Search.Searching.EmptyState.NoResults" = "No results"; +"Scene.Search.Searching.Hashtag" = "Go to #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Go to @%@@%@"; "Scene.Search.Searching.RecentSearch" = "Recent searches"; -"Scene.Search.Searching.Segment.All" = "All"; -"Scene.Search.Searching.Segment.Hashtags" = "Hashtags"; -"Scene.Search.Searching.Segment.People" = "People"; -"Scene.Search.Searching.Segment.Posts" = "Posts"; +"Scene.Search.Searching.Url" = "Open URL in Mastodon"; "Scene.Search.Title" = "Search"; "Scene.ServerPicker.Button.Category.Academia" = "academia"; "Scene.ServerPicker.Button.Category.Activism" = "activism"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.strings index 69ae61e3f..78a705417 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.strings @@ -440,12 +440,14 @@ subirse a Mastodon."; "Scene.Search.SearchBar.Cancel" = "Cancelar"; "Scene.Search.SearchBar.Placeholder" = "Buscar etiquetas y usuarios"; "Scene.Search.Searching.Clear" = "Borrar"; +"Scene.Search.Searching.ClearAll" = "Clear all"; "Scene.Search.Searching.EmptyState.NoResults" = "Sin resultados"; +"Scene.Search.Searching.Hashtag" = "Go to #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Go to @%@@%@"; "Scene.Search.Searching.RecentSearch" = "Búsquedas recientes"; -"Scene.Search.Searching.Segment.All" = "Todo"; -"Scene.Search.Searching.Segment.Hashtags" = "Etiquetas"; -"Scene.Search.Searching.Segment.People" = "Gente"; -"Scene.Search.Searching.Segment.Posts" = "Publicaciones"; +"Scene.Search.Searching.Url" = "Open URL in Mastodon"; "Scene.Search.Title" = "Buscar"; "Scene.ServerPicker.Button.Category.Academia" = "académicos"; "Scene.ServerPicker.Button.Category.Activism" = "activismo"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings index a2bf96287..c6711927f 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings @@ -440,12 +440,14 @@ Mastodonera igo."; "Scene.Search.SearchBar.Cancel" = "Utzi"; "Scene.Search.SearchBar.Placeholder" = "Bilatu traolak eta erabiltzaileak"; "Scene.Search.Searching.Clear" = "Garbitu"; +"Scene.Search.Searching.ClearAll" = "Clear all"; "Scene.Search.Searching.EmptyState.NoResults" = "Emaitzarik ez"; +"Scene.Search.Searching.Hashtag" = "Go to #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Go to @%@@%@"; "Scene.Search.Searching.RecentSearch" = "Azken bilaketak"; -"Scene.Search.Searching.Segment.All" = "Guztiak"; -"Scene.Search.Searching.Segment.Hashtags" = "Traolak"; -"Scene.Search.Searching.Segment.People" = "Jendea"; -"Scene.Search.Searching.Segment.Posts" = "Bidalketak"; +"Scene.Search.Searching.Url" = "Open URL in Mastodon"; "Scene.Search.Title" = "Bilatu"; "Scene.ServerPicker.Button.Category.Academia" = "akademia"; "Scene.ServerPicker.Button.Category.Activism" = "aktibismoa"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings index d2bac1841..7b6cb0266 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings @@ -1,19 +1,19 @@ "Common.Alerts.BlockDomain.BlockEntireDomain" = "Estä verkkotunnus"; -"Common.Alerts.BlockDomain.Title" = "Are you really, really sure you want to block the entire %@? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain and any of your followers from that domain will be removed."; +"Common.Alerts.BlockDomain.Title" = "Haluatko aivan varmasti estää palvelun %@ täysin? Useimmiten muutama kohdistettu esto tai mykistys on riittävä ja suositeltava toimenpide. Et näe kyseisen palvelun sisältöä julkisilla aikajanoilla tai ilmoituksissa. Tälle palvelulle kuuluvat seuraajasi poistetaan."; "Common.Alerts.CleanCache.Message" = "%@ välimuisti tyhjennetty onnistuneesti."; "Common.Alerts.CleanCache.Title" = "Puhdista välimuisti"; "Common.Alerts.Common.PleaseTryAgain" = "Yritä uudelleen."; "Common.Alerts.Common.PleaseTryAgainLater" = "Yritä uudelleen myöhemmin."; -"Common.Alerts.DeletePost.Message" = "Are you sure you want to delete this post?"; +"Common.Alerts.DeletePost.Message" = "Haluatko varmasti poistaa julkaisun?"; "Common.Alerts.DeletePost.Title" = "Haluatko varmasti poistaa tämän julkaisun?"; "Common.Alerts.EditProfileFailure.Message" = "Profiilia ei voida muoka. Yritä uudelleen."; "Common.Alerts.EditProfileFailure.Title" = "Virhe profiilin muokkauksessa"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "Ei voi liittä yhtä videota enempää."; -"Common.Alerts.PublishPostFailure.AttachmentsMessage.VideoAttachWithPhoto" = "Cannot attach a video to a post that already contains images."; +"Common.Alerts.PublishPostFailure.AttachmentsMessage.VideoAttachWithPhoto" = "Videota ei voi liittää tilapäivitykseen, joka sisältää jo kuvia."; "Common.Alerts.PublishPostFailure.Message" = "Julkaisun julkaiseminen epäonnistui. Tarkista internet-yhteytesi."; "Common.Alerts.PublishPostFailure.Title" = "Julkaiseminen epäonnistui"; -"Common.Alerts.SavePhotoFailure.Message" = "Please enable the photo library access permission to save the photo."; +"Common.Alerts.SavePhotoFailure.Message" = "Myönnä kuvakirjaston käyttöoikeus tallentaaksesi kuvan."; "Common.Alerts.SavePhotoFailure.Title" = "Kuvan tallentaminen epäonnistui"; "Common.Alerts.ServerError.Title" = "Palvelinvirhe"; "Common.Alerts.SignOut.Confirm" = "Kirjaudu ulos"; @@ -21,14 +21,14 @@ Tarkista internet-yhteytesi."; "Common.Alerts.SignOut.Title" = "Kirjaudu ulos"; "Common.Alerts.SignUpFailure.Title" = "Rekisteröinti epäonnistui"; "Common.Alerts.TranslationFailed.Button" = "OK"; -"Common.Alerts.TranslationFailed.Message" = "Translation failed. Maybe the administrator has not enabled translations on this server or this server is running an older version of Mastodon where translations are not yet supported."; -"Common.Alerts.TranslationFailed.Title" = "Note"; +"Common.Alerts.TranslationFailed.Message" = "Käännös epäonnistui. Ehkä palvelimen ylläpito ei ole ottanut käännösominaisuutta käyttöön tai se käyttää Mastodonin vanhempaa versiota, joka ei vielä tue käännöksiä."; +"Common.Alerts.TranslationFailed.Title" = "Huomautus"; "Common.Alerts.VoteFailure.PollEnded" = "Kysely on päättynyt"; -"Common.Alerts.VoteFailure.Title" = "Vote Failure"; +"Common.Alerts.VoteFailure.Title" = "Äänestys epäonnistui"; "Common.Controls.Actions.Add" = "Lisää"; "Common.Controls.Actions.Back" = "Takaisin"; "Common.Controls.Actions.BlockDomain" = "Estä %@"; -"Common.Controls.Actions.Bookmark" = "Bookmark"; +"Common.Controls.Actions.Bookmark" = "Kirjanmerkki"; "Common.Controls.Actions.Cancel" = "Kumoa"; "Common.Controls.Actions.Compose" = "Koosta"; "Common.Controls.Actions.Confirm" = "Vahvista"; @@ -41,7 +41,7 @@ Tarkista internet-yhteytesi."; "Common.Controls.Actions.Edit" = "Muokkaa"; "Common.Controls.Actions.EditPost" = "Muokkaa"; "Common.Controls.Actions.FindPeople" = "Löydä tilejä seurattavaksi"; -"Common.Controls.Actions.Follow" = "Follow %@"; +"Common.Controls.Actions.Follow" = "Seuraa käyttäjää %@"; "Common.Controls.Actions.ManuallySearch" = "Etsi sen sijaan manuaalisesti"; "Common.Controls.Actions.Next" = "Seuraava"; "Common.Controls.Actions.Ok" = "OK"; @@ -51,7 +51,7 @@ Tarkista internet-yhteytesi."; "Common.Controls.Actions.Preview" = "Esikatselu"; "Common.Controls.Actions.Previous" = "Edellinen"; "Common.Controls.Actions.Remove" = "Poista"; -"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; +"Common.Controls.Actions.RemoveBookmark" = "Poista kirjanmerkki"; "Common.Controls.Actions.Reply" = "Vastaa"; "Common.Controls.Actions.ReportUser" = "Ilmianna %@"; "Common.Controls.Actions.Save" = "Tallenna"; @@ -68,7 +68,7 @@ Tarkista internet-yhteytesi."; "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Tuntematon"; "Common.Controls.Actions.TryAgain" = "Yritä uudelleen"; "Common.Controls.Actions.UnblockDomain" = "Poista esto %@"; -"Common.Controls.Actions.Unfollow" = "Unfollow %@"; +"Common.Controls.Actions.Unfollow" = "Lopeta käyttäjän %@ seuraaminen"; "Common.Controls.Friendship.Block" = "Estä"; "Common.Controls.Friendship.BlockDomain" = "Estä %@"; "Common.Controls.Friendship.BlockUser" = "Estä %@"; @@ -440,12 +440,14 @@ uploaded to Mastodon."; "Scene.Search.SearchBar.Cancel" = "Kumoa"; "Scene.Search.SearchBar.Placeholder" = "Haku"; "Scene.Search.Searching.Clear" = "Tyhjennä"; +"Scene.Search.Searching.ClearAll" = "Tyhjennä kaikki"; "Scene.Search.Searching.EmptyState.NoResults" = "Ei hakutuloksia"; +"Scene.Search.Searching.Hashtag" = "Siirry #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Avaa profiilii @%@@%@"; "Scene.Search.Searching.RecentSearch" = "Viimeaikaiset"; -"Scene.Search.Searching.Segment.All" = "Kaikki"; -"Scene.Search.Searching.Segment.Hashtags" = "Hashtagit"; -"Scene.Search.Searching.Segment.People" = "Tilit"; -"Scene.Search.Searching.Segment.Posts" = "Julkaisut"; +"Scene.Search.Searching.Url" = "Avaa URL Mastodonissa"; "Scene.Search.Title" = "Haku"; "Scene.ServerPicker.Button.Category.Academia" = "akateeminen"; "Scene.ServerPicker.Button.Category.Activism" = "aktivismi"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.strings index e4d803933..00c2e610b 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.strings @@ -28,7 +28,7 @@ Veuillez vérifier votre accès à Internet."; "Common.Controls.Actions.Add" = "Ajouter"; "Common.Controls.Actions.Back" = "Retour"; "Common.Controls.Actions.BlockDomain" = "Bloquer %@"; -"Common.Controls.Actions.Bookmark" = "Bookmark"; +"Common.Controls.Actions.Bookmark" = "Ajouter aux signets"; "Common.Controls.Actions.Cancel" = "Annuler"; "Common.Controls.Actions.Compose" = "Rédiger"; "Common.Controls.Actions.Confirm" = "Confirmer"; @@ -41,7 +41,7 @@ Veuillez vérifier votre accès à Internet."; "Common.Controls.Actions.Edit" = "Éditer"; "Common.Controls.Actions.EditPost" = "Éditer"; "Common.Controls.Actions.FindPeople" = "Trouver des personnes à suivre"; -"Common.Controls.Actions.Follow" = "Follow %@"; +"Common.Controls.Actions.Follow" = "S’abonner à %@"; "Common.Controls.Actions.ManuallySearch" = "Rechercher manuellement à la place"; "Common.Controls.Actions.Next" = "Suivant"; "Common.Controls.Actions.Ok" = "OK"; @@ -51,7 +51,7 @@ Veuillez vérifier votre accès à Internet."; "Common.Controls.Actions.Preview" = "Aperçu"; "Common.Controls.Actions.Previous" = "Précédent"; "Common.Controls.Actions.Remove" = "Supprimer"; -"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; +"Common.Controls.Actions.RemoveBookmark" = "Supprimer le signet"; "Common.Controls.Actions.Reply" = "Répondre"; "Common.Controls.Actions.ReportUser" = "Signaler %@"; "Common.Controls.Actions.Save" = "Enregistrer"; @@ -68,7 +68,7 @@ Veuillez vérifier votre accès à Internet."; "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "Inconnu"; "Common.Controls.Actions.TryAgain" = "Réessayer"; "Common.Controls.Actions.UnblockDomain" = "Débloquer %@"; -"Common.Controls.Actions.Unfollow" = "Unfollow %@"; +"Common.Controls.Actions.Unfollow" = "Se désabonner de %@"; "Common.Controls.Friendship.Block" = "Bloquer"; "Common.Controls.Friendship.BlockDomain" = "Bloquer %@"; "Common.Controls.Friendship.BlockUser" = "Bloquer %@"; @@ -118,12 +118,12 @@ Veuillez vérifier votre accès à Internet."; "Common.Controls.Status.Actions.Unfavorite" = "Retirer des favoris"; "Common.Controls.Status.Actions.Unreblog" = "Annuler le reblog"; "Common.Controls.Status.Buttons.EditHistoryDetail" = "Dernière modification %@"; -"Common.Controls.Status.Buttons.EditHistoryTitle" = "Modifier l'historique"; +"Common.Controls.Status.Buttons.EditHistoryTitle" = "Historique des modifications"; "Common.Controls.Status.Buttons.FavoritesTitle" = "Favoris"; "Common.Controls.Status.Buttons.ReblogsTitle" = "Reblogs"; "Common.Controls.Status.ContentWarning" = "Avertissement de contenu"; "Common.Controls.Status.EditHistory.OriginalPost" = "Message original · %@"; -"Common.Controls.Status.EditHistory.Title" = "Modifier l'historique"; +"Common.Controls.Status.EditHistory.Title" = "Historique des modifications"; "Common.Controls.Status.EditedAtTimestampPrefix" = "Édité %@"; "Common.Controls.Status.LinkViaUser" = "%@ via %@"; "Common.Controls.Status.LoadEmbed" = "Charger l'intégration"; @@ -183,7 +183,7 @@ Votre profil ressemble à ça pour lui."; "Common.Controls.Timeline.Loader.LoadingMissingPosts" = "Chargement des publications manquantes..."; "Common.Controls.Timeline.Loader.ShowMoreReplies" = "Charger plus de réponses"; "Common.Controls.Timeline.Timestamp.Now" = "À l’instant"; -"Common.UserList.FollowersCount" = "%@ abonnés"; +"Common.UserList.FollowersCount" = "%@ abonné·e·s"; "Common.UserList.NoVerifiedLink" = "Lien non vérifié"; "Extension.OpenIn.InvalidLinkError" = "Cela ne semble pas être un lien Mastodon valide."; "Scene.AccountList.AddAccount" = "Ajouter un compte"; @@ -248,7 +248,7 @@ téléversé sur Mastodon."; "Scene.Compose.Title.NewPost" = "Nouvelle Publication"; "Scene.Compose.Title.NewReply" = "Nouvelle réponse"; "Scene.Compose.Visibility.Direct" = "Seulement les personnes que je mentionne"; -"Scene.Compose.Visibility.Private" = "Abonnés seulement"; +"Scene.Compose.Visibility.Private" = "Abonné·e·s seulement"; "Scene.Compose.Visibility.Public" = "Public"; "Scene.Compose.Visibility.Unlisted" = "Non listé"; "Scene.ConfirmEmail.Button.Resend" = "Renvoyer"; @@ -283,7 +283,7 @@ téléversé sur Mastodon."; "Scene.Follower.Footer" = "Les abonné·e·s issus des autres serveurs ne sont pas affiché·e·s."; "Scene.Follower.Title" = "abonné·e"; "Scene.Following.Footer" = "Les abonnés issus des autres serveurs ne sont pas affichés."; -"Scene.Following.Title" = "abonnement"; +"Scene.Following.Title" = "abonnements"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Appuyez pour faire défiler vers le haut et appuyez à nouveau vers l'emplacement précédent"; "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Mastodon"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Voir les nouvelles publications"; @@ -301,7 +301,7 @@ téléversé sur Mastodon."; "Scene.Notification.Keyobard.ShowEverything" = "Tout Afficher"; "Scene.Notification.Keyobard.ShowMentions" = "Afficher les mentions"; "Scene.Notification.NotificationDescription.FavoritedYourPost" = "a ajouté votre message à ses favoris"; -"Scene.Notification.NotificationDescription.FollowedYou" = "s’est abonné à vous"; +"Scene.Notification.NotificationDescription.FollowedYou" = "s’est abonné·e à vous"; "Scene.Notification.NotificationDescription.MentionedYou" = "vous a mentionné"; "Scene.Notification.NotificationDescription.PollHasEnded" = "le sondage est terminé"; "Scene.Notification.NotificationDescription.RebloggedYourPost" = "a partagé votre message"; @@ -315,16 +315,16 @@ téléversé sur Mastodon."; "Scene.Privacy.Description" = "Bien que l’application Mastodon ne collecte aucune donnée, le serveur auquel vous vous inscrivez peut avoir une politique différente. Prenez une minute pour examiner et accepter la politique de confidentialité de l’application Mastodon ainsi que celle de votre serveur."; "Scene.Privacy.Policy.Ios" = "Politique de confidentialité - Mastodon pour iOS"; "Scene.Privacy.Policy.Server" = "Politique de Confidentialité - %@"; -"Scene.Privacy.Title" = "Confidentialité"; +"Scene.Privacy.Title" = "Vie privée"; "Scene.Profile.Accessibility.DoubleTapToOpenTheList" = "Appuyer deux fois pour ouvrir la liste"; "Scene.Profile.Accessibility.EditAvatarImage" = "Modifier l’avatar"; "Scene.Profile.Accessibility.ShowAvatarImage" = "Afficher l’avatar"; "Scene.Profile.Accessibility.ShowBannerImage" = "Afficher l’image de la bannière"; "Scene.Profile.Dashboard.FamiliarFollowers" = "mutuel"; -"Scene.Profile.Dashboard.MyFollowers" = "abonnés"; -"Scene.Profile.Dashboard.MyFollowing" = "abonnement"; +"Scene.Profile.Dashboard.MyFollowers" = "abonné·e·s"; +"Scene.Profile.Dashboard.MyFollowing" = "abonnements"; "Scene.Profile.Dashboard.MyPosts" = "messages"; -"Scene.Profile.Dashboard.OtherFollowers" = "abonnés"; +"Scene.Profile.Dashboard.OtherFollowers" = "abonné·e·s"; "Scene.Profile.Dashboard.OtherFollowing" = "abonnement"; "Scene.Profile.Dashboard.OtherPosts" = "publications"; "Scene.Profile.Fields.AddRow" = "Ajouter une rangée"; @@ -440,12 +440,14 @@ téléversé sur Mastodon."; "Scene.Search.SearchBar.Cancel" = "Annuler"; "Scene.Search.SearchBar.Placeholder" = "Rechercher des hashtags et des utilisateurs"; "Scene.Search.Searching.Clear" = "Effacer"; +"Scene.Search.Searching.ClearAll" = "Effacer tout"; "Scene.Search.Searching.EmptyState.NoResults" = "Aucun résultat"; +"Scene.Search.Searching.Hashtag" = "Go to #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Aller à @%@@%@"; "Scene.Search.Searching.RecentSearch" = "Recherches récentes"; -"Scene.Search.Searching.Segment.All" = "Tout"; -"Scene.Search.Searching.Segment.Hashtags" = "Hashtags"; -"Scene.Search.Searching.Segment.People" = "Personnes"; -"Scene.Search.Searching.Segment.Posts" = "Publications"; +"Scene.Search.Searching.Url" = "Open URL in Mastodon"; "Scene.Search.Title" = "Rechercher"; "Scene.ServerPicker.Button.Category.Academia" = "domaine universitaire"; "Scene.ServerPicker.Button.Category.Activism" = "activisme"; @@ -507,7 +509,7 @@ téléversé sur Mastodon."; "Scene.Settings.Section.Notifications.Title" = "Notifications"; "Scene.Settings.Section.Notifications.Trigger.Anyone" = "n’importe qui"; "Scene.Settings.Section.Notifications.Trigger.Follow" = "toute personne que je suis"; -"Scene.Settings.Section.Notifications.Trigger.Follower" = "un abonné"; +"Scene.Settings.Section.Notifications.Trigger.Follower" = "un·e abonné·e"; "Scene.Settings.Section.Notifications.Trigger.Noone" = "personne"; "Scene.Settings.Section.Notifications.Trigger.Title" = "Me notifier lorsque"; "Scene.Settings.Section.Preference.DisableAvatarAnimation" = "Désactiver les avatars animés"; @@ -519,8 +521,8 @@ téléversé sur Mastodon."; "Scene.Settings.Section.SpicyZone.Signout" = "Se déconnecter"; "Scene.Settings.Section.SpicyZone.Title" = "La Zone Épicée"; "Scene.Settings.Title" = "Paramètres"; -"Scene.SuggestionAccount.FollowAll" = "Follow all"; -"Scene.SuggestionAccount.Title" = "Popular on Mastodon"; +"Scene.SuggestionAccount.FollowAll" = "Tout suivre"; +"Scene.SuggestionAccount.Title" = "Populaire sur Mastodon"; "Scene.Thread.BackTitle" = "Publication"; "Scene.Thread.Title" = "Publication de %@"; "Scene.Welcome.Education.A11Y.WhatIsMastodon.Title" = "Qu’est-ce que Mastodon ?"; @@ -528,7 +530,7 @@ téléversé sur Mastodon."; "Scene.Welcome.Education.Mastodon.Title" = "Bienvenue sur Mastodon"; "Scene.Welcome.Education.Servers.Description" = "Chaque compte Mastodon est hébergé sur un serveur — chacun avec ses propres valeurs, règles, et administrateurs. Peu importe celui que vous choisissez, vous pouvez suivre et interagir avec des personnes sur n'importe quel serveur."; "Scene.Welcome.Education.Servers.Title" = "Que sont les serveurs ?"; -"Scene.Welcome.JoinDefaultServer" = "Join %@"; +"Scene.Welcome.JoinDefaultServer" = "Rejoindre %@"; "Scene.Welcome.LearnMore" = "En savoir plus"; "Scene.Welcome.LogIn" = "Se connecter"; "Scene.Welcome.PickServer" = "Trouver un autre serveur"; @@ -537,8 +539,8 @@ téléversé sur Mastodon."; "Widget.Common.UserNotLoggedIn" = "Veuillez ouvrir Mastodon pour vous connecter à un compte."; "Widget.FollowersCount.ConfigurationDescription" = "Afficher le nombre d'abonnés."; "Widget.FollowersCount.ConfigurationDisplayName" = "Abonné·e·s"; -"Widget.FollowersCount.FollowersToday" = "%@ abonnés aujourd'hui"; -"Widget.FollowersCount.Title" = "ABONNES"; +"Widget.FollowersCount.FollowersToday" = "%@ abonné·e·s aujourd'hui"; +"Widget.FollowersCount.Title" = "ABONNÉ·E·S"; "Widget.Hashtag.Configuration.Description" = "Affiche un post récent avec le hashtag sélectionné."; "Widget.Hashtag.Configuration.DisplayName" = "Hashtag"; "Widget.Hashtag.NotFound.Account" = "@johnMastodon@no-such.account"; @@ -548,10 +550,10 @@ téléversé sur Mastodon."; "Widget.Hashtag.Placeholder.AccountName" = "John Mastodon"; "Widget.Hashtag.Placeholder.Content" = "Voici à quoi ressemblerait un message avec un #hashtag. Choisissez le #hashtag que vous voulez dans les paramètres du widget."; "Widget.LatestFollowers.ConfigurationDescription" = "Afficher les derniers abonnés."; -"Widget.LatestFollowers.ConfigurationDisplayName" = "Derniers abonnés"; +"Widget.LatestFollowers.ConfigurationDisplayName" = "Derniers abonné·e·s"; "Widget.LatestFollowers.LastUpdate" = "Dernière mise à jour: %@"; -"Widget.LatestFollowers.Title" = "Derniers abonnés"; +"Widget.LatestFollowers.Title" = "Derniers abonné·e·s"; "Widget.MultipleFollowers.ConfigurationDescription" = "Afficher le nombre d'abonnés pour plusieurs comptes."; -"Widget.MultipleFollowers.ConfigurationDisplayName" = "Abonnés multiples"; +"Widget.MultipleFollowers.ConfigurationDisplayName" = "Abonné·e·s multiples"; "Widget.MultipleFollowers.MockUser.AccountName" = "another@follower.social"; -"Widget.MultipleFollowers.MockUser.DisplayName" = "Autres abonnés"; \ No newline at end of file +"Widget.MultipleFollowers.MockUser.DisplayName" = "Autres abonné·e·s"; \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.stringsdict index 59bbf904e..2f33fd97b 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.stringsdict @@ -186,7 +186,7 @@ one 1 reblog other - %ld re-blogs + %ld reblogs plural.count.reply diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/gd.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/gd.lproj/Localizable.strings index e7f9f86c7..914550410 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/gd.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/gd.lproj/Localizable.strings @@ -440,12 +440,14 @@ a luchdadh suas gu Mastodon."; "Scene.Search.SearchBar.Cancel" = "Sguir dheth"; "Scene.Search.SearchBar.Placeholder" = "Lorg sna tagaichean hais is cleachdaichean"; "Scene.Search.Searching.Clear" = "Falamhaich"; +"Scene.Search.Searching.ClearAll" = "Clear all"; "Scene.Search.Searching.EmptyState.NoResults" = "Gun toradh"; +"Scene.Search.Searching.Hashtag" = "Go to #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Go to @%@@%@"; "Scene.Search.Searching.RecentSearch" = "Na lorg thu o chionn goirid"; -"Scene.Search.Searching.Segment.All" = "Na h-uile"; -"Scene.Search.Searching.Segment.Hashtags" = "Tagaichean hais"; -"Scene.Search.Searching.Segment.People" = "Daoine"; -"Scene.Search.Searching.Segment.Posts" = "Postaichean"; +"Scene.Search.Searching.Url" = "Open URL in Mastodon"; "Scene.Search.Title" = "Lorg"; "Scene.ServerPicker.Button.Category.Academia" = "saoghal nan sgoilear"; "Scene.ServerPicker.Button.Category.Activism" = "iomairteachd"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.strings index f1cba68cd..ab2882fca 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.strings @@ -440,12 +440,14 @@ ser subido a Mastodon."; "Scene.Search.SearchBar.Cancel" = "Cancelar"; "Scene.Search.SearchBar.Placeholder" = "Buscar cancelos e usuarias"; "Scene.Search.Searching.Clear" = "Limpar"; +"Scene.Search.Searching.ClearAll" = "Clear all"; "Scene.Search.Searching.EmptyState.NoResults" = "Sen resultados"; +"Scene.Search.Searching.Hashtag" = "Go to #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Go to @%@@%@"; "Scene.Search.Searching.RecentSearch" = "Buscas recentes"; -"Scene.Search.Searching.Segment.All" = "Todo"; -"Scene.Search.Searching.Segment.Hashtags" = "Cancelos"; -"Scene.Search.Searching.Segment.People" = "Persoas"; -"Scene.Search.Searching.Segment.Posts" = "Publicacións"; +"Scene.Search.Searching.Url" = "Open URL in Mastodon"; "Scene.Search.Title" = "Procurar"; "Scene.ServerPicker.Button.Category.Academia" = "academia"; "Scene.ServerPicker.Button.Category.Activism" = "activismo"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.strings index 1eb26fa5a..d1e186445 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.strings @@ -440,12 +440,14 @@ caricato su Mastodon."; "Scene.Search.SearchBar.Cancel" = "Annulla"; "Scene.Search.SearchBar.Placeholder" = "Cerca hashtag e utenti"; "Scene.Search.Searching.Clear" = "Cancella"; +"Scene.Search.Searching.ClearAll" = "Cancella tutto"; "Scene.Search.Searching.EmptyState.NoResults" = "Nessun risultato"; +"Scene.Search.Searching.Hashtag" = "Vai a #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Vai a @%@@%@"; "Scene.Search.Searching.RecentSearch" = "Ricerche recenti"; -"Scene.Search.Searching.Segment.All" = "Tutto"; -"Scene.Search.Searching.Segment.Hashtags" = "Hashtags"; -"Scene.Search.Searching.Segment.People" = "Persone"; -"Scene.Search.Searching.Segment.Posts" = "Post"; +"Scene.Search.Searching.Url" = "Apri l'URL su Mastodon"; "Scene.Search.Title" = "Cerca"; "Scene.ServerPicker.Button.Category.Academia" = "accademia"; "Scene.ServerPicker.Button.Category.Activism" = "attivismo"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.strings index 4255ed496..dc59a9488 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.strings @@ -435,12 +435,14 @@ "Scene.Search.SearchBar.Cancel" = "キャンセル"; "Scene.Search.SearchBar.Placeholder" = "ハッシュタグとユーザーを検索"; "Scene.Search.Searching.Clear" = "クリア"; +"Scene.Search.Searching.ClearAll" = "Clear all"; "Scene.Search.Searching.EmptyState.NoResults" = "なし"; +"Scene.Search.Searching.Hashtag" = "Go to #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Go to @%@@%@"; "Scene.Search.Searching.RecentSearch" = "最近の検索"; -"Scene.Search.Searching.Segment.All" = "すべて"; -"Scene.Search.Searching.Segment.Hashtags" = "ハッシュタグ"; -"Scene.Search.Searching.Segment.People" = "人々"; -"Scene.Search.Searching.Segment.Posts" = "投稿"; +"Scene.Search.Searching.Url" = "Open URL in Mastodon"; "Scene.Search.Title" = "検索"; "Scene.ServerPicker.Button.Category.Academia" = "アカデミア"; "Scene.ServerPicker.Button.Category.Activism" = "アクティビズム"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.strings index 04157c456..44ab1ec82 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.strings @@ -440,12 +440,14 @@ Ad d-yettwasali ɣef Mastodon."; "Scene.Search.SearchBar.Cancel" = "Sefsex"; "Scene.Search.SearchBar.Placeholder" = "Nadi hashtags d yiseqdacen"; "Scene.Search.Searching.Clear" = "Sfeḍ"; +"Scene.Search.Searching.ClearAll" = "Clear all"; "Scene.Search.Searching.EmptyState.NoResults" = "Ulac igemmaḍ"; +"Scene.Search.Searching.Hashtag" = "Go to #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Go to @%@@%@"; "Scene.Search.Searching.RecentSearch" = "Inadiyen imaynuten"; -"Scene.Search.Searching.Segment.All" = "Akk"; -"Scene.Search.Searching.Segment.Hashtags" = "Ihacṭagen"; -"Scene.Search.Searching.Segment.People" = "Imdanen"; -"Scene.Search.Searching.Segment.Posts" = "Tisuffaɣ"; +"Scene.Search.Searching.Url" = "Open URL in Mastodon"; "Scene.Search.Title" = "Nadi"; "Scene.ServerPicker.Button.Category.Academia" = "akadimi"; "Scene.ServerPicker.Button.Category.Activism" = "tinuɣmest"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.strings index 9350f13fe..f0c54b536 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.strings @@ -440,12 +440,14 @@ Profîla te ji wan ra wiha xuya dike."; "Scene.Search.SearchBar.Cancel" = "Dev jê berde"; "Scene.Search.SearchBar.Placeholder" = "Li hashtag û bikarhêneran bigere"; "Scene.Search.Searching.Clear" = "Pak bike"; +"Scene.Search.Searching.ClearAll" = "Clear all"; "Scene.Search.Searching.EmptyState.NoResults" = "Encam tune"; +"Scene.Search.Searching.Hashtag" = "Go to #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Go to @%@@%@"; "Scene.Search.Searching.RecentSearch" = "Lêgerînên dawî"; -"Scene.Search.Searching.Segment.All" = "Hemû"; -"Scene.Search.Searching.Segment.Hashtags" = "Hashtag"; -"Scene.Search.Searching.Segment.People" = "Mirov"; -"Scene.Search.Searching.Segment.Posts" = "Şandî"; +"Scene.Search.Searching.Url" = "Open URL in Mastodon"; "Scene.Search.Title" = "Bigere"; "Scene.ServerPicker.Button.Category.Academia" = "akademî"; "Scene.ServerPicker.Button.Category.Activism" = "çalakî"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings index a9a095ece..c636b5fb6 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings @@ -434,12 +434,14 @@ Jouw profiel ziet er zo uit voor hen."; "Scene.Search.SearchBar.Cancel" = "Annuleren"; "Scene.Search.SearchBar.Placeholder" = "Zoek hashtags en gebruikers"; "Scene.Search.Searching.Clear" = "Wissen"; +"Scene.Search.Searching.ClearAll" = "Clear all"; "Scene.Search.Searching.EmptyState.NoResults" = "Geen resultaten"; +"Scene.Search.Searching.Hashtag" = "Go to #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Go to @%@@%@"; "Scene.Search.Searching.RecentSearch" = "Recente zoekopdrachten"; -"Scene.Search.Searching.Segment.All" = "Alles"; -"Scene.Search.Searching.Segment.Hashtags" = "Hashtags"; -"Scene.Search.Searching.Segment.People" = "Gebruikers"; -"Scene.Search.Searching.Segment.Posts" = "Berichten"; +"Scene.Search.Searching.Url" = "Open URL in Mastodon"; "Scene.Search.Title" = "Zoeken"; "Scene.ServerPicker.Button.Category.Academia" = "academisch"; "Scene.ServerPicker.Button.Category.Activism" = "activisme"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings index 27d902a05..481e2851d 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings @@ -448,12 +448,14 @@ "Scene.Search.SearchBar.Cancel" = "Отмена"; "Scene.Search.SearchBar.Placeholder" = "Поиск хэштегов и пользователей"; "Scene.Search.Searching.Clear" = "Очистить"; +"Scene.Search.Searching.ClearAll" = "Clear all"; "Scene.Search.Searching.EmptyState.NoResults" = "Нет результатов"; +"Scene.Search.Searching.Hashtag" = "Go to #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Go to @%@@%@"; "Scene.Search.Searching.RecentSearch" = "Последние запросы"; -"Scene.Search.Searching.Segment.All" = "Всё"; -"Scene.Search.Searching.Segment.Hashtags" = "Хэштеги"; -"Scene.Search.Searching.Segment.People" = "Люди"; -"Scene.Search.Searching.Segment.Posts" = "Посты"; +"Scene.Search.Searching.Url" = "Open URL in Mastodon"; "Scene.Search.Title" = "Поиск"; "Scene.ServerPicker.Button.Category.Academia" = "академия"; "Scene.ServerPicker.Button.Category.Activism" = "активизм"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/sl.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/sl.lproj/Localizable.strings index 6787f8bc4..f2bc2531f 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/sl.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/sl.lproj/Localizable.strings @@ -440,12 +440,14 @@ možno naložiti v Mastodon."; "Scene.Search.SearchBar.Cancel" = "Prekliči"; "Scene.Search.SearchBar.Placeholder" = "Išči ključnike in uporabnike"; "Scene.Search.Searching.Clear" = "Počisti"; +"Scene.Search.Searching.ClearAll" = "Clear all"; "Scene.Search.Searching.EmptyState.NoResults" = "Ni rezultatov"; +"Scene.Search.Searching.Hashtag" = "Go to #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Go to @%@@%@"; "Scene.Search.Searching.RecentSearch" = "Nedavna iskanja"; -"Scene.Search.Searching.Segment.All" = "Vse"; -"Scene.Search.Searching.Segment.Hashtags" = "Ključniki"; -"Scene.Search.Searching.Segment.People" = "Ljudje"; -"Scene.Search.Searching.Segment.Posts" = "Objave"; +"Scene.Search.Searching.Url" = "Open URL in Mastodon"; "Scene.Search.Title" = "Iskanje"; "Scene.ServerPicker.Button.Category.Academia" = "akademsko"; "Scene.ServerPicker.Button.Category.Activism" = "aktivizem"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.strings index 66250f6f9..0f1c1c081 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.strings @@ -440,12 +440,14 @@ laddas upp till Mastodon."; "Scene.Search.SearchBar.Cancel" = "Avbryt"; "Scene.Search.SearchBar.Placeholder" = "Sök hashtaggar och användare"; "Scene.Search.Searching.Clear" = "Rensa"; +"Scene.Search.Searching.ClearAll" = "Rensa alla"; "Scene.Search.Searching.EmptyState.NoResults" = "Inga resultat"; +"Scene.Search.Searching.Hashtag" = "Go to #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Go to @%@@%@"; "Scene.Search.Searching.RecentSearch" = "Senaste sökningarna"; -"Scene.Search.Searching.Segment.All" = "Allt"; -"Scene.Search.Searching.Segment.Hashtags" = "Hashtaggar"; -"Scene.Search.Searching.Segment.People" = "Personer"; -"Scene.Search.Searching.Segment.Posts" = "Inlägg"; +"Scene.Search.Searching.Url" = "Open URL in Mastodon"; "Scene.Search.Title" = "Sök"; "Scene.ServerPicker.Button.Category.Academia" = "vetenskap"; "Scene.ServerPicker.Button.Category.Activism" = "aktivism"; @@ -534,8 +536,8 @@ laddas upp till Mastodon."; "Scene.Welcome.PickServer" = "Hitta en annan server"; "Scene.Welcome.Separator.Or" = "eller"; "Widget.Common.UnsupportedWidgetFamily" = "Sorry but this Widget family is unsupported."; -"Widget.Common.UserNotLoggedIn" = "Please open Mastodon to log in to an Account."; -"Widget.FollowersCount.ConfigurationDescription" = "Show number of followers."; +"Widget.Common.UserNotLoggedIn" = "Öppna Mastodon för att logga in på ett konto."; +"Widget.FollowersCount.ConfigurationDescription" = "Visa antal följare."; "Widget.FollowersCount.ConfigurationDisplayName" = "Följare"; "Widget.FollowersCount.FollowersToday" = "%@ följare idag"; "Widget.FollowersCount.Title" = "FÖLJARE"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.stringsdict index 2dd03d1e3..44132e62d 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.stringsdict @@ -344,7 +344,7 @@ NSStringFormatValueTypeKey ld one - %ld timme kvar + 1 timme kvar other %ld timmar kvar @@ -360,7 +360,7 @@ NSStringFormatValueTypeKey ld one - %ld minut kvar + 1 minut kvar other %ld minuter kvar diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.strings index c32884677..514b9944c 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.strings @@ -440,12 +440,14 @@ "Scene.Search.SearchBar.Cancel" = "ยกเลิก"; "Scene.Search.SearchBar.Placeholder" = "ค้นหาแฮชแท็กและผู้ใช้"; "Scene.Search.Searching.Clear" = "ล้าง"; +"Scene.Search.Searching.ClearAll" = "Clear all"; "Scene.Search.Searching.EmptyState.NoResults" = "ไม่มีผลลัพธ์"; +"Scene.Search.Searching.Hashtag" = "Go to #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Go to @%@@%@"; "Scene.Search.Searching.RecentSearch" = "การค้นหาล่าสุด"; -"Scene.Search.Searching.Segment.All" = "ทั้งหมด"; -"Scene.Search.Searching.Segment.Hashtags" = "แฮชแท็ก"; -"Scene.Search.Searching.Segment.People" = "ผู้คน"; -"Scene.Search.Searching.Segment.Posts" = "โพสต์"; +"Scene.Search.Searching.Url" = "Open URL in Mastodon"; "Scene.Search.Title" = "ค้นหา"; "Scene.ServerPicker.Button.Category.Academia" = "สถาบันการศึกษา"; "Scene.ServerPicker.Button.Category.Activism" = "กิจกรรมเพื่อการเปลี่ยนแปลง"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.strings index 267075070..d10279ff4 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.strings @@ -221,7 +221,7 @@ yüklenemiyor."; "Scene.Compose.Keyboard.ToggleContentWarning" = "İçerik Uyarısı durumunu değiştir"; "Scene.Compose.Keyboard.TogglePoll" = "Anketi Aç/Kapat"; "Scene.Compose.Language.Other" = "Other Language…"; -"Scene.Compose.Language.Recent" = "Recent"; +"Scene.Compose.Language.Recent" = "En Son"; "Scene.Compose.Language.Suggested" = "Önerilen"; "Scene.Compose.Language.Title" = "Gönderi dili"; "Scene.Compose.MediaSelection.Browse" = "Göz at"; @@ -229,8 +229,8 @@ yüklenemiyor."; "Scene.Compose.MediaSelection.PhotoLibrary" = "Fotoğraf Albümü"; "Scene.Compose.Poll.AddOption" = "Seçenek Ekle"; "Scene.Compose.Poll.DurationTime" = "Süre: %@"; -"Scene.Compose.Poll.MoveDown" = "Move Down"; -"Scene.Compose.Poll.MoveUp" = "Move Up"; +"Scene.Compose.Poll.MoveDown" = "Aşağı Taşı"; +"Scene.Compose.Poll.MoveUp" = "Yukarı Taşı"; "Scene.Compose.Poll.OneDay" = "1 Gün"; "Scene.Compose.Poll.OneHour" = "1 Saat"; "Scene.Compose.Poll.OptionNumber" = "Seçenek %ld"; @@ -439,12 +439,14 @@ yüklenemiyor."; "Scene.Search.SearchBar.Cancel" = "İptal"; "Scene.Search.SearchBar.Placeholder" = "Etiketleri ve kullanıcıları ara"; "Scene.Search.Searching.Clear" = "Temizle"; +"Scene.Search.Searching.ClearAll" = "Clear all"; "Scene.Search.Searching.EmptyState.NoResults" = "Sonuç yok"; +"Scene.Search.Searching.Hashtag" = "Go to #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Go to @%@@%@"; "Scene.Search.Searching.RecentSearch" = "Son aramalar"; -"Scene.Search.Searching.Segment.All" = "Tümü"; -"Scene.Search.Searching.Segment.Hashtags" = "Etiketler"; -"Scene.Search.Searching.Segment.People" = "İnsanlar"; -"Scene.Search.Searching.Segment.Posts" = "Gönderiler"; +"Scene.Search.Searching.Url" = "Open URL in Mastodon"; "Scene.Search.Title" = "Arama"; "Scene.ServerPicker.Button.Category.Academia" = "akademi"; "Scene.ServerPicker.Button.Category.Activism" = "aktivizm"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.strings index f967f5ef0..63f638498 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.strings @@ -440,12 +440,14 @@ tải lên Mastodon."; "Scene.Search.SearchBar.Cancel" = "Hủy bỏ"; "Scene.Search.SearchBar.Placeholder" = "Tìm hashtag và mọi người"; "Scene.Search.Searching.Clear" = "Xóa"; +"Scene.Search.Searching.ClearAll" = "Clear all"; "Scene.Search.Searching.EmptyState.NoResults" = "Không có kết quả"; +"Scene.Search.Searching.Hashtag" = "Go to #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Go to @%@@%@"; "Scene.Search.Searching.RecentSearch" = "Tìm kiếm gần đây"; -"Scene.Search.Searching.Segment.All" = "Tất cả"; -"Scene.Search.Searching.Segment.Hashtags" = "Hashtag"; -"Scene.Search.Searching.Segment.People" = "Mọi người"; -"Scene.Search.Searching.Segment.Posts" = "Tút"; +"Scene.Search.Searching.Url" = "Open URL in Mastodon"; "Scene.Search.Title" = "Tìm kiếm"; "Scene.ServerPicker.Button.Category.Academia" = "học thuật"; "Scene.ServerPicker.Button.Category.Activism" = "hoạt động xã hội"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.strings index 00fa499c7..115881e6d 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.strings @@ -28,7 +28,7 @@ "Common.Controls.Actions.Add" = "添加"; "Common.Controls.Actions.Back" = "返回"; "Common.Controls.Actions.BlockDomain" = "屏蔽 %@"; -"Common.Controls.Actions.Bookmark" = "Bookmark"; +"Common.Controls.Actions.Bookmark" = "添加书签"; "Common.Controls.Actions.Cancel" = "取消"; "Common.Controls.Actions.Compose" = "撰写"; "Common.Controls.Actions.Confirm" = "确认"; @@ -41,7 +41,7 @@ "Common.Controls.Actions.Edit" = "编辑"; "Common.Controls.Actions.EditPost" = "编辑"; "Common.Controls.Actions.FindPeople" = "查看推荐关注的用户"; -"Common.Controls.Actions.Follow" = "Follow %@"; +"Common.Controls.Actions.Follow" = "关注 %@"; "Common.Controls.Actions.ManuallySearch" = "手动搜索用户"; "Common.Controls.Actions.Next" = "下一个"; "Common.Controls.Actions.Ok" = "好的"; @@ -51,7 +51,7 @@ "Common.Controls.Actions.Preview" = "预览"; "Common.Controls.Actions.Previous" = "上一个"; "Common.Controls.Actions.Remove" = "删除"; -"Common.Controls.Actions.RemoveBookmark" = "Remove Bookmark"; +"Common.Controls.Actions.RemoveBookmark" = "移除书签"; "Common.Controls.Actions.Reply" = "回复"; "Common.Controls.Actions.ReportUser" = "举报 %@"; "Common.Controls.Actions.Save" = "保存"; @@ -68,7 +68,7 @@ "Common.Controls.Actions.TranslatePost.UnknownLanguage" = "未知的"; "Common.Controls.Actions.TryAgain" = "再试一次"; "Common.Controls.Actions.UnblockDomain" = "解除屏蔽 %@"; -"Common.Controls.Actions.Unfollow" = "Unfollow %@"; +"Common.Controls.Actions.Unfollow" = "不再关注 %@"; "Common.Controls.Friendship.Block" = "屏蔽"; "Common.Controls.Friendship.BlockDomain" = "屏蔽 %@"; "Common.Controls.Friendship.BlockUser" = "屏蔽 %@"; @@ -119,7 +119,7 @@ "Common.Controls.Status.Actions.Unreblog" = "取消转发"; "Common.Controls.Status.Buttons.EditHistoryDetail" = "编辑于:%@"; "Common.Controls.Status.Buttons.EditHistoryTitle" = "编辑历史"; -"Common.Controls.Status.Buttons.FavoritesTitle" = "收藏"; +"Common.Controls.Status.Buttons.FavoritesTitle" = "喜欢"; "Common.Controls.Status.Buttons.ReblogsTitle" = "转发"; "Common.Controls.Status.ContentWarning" = "内容警告"; "Common.Controls.Status.EditHistory.OriginalPost" = "原始帖文 · %@"; @@ -272,8 +272,8 @@ "Scene.Discovery.Tabs.Posts" = "嘟文"; "Scene.Familiarfollowers.FollowedByNames" = "%@ 关注了这个账号"; "Scene.Familiarfollowers.Title" = "你熟悉的关注者"; -"Scene.Favorite.Title" = "收藏"; -"Scene.FavoritedBy.Title" = "收藏者"; +"Scene.Favorite.Title" = "喜欢"; +"Scene.FavoritedBy.Title" = "喜欢者"; "Scene.FollowedTags.Actions.Follow" = "关注"; "Scene.FollowedTags.Actions.Unfollow" = "取消关注"; "Scene.FollowedTags.Header.Participants" = "参与者"; @@ -440,12 +440,14 @@ "Scene.Search.SearchBar.Cancel" = "取消"; "Scene.Search.SearchBar.Placeholder" = "搜索标签和用户"; "Scene.Search.Searching.Clear" = "清除"; +"Scene.Search.Searching.ClearAll" = "Clear all"; "Scene.Search.Searching.EmptyState.NoResults" = "无结果"; +"Scene.Search.Searching.Hashtag" = "Go to #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "Go to @%@@%@"; "Scene.Search.Searching.RecentSearch" = "最近搜索"; -"Scene.Search.Searching.Segment.All" = "全部"; -"Scene.Search.Searching.Segment.Hashtags" = "标签"; -"Scene.Search.Searching.Segment.People" = "用户"; -"Scene.Search.Searching.Segment.Posts" = "帖子"; +"Scene.Search.Searching.Url" = "Open URL in Mastodon"; "Scene.Search.Title" = "搜索"; "Scene.ServerPicker.Button.Category.Academia" = "学术"; "Scene.ServerPicker.Button.Category.Activism" = "行动主义"; @@ -528,7 +530,7 @@ "Scene.Welcome.Education.Mastodon.Title" = "欢迎来到 Mastodon"; "Scene.Welcome.Education.Servers.Description" = "所有的 Mastodon 帐号皆托管于各自的服务器上,每个服务器有各自的价值取向、规则与管理员。无论你选择哪个服务器,你都能关注并与其他任何服务器上的用户互动。"; "Scene.Welcome.Education.Servers.Title" = "服务器是什么?"; -"Scene.Welcome.JoinDefaultServer" = "Join %@"; +"Scene.Welcome.JoinDefaultServer" = "加入 %@"; "Scene.Welcome.LearnMore" = "了解详情"; "Scene.Welcome.LogIn" = "登录"; "Scene.Welcome.PickServer" = "选择另一个服务器"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.strings index 44e3fb585..69222f495 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.strings @@ -435,12 +435,14 @@ "Scene.Search.SearchBar.Cancel" = "取消"; "Scene.Search.SearchBar.Placeholder" = "搜尋主題標籤及使用者"; "Scene.Search.Searching.Clear" = "清除"; +"Scene.Search.Searching.ClearAll" = "清除全部"; "Scene.Search.Searching.EmptyState.NoResults" = "沒有任何結果"; +"Scene.Search.Searching.Hashtag" = "前往 #%@"; +"Scene.Search.Searching.People" = "People matching \"%@\""; +"Scene.Search.Searching.Posts" = "Posts matching \"%@\""; +"Scene.Search.Searching.Profile" = "前往 @%@@%@"; "Scene.Search.Searching.RecentSearch" = "最近的搜尋"; -"Scene.Search.Searching.Segment.All" = "全部"; -"Scene.Search.Searching.Segment.Hashtags" = "主題標籤"; -"Scene.Search.Searching.Segment.People" = "使用者"; -"Scene.Search.Searching.Segment.Posts" = "嘟文"; +"Scene.Search.Searching.Url" = "於 Mastodon 中開啟連結"; "Scene.Search.Title" = "搜尋"; "Scene.ServerPicker.Button.Category.Academia" = "學術"; "Scene.ServerPicker.Button.Category.Activism" = "社會運動"; From 5ac8d02b0bf6f950687bcad137cd945691bba4d2 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 20 Sep 2023 23:55:21 +0200 Subject: [PATCH 83/87] Re-add keys This whole localization workflow is super annyoing and fragile. --- Localization/StringsConvertor/input/Base.lproj/app.json | 4 ++++ Localization/app.json | 4 ++++ .../Resources/Base.lproj/Localizable.strings | 4 +++- .../Resources/en.lproj/Localizable.strings | 4 +++- 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index 4a7792b8b..a2a6812fc 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -655,6 +655,10 @@ "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", + "no_user": { + "title": "No User Account Found", + "message": "There's no Useraccount \"%s\" on %s" + } "empty_state": { "no_results": "No results" }, diff --git a/Localization/app.json b/Localization/app.json index 4a7792b8b..a2a6812fc 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -655,6 +655,10 @@ "profile": "Go to @%s@%s", "url": "Open URL in Mastodon", "hashtag": "Go to #%s", + "no_user": { + "title": "No User Account Found", + "message": "There's no Useraccount \"%s\" on %s" + } "empty_state": { "no_results": "No results" }, diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index e5cb95e4d..cff9f0672 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -448,6 +448,8 @@ uploaded to Mastodon."; "Scene.Search.Searching.Profile" = "Go to @%@@%@"; "Scene.Search.Searching.RecentSearch" = "Recent searches"; "Scene.Search.Searching.Url" = "Open URL in Mastodon"; +"Scene.Search.Searching.NoUser.Title" = "No User Account Found"; +"Scene.Search.Searching.NoUser.Message" = "There's no Useraccount \"%@\" on %@"; "Scene.Search.Title" = "Search"; "Scene.ServerPicker.Button.Category.Academia" = "academia"; "Scene.ServerPicker.Button.Category.Activism" = "activism"; @@ -556,4 +558,4 @@ uploaded to Mastodon."; "Widget.MultipleFollowers.ConfigurationDescription" = "Show number of followers for multiple accounts."; "Widget.MultipleFollowers.ConfigurationDisplayName" = "Multiple followers"; "Widget.MultipleFollowers.MockUser.AccountName" = "another@follower.social"; -"Widget.MultipleFollowers.MockUser.DisplayName" = "Another follower"; \ No newline at end of file +"Widget.MultipleFollowers.MockUser.DisplayName" = "Another follower"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings index e5cb95e4d..cff9f0672 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings @@ -448,6 +448,8 @@ uploaded to Mastodon."; "Scene.Search.Searching.Profile" = "Go to @%@@%@"; "Scene.Search.Searching.RecentSearch" = "Recent searches"; "Scene.Search.Searching.Url" = "Open URL in Mastodon"; +"Scene.Search.Searching.NoUser.Title" = "No User Account Found"; +"Scene.Search.Searching.NoUser.Message" = "There's no Useraccount \"%@\" on %@"; "Scene.Search.Title" = "Search"; "Scene.ServerPicker.Button.Category.Academia" = "academia"; "Scene.ServerPicker.Button.Category.Activism" = "activism"; @@ -556,4 +558,4 @@ uploaded to Mastodon."; "Widget.MultipleFollowers.ConfigurationDescription" = "Show number of followers for multiple accounts."; "Widget.MultipleFollowers.ConfigurationDisplayName" = "Multiple followers"; "Widget.MultipleFollowers.MockUser.AccountName" = "another@follower.social"; -"Widget.MultipleFollowers.MockUser.DisplayName" = "Another follower"; \ No newline at end of file +"Widget.MultipleFollowers.MockUser.DisplayName" = "Another follower"; From 7a2d084e7878f23750500c3eef0638d5111847ee Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 20 Sep 2023 23:55:34 +0200 Subject: [PATCH 84/87] Remove unused dependency --- .../xcshareddata/swiftpm/Package.resolved | 9 --------- MastodonSDK/Package.swift | 2 -- 2 files changed, 11 deletions(-) diff --git a/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved index 232ec9c87..286e43818 100644 --- a/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -19,15 +19,6 @@ "version": "4.2.0" } }, - { - "package": "CommonOSLog", - "repositoryURL": "https://github.com/MainasuK/CommonOSLog", - "state": { - "branch": null, - "revision": "c121624a30698e9886efe38aebb36ff51c01b6c2", - "version": "0.1.1" - } - }, { "package": "FaviconFinder", "repositoryURL": "https://github.com/will-lumley/FaviconFinder.git", diff --git a/MastodonSDK/Package.swift b/MastodonSDK/Package.swift index 12aadd888..75990451c 100644 --- a/MastodonSDK/Package.swift +++ b/MastodonSDK/Package.swift @@ -46,7 +46,6 @@ let package = Package( .package(url: "https://github.com/kean/Nuke-FLAnimatedImage-Plugin.git", from: "8.0.0"), .package(url: "https://github.com/kean/Nuke.git", from: "10.3.1"), .package(url: "https://github.com/kishikawakatsumi/KeychainAccess.git", from: "4.2.2"), - .package(url: "https://github.com/MainasuK/CommonOSLog", from: "0.1.1"), .package(url: "https://github.com/MainasuK/FPSIndicator.git", from: "1.0.0"), .package(url: "https://github.com/slackhq/PanModal.git", from: "1.2.7"), .package(url: "https://github.com/TimOliver/TOCropViewController.git", from: "2.6.1"), @@ -93,7 +92,6 @@ let package = Package( "MastodonSDK", .product(name: "Alamofire", package: "Alamofire"), .product(name: "AlamofireImage", package: "AlamofireImage"), - .product(name: "CommonOSLog", package: "CommonOSLog"), .product(name: "ArkanaKeys", package: "ArkanaKeys"), .product(name: "KeychainAccess", package: "KeychainAccess"), .product(name: "MetaTextKit", package: "MetaTextKit") From 305fc341bc8e3643fc01c30535dadbd7caebb1aa Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Thu, 21 Sep 2023 00:04:18 +0200 Subject: [PATCH 85/87] Revert "Remove unused dependency" This reverts commit 7a2d084e7878f23750500c3eef0638d5111847ee. --- .../xcshareddata/swiftpm/Package.resolved | 9 +++++++++ MastodonSDK/Package.swift | 2 ++ 2 files changed, 11 insertions(+) diff --git a/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved index 286e43818..232ec9c87 100644 --- a/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -19,6 +19,15 @@ "version": "4.2.0" } }, + { + "package": "CommonOSLog", + "repositoryURL": "https://github.com/MainasuK/CommonOSLog", + "state": { + "branch": null, + "revision": "c121624a30698e9886efe38aebb36ff51c01b6c2", + "version": "0.1.1" + } + }, { "package": "FaviconFinder", "repositoryURL": "https://github.com/will-lumley/FaviconFinder.git", diff --git a/MastodonSDK/Package.swift b/MastodonSDK/Package.swift index 75990451c..12aadd888 100644 --- a/MastodonSDK/Package.swift +++ b/MastodonSDK/Package.swift @@ -46,6 +46,7 @@ let package = Package( .package(url: "https://github.com/kean/Nuke-FLAnimatedImage-Plugin.git", from: "8.0.0"), .package(url: "https://github.com/kean/Nuke.git", from: "10.3.1"), .package(url: "https://github.com/kishikawakatsumi/KeychainAccess.git", from: "4.2.2"), + .package(url: "https://github.com/MainasuK/CommonOSLog", from: "0.1.1"), .package(url: "https://github.com/MainasuK/FPSIndicator.git", from: "1.0.0"), .package(url: "https://github.com/slackhq/PanModal.git", from: "1.2.7"), .package(url: "https://github.com/TimOliver/TOCropViewController.git", from: "2.6.1"), @@ -92,6 +93,7 @@ let package = Package( "MastodonSDK", .product(name: "Alamofire", package: "Alamofire"), .product(name: "AlamofireImage", package: "AlamofireImage"), + .product(name: "CommonOSLog", package: "CommonOSLog"), .product(name: "ArkanaKeys", package: "ArkanaKeys"), .product(name: "KeychainAccess", package: "KeychainAccess"), .product(name: "MetaTextKit", package: "MetaTextKit") From 6e6341afb880d52c0cb960f5bcfbe13ce41ee3f6 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Thu, 21 Sep 2023 00:05:26 +0200 Subject: [PATCH 86/87] Run swiftgen --- .../Sources/MastodonLocalization/Generated/Strings.swift | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index dd45d6963..3367b4805 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -1303,6 +1303,14 @@ public enum L10n { /// No results public static let noResults = L10n.tr("Localizable", "Scene.Search.Searching.EmptyState.NoResults", fallback: "No results") } + public enum NoUser { + /// There's no Useraccount "%@" on %@ + public static func message(_ p1: Any, _ p2: Any) -> String { + return L10n.tr("Localizable", "Scene.Search.Searching.NoUser.Message", String(describing: p1), String(describing: p2), fallback: "There's no Useraccount \"%@\" on %@") + } + /// No User Account Found + public static let title = L10n.tr("Localizable", "Scene.Search.Searching.NoUser.Title", fallback: "No User Account Found") + } } } public enum ServerPicker { From 8f280c6252c026752b80f32fa1a1bbeefb196282 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 21 Sep 2023 00:07:11 +0200 Subject: [PATCH 87/87] New Crowdin updates (#1118) --- .../StringsConvertor/input/ca.lproj/app.json | 4 +- .../input/es-AR.lproj/app.json | 4 +- .../input/fi.lproj/Localizable.stringsdict | 12 +- .../StringsConvertor/input/fi.lproj/app.json | 158 +++++++++--------- .../StringsConvertor/input/sv.lproj/app.json | 6 +- 5 files changed, 92 insertions(+), 92 deletions(-) diff --git a/Localization/StringsConvertor/input/ca.lproj/app.json b/Localization/StringsConvertor/input/ca.lproj/app.json index f5dc76b88..334d4bbe5 100644 --- a/Localization/StringsConvertor/input/ca.lproj/app.json +++ b/Localization/StringsConvertor/input/ca.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts matching \"%s\"", - "people": "People matching \"%s\"", + "posts": "Tuts coincidents amb \"%s\"", + "people": "Perfils coincidents amb \"%s\"", "profile": "Vés a @%s@%s", "url": "Obre l'enllaç a Mastodon", "hashtag": "Vés a #%s", diff --git a/Localization/StringsConvertor/input/es-AR.lproj/app.json b/Localization/StringsConvertor/input/es-AR.lproj/app.json index 83faebb28..33b537cb3 100644 --- a/Localization/StringsConvertor/input/es-AR.lproj/app.json +++ b/Localization/StringsConvertor/input/es-AR.lproj/app.json @@ -650,8 +650,8 @@ } }, "searching": { - "posts": "Posts matching \"%s\"", - "people": "People matching \"%s\"", + "posts": "Mensajes que coinciden con %s\"", + "people": "Personas que coinciden con \"%s\"", "profile": "Ir a @%s@%s", "url": "Abrir dirección web en Mastodon", "hashtag": "Ir a %s", diff --git a/Localization/StringsConvertor/input/fi.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/fi.lproj/Localizable.stringsdict index f226c44dc..d97fbfc9b 100644 --- a/Localization/StringsConvertor/input/fi.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/fi.lproj/Localizable.stringsdict @@ -88,9 +88,9 @@ NSStringFormatValueTypeKey ld one - Followed by %1$@, and another mutual + %1$@ seuraajaa, joista yhteistä other - Followed by %1$@, and %ld mutuals + %1$@ seuraajaa, joista %ld yhteistä plural.count.metric_formatted.post @@ -120,9 +120,9 @@ NSStringFormatValueTypeKey ld one - 1 media + Yksi media other - %ld media + %ld mediaa plural.count.post @@ -200,9 +200,9 @@ NSStringFormatValueTypeKey ld one - 1 reply + Yksi vastaus other - %ld replies + %ld vastausta plural.count.vote diff --git a/Localization/StringsConvertor/input/fi.lproj/app.json b/Localization/StringsConvertor/input/fi.lproj/app.json index aac581c2f..8c0a995ae 100644 --- a/Localization/StringsConvertor/input/fi.lproj/app.json +++ b/Localization/StringsConvertor/input/fi.lproj/app.json @@ -185,10 +185,10 @@ "emoji": "Emoji" }, "visibility": { - "unlisted": "Everyone can see this post but not display in the public timeline.", - "private": "Only their followers can see this post.", - "private_from_me": "Only my followers can see this post.", - "direct": "Only mentioned user can see this post." + "unlisted": "Kaikki voivat nähdä julkaisun, mutta sitä ei näytetä julkisella aikajanalla.", + "private": "Vain heidän seuraajansa voivat nähdä julkaisun.", + "private_from_me": "Vain omat seuraajat voivat nähdä julkaisun.", + "direct": "Vain mainittu käyttäjä voi nähdä julkaisun." }, "translation": { "translated_from": "Käännetty kielestä %s palvelulla %s", @@ -266,7 +266,7 @@ "log_in": "Kirjaudu sisään", "learn_more": "Lue lisää", "join_default_server": "Liity palvelimelle %@", - "pick_server": "Pick another server", + "pick_server": "Valitse eri palvelin", "separator": { "or": "tai" }, @@ -288,9 +288,9 @@ }, "login": { "title": "Tervetuloa takaisin", - "subtitle": "Log you in on the server you created your account on.", + "subtitle": "Kirjaudu palvelimelle, jolla loit tilisi.", "server_search_field": { - "placeholder": "Enter URL or search for your server" + "placeholder": "Syötä URL-osoite tai etsi palvelintasi" } }, "server_picker": { @@ -323,7 +323,7 @@ "category": "KATEGORIA" }, "input": { - "search_servers_or_enter_url": "Search communities or enter URL" + "search_servers_or_enter_url": "Etsi yhteisöjä tai syötä URL-osoite" }, "empty_state": { "finding_servers": "Etsistään saatavilla olevia palvelimia...", @@ -374,7 +374,7 @@ "password": { "placeholder": "salasana", "confirmation_placeholder": "Vahvista salasana", - "require": "Your password needs at least:", + "require": "Salasanasi on oltava ainakin:", "character_limit": "8 merkkiä", "accessibility": { "checked": "tarkastettu", @@ -457,13 +457,13 @@ "Publishing": "Julkaistaan julkaisua...", "accessibility": { "logo_label": "Mastodon", - "logo_hint": "Tap to scroll to top and tap again to previous location" + "logo_hint": "Siirry ylös napautuksella ja edelliseen napauttamalla uudestaan" } } }, "suggestion_account": { - "title": "Popular on Mastodon", - "follow_all": "Follow all" + "title": "Suosittua Mastodonissa", + "follow_all": "Seuraa kaikkia" }, "compose": { "title": { @@ -482,15 +482,15 @@ "attachment": { "photo": "kuva", "video": "video", - "attachment_broken": "This %s is broken and can’t be\nuploaded to Mastodon.", + "attachment_broken": "Tämä %s on viallinen, eikä sitä voida\nkopioida Mastodoniin.", "description_photo": "Kuvaile kuva näkövammaisille...", "description_video": "Kuvaile video näkövammaisille...", - "load_failed": "Load Failed", - "upload_failed": "Upload Failed", - "can_not_recognize_this_media_attachment": "Can not recognize this media attachment", - "attachment_too_large": "Attachment too large", + "load_failed": "Lataus epäonnistui", + "upload_failed": "Lähetys epäonnistui", + "can_not_recognize_this_media_attachment": "Medialiitettä ei tunnisteta", + "attachment_too_large": "Liite on liian suuri", "compressing_state": "Pakataan...", - "server_processing_state": "Server Processing..." + "server_processing_state": "Palvelin käsittelee..." }, "poll": { "title": "Kysely", @@ -502,8 +502,8 @@ "three_days": "3 päivää", "seven_days": "7 päivää", "option_number": "Vaihtoehto %ld", - "the_poll_is_invalid": "The poll is invalid", - "the_poll_has_empty_option": "The poll has empty option", + "the_poll_is_invalid": "Kysely on virheellinen", + "the_poll_has_empty_option": "Kyselyssä on tyhjä vaihtoehto", "add_option": "Lisää vaihtoehto", "remove_option": "Poista vaihtoehto", "move_up": "Siirrä ylemmäs", @@ -519,7 +519,7 @@ "direct": "Vain mainitsemani tilit" }, "auto_complete": { - "space_to_add": "Space to add" + "space_to_add": "Lisättävä tila" }, "accessibility": { "append_attachment": "Lisää liite", @@ -529,8 +529,8 @@ "enable_content_warning": "Ota sisältövaroitus käyttöön", "disable_content_warning": "Poista sisältövaroitus käytöstä", "post_visibility_menu": "Julkaisun näkyvyysvalikko", - "post_options": "Post Options", - "posting_as": "Posting as %s" + "post_options": "Julkaisun valinnat", + "posting_as": "Julkaistaan tunnuksella %s" }, "keyboard": { "discard_post": "Hylkää julkaisu", @@ -549,7 +549,7 @@ }, "profile": { "header": { - "follows_you": "Follows You" + "follows_you": "Seuraa sinua" }, "dashboard": { "my_posts": "julkaisut", @@ -561,22 +561,22 @@ "familiar_followers": "yhteiset" }, "fields": { - "joined": "Joined", + "joined": "Liittynyt", "add_row": "Lisää rivi", "placeholder": { "label": "Nimi", "content": "Sisältö" }, "verified": { - "short": "Verified on %s", - "long": "Ownership of this link was checked on %s" + "short": "Vahvistettu %s", + "long": "Linkin omistajuus on tarkastettu %s" } }, "segmented_control": { "posts": "Julkaisut", "replies": "Vastaukset", - "posts_and_replies": "Posts and Replies", - "media": "Media", + "posts_and_replies": "Julkaisut ja vastaukset", + "media": "Mediat", "about": "Tietoja" }, "relationship_action_alert": { @@ -590,11 +590,11 @@ }, "confirm_block_user": { "title": "Estä tili", - "message": "Confirm to block %s" + "message": "Vahvista käyttäjän %s esto" }, "confirm_unblock_user": { - "title": "Unblock Account", - "message": "Confirm to unblock %s" + "title": "Poista tilin esto", + "message": "Vahvista tilin %s eston poisto" }, "confirm_show_reblogs": { "title": "Show Reblogs", @@ -716,13 +716,13 @@ "look_and_feel": { "title": "Look and Feel", "use_system": "Use System", - "really_dark": "Really Dark", - "sorta_dark": "Sorta Dark", - "light": "Light" + "really_dark": "Erittäin tumma", + "sorta_dark": "Tummahko", + "light": "Vaalea" }, "notifications": { "title": "Ilmoitukset", - "favorites": "Favorites my post", + "favorites": "Lisää julkaisuni suosikkeihinsa", "follows": "Seuraa minua", "boosts": "Omien julkaisujen edelleen jaot", "mentions": "Mainitsee minut", @@ -739,7 +739,7 @@ "disable_avatar_animation": "Poista käytöstä animoidut avatarit", "disable_emoji_animation": "Poista käytöstä animoidut emojit", "using_default_browser": "Käytä oletusselainta linkkien avaamiseen", - "open_links_in_mastodon": "Open links in Mastodon" + "open_links_in_mastodon": "Avaa linkit Mastodonissa" }, "boring_zone": { "title": "Tylsä alue", @@ -761,58 +761,58 @@ } }, "report": { - "title_report": "Report", + "title_report": "Raportoi", "title": "Ilmianna %s", "step1": "Vaihe 1/2", "step2": "Vaihe 2/2", "content1": "Onko julkaisuja, joita haluaisit lisätä ilmiantoon?", "content2": "Onko valvojien syytä tietää tästä ilmiannosta?", - "report_sent_title": "Thanks for reporting, we’ll look into this.", + "report_sent_title": "Kiitos ilmoituksesta, tutkimme asiaa.", "send": "Lähetä ilmianto", "skip_to_send": "Lähetä ilman kommentteja", "text_placeholder": "Kirjoita tai liitä lisäkommentteja", - "reported": "REPORTED", + "reported": "ILMOITETTU", "step_one": { - "step_1_of_4": "Step 1 of 4", - "whats_wrong_with_this_post": "What's wrong with this post?", - "whats_wrong_with_this_account": "What's wrong with this account?", - "whats_wrong_with_this_username": "What's wrong with %s?", - "select_the_best_match": "Select the best match", - "i_dont_like_it": "I don’t like it", - "it_is_not_something_you_want_to_see": "It is not something you want to see", - "its_spam": "It’s spam", - "malicious_links_fake_engagement_or_repetetive_replies": "Malicious links, fake engagement, or repetetive replies", - "it_violates_server_rules": "It violates server rules", - "you_are_aware_that_it_breaks_specific_rules": "You are aware that it breaks specific rules", - "its_something_else": "It’s something else", - "the_issue_does_not_fit_into_other_categories": "The issue does not fit into other categories" + "step_1_of_4": "Vaihe 1/4", + "whats_wrong_with_this_post": "Mitä vikaa tässä julkaisussa on?", + "whats_wrong_with_this_account": "Mitä vikaa tässä tilissä on?", + "whats_wrong_with_this_username": "Mitä vikaa käyttäjässä %s on?", + "select_the_best_match": "Valitse sopivin", + "i_dont_like_it": "En pidä siitä", + "it_is_not_something_you_want_to_see": "Tätä ei halua nähdä", + "its_spam": "Se on roskapostia", + "malicious_links_fake_engagement_or_repetetive_replies": "Haitallisia linkkejä, valheellinen osanotto tai toistuvia vastauksia", + "it_violates_server_rules": "Se rikkoo palvelimen sääntöjä", + "you_are_aware_that_it_breaks_specific_rules": "Tiedät sen rikkovan tiettyjä sääntöjä", + "its_something_else": "Jotain muuta", + "the_issue_does_not_fit_into_other_categories": "Ongelma ei sovi muihin kategorioihin" }, "step_two": { - "step_2_of_4": "Step 2 of 4", - "which_rules_are_being_violated": "Which rules are being violated?", - "select_all_that_apply": "Select all that apply", - "i_just_don’t_like_it": "I just don’t like it" + "step_2_of_4": "Vaihe 2/4", + "which_rules_are_being_violated": "Mitä sääntöjä rikotaan?", + "select_all_that_apply": "Valitse kaikki sopivat", + "i_just_don’t_like_it": "En vain pidä siitä" }, "step_three": { - "step_3_of_4": "Step 3 of 4", - "are_there_any_posts_that_back_up_this_report": "Are there any posts that back up this report?", - "select_all_that_apply": "Select all that apply" + "step_3_of_4": "Vaihe 3/4", + "are_there_any_posts_that_back_up_this_report": "Onko raporttia tukevia julkaisuja?", + "select_all_that_apply": "Valitse kaikki sopivat" }, "step_four": { - "step_4_of_4": "Step 4 of 4", - "is_there_anything_else_we_should_know": "Is there anything else we should know?" + "step_4_of_4": "Vaihe 4/4", + "is_there_anything_else_we_should_know": "Pitäisikö meidän tietää jotain muuta?" }, "step_final": { - "dont_want_to_see_this": "Don’t want to see this?", - "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "When you see something you don’t like on Mastodon, you can remove the person from your experience.", - "unfollow": "Unfollow", - "unfollowed": "Unfollowed", - "unfollow_user": "Unfollow %s", - "mute_user": "Mute %s", - "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted.", - "block_user": "Block %s", - "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked.", - "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + "dont_want_to_see_this": "Etkö halua nähdä tätä?", + "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "Kun näet Mastodonissa jotain sellaista, josta et pidä, voit sulkea käyttäjän käyttökokemuksesi ulkopuolelle.", + "unfollow": "Lopeta seuraaminen", + "unfollowed": "Seuraaminen lopetettiin", + "unfollow_user": "Lopeta käyttäjän %s seuraaminen", + "mute_user": "Mykistä %s", + "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "Et näe heidän julkaisujaan tai jatkojulkaisujaan kotisyötteessäsi. He eivät tiedä sinun mykistäneen heidät.", + "block_user": "Estä %s", + "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "He eivät enää voi seurata tai nähdä julkaisujasi, eivätkä myöskään tiedä sinun estäneen heidät.", + "while_we_review_this_you_can_take_action_against_user": "Sillä välin kun tarkistamme tätä, voit ryhtyä toimenpiteisiin käyttäjää %s vastaan" } }, "preview": { @@ -828,18 +828,18 @@ "add_account": "Lisää tili" }, "bookmark": { - "title": "Bookmarks" + "title": "Kirjanmerkit" }, "followed_tags": { - "title": "Followed Tags", + "title": "Seuratut tunnisteet", "header": { - "posts": "posts", - "participants": "participants", - "posts_today": "posts today" + "posts": "julkaisua", + "participants": "osallistujaa", + "posts_today": "julkaisua tänään" }, "actions": { - "follow": "Follow", - "unfollow": "Unfollow" + "follow": "Seuraa", + "unfollow": "Lopeta seuraaminen" } } }, diff --git a/Localization/StringsConvertor/input/sv.lproj/app.json b/Localization/StringsConvertor/input/sv.lproj/app.json index 8790dc9b7..4631f1fdc 100644 --- a/Localization/StringsConvertor/input/sv.lproj/app.json +++ b/Localization/StringsConvertor/input/sv.lproj/app.json @@ -652,9 +652,9 @@ "searching": { "posts": "Posts matching \"%s\"", "people": "People matching \"%s\"", - "profile": "Go to @%s@%s", - "url": "Open URL in Mastodon", - "hashtag": "Go to #%s", + "profile": "Gå till @%s@%s", + "url": "Öppna URL i Mastodon", + "hashtag": "Gå till #%s", "empty_state": { "no_results": "Inga resultat" },