Merge branch 'develop' into performance_experiments
2
.github/scripts/build.sh
vendored
@ -7,6 +7,6 @@ set -eo pipefail
|
||||
|
||||
xcodebuild -workspace Mastodon.xcworkspace \
|
||||
-scheme Mastodon \
|
||||
-destination "platform=iOS Simulator,name=iPhone SE (2nd generation)" \
|
||||
-destination "platform=iOS Simulator,name=iPhone SE (3rd generation)" \
|
||||
clean \
|
||||
build | xcpretty
|
||||
|
@ -3,29 +3,29 @@ name: CI
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
- feature/*
|
||||
- feature-*
|
||||
- issue/*
|
||||
- issue-*
|
||||
- master
|
||||
- develop
|
||||
- feature/*
|
||||
- feature-*
|
||||
- issue/*
|
||||
- issue-*
|
||||
pull_request:
|
||||
branches:
|
||||
- develop
|
||||
- develop
|
||||
|
||||
# macOS environments: https://github.com/actions/virtual-environments/tree/main/images/macos
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: CI build
|
||||
runs-on: macos-12
|
||||
runs-on: macos-13
|
||||
steps:
|
||||
- name: checkout
|
||||
- name: Repository
|
||||
uses: actions/checkout@v2
|
||||
- name: setup
|
||||
env:
|
||||
- name: Setup Build Environment
|
||||
env:
|
||||
NotificationEndpointDebug: ${{ secrets.NotificationEndpointDebug }}
|
||||
NotificationEndpointRelease: ${{ secrets.NotificationEndpointRelease }}
|
||||
run: exec ./.github/scripts/setup.sh
|
||||
- name: build
|
||||
run: exec ./.github/scripts/build.sh
|
||||
- name: Build App
|
||||
run: bundle exec fastlane ios build_only
|
40
.github/workflows/deploy-appstore.yml
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
name: Deploy App Store
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
- release*
|
||||
jobs:
|
||||
deploy_appstore:
|
||||
name: Deploy App Store
|
||||
runs-on: macos-13
|
||||
steps:
|
||||
- name: Install SSH key
|
||||
uses: webfactory/ssh-agent@v0.5.3
|
||||
with:
|
||||
ssh-private-key: |
|
||||
${{ secrets.MATCH_SSH_PRIVATE_KEY }}
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Build Environment
|
||||
env:
|
||||
NotificationEndpointDebug: ${{ secrets.NotificationEndpointDebug }}
|
||||
NotificationEndpointRelease: ${{ secrets.NotificationEndpointRelease }}
|
||||
run: exec ./.github/scripts/setup.sh
|
||||
- name: Select required Xcode version
|
||||
run: sudo xcode-select -switch /Applications/Xcode_15.0.0.app
|
||||
- name: Deploy App Store
|
||||
env:
|
||||
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
|
||||
ITC_KEY_ID: ${{ secrets.APPSTORE_KEY_ID }}
|
||||
ITC_ISSUER_ID: ${{ secrets.APPSTORE_ISSUER_ID }}
|
||||
ITC_KEY: ${{ secrets.APPSTORE_PRIVATE_KEY }}
|
||||
run: bundle exec fastlane ios deploy_appstore
|
||||
- name: Tag commit
|
||||
uses: tvdias/github-tagger@v0.0.1
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
tag: "${{ env.GITHUB_TAG_NAME }}"
|
74
.github/workflows/develop-build.yml
vendored
@ -1,74 +0,0 @@
|
||||
name: Build for Develop TestFlight
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
- release*
|
||||
- ci-test
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: macOS-12
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup
|
||||
env:
|
||||
NotificationEndpointDebug: ${{ secrets.NotificationEndpointDebug }}
|
||||
NotificationEndpointRelease: ${{ secrets.NotificationEndpointRelease }}
|
||||
run: exec ./.github/scripts/setup.sh
|
||||
|
||||
- name: Install codemagic-cli-tools
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.10'
|
||||
- run: |
|
||||
pip3 install codemagic-cli-tools
|
||||
- run: |
|
||||
codemagic-cli-tools --version || true
|
||||
|
||||
- name: Import Code-Signing Certificates
|
||||
uses: Apple-Actions/import-codesign-certs@v1 # https://github.com/Apple-Actions/import-codesign-certs
|
||||
with:
|
||||
keychain: build-p12
|
||||
p12-file-base64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
|
||||
p12-password: ${{ secrets.P12_PASSWORD }}
|
||||
|
||||
- name: Download Provisioning Profiles
|
||||
uses: Apple-Actions/download-provisioning-profiles@v1 # https://github.com/Apple-Actions/download-provisioning-profiles
|
||||
with:
|
||||
bundle-id: org.joinmastodon.app
|
||||
issuer-id: ${{ secrets.APPSTORE_ISSUER_ID }}
|
||||
api-key-id: ${{ secrets.APPSTORE_KEY_ID }}
|
||||
api-private-key: ${{ secrets.APPSTORE_PRIVATE_KEY }}
|
||||
|
||||
- name: Build
|
||||
env:
|
||||
ENV_APP_ID: ${{ secrets.APP_ID }}
|
||||
ENV_ISSUER_ID: ${{ secrets.APPSTORE_ISSUER_ID }}
|
||||
ENV_API_KEY_ID: ${{ secrets.APPSTORE_KEY_ID }}
|
||||
ENV_API_PRIVATE_KEY: ${{ secrets.APPSTORE_PRIVATE_KEY }}
|
||||
ENV_API_PRIVATE_KEY_BASE64: ${{ secrets.APP_STORE_CONNECT_KEY_BASE64 }}
|
||||
run: exec ./.github/scripts/build-release.sh
|
||||
|
||||
- name: Upload TestFlight Build
|
||||
uses: Apple-Actions/upload-testflight-build@master
|
||||
with:
|
||||
app-path: .build/Artifacts/Mastodon.ipa/Mastodon.ipa
|
||||
issuer-id: ${{ secrets.APPSTORE_ISSUER_ID }}
|
||||
api-key-id: ${{ secrets.APPSTORE_KEY_ID }}
|
||||
api-private-key: ${{ secrets.APPSTORE_PRIVATE_KEY }}
|
||||
|
||||
- name: Tag commit
|
||||
uses: tvdias/github-tagger@v0.0.1
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
tag: "${{ env.GITHUB_TAG_NAME }}"
|
||||
|
||||
- name: Clean up keychain and provisioning profile
|
||||
if: ${{ always() }}
|
||||
run: |
|
||||
security delete-keychain build-p12.keychain-db
|
2
.gitignore
vendored
@ -88,6 +88,8 @@ fastlane/report.xml
|
||||
fastlane/Preview.html
|
||||
fastlane/screenshots/**/*.png
|
||||
fastlane/test_output
|
||||
fastlane/.env
|
||||
fastlane/devices.txt
|
||||
|
||||
# Code Injection
|
||||
# After new code Injection tools there's a generated folder /iOSInjectionProject
|
||||
|
21
Documentation/Deployment.md
Normal file
@ -0,0 +1,21 @@
|
||||
# Deployment
|
||||
|
||||
## Your Device
|
||||
|
||||
### As a Mastodon Collaborator WITH access to the Mastodon Apple Developer Program
|
||||
|
||||
To ensure you're able to build the App for your Device please create a `fastlane/devices.txt` and add your device's UDID.
|
||||
You may use `fastlane/devices.text.example` as a starting point. Please note that fastlane expects you to use tabs in this file.
|
||||
|
||||
After adding your device please run `bundle exec fastlane ios register_devices` to add your device(s) to the Apple Develper Account.
|
||||
Then run `bundle exec fastlane ios update_certificates` to re-generate the Codesigning Provisioning Profiles.
|
||||
|
||||
You should now be able to run the App using Xcode on your Device.
|
||||
|
||||
### As a Mastodon Contributor WITHOUT access to the Mastodon Apple Developer Program
|
||||
|
||||
To run the App on your Device you'll need to take care of Codesigning yourself by adjusting the App's Codesigning Settings in Xcode to your needs.
|
||||
|
||||
## App Store
|
||||
|
||||
We're using [Fastlane](https://fastlane.tools) to deploy the App to App Store Connect. Please see the [Fastlane README](../fastlane/README.md) on the available commands.
|
4
Gemfile
@ -5,3 +5,7 @@ gem "cocoapods"
|
||||
gem "cocoapods-clean"
|
||||
gem "xcpretty"
|
||||
|
||||
# Fastlane
|
||||
gem "fastlane"
|
||||
plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
|
||||
eval_gemfile(plugins_path) if File.exist?(plugins_path)
|
||||
|
207
Gemfile.lock
@ -4,9 +4,14 @@ GEM
|
||||
CFPropertyList (3.0.6)
|
||||
rexml
|
||||
activesupport (7.0.8)
|
||||
base64
|
||||
bigdecimal
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
connection_pool (>= 2.2.5)
|
||||
drb
|
||||
i18n (>= 1.6, < 2)
|
||||
minitest (>= 5.1)
|
||||
mutex_m
|
||||
tzinfo (~> 2.0)
|
||||
addressable (2.8.5)
|
||||
public_suffix (>= 2.0.2, < 6.0)
|
||||
@ -17,12 +22,32 @@ GEM
|
||||
dotenv (~> 2.7)
|
||||
rainbow (~> 3.1.1)
|
||||
yaml (~> 0.2)
|
||||
artifactory (3.0.15)
|
||||
atomos (0.1.3)
|
||||
aws-eventstream (1.2.0)
|
||||
aws-partitions (1.833.0)
|
||||
aws-sdk-core (3.185.0)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
aws-partitions (~> 1, >= 1.651.0)
|
||||
aws-sigv4 (~> 1.5)
|
||||
jmespath (~> 1, >= 1.6.1)
|
||||
aws-sdk-kms (1.72.0)
|
||||
aws-sdk-core (~> 3, >= 3.184.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sdk-s3 (1.136.0)
|
||||
aws-sdk-core (~> 3, >= 3.181.0)
|
||||
aws-sdk-kms (~> 1)
|
||||
aws-sigv4 (~> 1.6)
|
||||
aws-sigv4 (1.6.0)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
babosa (1.0.4)
|
||||
base64 (0.1.1)
|
||||
bigdecimal (3.1.4)
|
||||
claide (1.1.0)
|
||||
cocoapods (1.12.1)
|
||||
cocoapods (1.13.0)
|
||||
addressable (~> 2.8)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
cocoapods-core (= 1.12.1)
|
||||
cocoapods-core (= 1.13.0)
|
||||
cocoapods-deintegrate (>= 1.0.3, < 2.0)
|
||||
cocoapods-downloader (>= 1.6.0, < 2.0)
|
||||
cocoapods-plugins (>= 1.0.0, < 2.0)
|
||||
@ -36,9 +61,9 @@ GEM
|
||||
molinillo (~> 0.8.0)
|
||||
nap (~> 1.0)
|
||||
ruby-macho (>= 2.3.0, < 3.0)
|
||||
xcodeproj (>= 1.21.0, < 2.0)
|
||||
xcodeproj (>= 1.23.0, < 2.0)
|
||||
cocoapods-clean (0.0.1)
|
||||
cocoapods-core (1.12.1)
|
||||
cocoapods-core (1.13.0)
|
||||
activesupport (>= 5.0, < 8)
|
||||
addressable (~> 2.8)
|
||||
algoliasearch (~> 1.0)
|
||||
@ -57,35 +82,201 @@ GEM
|
||||
nap (>= 0.8, < 2.0)
|
||||
netrc (~> 0.11)
|
||||
cocoapods-try (1.2.0)
|
||||
colored (1.2)
|
||||
colored2 (3.1.2)
|
||||
commander (4.6.0)
|
||||
highline (~> 2.0.0)
|
||||
concurrent-ruby (1.2.2)
|
||||
connection_pool (2.4.1)
|
||||
declarative (0.0.20)
|
||||
digest-crc (0.6.5)
|
||||
rake (>= 12.0.0, < 14.0.0)
|
||||
domain_name (0.5.20190701)
|
||||
unf (>= 0.0.5, < 1.0.0)
|
||||
dotenv (2.8.1)
|
||||
drb (2.1.1)
|
||||
ruby2_keywords
|
||||
emoji_regex (3.2.3)
|
||||
escape (0.0.4)
|
||||
ethon (0.16.0)
|
||||
ffi (>= 1.15.0)
|
||||
ffi (1.15.5)
|
||||
excon (0.104.0)
|
||||
faraday (1.10.3)
|
||||
faraday-em_http (~> 1.0)
|
||||
faraday-em_synchrony (~> 1.0)
|
||||
faraday-excon (~> 1.1)
|
||||
faraday-httpclient (~> 1.0)
|
||||
faraday-multipart (~> 1.0)
|
||||
faraday-net_http (~> 1.0)
|
||||
faraday-net_http_persistent (~> 1.0)
|
||||
faraday-patron (~> 1.0)
|
||||
faraday-rack (~> 1.0)
|
||||
faraday-retry (~> 1.0)
|
||||
ruby2_keywords (>= 0.0.4)
|
||||
faraday-cookie_jar (0.0.7)
|
||||
faraday (>= 0.8.0)
|
||||
http-cookie (~> 1.0.0)
|
||||
faraday-em_http (1.0.0)
|
||||
faraday-em_synchrony (1.0.0)
|
||||
faraday-excon (1.1.0)
|
||||
faraday-httpclient (1.0.1)
|
||||
faraday-multipart (1.0.4)
|
||||
multipart-post (~> 2)
|
||||
faraday-net_http (1.0.1)
|
||||
faraday-net_http_persistent (1.2.0)
|
||||
faraday-patron (1.0.0)
|
||||
faraday-rack (1.0.0)
|
||||
faraday-retry (1.0.3)
|
||||
faraday_middleware (1.2.0)
|
||||
faraday (~> 1.0)
|
||||
fastimage (2.2.7)
|
||||
fastlane (2.216.0)
|
||||
CFPropertyList (>= 2.3, < 4.0.0)
|
||||
addressable (>= 2.8, < 3.0.0)
|
||||
artifactory (~> 3.0)
|
||||
aws-sdk-s3 (~> 1.0)
|
||||
babosa (>= 1.0.3, < 2.0.0)
|
||||
bundler (>= 1.12.0, < 3.0.0)
|
||||
colored
|
||||
commander (~> 4.6)
|
||||
dotenv (>= 2.1.1, < 3.0.0)
|
||||
emoji_regex (>= 0.1, < 4.0)
|
||||
excon (>= 0.71.0, < 1.0.0)
|
||||
faraday (~> 1.0)
|
||||
faraday-cookie_jar (~> 0.0.6)
|
||||
faraday_middleware (~> 1.0)
|
||||
fastimage (>= 2.1.0, < 3.0.0)
|
||||
gh_inspector (>= 1.1.2, < 2.0.0)
|
||||
google-apis-androidpublisher_v3 (~> 0.3)
|
||||
google-apis-playcustomapp_v1 (~> 0.1)
|
||||
google-cloud-storage (~> 1.31)
|
||||
highline (~> 2.0)
|
||||
http-cookie (~> 1.0.5)
|
||||
json (< 3.0.0)
|
||||
jwt (>= 2.1.0, < 3)
|
||||
mini_magick (>= 4.9.4, < 5.0.0)
|
||||
multipart-post (>= 2.0.0, < 3.0.0)
|
||||
naturally (~> 2.2)
|
||||
optparse (~> 0.1.1)
|
||||
plist (>= 3.1.0, < 4.0.0)
|
||||
rubyzip (>= 2.0.0, < 3.0.0)
|
||||
security (= 0.1.3)
|
||||
simctl (~> 1.6.3)
|
||||
terminal-notifier (>= 2.0.0, < 3.0.0)
|
||||
terminal-table (~> 3)
|
||||
tty-screen (>= 0.6.3, < 1.0.0)
|
||||
tty-spinner (>= 0.8.0, < 1.0.0)
|
||||
word_wrap (~> 1.0.0)
|
||||
xcodeproj (>= 1.13.0, < 2.0.0)
|
||||
xcpretty (~> 0.3.0)
|
||||
xcpretty-travis-formatter (>= 0.0.3)
|
||||
fastlane-plugin-versioning (0.5.2)
|
||||
ffi (1.16.3)
|
||||
fourflusher (2.3.1)
|
||||
fuzzy_match (2.0.4)
|
||||
gh_inspector (1.1.3)
|
||||
google-apis-androidpublisher_v3 (0.50.0)
|
||||
google-apis-core (>= 0.11.0, < 2.a)
|
||||
google-apis-core (0.11.1)
|
||||
addressable (~> 2.5, >= 2.5.1)
|
||||
googleauth (>= 0.16.2, < 2.a)
|
||||
httpclient (>= 2.8.1, < 3.a)
|
||||
mini_mime (~> 1.0)
|
||||
representable (~> 3.0)
|
||||
retriable (>= 2.0, < 4.a)
|
||||
rexml
|
||||
webrick
|
||||
google-apis-iamcredentials_v1 (0.17.0)
|
||||
google-apis-core (>= 0.11.0, < 2.a)
|
||||
google-apis-playcustomapp_v1 (0.13.0)
|
||||
google-apis-core (>= 0.11.0, < 2.a)
|
||||
google-apis-storage_v1 (0.19.0)
|
||||
google-apis-core (>= 0.9.0, < 2.a)
|
||||
google-cloud-core (1.6.0)
|
||||
google-cloud-env (~> 1.0)
|
||||
google-cloud-errors (~> 1.0)
|
||||
google-cloud-env (1.6.0)
|
||||
faraday (>= 0.17.3, < 3.0)
|
||||
google-cloud-errors (1.3.1)
|
||||
google-cloud-storage (1.44.0)
|
||||
addressable (~> 2.8)
|
||||
digest-crc (~> 0.4)
|
||||
google-apis-iamcredentials_v1 (~> 0.1)
|
||||
google-apis-storage_v1 (~> 0.19.0)
|
||||
google-cloud-core (~> 1.6)
|
||||
googleauth (>= 0.16.2, < 2.a)
|
||||
mini_mime (~> 1.0)
|
||||
googleauth (1.8.1)
|
||||
faraday (>= 0.17.3, < 3.a)
|
||||
jwt (>= 1.4, < 3.0)
|
||||
multi_json (~> 1.11)
|
||||
os (>= 0.9, < 2.0)
|
||||
signet (>= 0.16, < 2.a)
|
||||
highline (2.0.3)
|
||||
http-cookie (1.0.5)
|
||||
domain_name (~> 0.5)
|
||||
httpclient (2.8.3)
|
||||
i18n (1.14.1)
|
||||
concurrent-ruby (~> 1.0)
|
||||
jmespath (1.6.2)
|
||||
json (2.6.3)
|
||||
jwt (2.7.1)
|
||||
mini_magick (4.12.0)
|
||||
mini_mime (1.1.5)
|
||||
minitest (5.20.0)
|
||||
molinillo (0.8.0)
|
||||
multi_json (1.15.0)
|
||||
multipart-post (2.3.0)
|
||||
mutex_m (0.1.2)
|
||||
nanaimo (0.3.0)
|
||||
nap (1.1.0)
|
||||
naturally (2.2.1)
|
||||
netrc (0.11.0)
|
||||
optparse (0.1.1)
|
||||
os (1.1.4)
|
||||
plist (3.7.0)
|
||||
public_suffix (4.0.7)
|
||||
rainbow (3.1.1)
|
||||
rake (13.0.6)
|
||||
representable (3.2.0)
|
||||
declarative (< 0.1.0)
|
||||
trailblazer-option (>= 0.1.1, < 0.2.0)
|
||||
uber (< 0.2.0)
|
||||
retriable (3.1.2)
|
||||
rexml (3.2.6)
|
||||
rouge (2.0.7)
|
||||
ruby-macho (2.5.1)
|
||||
ruby2_keywords (0.0.5)
|
||||
rubyzip (2.3.2)
|
||||
security (0.1.3)
|
||||
signet (0.18.0)
|
||||
addressable (~> 2.8)
|
||||
faraday (>= 0.17.5, < 3.a)
|
||||
jwt (>= 1.5, < 3.0)
|
||||
multi_json (~> 1.10)
|
||||
simctl (1.6.10)
|
||||
CFPropertyList
|
||||
naturally
|
||||
terminal-notifier (2.0.0)
|
||||
terminal-table (3.0.2)
|
||||
unicode-display_width (>= 1.1.1, < 3)
|
||||
trailblazer-option (0.1.2)
|
||||
tty-cursor (0.7.1)
|
||||
tty-screen (0.8.1)
|
||||
tty-spinner (0.9.3)
|
||||
tty-cursor (~> 0.7)
|
||||
typhoeus (1.4.0)
|
||||
ethon (>= 0.9.0)
|
||||
tzinfo (2.0.6)
|
||||
concurrent-ruby (~> 1.0)
|
||||
xcodeproj (1.22.0)
|
||||
uber (0.1.0)
|
||||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.8.2)
|
||||
unicode-display_width (2.5.0)
|
||||
webrick (1.8.1)
|
||||
word_wrap (1.0.0)
|
||||
xcodeproj (1.23.0)
|
||||
CFPropertyList (>= 2.3.3, < 4.0)
|
||||
atomos (~> 0.1.3)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
@ -94,6 +285,8 @@ GEM
|
||||
rexml (~> 3.2.4)
|
||||
xcpretty (0.3.0)
|
||||
rouge (~> 2.0.7)
|
||||
xcpretty-travis-formatter (1.0.1)
|
||||
xcpretty (~> 0.2, >= 0.0.7)
|
||||
yaml (0.2.1)
|
||||
|
||||
PLATFORMS
|
||||
@ -106,6 +299,8 @@ DEPENDENCIES
|
||||
arkana
|
||||
cocoapods
|
||||
cocoapods-clean
|
||||
fastlane
|
||||
fastlane-plugin-versioning
|
||||
xcpretty
|
||||
|
||||
BUNDLED WITH
|
||||
|
@ -715,6 +715,7 @@
|
||||
"notifications": "Notifications",
|
||||
"support_mastodon": "Support Mastodon",
|
||||
"about_mastodon": "About Mastodon",
|
||||
"server_details": "Server Details",
|
||||
"logout": "Logout %@"
|
||||
}
|
||||
|
||||
@ -725,6 +726,9 @@
|
||||
"privacy_policy": "Privacy Policy",
|
||||
"clear_media_storage": "Clear Media Storage"
|
||||
},
|
||||
"about_instance": {
|
||||
"message_admin": "Message Admin"
|
||||
},
|
||||
"general": {
|
||||
"title": "General",
|
||||
"appearance": {
|
||||
|
@ -715,6 +715,7 @@
|
||||
"notifications": "Notifications",
|
||||
"support_mastodon": "Support Mastodon",
|
||||
"about_mastodon": "About Mastodon",
|
||||
"server_details": "Server Details",
|
||||
"logout": "Logout %@"
|
||||
}
|
||||
|
||||
|
@ -715,6 +715,7 @@
|
||||
"notifications": "Notifications",
|
||||
"support_mastodon": "Support Mastodon",
|
||||
"about_mastodon": "About Mastodon",
|
||||
"server_details": "Server Details",
|
||||
"logout": "Logout %@"
|
||||
}
|
||||
|
||||
@ -725,6 +726,16 @@
|
||||
"privacy_policy": "Privacy Policy",
|
||||
"clear_media_storage": "Clear Media Storage"
|
||||
},
|
||||
|
||||
"server_details": {
|
||||
"about": "About",
|
||||
"rules": "Rules"
|
||||
"about_instance": {
|
||||
"title": "Adminstrator"
|
||||
"message_admin": "Message Admin",
|
||||
"legal_notice": "A legal notice"
|
||||
}
|
||||
},
|
||||
"general": {
|
||||
"title": "General",
|
||||
"appearance": {
|
||||
|
@ -3,7 +3,7 @@
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 54;
|
||||
objectVersion = 60;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
@ -20,7 +20,6 @@
|
||||
0FB3D31E25E534C700AAD544 /* PickServerCategoryCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D31D25E534C700AAD544 /* PickServerCategoryCollectionViewCell.swift */; };
|
||||
0FB3D33825E6401400AAD544 /* PickServerCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D33725E6401400AAD544 /* PickServerCell.swift */; };
|
||||
164F0EBC267D4FE400249499 /* BoopSound.caf in Resources */ = {isa = PBXBuildFile; fileRef = 164F0EBB267D4FE400249499 /* BoopSound.caf */; };
|
||||
18BC7629F65E6DB12CB8416D /* Pods_Mastodon_MastodonUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C030226D3C73DCC23D67452 /* Pods_Mastodon_MastodonUITests.framework */; };
|
||||
27D701F5292FC2D60031BCBB /* DataSourceFacade+URL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27D701F4292FC2D60031BCBB /* DataSourceFacade+URL.swift */; };
|
||||
2A1BF99529F7E68400FA1BA5 /* DataSourceFacade+UserView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A1BF99429F7E68400FA1BA5 /* DataSourceFacade+UserView.swift */; };
|
||||
2A1FE47C2938BB2600784BF1 /* FollowedTagsViewModel+DiffableDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A1FE47B2938BB2600784BF1 /* FollowedTagsViewModel+DiffableDataSource.swift */; };
|
||||
@ -109,29 +108,31 @@
|
||||
5D0393962612D266007FE196 /* WebViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D0393952612D266007FE196 /* WebViewModel.swift */; };
|
||||
5DA732CC2629CEF500A92342 /* UIView+Remove.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DA732CB2629CEF500A92342 /* UIView+Remove.swift */; };
|
||||
5DF1056425F887CB00D6C0D4 /* AVPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DF1056325F887CB00D6C0D4 /* AVPlayer.swift */; };
|
||||
5E0DEC05797A7E6933788DDB /* Pods_MastodonTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 452147B2903DF38070FE56A2 /* Pods_MastodonTests.framework */; };
|
||||
5E44BF88AD33646E64727BCF /* Pods_MastodonTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD92E0F10BDE4FE7C4B999F2 /* Pods_MastodonTests.framework */; };
|
||||
6213AF5A28939C8400BCADB6 /* BookmarkViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6213AF5928939C8400BCADB6 /* BookmarkViewModel.swift */; };
|
||||
6213AF5C28939C8A00BCADB6 /* BookmarkViewModel+State.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6213AF5B28939C8A00BCADB6 /* BookmarkViewModel+State.swift */; };
|
||||
6213AF5E2893A8B200BCADB6 /* DataSourceFacade+Bookmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6213AF5D2893A8B200BCADB6 /* DataSourceFacade+Bookmark.swift */; };
|
||||
62FD27D12893707600B205C5 /* BookmarkViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62FD27D02893707600B205C5 /* BookmarkViewController.swift */; };
|
||||
62FD27D32893707B00B205C5 /* BookmarkViewController+DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62FD27D22893707B00B205C5 /* BookmarkViewController+DataSourceProvider.swift */; };
|
||||
62FD27D52893708A00B205C5 /* BookmarkViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62FD27D42893708A00B205C5 /* BookmarkViewModel+Diffable.swift */; };
|
||||
71458AF57697DB405CFEC37C /* Pods_Mastodon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C2A2448AEEDA65B4CD099FC /* Pods_Mastodon.framework */; };
|
||||
7910197261F9D06EFCDCCDBC /* Pods_MastodonTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 89FE8B85A00419CEF4678056 /* Pods_MastodonTests.framework */; };
|
||||
855149C8295F1C5F00943D96 /* UIInterfaceOrientationMask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 855149C7295F1C5F00943D96 /* UIInterfaceOrientationMask.swift */; };
|
||||
855149CA29606D6400943D96 /* PortraitAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 855149C929606D6400943D96 /* PortraitAlertController.swift */; };
|
||||
85904C02293BC0EB0011C817 /* ImageProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85904C01293BC0EB0011C817 /* ImageProvider.swift */; };
|
||||
85904C04293BC1940011C817 /* URLActivityItemWithMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85904C03293BC1940011C817 /* URLActivityItemWithMetadata.swift */; };
|
||||
85BC11B32932414900E191CD /* AltTextViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85BC11B22932414900E191CD /* AltTextViewController.swift */; };
|
||||
87FFDA5D898A5C42ADCB35E7 /* Pods_Mastodon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A4ABE34829701A4496C5BB64 /* Pods_Mastodon.framework */; };
|
||||
9E44C7202967AD17004B2A72 /* MastodonSDKDynamic in Frameworks */ = {isa = PBXBuildFile; productRef = 9E44C71F2967AD17004B2A72 /* MastodonSDKDynamic */; };
|
||||
9E44C7222967AD17004B2A72 /* MastodonSDKDynamic in Embed Frameworks */ = {isa = PBXBuildFile; productRef = 9E44C71F2967AD17004B2A72 /* MastodonSDKDynamic */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
C24C97032922F30500BAE8CB /* RefreshControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C24C97022922F30500BAE8CB /* RefreshControl.swift */; };
|
||||
D807C6C029DE197900A4E17C /* EducationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D807C6BF29DE197900A4E17C /* EducationViewController.swift */; };
|
||||
D808B94C296ECFDC0031EB1E /* StatusEditHistoryViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D808B94B296ECFDC0031EB1E /* StatusEditHistoryViewModel.swift */; };
|
||||
D808B94E296EFBBA0031EB1E /* StatusEditHistoryTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D808B94D296EFBBA0031EB1E /* StatusEditHistoryTableViewCell.swift */; };
|
||||
D80911082AC4BFDE00EB4D15 /* ServerDetailsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D80911072AC4BFDE00EB4D15 /* ServerDetailsViewController.swift */; };
|
||||
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 */; };
|
||||
D81439862AD415DE0071A88F /* AboutInstance.swift in Sources */ = {isa = PBXBuildFile; fileRef = D81439852AD415DE0071A88F /* AboutInstance.swift */; };
|
||||
D81439882AD450A40071A88F /* AboutInstanceTableViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = D81439872AD450A40071A88F /* AboutInstanceTableViewDataSource.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 */; };
|
||||
@ -144,6 +145,8 @@
|
||||
D8318A882A4468D300C0FB73 /* NotificationSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8318A872A4468D300C0FB73 /* NotificationSettingsViewController.swift */; };
|
||||
D8318A8A2A4468DC00C0FB73 /* AboutViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8318A892A4468DC00C0FB73 /* AboutViewController.swift */; };
|
||||
D8363B1629469CE200A74079 /* OnboardingNextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8363B1529469CE200A74079 /* OnboardingNextView.swift */; };
|
||||
D852C23C2AC5D02C00309232 /* AboutInstanceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D852C23B2AC5D02C00309232 /* AboutInstanceViewController.swift */; };
|
||||
D852C23E2AC5D03300309232 /* InstanceRulesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D852C23D2AC5D03300309232 /* InstanceRulesViewController.swift */; };
|
||||
D87BFC8B291D5C6B00FEE264 /* MastodonLoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D87BFC8A291D5C6B00FEE264 /* MastodonLoginView.swift */; };
|
||||
D87BFC8D291EB81200FEE264 /* MastodonLoginViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D87BFC8C291EB81200FEE264 /* MastodonLoginViewModel.swift */; };
|
||||
D87BFC8F291EC26A00FEE264 /* MastodonLoginServerTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D87BFC8E291EC26A00FEE264 /* MastodonLoginServerTableViewCell.swift */; };
|
||||
@ -173,6 +176,10 @@
|
||||
D8F917112A4C6B40008A5370 /* GeneralSettingToggleTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8F917102A4C6B40008A5370 /* GeneralSettingToggleTableViewCell.swift */; };
|
||||
D8F917122A4C6B67008A5370 /* GeneralSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8318A832A4468A800C0FB73 /* GeneralSettingsViewController.swift */; };
|
||||
D8F917142A4D74C3008A5370 /* GeneralSettingsDiffableTableViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8F917132A4D74C3008A5370 /* GeneralSettingsDiffableTableViewDataSource.swift */; };
|
||||
D8FAAE3D2AD042E700DC1832 /* AdminTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8FAAE3C2AD042E700DC1832 /* AdminTableViewCell.swift */; };
|
||||
D8FAAE3F2AD0430E00DC1832 /* ContactAdminTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8FAAE3E2AD0430E00DC1832 /* ContactAdminTableViewCell.swift */; };
|
||||
D8FAAE412AD0475900DC1832 /* AboutInstanceTableViewHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8FAAE402AD0475900DC1832 /* AboutInstanceTableViewHeader.swift */; };
|
||||
D8FAAE432AD047B200DC1832 /* AboutInstanceTableFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8FAAE422AD047B200DC1832 /* AboutInstanceTableFooterView.swift */; };
|
||||
DB0009A626AEE5DC009B9D2D /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = DB0009A926AEE5DC009B9D2D /* Intents.intentdefinition */; settings = {ATTRIBUTES = (codegen, ); }; };
|
||||
DB0009A726AEE5DC009B9D2D /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = DB0009A926AEE5DC009B9D2D /* Intents.intentdefinition */; };
|
||||
DB023D26279FFB0A005AC798 /* ShareActivityProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB023D25279FFB0A005AC798 /* ShareActivityProvider.swift */; };
|
||||
@ -488,6 +495,7 @@
|
||||
DBFEEC99279BDCDE004F81DD /* ProfileAboutViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBFEEC98279BDCDE004F81DD /* ProfileAboutViewModel.swift */; };
|
||||
DBFEEC9B279BDDD9004F81DD /* ProfileAboutViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBFEEC9A279BDDD9004F81DD /* ProfileAboutViewModel+Diffable.swift */; };
|
||||
DBFEEC9D279C12C1004F81DD /* ProfileFieldEditCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBFEEC9C279C12C1004F81DD /* ProfileFieldEditCollectionViewCell.swift */; };
|
||||
EF7771EAA493A869D65A105C /* Pods_Mastodon_MastodonUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD12474E169668871A9F6AB4 /* Pods_Mastodon_MastodonUITests.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@ -713,7 +721,6 @@
|
||||
2D8434FA25FF46B300EECE90 /* HomeTimelineNavigationBarTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeTimelineNavigationBarTitleView.swift; sourceTree = "<group>"; };
|
||||
2D84350425FF858100EECE90 /* UIScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIScrollView.swift; sourceTree = "<group>"; };
|
||||
2D939AB425EDD8A90076FA61 /* String.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = "<group>"; };
|
||||
2DA7D05025CA545E00804E11 /* LoadMoreConfigurableTableViewContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadMoreConfigurableTableViewContainer.swift; sourceTree = "<group>"; };
|
||||
2DAC9E37262FC2320062E1A6 /* SuggestionAccountViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuggestionAccountViewController.swift; sourceTree = "<group>"; };
|
||||
2DAC9E3D262FC2400062E1A6 /* SuggestionAccountViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuggestionAccountViewModel.swift; sourceTree = "<group>"; };
|
||||
2DAC9E45262FC9FD0062E1A6 /* SuggestionAccountTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuggestionAccountTableViewCell.swift; sourceTree = "<group>"; };
|
||||
@ -721,9 +728,7 @@
|
||||
2DE0FACD2615F7AD00CDF649 /* RecommendAccountSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendAccountSection.swift; sourceTree = "<group>"; };
|
||||
2E1F6A67FDF9771D3E064FDC /* Pods-Mastodon.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.debug.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
3B7FD8F28DDA8FBCE5562B78 /* Pods-NotificationService.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NotificationService.asdk - debug.xcconfig"; path = "Target Support Files/Pods-NotificationService/Pods-NotificationService.asdk - debug.xcconfig"; sourceTree = "<group>"; };
|
||||
3C030226D3C73DCC23D67452 /* Pods_Mastodon_MastodonUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Mastodon_MastodonUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
3E08A432F40BA7B9CAA9DB68 /* Pods-AppShared.release snapshot.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AppShared.release snapshot.xcconfig"; path = "Target Support Files/Pods-AppShared/Pods-AppShared.release snapshot.xcconfig"; sourceTree = "<group>"; };
|
||||
452147B2903DF38070FE56A2 /* Pods_MastodonTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MastodonTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
459EA4F43058CAB47719E963 /* Pods-Mastodon-MastodonUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-MastodonUITests.debug.xcconfig"; path = "Target Support Files/Pods-Mastodon-MastodonUITests/Pods-Mastodon-MastodonUITests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
46DAB0EBDDFB678347CD96FF /* Pods-MastodonTests.asdk - release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonTests.asdk - release.xcconfig"; path = "Target Support Files/Pods-MastodonTests/Pods-MastodonTests.asdk - release.xcconfig"; sourceTree = "<group>"; };
|
||||
5B24BBD7262DB14800A9381B /* ReportViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReportViewModel.swift; sourceTree = "<group>"; };
|
||||
@ -755,12 +760,13 @@
|
||||
85904C03293BC1940011C817 /* URLActivityItemWithMetadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLActivityItemWithMetadata.swift; sourceTree = "<group>"; };
|
||||
85BC11B22932414900E191CD /* AltTextViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AltTextViewController.swift; sourceTree = "<group>"; };
|
||||
8850E70A1D5FF51432E43653 /* Pods-Mastodon-MastodonUITests.asdk - release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-MastodonUITests.asdk - release.xcconfig"; path = "Target Support Files/Pods-Mastodon-MastodonUITests/Pods-Mastodon-MastodonUITests.asdk - release.xcconfig"; sourceTree = "<group>"; };
|
||||
89FE8B85A00419CEF4678056 /* Pods_MastodonTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MastodonTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
8C2A2448AEEDA65B4CD099FC /* Pods_Mastodon.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Mastodon.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
8E79CCBE51FBC3F7FE8CF49F /* Pods-MastodonTests.release snapshot.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonTests.release snapshot.xcconfig"; path = "Target Support Files/Pods-MastodonTests/Pods-MastodonTests.release snapshot.xcconfig"; sourceTree = "<group>"; };
|
||||
8ED8C4B1F1BA2DCFF2926BB1 /* Pods-Mastodon-NotificationService.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-NotificationService.debug.xcconfig"; path = "Target Support Files/Pods-Mastodon-NotificationService/Pods-Mastodon-NotificationService.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
9780A4C98FFC65B32B50D1C0 /* Pods-MastodonTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonTests.release.xcconfig"; path = "Target Support Files/Pods-MastodonTests/Pods-MastodonTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
9A0982D8F349244EB558CDFD /* Pods-AppShared.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AppShared.debug.xcconfig"; path = "Target Support Files/Pods-AppShared/Pods-AppShared.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
9CFF58FD900AC059428700E7 /* Pods-NotificationService.asdk - release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NotificationService.asdk - release.xcconfig"; path = "Target Support Files/Pods-NotificationService/Pods-NotificationService.asdk - release.xcconfig"; sourceTree = "<group>"; };
|
||||
A4ABE34829701A4496C5BB64 /* Pods_Mastodon.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Mastodon.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A67FD038ECDA0E411AF8DB4D /* Pods-Mastodon-MastodonUITests.asdk.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-MastodonUITests.asdk.xcconfig"; path = "Target Support Files/Pods-Mastodon-MastodonUITests/Pods-Mastodon-MastodonUITests.asdk.xcconfig"; sourceTree = "<group>"; };
|
||||
A9B1FB898DFD6063B044298C /* Pods-AppShared.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AppShared.asdk - debug.xcconfig"; path = "Target Support Files/Pods-AppShared/Pods-AppShared.asdk - debug.xcconfig"; sourceTree = "<group>"; };
|
||||
B31D44635FCF6452F7E1B865 /* Pods-Mastodon-AppShared.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-AppShared.release.xcconfig"; path = "Target Support Files/Pods-Mastodon-AppShared/Pods-Mastodon-AppShared.release.xcconfig"; sourceTree = "<group>"; };
|
||||
@ -769,14 +775,16 @@
|
||||
BD7598A87F4497045EDEF252 /* Pods-Mastodon.asdk - release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.asdk - release.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.asdk - release.xcconfig"; sourceTree = "<group>"; };
|
||||
C24C97022922F30500BAE8CB /* RefreshControl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RefreshControl.swift; sourceTree = "<group>"; };
|
||||
C3789232A52F43529CA67E95 /* Pods-MastodonIntent.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonIntent.asdk - debug.xcconfig"; path = "Target Support Files/Pods-MastodonIntent/Pods-MastodonIntent.asdk - debug.xcconfig"; sourceTree = "<group>"; };
|
||||
CD92E0F10BDE4FE7C4B999F2 /* Pods_MastodonTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MastodonTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D7D7CF93E262178800077512 /* Pods-Mastodon-AppShared.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-AppShared.debug.xcconfig"; path = "Target Support Files/Pods-Mastodon-AppShared/Pods-Mastodon-AppShared.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
D807C6BF29DE197900A4E17C /* EducationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EducationViewController.swift; sourceTree = "<group>"; };
|
||||
D808B94B296ECFDC0031EB1E /* StatusEditHistoryViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusEditHistoryViewModel.swift; sourceTree = "<group>"; };
|
||||
D808B94D296EFBBA0031EB1E /* StatusEditHistoryTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusEditHistoryTableViewCell.swift; sourceTree = "<group>"; };
|
||||
D80911072AC4BFDE00EB4D15 /* ServerDetailsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerDetailsViewController.swift; sourceTree = "<group>"; };
|
||||
D8099077294BC8A30050219F /* PrivacyTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacyTableViewController.swift; sourceTree = "<group>"; };
|
||||
D8099079294BC9390050219F /* PrivacyTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacyTableViewCell.swift; sourceTree = "<group>"; };
|
||||
D809907B294D25510050219F /* PrivacyViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacyViewModel.swift; sourceTree = "<group>"; };
|
||||
D81439852AD415DE0071A88F /* AboutInstance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutInstance.swift; sourceTree = "<group>"; };
|
||||
D81439872AD450A40071A88F /* AboutInstanceTableViewDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutInstanceTableViewDataSource.swift; sourceTree = "<group>"; };
|
||||
D81A22742AB4643200905D71 /* SearchResultsOverviewTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultsOverviewTableViewController.swift; sourceTree = "<group>"; };
|
||||
D81A22772AB4782400905D71 /* SearchResultOverviewSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultOverviewSection.swift; sourceTree = "<group>"; };
|
||||
D81A227A2AB47B9A00905D71 /* SearchResultDefaultSectionTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultDefaultSectionTableViewCell.swift; sourceTree = "<group>"; };
|
||||
@ -786,7 +794,6 @@
|
||||
D82463532A52B47B00A3DBDD /* be */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = be; path = be.lproj/WidgetExtension.strings; sourceTree = "<group>"; };
|
||||
D82463542A52B47B00A3DBDD /* be */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = be; path = be.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
D82463552A52B47B00A3DBDD /* be */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = be; path = be.lproj/Intents.stringsdict; sourceTree = "<group>"; };
|
||||
D82BD7512ABC42D6009A374A /* Coordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Coordinator.swift; sourceTree = "<group>"; };
|
||||
D82BD7542ABC73AF009A374A /* NotificationPolicyTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationPolicyTableViewCell.swift; sourceTree = "<group>"; };
|
||||
D8318A7F2A4466D300C0FB73 /* SettingsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsCoordinator.swift; sourceTree = "<group>"; };
|
||||
D8318A832A4468A800C0FB73 /* GeneralSettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneralSettingsViewController.swift; sourceTree = "<group>"; };
|
||||
@ -794,6 +801,8 @@
|
||||
D8318A872A4468D300C0FB73 /* NotificationSettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsViewController.swift; sourceTree = "<group>"; };
|
||||
D8318A892A4468DC00C0FB73 /* AboutViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutViewController.swift; sourceTree = "<group>"; };
|
||||
D8363B1529469CE200A74079 /* OnboardingNextView.swift */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = OnboardingNextView.swift; sourceTree = "<group>"; tabWidth = 4; };
|
||||
D852C23B2AC5D02C00309232 /* AboutInstanceViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutInstanceViewController.swift; sourceTree = "<group>"; };
|
||||
D852C23D2AC5D03300309232 /* InstanceRulesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstanceRulesViewController.swift; sourceTree = "<group>"; };
|
||||
D87BFC8A291D5C6B00FEE264 /* MastodonLoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonLoginView.swift; sourceTree = "<group>"; };
|
||||
D87BFC8C291EB81200FEE264 /* MastodonLoginViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonLoginViewModel.swift; sourceTree = "<group>"; };
|
||||
D87BFC8E291EC26A00FEE264 /* MastodonLoginServerTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonLoginServerTableViewCell.swift; sourceTree = "<group>"; };
|
||||
@ -833,6 +842,10 @@
|
||||
D8F9170E2A4B47EF008A5370 /* Coordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Coordinator.swift; sourceTree = "<group>"; };
|
||||
D8F917102A4C6B40008A5370 /* GeneralSettingToggleTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneralSettingToggleTableViewCell.swift; sourceTree = "<group>"; };
|
||||
D8F917132A4D74C3008A5370 /* GeneralSettingsDiffableTableViewDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneralSettingsDiffableTableViewDataSource.swift; sourceTree = "<group>"; };
|
||||
D8FAAE3C2AD042E700DC1832 /* AdminTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdminTableViewCell.swift; sourceTree = "<group>"; };
|
||||
D8FAAE3E2AD0430E00DC1832 /* ContactAdminTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactAdminTableViewCell.swift; sourceTree = "<group>"; };
|
||||
D8FAAE402AD0475900DC1832 /* AboutInstanceTableViewHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutInstanceTableViewHeader.swift; sourceTree = "<group>"; };
|
||||
D8FAAE422AD047B200DC1832 /* AboutInstanceTableFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutInstanceTableFooterView.swift; sourceTree = "<group>"; };
|
||||
DB0009A826AEE5DC009B9D2D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; name = Base; path = Base.lproj/Intents.intentdefinition; sourceTree = "<group>"; };
|
||||
DB0009AD26AEE5E4009B9D2D /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Intents.strings; sourceTree = "<group>"; };
|
||||
DB023D25279FFB0A005AC798 /* ShareActivityProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareActivityProvider.swift; sourceTree = "<group>"; };
|
||||
@ -896,7 +909,6 @@
|
||||
DB1FD44325F26CCC004CFCFC /* PickServerSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerSection.swift; sourceTree = "<group>"; };
|
||||
DB1FD44F25F26FA1004CFCFC /* MastodonPickServerViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MastodonPickServerViewModel+Diffable.swift"; sourceTree = "<group>"; };
|
||||
DB1FD45925F27898004CFCFC /* CategoryPickerItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CategoryPickerItem.swift; sourceTree = "<group>"; };
|
||||
DB1FD45F25F278AF004CFCFC /* CategoryPickerSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CategoryPickerSection.swift; sourceTree = "<group>"; };
|
||||
DB2B3ABD25E37E15007045F9 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
DB2F073325E8ECF000957B2D /* AuthenticationViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthenticationViewModel.swift; sourceTree = "<group>"; };
|
||||
DB336F3E278E668C0031E64B /* StatusTableViewCell+ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "StatusTableViewCell+ViewModel.swift"; sourceTree = "<group>"; };
|
||||
@ -1237,6 +1249,7 @@
|
||||
DBFEEC9A279BDDD9004F81DD /* ProfileAboutViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ProfileAboutViewModel+Diffable.swift"; sourceTree = "<group>"; };
|
||||
DBFEEC9C279C12C1004F81DD /* ProfileFieldEditCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileFieldEditCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||
DBFEF06726A58D07006D7ED1 /* ShareActionExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ShareActionExtension.entitlements; sourceTree = "<group>"; };
|
||||
DD12474E169668871A9F6AB4 /* Pods_Mastodon_MastodonUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Mastodon_MastodonUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
DDB1B139FA8EA26F510D58B6 /* Pods-AppShared.asdk - release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AppShared.asdk - release.xcconfig"; path = "Target Support Files/Pods-AppShared/Pods-AppShared.asdk - release.xcconfig"; sourceTree = "<group>"; };
|
||||
DF65937EC1FF64462BC002EE /* Pods-MastodonTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonTests.profile.xcconfig"; path = "Target Support Files/Pods-MastodonTests/Pods-MastodonTests.profile.xcconfig"; sourceTree = "<group>"; };
|
||||
E5C7236E58D14A0322FE00F2 /* Pods-Mastodon-MastodonUITests.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-MastodonUITests.asdk - debug.xcconfig"; path = "Target Support Files/Pods-Mastodon-MastodonUITests/Pods-Mastodon-MastodonUITests.asdk - debug.xcconfig"; sourceTree = "<group>"; };
|
||||
@ -1246,7 +1259,6 @@
|
||||
ECA373ABA86BE3C2D7ED878E /* Pods-AppShared.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AppShared.release.xcconfig"; path = "Target Support Files/Pods-AppShared/Pods-AppShared.release.xcconfig"; sourceTree = "<group>"; };
|
||||
EE13214BC0246BE5210CCC10 /* Pods-AppShared.asdk.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AppShared.asdk.xcconfig"; path = "Target Support Files/Pods-AppShared/Pods-AppShared.asdk.xcconfig"; sourceTree = "<group>"; };
|
||||
F31E7502A7E3945B98C6CBAF /* Pods-NotificationService.asdk.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NotificationService.asdk.xcconfig"; path = "Target Support Files/Pods-NotificationService/Pods-NotificationService.asdk.xcconfig"; sourceTree = "<group>"; };
|
||||
F4A2A2D7000E477CA459ADA9 /* Pods_AppShared.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AppShared.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F920AD4EC23B0D00F5CCA58E /* Pods-MastodonIntent.asdk - release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonIntent.asdk - release.xcconfig"; path = "Target Support Files/Pods-MastodonIntent/Pods-MastodonIntent.asdk - release.xcconfig"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
@ -1277,7 +1289,7 @@
|
||||
files = (
|
||||
357FEEAF29523D470021C9DC /* MastodonSDKDynamic in Frameworks */,
|
||||
DBF96326262EC0A6001D8D25 /* AuthenticationServices.framework in Frameworks */,
|
||||
87FFDA5D898A5C42ADCB35E7 /* Pods_Mastodon.framework in Frameworks */,
|
||||
71458AF57697DB405CFEC37C /* Pods_Mastodon.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -1286,8 +1298,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9E44C7202967AD17004B2A72 /* MastodonSDKDynamic in Frameworks */,
|
||||
5E44BF88AD33646E64727BCF /* Pods_MastodonTests.framework in Frameworks */,
|
||||
5E0DEC05797A7E6933788DDB /* Pods_MastodonTests.framework in Frameworks */,
|
||||
7910197261F9D06EFCDCCDBC /* Pods_MastodonTests.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -1295,7 +1306,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
18BC7629F65E6DB12CB8416D /* Pods_Mastodon_MastodonUITests.framework in Frameworks */,
|
||||
EF7771EAA493A869D65A105C /* Pods_Mastodon_MastodonUITests.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -1720,15 +1731,14 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DBF96325262EC0A6001D8D25 /* AuthenticationServices.framework */,
|
||||
A4ABE34829701A4496C5BB64 /* Pods_Mastodon.framework */,
|
||||
3C030226D3C73DCC23D67452 /* Pods_Mastodon_MastodonUITests.framework */,
|
||||
452147B2903DF38070FE56A2 /* Pods_MastodonTests.framework */,
|
||||
F4A2A2D7000E477CA459ADA9 /* Pods_AppShared.framework */,
|
||||
DB8FAB9E26AEC3A2008E5AF4 /* Intents.framework */,
|
||||
DB8FABA926AEC3A2008E5AF4 /* IntentsUI.framework */,
|
||||
2A6451022964223800CD8B8A /* UniformTypeIdentifiers.framework */,
|
||||
2A728121297EA9D7004138C5 /* WidgetKit.framework */,
|
||||
2A728123297EA9D7004138C5 /* SwiftUI.framework */,
|
||||
8C2A2448AEEDA65B4CD099FC /* Pods_Mastodon.framework */,
|
||||
DD12474E169668871A9F6AB4 /* Pods_Mastodon_MastodonUITests.framework */,
|
||||
89FE8B85A00419CEF4678056 /* Pods_MastodonTests.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
@ -1754,6 +1764,7 @@
|
||||
D8F916FF2A4AD898008A5370 /* Settings Overview */,
|
||||
D8F917042A4B0657008A5370 /* General Settings */,
|
||||
D81D12432A4E181C005009D4 /* Notification Settings */,
|
||||
D80911062AC4BFD100EB4D15 /* Server Details */,
|
||||
D8F917092A4B2AFF008A5370 /* About Mastodon */,
|
||||
D8318A7F2A4466D300C0FB73 /* SettingsCoordinator.swift */,
|
||||
);
|
||||
@ -1781,6 +1792,17 @@
|
||||
path = Bookmark;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D80911062AC4BFD100EB4D15 /* Server Details */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D8FAAE3B2AD042CD00DC1832 /* Table View Components */,
|
||||
D80911072AC4BFDE00EB4D15 /* ServerDetailsViewController.swift */,
|
||||
D852C23B2AC5D02C00309232 /* AboutInstanceViewController.swift */,
|
||||
D852C23D2AC5D03300309232 /* InstanceRulesViewController.swift */,
|
||||
);
|
||||
path = "Server Details";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D8099076294BC2BA0050219F /* Privacy */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -1927,6 +1949,19 @@
|
||||
path = "About Mastodon";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D8FAAE3B2AD042CD00DC1832 /* Table View Components */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D8FAAE3C2AD042E700DC1832 /* AdminTableViewCell.swift */,
|
||||
D8FAAE3E2AD0430E00DC1832 /* ContactAdminTableViewCell.swift */,
|
||||
D8FAAE402AD0475900DC1832 /* AboutInstanceTableViewHeader.swift */,
|
||||
D8FAAE422AD047B200DC1832 /* AboutInstanceTableFooterView.swift */,
|
||||
D81439852AD415DE0071A88F /* AboutInstance.swift */,
|
||||
D81439872AD450A40071A88F /* AboutInstanceTableViewDataSource.swift */,
|
||||
);
|
||||
path = "Table View Components";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DB01409B25C40BB600F9F3CF /* Onboarding */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -2108,7 +2143,6 @@
|
||||
DB427DD325BAA00100D1B89D /* Products */,
|
||||
1EBA4F56E920856A3FC84ACB /* Pods */,
|
||||
3FE14AD363ED19AE7FF210A6 /* Frameworks */,
|
||||
DB98335F25C93B0400AD9700 /* Recovered References */,
|
||||
D8A6FE6029325F5900666A47 /* Localization */,
|
||||
);
|
||||
indentWidth = 4;
|
||||
@ -2635,17 +2669,6 @@
|
||||
path = Thread;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DB98335F25C93B0400AD9700 /* Recovered References */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CD92E0F10BDE4FE7C4B999F2 /* Pods_MastodonTests.framework */,
|
||||
2DA7D05025CA545E00804E11 /* LoadMoreConfigurableTableViewContainer.swift */,
|
||||
DB1FD45F25F278AF004CFCFC /* CategoryPickerSection.swift */,
|
||||
D82BD7512ABC42D6009A374A /* Coordinator.swift */,
|
||||
);
|
||||
name = "Recovered References";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DB98EB4A27B0F0F50082E365 /* Cell */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -3266,7 +3289,7 @@
|
||||
};
|
||||
};
|
||||
buildConfigurationList = DB427DCD25BAA00100D1B89D /* Build configuration list for PBXProject "Mastodon" */;
|
||||
compatibilityVersion = "Xcode 9.3";
|
||||
compatibilityVersion = "Xcode 15.0";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
@ -3612,6 +3635,7 @@
|
||||
DB023D26279FFB0A005AC798 /* ShareActivityProvider.swift in Sources */,
|
||||
5D0393962612D266007FE196 /* WebViewModel.swift in Sources */,
|
||||
5B24BBDA262DB14800A9381B /* ReportViewModel.swift in Sources */,
|
||||
D80911082AC4BFDE00EB4D15 /* ServerDetailsViewController.swift in Sources */,
|
||||
2D5A3D3825CF8D9F002347D6 /* ScrollViewContainer.swift in Sources */,
|
||||
DB6180EF26391CA50018D199 /* MediaPreviewImageViewController.swift in Sources */,
|
||||
DB1E347825F519300079D7DF /* PickServerItem.swift in Sources */,
|
||||
@ -3639,11 +3663,14 @@
|
||||
DB697DD6278F4C29004EF2F7 /* DataSourceProvider.swift in Sources */,
|
||||
DB0FCB8E2796C0B7006C02E2 /* TrendCollectionViewCell.swift in Sources */,
|
||||
0F1E2D0B2615C39400C38565 /* DoubleTitleLabelNavigationBarTitleView.swift in Sources */,
|
||||
D81439862AD415DE0071A88F /* AboutInstance.swift in Sources */,
|
||||
DBDFF1902805543100557A48 /* DiscoveryPostsViewController.swift in Sources */,
|
||||
DB697DD9278F4CED004EF2F7 /* HomeTimelineViewController+DataSourceProvider.swift in Sources */,
|
||||
DB45FAD725CA6C76005A8AC7 /* UIBarButtonItem.swift in Sources */,
|
||||
D8FAAE432AD047B200DC1832 /* AboutInstanceTableFooterView.swift in Sources */,
|
||||
D808B94E296EFBBA0031EB1E /* StatusEditHistoryTableViewCell.swift in Sources */,
|
||||
2D8434F525FF465D00EECE90 /* HomeTimelineNavigationBarTitleViewModel.swift in Sources */,
|
||||
D852C23E2AC5D03300309232 /* InstanceRulesViewController.swift in Sources */,
|
||||
DB938F0F2624119800E5B6C1 /* ThreadViewModel+LoadThreadState.swift in Sources */,
|
||||
DB6180F226391CF40018D199 /* MediaPreviewImageViewModel.swift in Sources */,
|
||||
62FD27D12893707600B205C5 /* BookmarkViewController.swift in Sources */,
|
||||
@ -3662,6 +3689,7 @@
|
||||
DBDFF19C28055BD600557A48 /* DiscoveryViewModel.swift in Sources */,
|
||||
DBB3BA2A26A81C020004F2D4 /* FLAnimatedImageView.swift in Sources */,
|
||||
DB3E6FF32806D97400B035AE /* DiscoveryNewsViewModel+State.swift in Sources */,
|
||||
D8FAAE3F2AD0430E00DC1832 /* ContactAdminTableViewCell.swift in Sources */,
|
||||
DB6746ED278F45F0008A6B94 /* AutoGenerateProtocolRelayDelegate.swift in Sources */,
|
||||
DB0618032785A7100030EE79 /* RegisterSection.swift in Sources */,
|
||||
DB63F76B279A5ED300455B82 /* NotificationTimelineViewModel+LoadOldestState.swift in Sources */,
|
||||
@ -3690,6 +3718,7 @@
|
||||
DBFEEC9D279C12C1004F81DD /* ProfileFieldEditCollectionViewCell.swift in Sources */,
|
||||
DB3E6FEC2806D7F100B035AE /* DiscoveryNewsViewController.swift in Sources */,
|
||||
DBCBED1726132DB500B49291 /* UserTimelineViewModel+Diffable.swift in Sources */,
|
||||
D8FAAE412AD0475900DC1832 /* AboutInstanceTableViewHeader.swift in Sources */,
|
||||
2DE0FACE2615F7AD00CDF649 /* RecommendAccountSection.swift in Sources */,
|
||||
2DAC9E3E262FC2400062E1A6 /* SuggestionAccountViewModel.swift in Sources */,
|
||||
DB603113279EBEBA00A935FE /* DataSourceFacade+Block.swift in Sources */,
|
||||
@ -3853,6 +3882,7 @@
|
||||
DB68A04A25E9027700CFDF14 /* AdaptiveStatusBarStyleNavigationController.swift in Sources */,
|
||||
0FB3D33825E6401400AAD544 /* PickServerCell.swift in Sources */,
|
||||
6213AF5C28939C8A00BCADB6 /* BookmarkViewModel+State.swift in Sources */,
|
||||
D81439882AD450A40071A88F /* AboutInstanceTableViewDataSource.swift in Sources */,
|
||||
D807C6C029DE197900A4E17C /* EducationViewController.swift in Sources */,
|
||||
2D364F7825E66D8300204FDC /* MastodonResendEmailViewModel.swift in Sources */,
|
||||
DBEFCD7B282A162400C0ABEA /* ReportReasonView.swift in Sources */,
|
||||
@ -3920,6 +3950,7 @@
|
||||
D8B5E4F42A4ED0240008970C /* NotificationSettingsViewModel.swift in Sources */,
|
||||
DBD376B2269302A4007FEC24 /* UITableViewCell.swift in Sources */,
|
||||
DB4F0966269ED52200D62E92 /* SearchResultViewModel.swift in Sources */,
|
||||
D852C23C2AC5D02C00309232 /* AboutInstanceViewController.swift in Sources */,
|
||||
D8F917142A4D74C3008A5370 /* GeneralSettingsDiffableTableViewDataSource.swift in Sources */,
|
||||
DB6180FA26391F2E0018D199 /* MediaPreviewViewModel.swift in Sources */,
|
||||
2D7631A825C1535600929FB9 /* StatusTableViewCell.swift in Sources */,
|
||||
@ -3935,6 +3966,7 @@
|
||||
DB3E6FE42806A5B800B035AE /* DiscoverySection.swift in Sources */,
|
||||
DB697DDB278F4DE3004EF2F7 /* DataSourceProvider+StatusTableViewCellDelegate.swift in Sources */,
|
||||
DB87D4512609CF1E00D12C0D /* ComposeStatusPollOptionAppendEntryCollectionViewCell.swift in Sources */,
|
||||
D8FAAE3D2AD042E700DC1832 /* AdminTableViewCell.swift in Sources */,
|
||||
DBB45B5627B39FC9002DC5A7 /* MediaPreviewVideoViewController.swift in Sources */,
|
||||
D8A6AB6C291C5136003AB663 /* MastodonLoginViewController.swift in Sources */,
|
||||
DB0FCB8027968F70006C02E2 /* MastodonStatusThreadViewModel.swift in Sources */,
|
||||
@ -4268,14 +4300,12 @@
|
||||
CODE_SIGN_ENTITLEMENTS = OpenInActionExtension/OpenInActionExtension.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = OpenInActionExtension/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "Open using Mastodon";
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
@ -4284,6 +4314,7 @@
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.OpenInActionExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
@ -4297,15 +4328,11 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = Icon;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CODE_SIGN_ENTITLEMENTS = OpenInActionExtension/OpenInActionExtension.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = OpenInActionExtension/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "Open using Mastodon";
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
@ -4327,15 +4354,13 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = Icon;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CODE_SIGN_ENTITLEMENTS = OpenInActionExtension/OpenInActionExtension.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 5Z4GVSS33P;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = OpenInActionExtension/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "Open using Mastodon";
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
@ -4344,6 +4369,7 @@
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.OpenInActionExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore org.joinmastodon.app.OpenInActionExtension";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
@ -4357,15 +4383,11 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = Icon;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CODE_SIGN_ENTITLEMENTS = OpenInActionExtension/OpenInActionExtension.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = OpenInActionExtension/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "Open using Mastodon";
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
@ -4390,14 +4412,12 @@
|
||||
CODE_SIGN_ENTITLEMENTS = WidgetExtension/WidgetExtension.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = WidgetExtension/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = WidgetExtension;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
@ -4406,6 +4426,7 @@
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.WidgetExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
@ -4420,15 +4441,11 @@
|
||||
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CODE_SIGN_ENTITLEMENTS = WidgetExtension/WidgetExtension.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = WidgetExtension/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = WidgetExtension;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
@ -4451,15 +4468,13 @@
|
||||
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CODE_SIGN_ENTITLEMENTS = WidgetExtension/WidgetExtension.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 5Z4GVSS33P;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = WidgetExtension/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = WidgetExtension;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
@ -4468,6 +4483,7 @@
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.WidgetExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore org.joinmastodon.app.WidgetExtension";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
@ -4482,15 +4498,11 @@
|
||||
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CODE_SIGN_ENTITLEMENTS = WidgetExtension/WidgetExtension.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = WidgetExtension/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = WidgetExtension;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
@ -4560,7 +4572,7 @@
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
INTENTS_CODEGEN_LANGUAGE = Swift;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
@ -4604,9 +4616,12 @@
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "Apple Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
@ -4618,7 +4633,7 @@
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
INTENTS_CODEGEN_LANGUAGE = Swift;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
@ -4668,10 +4683,9 @@
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 5Z4GVSS33P;
|
||||
EXCLUDED_SOURCE_FILE_NAMES = "Mastodon/Resources/Preview\\ Assets.xcassets";
|
||||
INFOPLIST_FILE = Mastodon/Info.plist;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
|
||||
@ -4683,6 +4697,7 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore org.joinmastodon.app";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Mastodon/Vender/Mastodon-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
@ -4696,6 +4711,7 @@
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 5889;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = MastodonTests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@ -4720,6 +4736,7 @@
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 5889;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = MastodonTests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@ -4743,6 +4760,7 @@
|
||||
baseConfigurationReference = 459EA4F43058CAB47719E963 /* Pods-Mastodon-MastodonUITests.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 5889;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = MastodonUITests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@ -4766,6 +4784,7 @@
|
||||
baseConfigurationReference = BB482D32A7B9825BF5327C4F /* Pods-Mastodon-MastodonUITests.release.xcconfig */;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 5889;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = MastodonUITests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@ -4837,7 +4856,7 @@
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
INTENTS_CODEGEN_LANGUAGE = Swift;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
@ -4856,8 +4875,6 @@
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = Mastodon/Info.plist;
|
||||
@ -4884,6 +4901,7 @@
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 5889;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = MastodonTests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@ -4907,6 +4925,7 @@
|
||||
baseConfigurationReference = 728DE51ADA27C395C6E1BAB5 /* Pods-Mastodon-MastodonUITests.profile.xcconfig */;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 5889;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = MastodonUITests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@ -4930,7 +4949,6 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = NotificationService/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@ -4951,7 +4969,6 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = ShareActionExtension/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@ -4973,7 +4990,6 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = MastodonIntent/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@ -4995,6 +5011,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = MastodonIntent/Info.plist;
|
||||
@ -5005,6 +5022,7 @@
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.MastodonIntent;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "APP_EXTENSION $(inherited)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
@ -5017,8 +5035,9 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = MastodonIntent/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@ -5027,6 +5046,7 @@
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.MastodonIntent;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore org.joinmastodon.app.MastodonIntent";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "APP_EXTENSION $(inherited)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
@ -5039,6 +5059,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = ShareActionExtension/Info.plist;
|
||||
@ -5049,6 +5070,7 @@
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.ShareActionExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "APP_EXTENSION $(inherited)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
@ -5061,8 +5083,9 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = ShareActionExtension/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@ -5071,6 +5094,7 @@
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.ShareActionExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore org.joinmastodon.app.ShareActionExtension";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "APP_EXTENSION $(inherited)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
@ -5127,7 +5151,7 @@
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
INTENTS_CODEGEN_LANGUAGE = Swift;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
@ -5147,8 +5171,6 @@
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = Mastodon/Info.plist;
|
||||
@ -5174,6 +5196,7 @@
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 5889;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = MastodonTests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@ -5197,6 +5220,7 @@
|
||||
baseConfigurationReference = 0827D1674B2523503E8605F6 /* Pods-Mastodon-MastodonUITests.release snapshot.xcconfig */;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 5889;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = MastodonUITests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@ -5220,7 +5244,6 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = NotificationService/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@ -5241,7 +5264,6 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = ShareActionExtension/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@ -5263,7 +5285,6 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = MastodonIntent/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@ -5286,6 +5307,7 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = NotificationService/Info.plist;
|
||||
@ -5296,6 +5318,7 @@
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.NotificationService;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
@ -5308,8 +5331,9 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = NotificationService/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@ -5318,6 +5342,7 @@
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.NotificationService;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore org.joinmastodon.app.NotificationService";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
|
@ -46,6 +46,15 @@
|
||||
"version": "3.1.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "FXPageControl",
|
||||
"repositoryURL": "https://github.com/nicklockwood/FXPageControl.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "a94633402ba98c52f86c2a70e61ff086dec9de78",
|
||||
"version": "1.6.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "KeychainAccess",
|
||||
"repositoryURL": "https://github.com/kishikawakatsumi/KeychainAccess.git",
|
||||
@ -91,15 +100,6 @@
|
||||
"version": "10.11.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "NukeFLAnimatedImagePlugin",
|
||||
"repositoryURL": "https://github.com/kean/Nuke-FLAnimatedImage-Plugin.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "b59c346a7d536336db3b0f12c72c6e53ee709e16",
|
||||
"version": "8.0.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "Pageboy",
|
||||
"repositoryURL": "https://github.com/uias/Pageboy",
|
||||
@ -216,6 +216,15 @@
|
||||
"revision": "20f513ded04a040cdf5467f0891849b1763ede3b",
|
||||
"version": "1.4.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "XLPagerTabStrip",
|
||||
"repositoryURL": "https://github.com/xmartlabs/XLPagerTabStrip.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "211ed62aa376722cf93c429802a8b6ff66a8bd52",
|
||||
"version": "9.1.0"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -541,7 +541,9 @@ private extension SceneCoordinator {
|
||||
accountName: accountName,
|
||||
setting: setting,
|
||||
appContext: appContext,
|
||||
authContext: authContext)
|
||||
authContext: authContext,
|
||||
sceneCoordinator: self
|
||||
)
|
||||
settingsCoordinator.delegate = self
|
||||
settingsCoordinator.start()
|
||||
|
||||
@ -643,7 +645,5 @@ extension SceneCoordinator: SettingsCoordinatorDelegate {
|
||||
authenticationController.authenticationSession?.start()
|
||||
|
||||
self.mastodonAuthenticationController = authenticationController
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -9,15 +9,7 @@ import SwiftUI
|
||||
|
||||
class AltTextViewController: UIViewController {
|
||||
let textView = {
|
||||
let textView: UITextView
|
||||
|
||||
if #available(iOS 16, *) {
|
||||
// TODO: update code below to use TextKit 2 when dropping iOS 15 support
|
||||
textView = UITextView(usingTextLayoutManager: false)
|
||||
} else {
|
||||
textView = UITextView()
|
||||
}
|
||||
|
||||
let textView = UITextView(usingTextLayoutManager: false)
|
||||
textView.textContainer.maximumNumberOfLines = 0
|
||||
textView.textContainer.lineBreakMode = .byWordWrapping
|
||||
textView.font = .preferredFont(forTextStyle: .callout)
|
||||
|
@ -31,17 +31,7 @@ final class MediaPreviewImageView: UIScrollView {
|
||||
|
||||
private var containerFrame: CGRect?
|
||||
|
||||
private var _interaction: UIInteraction? = {
|
||||
if #available(iOS 16.0, *) {
|
||||
return ImageAnalysisInteraction()
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}()
|
||||
@available(iOS 16.0, *)
|
||||
var liveTextInteraction: ImageAnalysisInteraction {
|
||||
_interaction as! ImageAnalysisInteraction
|
||||
}
|
||||
let liveTextInteraction = ImageAnalysisInteraction()
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
@ -72,9 +62,7 @@ extension MediaPreviewImageView {
|
||||
doubleTapGestureRecognizer.delegate = self
|
||||
|
||||
imageView.addGestureRecognizer(doubleTapGestureRecognizer)
|
||||
if #available(iOS 16.0, *) {
|
||||
imageView.addInteraction(liveTextInteraction)
|
||||
}
|
||||
imageView.addInteraction(liveTextInteraction)
|
||||
|
||||
delegate = self
|
||||
}
|
||||
@ -119,8 +107,7 @@ extension MediaPreviewImageView: UIGestureRecognizerDelegate {
|
||||
// but only if the Live Text button is toggled off
|
||||
if let gr = otherGestureRecognizer as? UITapGestureRecognizer,
|
||||
gr.numberOfTapsRequired == 2,
|
||||
#available(iOS 16, *),
|
||||
!liveTextInteraction.selectableItemsHighlighted {
|
||||
liveTextInteraction.selectableItemsHighlighted == false {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@ -151,18 +138,16 @@ extension MediaPreviewImageView {
|
||||
|
||||
centerScrollViewContents()
|
||||
|
||||
if #available(iOS 16.0, *) {
|
||||
Task.detached(priority: .userInitiated) {
|
||||
do {
|
||||
let analysis = try await ImageAnalyzer.shared.analyze(image, configuration: ImageAnalyzer.Configuration([.text, .machineReadableCode]))
|
||||
await MainActor.run {
|
||||
self.liveTextInteraction.analysis = analysis
|
||||
self.liveTextInteraction.preferredInteractionTypes = .automatic
|
||||
}
|
||||
} catch {
|
||||
await MainActor.run {
|
||||
self.liveTextInteraction.preferredInteractionTypes = []
|
||||
}
|
||||
Task.detached(priority: .userInitiated) {
|
||||
do {
|
||||
let analysis = try await ImageAnalyzer.shared.analyze(image, configuration: ImageAnalyzer.Configuration([.text, .machineReadableCode]))
|
||||
await MainActor.run {
|
||||
self.liveTextInteraction.analysis = analysis
|
||||
self.liveTextInteraction.preferredInteractionTypes = .automatic
|
||||
}
|
||||
} catch {
|
||||
await MainActor.run {
|
||||
self.liveTextInteraction.preferredInteractionTypes = []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,9 +40,7 @@ extension MediaPreviewImageViewController {
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
if #available(iOS 16.0, *) {
|
||||
previewImageView.liveTextInteraction.delegate = self
|
||||
}
|
||||
previewImageView.liveTextInteraction.delegate = self
|
||||
previewImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.addSubview(previewImageView)
|
||||
NSLayoutConstraint.activate([
|
||||
@ -90,16 +88,13 @@ extension MediaPreviewImageViewController {
|
||||
|
||||
extension MediaPreviewImageViewController: MediaPreviewPage {
|
||||
func setShowingChrome(_ showingChrome: Bool) {
|
||||
if #available(iOS 16.0, *) {
|
||||
UIView.animate(withDuration: 0.3) {
|
||||
self.previewImageView.liveTextInteraction.setSupplementaryInterfaceHidden(!showingChrome, animated: true)
|
||||
}
|
||||
UIView.animate(withDuration: 0.3) {
|
||||
self.previewImageView.liveTextInteraction.setSupplementaryInterfaceHidden(!showingChrome, animated: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - ImageAnalysisInteractionDelegate
|
||||
@available(iOS 16.0, *)
|
||||
extension MediaPreviewImageViewController: ImageAnalysisInteractionDelegate {
|
||||
func presentingViewController(for interaction: ImageAnalysisInteraction) -> UIViewController? {
|
||||
self
|
||||
@ -109,18 +104,14 @@ extension MediaPreviewImageViewController: ImageAnalysisInteractionDelegate {
|
||||
// MARK: - UIGestureRecognizerDelegate
|
||||
extension MediaPreviewImageViewController: UIGestureRecognizerDelegate {
|
||||
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
|
||||
if #available(iOS 16.0, *) {
|
||||
let location = touch.location(in: previewImageView.imageView)
|
||||
// for tap gestures, only items that can be tapped are relevant
|
||||
if gestureRecognizer is UITapGestureRecognizer {
|
||||
return !previewImageView.liveTextInteraction.hasSupplementaryInterface(at: location)
|
||||
&& !previewImageView.liveTextInteraction.hasDataDetector(at: location)
|
||||
} else {
|
||||
// for long press, block out everything
|
||||
return !previewImageView.liveTextInteraction.hasInteractiveItem(at: location)
|
||||
}
|
||||
let location = touch.location(in: previewImageView.imageView)
|
||||
// for tap gestures, only items that can be tapped are relevant
|
||||
if gestureRecognizer is UITapGestureRecognizer {
|
||||
return !previewImageView.liveTextInteraction.hasSupplementaryInterface(at: location)
|
||||
&& !previewImageView.liveTextInteraction.hasDataDetector(at: location)
|
||||
} else {
|
||||
return true
|
||||
// for long press, block out everything
|
||||
return !previewImageView.liveTextInteraction.hasInteractiveItem(at: location)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -129,10 +120,8 @@ extension MediaPreviewImageViewController: UIGestureRecognizerDelegate {
|
||||
extension MediaPreviewImageViewController: UIContextMenuInteractionDelegate {
|
||||
func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
|
||||
|
||||
if #available(iOS 16.0, *) {
|
||||
if previewImageView.liveTextInteraction.hasInteractiveItem(at: previewImageView.imageView.convert(location, from: previewImageView)) {
|
||||
return nil
|
||||
}
|
||||
if previewImageView.liveTextInteraction.hasInteractiveItem(at: previewImageView.imageView.convert(location, from: previewImageView)) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
|
@ -10,7 +10,7 @@ import MastodonAsset
|
||||
import MastodonLocalization
|
||||
|
||||
final class ServerRulesTableViewCell: UITableViewCell {
|
||||
|
||||
static let reuseIdentifier = "ServerRulesTableViewCell"
|
||||
static let margin: CGFloat = 23
|
||||
|
||||
let indexImageView: UIImageView = {
|
||||
|
@ -15,10 +15,7 @@ extension MastodonServerRulesViewModel {
|
||||
|
||||
var snapshot = NSDiffableDataSourceSnapshot<ServerRuleSection, ServerRuleItem>()
|
||||
snapshot.appendSections([.rules])
|
||||
let ruleItems: [ServerRuleItem] = rules.enumerated().map { i, rule in
|
||||
let ruleContext = ServerRuleItem.RuleContext(index: i, rule: rule)
|
||||
return ServerRuleItem.rule(ruleContext)
|
||||
}
|
||||
let ruleItems: [ServerRuleItem] = rules.enumerated().map { index, rule in return ServerRuleItem.rule(index: index, rule: rule) }
|
||||
snapshot.appendItems(ruleItems, toSection: .rules)
|
||||
diffableDataSource?.apply(snapshot, animatingDifferences: false)
|
||||
}
|
||||
|
@ -9,12 +9,5 @@ import Foundation
|
||||
import MastodonSDK
|
||||
|
||||
enum ServerRuleItem: Hashable {
|
||||
case rule(RuleContext)
|
||||
}
|
||||
|
||||
extension ServerRuleItem {
|
||||
struct RuleContext: Hashable {
|
||||
let index: Int
|
||||
let rule: Mastodon.Entity.Instance.Rule
|
||||
}
|
||||
case rule(index: Int, rule: Mastodon.Entity.Instance.Rule)
|
||||
}
|
||||
|
@ -19,11 +19,11 @@ extension ServerRuleSection {
|
||||
) -> UITableViewDiffableDataSource<ServerRuleSection, ServerRuleItem> {
|
||||
return UITableViewDiffableDataSource(tableView: tableView) { tableView, indexPath, item in
|
||||
switch item {
|
||||
case .rule(let ruleContext):
|
||||
case .rule(let index, let rule):
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: ServerRulesTableViewCell.self), for: indexPath) as! ServerRulesTableViewCell
|
||||
cell.indexImageView.image = UIImage(systemName: "\(ruleContext.index + 1).circle") ?? UIImage(systemName: "questionmark.circle")
|
||||
cell.indexImageView.image = UIImage(systemName: "\(index + 1).circle") ?? UIImage(systemName: "questionmark.circle")
|
||||
cell.indexImageView.tintColor = Asset.Colors.Brand.lightBlurple.color
|
||||
cell.ruleLabel.text = ruleContext.rule.text
|
||||
cell.ruleLabel.text = rule.text
|
||||
return cell
|
||||
}
|
||||
}
|
||||
|
@ -28,13 +28,8 @@ final class ProfileFieldCollectionViewCell: UICollectionViewCell {
|
||||
let checkmark = UIImageView(image: Asset.Editing.checkmark.image.withRenderingMode(.alwaysTemplate))
|
||||
var checkmarkPopoverString: String? = nil;
|
||||
let tapGesture = UITapGestureRecognizer();
|
||||
private var _editMenuInteraction: Any? = nil
|
||||
@available(iOS 16, *)
|
||||
fileprivate var editMenuInteraction: UIEditMenuInteraction {
|
||||
_editMenuInteraction = _editMenuInteraction ?? UIEditMenuInteraction(delegate: self)
|
||||
return _editMenuInteraction as! UIEditMenuInteraction
|
||||
}
|
||||
|
||||
var editMenuInteraction: UIEditMenuInteraction!
|
||||
|
||||
override func prepareForReuse() {
|
||||
super.prepareForReuse()
|
||||
|
||||
@ -56,6 +51,9 @@ final class ProfileFieldCollectionViewCell: UICollectionViewCell {
|
||||
extension ProfileFieldCollectionViewCell {
|
||||
|
||||
private func _init() {
|
||||
|
||||
editMenuInteraction = UIEditMenuInteraction(delegate: self)
|
||||
|
||||
// Setup colors
|
||||
checkmark.tintColor = Asset.Scene.Profile.About.bioAboutFieldVerifiedText.color;
|
||||
|
||||
@ -63,10 +61,8 @@ extension ProfileFieldCollectionViewCell {
|
||||
tapGesture.addTarget(self, action: #selector(ProfileFieldCollectionViewCell.didTapCheckmark(_:)))
|
||||
checkmark.addGestureRecognizer(tapGesture)
|
||||
checkmark.isUserInteractionEnabled = true
|
||||
if #available(iOS 16, *) {
|
||||
checkmark.addInteraction(editMenuInteraction)
|
||||
}
|
||||
|
||||
checkmark.addInteraction(editMenuInteraction)
|
||||
|
||||
// Setup Accessibility
|
||||
checkmark.isAccessibilityElement = true
|
||||
checkmark.accessibilityTraits = .none
|
||||
@ -111,22 +107,7 @@ extension ProfileFieldCollectionViewCell {
|
||||
}
|
||||
|
||||
@objc public func didTapCheckmark(_ recognizer: UITapGestureRecognizer) {
|
||||
if #available(iOS 16, *) {
|
||||
editMenuInteraction.presentEditMenu(with: UIEditMenuConfiguration(identifier: nil, sourcePoint: recognizer.location(in: checkmark)))
|
||||
} else {
|
||||
guard let editMenuLabel = checkmarkPopoverString else { return }
|
||||
|
||||
self.isUserInteractionEnabled = true
|
||||
self.becomeFirstResponder()
|
||||
|
||||
UIMenuController.shared.menuItems = [
|
||||
UIMenuItem(
|
||||
title: editMenuLabel,
|
||||
action: #selector(dismissVerifiedMenu)
|
||||
)
|
||||
]
|
||||
UIMenuController.shared.showMenu(from: checkmark, rect: checkmark.bounds)
|
||||
}
|
||||
editMenuInteraction?.presentEditMenu(with: UIEditMenuConfiguration(identifier: nil, sourcePoint: recognizer.location(in: checkmark)))
|
||||
}
|
||||
|
||||
private var valueMetas: [(title: String, Meta)] {
|
||||
@ -190,7 +171,6 @@ extension ProfileFieldCollectionViewCell: MetaLabelDelegate {
|
||||
}
|
||||
|
||||
// MARK: UIEditMenuInteractionDelegate
|
||||
@available(iOS 16.0, *)
|
||||
extension ProfileFieldCollectionViewCell: UIEditMenuInteractionDelegate {
|
||||
func editMenuInteraction(_ interaction: UIEditMenuInteraction, menuFor configuration: UIEditMenuConfiguration, suggestedActions: [UIMenuElement]) -> UIMenu? {
|
||||
guard let editMenuLabel = checkmarkPopoverString else { return UIMenu(children: []) }
|
||||
|
@ -62,11 +62,7 @@ final class RootSplitViewController: UISplitViewController, NeedsDependency {
|
||||
// disable edge swipe gesture
|
||||
presentsWithGesture = false
|
||||
|
||||
if #available(iOS 14.5, *) {
|
||||
displayModeButtonVisibility = .never
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
displayModeButtonVisibility = .never
|
||||
|
||||
setViewController(searchViewController, for: .primary)
|
||||
setViewController(contentSplitViewController, for: .secondary)
|
||||
|
@ -23,7 +23,7 @@ enum AboutSettingsEntry: Hashable {
|
||||
case .privacyPolicy:
|
||||
return L10n.Scene.Settings.AboutMastodon.privacyPolicy
|
||||
case .clearMediaCache(_):
|
||||
return L10n.Scene.Settings.AboutMastodon.cleaerMediaStorage
|
||||
return L10n.Scene.Settings.AboutMastodon.clearMediaStorage
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,155 @@
|
||||
// Copyright © 2023 Mastodon gGmbH. All rights reserved.
|
||||
|
||||
import UIKit
|
||||
import MastodonSDK
|
||||
|
||||
protocol AboutInstanceViewControllerDelegate: AnyObject {
|
||||
func showAdminAccount(_ viewController: AboutInstanceViewController, account: Mastodon.Entity.Account)
|
||||
func sendEmailToAdmin(_ viewController: AboutInstanceViewController, emailAddress: String)
|
||||
}
|
||||
|
||||
class AboutInstanceViewController: UIViewController {
|
||||
|
||||
weak var delegate: AboutInstanceViewControllerDelegate?
|
||||
var dataSource: AboutInstanceTableViewDataSource?
|
||||
|
||||
let tableView: UITableView
|
||||
let headerView: AboutInstanceTableHeaderView
|
||||
let footerView: AboutInstanceTableFooterView
|
||||
|
||||
var instance: Mastodon.Entity.V2.Instance?
|
||||
|
||||
init() {
|
||||
tableView = UITableView(frame: .zero, style: .insetGrouped)
|
||||
tableView.translatesAutoresizingMaskIntoConstraints = false
|
||||
tableView.register(ContactAdminTableViewCell.self, forCellReuseIdentifier: ContactAdminTableViewCell.reuseIdentifier)
|
||||
tableView.register(AdminTableViewCell.self, forCellReuseIdentifier: AdminTableViewCell.reuseIdentifier)
|
||||
|
||||
headerView = AboutInstanceTableHeaderView()
|
||||
footerView = AboutInstanceTableFooterView()
|
||||
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
|
||||
let dataSource = AboutInstanceTableViewDataSource(tableView: tableView) { tableView, indexPath, itemIdentifier in
|
||||
switch itemIdentifier {
|
||||
|
||||
case .adminAccount(let account):
|
||||
guard let cell = tableView.dequeueReusableCell(withIdentifier: AdminTableViewCell.reuseIdentifier, for: indexPath) as? AdminTableViewCell else { fatalError("WTF?! Wrong cell.") }
|
||||
|
||||
cell.condensedUserView.configure(with: account, showFollowers: false)
|
||||
|
||||
return cell
|
||||
|
||||
case .contactAdmin:
|
||||
guard let cell = tableView.dequeueReusableCell(withIdentifier: ContactAdminTableViewCell.reuseIdentifier, for: indexPath) as? ContactAdminTableViewCell else { fatalError("WTF?! Wrong cell.") }
|
||||
|
||||
cell.configure()
|
||||
|
||||
return cell
|
||||
}
|
||||
}
|
||||
|
||||
tableView.delegate = self
|
||||
tableView.dataSource = dataSource
|
||||
|
||||
self.dataSource = dataSource
|
||||
|
||||
view.addSubview(tableView)
|
||||
|
||||
setupConstraints()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
|
||||
|
||||
private func setupConstraints() {
|
||||
let constraints = [
|
||||
tableView.topAnchor.constraint(equalTo: view.topAnchor),
|
||||
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||
view.trailingAnchor.constraint(equalTo: tableView.trailingAnchor),
|
||||
view.bottomAnchor.constraint(equalTo: tableView.bottomAnchor),
|
||||
]
|
||||
|
||||
NSLayoutConstraint.activate(constraints)
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
tableView.tableHeaderView = headerView
|
||||
tableView.tableFooterView = footerView
|
||||
}
|
||||
|
||||
override func viewWillLayoutSubviews() {
|
||||
super.viewWillLayoutSubviews()
|
||||
|
||||
if let tableHeaderView = tableView.tableHeaderView {
|
||||
let size = tableHeaderView.systemLayoutSizeFitting(.init(width: self.tableView.frame.width, height: 10_000))
|
||||
tableHeaderView.frame.size = size
|
||||
tableView.tableHeaderView = tableHeaderView
|
||||
}
|
||||
|
||||
if let tableFooterView = tableView.tableFooterView {
|
||||
let size = tableFooterView.systemLayoutSizeFitting(.init(width: self.tableView.frame.width, height: 10_000))
|
||||
tableFooterView.frame.size = size
|
||||
tableView.tableFooterView = tableFooterView
|
||||
}
|
||||
|
||||
super.viewWillLayoutSubviews()
|
||||
}
|
||||
|
||||
func update(with instance: Mastodon.Entity.V2.Instance) {
|
||||
|
||||
self.instance = instance
|
||||
var snapshot = NSDiffableDataSourceSnapshot<AboutInstanceSection, AboutInstanceItem>()
|
||||
|
||||
snapshot.appendSections([.main])
|
||||
if let account = instance.contact?.account {
|
||||
snapshot.appendItems([.adminAccount(account)], toSection: .main)
|
||||
}
|
||||
|
||||
if let email = instance.contact?.email {
|
||||
snapshot.appendItems([.contactAdmin(email)], toSection: .main)
|
||||
}
|
||||
|
||||
dataSource?.apply(snapshot, animatingDifferences: false)
|
||||
|
||||
guard let thumbnailUrlString = instance.thumbnail?.url, let thumbnailUrl = URL(string: thumbnailUrlString) else { return }
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.headerView.updateImage(with: thumbnailUrl) { [weak self] in
|
||||
DispatchQueue.main.async {
|
||||
guard let self else { return }
|
||||
|
||||
self.view.setNeedsLayout()
|
||||
self.view.layoutIfNeeded()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updateFooter(with extendedDescription: Mastodon.Entity.ExtendedDescription) {
|
||||
DispatchQueue.main.async {
|
||||
self.footerView.update(with: extendedDescription)
|
||||
|
||||
self.view.setNeedsLayout()
|
||||
self.view.layoutIfNeeded()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension AboutInstanceViewController: UITableViewDelegate {
|
||||
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
guard let snapshot = dataSource?.snapshot() else {
|
||||
return tableView.deselectRow(at: indexPath, animated: true)
|
||||
}
|
||||
|
||||
switch snapshot.itemIdentifiers(inSection: .main)[indexPath.row] {
|
||||
case .adminAccount(let account):
|
||||
delegate?.showAdminAccount(self, account: account)
|
||||
case .contactAdmin(let email):
|
||||
delegate?.sendEmailToAdmin(self, emailAddress: email)
|
||||
}
|
||||
|
||||
tableView.deselectRow(at: indexPath, animated: true)
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
// Copyright © 2023 Mastodon gGmbH. All rights reserved.
|
||||
|
||||
import UIKit
|
||||
import MastodonSDK
|
||||
|
||||
protocol InstanceRulesViewControllerDelegate: AnyObject {
|
||||
|
||||
}
|
||||
|
||||
class InstanceRulesViewController: UIViewController {
|
||||
|
||||
weak var delegate: InstanceRulesViewControllerDelegate?
|
||||
let tableView: UITableView
|
||||
var dataSource: UITableViewDiffableDataSource<ServerRuleSection, ServerRuleItem>?
|
||||
|
||||
var sections: [ServerRuleSection] = []
|
||||
|
||||
init() {
|
||||
tableView = UITableView(frame: .zero, style: .insetGrouped)
|
||||
tableView.translatesAutoresizingMaskIntoConstraints = false
|
||||
tableView.register(ServerRulesTableViewCell.self, forCellReuseIdentifier: ServerRulesTableViewCell.reuseIdentifier)
|
||||
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
view.addSubview(tableView)
|
||||
|
||||
let dataSource = ServerRuleSection.tableViewDiffableDataSource(tableView: tableView)
|
||||
|
||||
tableView.dataSource = dataSource
|
||||
self.dataSource = dataSource
|
||||
|
||||
setupConstraints()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
|
||||
|
||||
private func setupConstraints() {
|
||||
let constraints = [
|
||||
tableView.topAnchor.constraint(equalTo: view.topAnchor),
|
||||
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||
view.trailingAnchor.constraint(equalTo: tableView.trailingAnchor),
|
||||
view.bottomAnchor.constraint(equalTo: tableView.bottomAnchor),
|
||||
]
|
||||
|
||||
NSLayoutConstraint.activate(constraints)
|
||||
}
|
||||
|
||||
func update(with instance: Mastodon.Entity.V2.Instance) {
|
||||
guard let dataSource, let rules = instance.rules, rules.isNotEmpty else { return }
|
||||
|
||||
var snapshot = NSDiffableDataSourceSnapshot<ServerRuleSection, ServerRuleItem>()
|
||||
|
||||
snapshot.appendSections([.rules])
|
||||
let ruleItems = rules.enumerated().compactMap { index, rule in ServerRuleItem.rule(index: index, rule: rule) }
|
||||
snapshot.appendItems(ruleItems, toSection: .rules)
|
||||
|
||||
dataSource.apply(snapshot)
|
||||
}
|
||||
}
|
@ -0,0 +1,165 @@
|
||||
// Copyright © 2023 Mastodon gGmbH. All rights reserved.
|
||||
|
||||
import UIKit
|
||||
import MastodonSDK
|
||||
import MastodonLocalization
|
||||
import MetaTextKit
|
||||
|
||||
enum ServerDetailsTab: Int, CaseIterable {
|
||||
case about = 0
|
||||
case rules = 1
|
||||
|
||||
var title: String {
|
||||
switch self {
|
||||
case .about: return L10n.Scene.Settings.ServerDetails.about
|
||||
case .rules: return L10n.Scene.Settings.ServerDetails.rules
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protocol ServerDetailsViewControllerDelegate: AnyObject {}
|
||||
|
||||
class ServerDetailsViewController: UIViewController {
|
||||
|
||||
weak var delegate: (ServerDetailsViewControllerDelegate & AboutInstanceViewControllerDelegate & InstanceRulesViewControllerDelegate & MetaLabelDelegate)? {
|
||||
didSet {
|
||||
aboutInstanceViewController.delegate = delegate
|
||||
instanceRulesViewController.delegate = delegate
|
||||
aboutInstanceViewController.footerView.contentLabel.linkDelegate = delegate
|
||||
}
|
||||
}
|
||||
let pageController: UIPageViewController
|
||||
|
||||
private let segmentedControlWrapper: UIView
|
||||
let segmentedControl: UISegmentedControl
|
||||
let aboutInstanceViewController: AboutInstanceViewController
|
||||
let instanceRulesViewController: InstanceRulesViewController
|
||||
let containerView: UIView
|
||||
|
||||
init(domain: String) {
|
||||
segmentedControl = UISegmentedControl()
|
||||
segmentedControl.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
segmentedControlWrapper = UIView()
|
||||
segmentedControlWrapper.translatesAutoresizingMaskIntoConstraints = false
|
||||
segmentedControlWrapper.addSubview(segmentedControl)
|
||||
|
||||
containerView = UIView()
|
||||
containerView.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
aboutInstanceViewController = AboutInstanceViewController()
|
||||
instanceRulesViewController = InstanceRulesViewController()
|
||||
|
||||
pageController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal)
|
||||
pageController.setViewControllers([aboutInstanceViewController], direction: .forward, animated: false)
|
||||
pageController.view.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
|
||||
view.addSubview(segmentedControlWrapper)
|
||||
view.addSubview(containerView)
|
||||
view.backgroundColor = .systemGroupedBackground
|
||||
|
||||
containerView.addSubview(pageController.view)
|
||||
addChild(pageController)
|
||||
pageController.didMove(toParent: self)
|
||||
pageController.delegate = self
|
||||
pageController.dataSource = self
|
||||
|
||||
ServerDetailsTab.allCases.forEach {
|
||||
segmentedControl.insertSegment(withTitle: $0.title, at: $0.rawValue, animated: false)
|
||||
}
|
||||
segmentedControl.selectedSegmentIndex = ServerDetailsTab.about.rawValue
|
||||
segmentedControl.addTarget(self, action: #selector(ServerDetailsViewController.segmentedControlValueChanged(_:)), for: .valueChanged)
|
||||
|
||||
setupConstraints()
|
||||
|
||||
title = domain
|
||||
|
||||
setupNavigationBarAppearance()
|
||||
setupNavigationBarBackgroundView()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
|
||||
|
||||
private func setupConstraints() {
|
||||
let constraints = [
|
||||
segmentedControlWrapper.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
|
||||
segmentedControlWrapper.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||
view.trailingAnchor.constraint(equalTo: segmentedControlWrapper.trailingAnchor),
|
||||
|
||||
containerView.topAnchor.constraint(equalTo: segmentedControlWrapper.bottomAnchor),
|
||||
containerView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||
view.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
|
||||
view.bottomAnchor.constraint(equalTo: containerView.bottomAnchor),
|
||||
|
||||
segmentedControl.topAnchor.constraint(equalTo: segmentedControlWrapper.topAnchor, constant: 4),
|
||||
segmentedControl.leadingAnchor.constraint(equalTo: segmentedControlWrapper.leadingAnchor, constant: 16),
|
||||
segmentedControlWrapper.trailingAnchor.constraint(equalTo: segmentedControl.trailingAnchor, constant: 16),
|
||||
segmentedControlWrapper.bottomAnchor.constraint(equalTo: segmentedControl.bottomAnchor, constant: 8),
|
||||
|
||||
pageController.view.topAnchor.constraint(equalTo: containerView.topAnchor),
|
||||
pageController.view.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
|
||||
containerView.trailingAnchor.constraint(equalTo: pageController.view.trailingAnchor),
|
||||
containerView.bottomAnchor.constraint(equalTo: pageController.view.bottomAnchor),
|
||||
]
|
||||
|
||||
NSLayoutConstraint.activate(constraints)
|
||||
}
|
||||
|
||||
//MARK: - Actions
|
||||
@objc
|
||||
func segmentedControlValueChanged(_ sender: UISegmentedControl) {
|
||||
guard let selectedTab = ServerDetailsTab(rawValue: sender.selectedSegmentIndex) else { return }
|
||||
|
||||
switch selectedTab {
|
||||
case .about:
|
||||
pageController.setViewControllers([aboutInstanceViewController], direction: .reverse, animated: true)
|
||||
case .rules:
|
||||
pageController.setViewControllers([instanceRulesViewController], direction: .forward, animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
func update(with instance: Mastodon.Entity.V2.Instance) {
|
||||
aboutInstanceViewController.update(with: instance)
|
||||
instanceRulesViewController.update(with: instance)
|
||||
}
|
||||
|
||||
func updateFooter(with extendedDescription: Mastodon.Entity.ExtendedDescription) {
|
||||
aboutInstanceViewController.updateFooter(with: extendedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - UIPageViewControllerDataSource
|
||||
extension ServerDetailsViewController: UIPageViewControllerDataSource {
|
||||
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
|
||||
if viewController == instanceRulesViewController {
|
||||
return aboutInstanceViewController
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
|
||||
if viewController == aboutInstanceViewController {
|
||||
return instanceRulesViewController
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - UIPageViewControllerDelegate
|
||||
extension ServerDetailsViewController: UIPageViewControllerDelegate {
|
||||
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
|
||||
guard let currentViewController = pageViewController.viewControllers?.first else { return }
|
||||
|
||||
if currentViewController == aboutInstanceViewController {
|
||||
segmentedControl.selectedSegmentIndex = ServerDetailsTab.about.rawValue
|
||||
} else if currentViewController == instanceRulesViewController {
|
||||
segmentedControl.selectedSegmentIndex = ServerDetailsTab.rules.rawValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension ServerDetailsViewController: OnboardingViewControllerAppearance {}
|
@ -0,0 +1,18 @@
|
||||
// Copyright © 2023 Mastodon gGmbH. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import MastodonSDK
|
||||
import MastodonLocalization
|
||||
|
||||
enum AboutInstanceSection: Int, Hashable {
|
||||
case main = 0
|
||||
|
||||
var title: String {
|
||||
return L10n.Scene.Settings.ServerDetails.AboutInstance.title
|
||||
}
|
||||
}
|
||||
|
||||
enum AboutInstanceItem: Hashable {
|
||||
case adminAccount(Mastodon.Entity.Account)
|
||||
case contactAdmin(String)
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
// Copyright © 2023 Mastodon gGmbH. All rights reserved.
|
||||
|
||||
import UIKit
|
||||
import MetaTextKit
|
||||
import MastodonSDK
|
||||
import MastodonMeta
|
||||
import MastodonCore
|
||||
import MastodonAsset
|
||||
import MastodonLocalization
|
||||
|
||||
class AboutInstanceTableFooterView: UIView {
|
||||
let headlineLabel: UILabel
|
||||
let contentLabel: MetaLabel
|
||||
|
||||
init() {
|
||||
|
||||
headlineLabel = UILabel()
|
||||
headlineLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
headlineLabel.font = UIFontMetrics(forTextStyle: .title2).scaledFont(for: .systemFont(ofSize: 22, weight: .bold))
|
||||
|
||||
contentLabel = MetaLabel(style: .aboutInstance)
|
||||
contentLabel.numberOfLines = 0
|
||||
contentLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
super.init(frame: .zero)
|
||||
|
||||
addSubview(headlineLabel)
|
||||
addSubview(contentLabel)
|
||||
|
||||
setupConstraints()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
|
||||
|
||||
private func setupConstraints() {
|
||||
|
||||
let horizontalMargin = 16.0
|
||||
let verticalMargin = 24.0
|
||||
|
||||
let constraints = [
|
||||
headlineLabel.topAnchor.constraint(equalTo: topAnchor, constant: verticalMargin),
|
||||
headlineLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: horizontalMargin),
|
||||
trailingAnchor.constraint(equalTo: headlineLabel.trailingAnchor, constant: horizontalMargin),
|
||||
|
||||
contentLabel.topAnchor.constraint(equalTo: headlineLabel.bottomAnchor, constant: 8),
|
||||
contentLabel.leadingAnchor.constraint(equalTo: headlineLabel.leadingAnchor),
|
||||
contentLabel.trailingAnchor.constraint(equalTo: headlineLabel.trailingAnchor),
|
||||
bottomAnchor.constraint(equalTo: contentLabel.bottomAnchor, constant: verticalMargin),
|
||||
]
|
||||
|
||||
NSLayoutConstraint.activate(constraints)
|
||||
}
|
||||
|
||||
func update(with extendedDescription: Mastodon.Entity.ExtendedDescription) {
|
||||
headlineLabel.text = L10n.Scene.Settings.ServerDetails.AboutInstance.legalNotice
|
||||
|
||||
let content = extendedDescription.content
|
||||
.replacingOccurrences(of: "<br>", with: "\n")
|
||||
.replacingOccurrences(of: "\n\n", with: "\n")
|
||||
|
||||
|
||||
if let metaContent = try? MastodonMetaContent.convert(document: MastodonContent(content: content, emojis: [:])) {
|
||||
contentLabel.configure(content: metaContent)
|
||||
} else {
|
||||
let content = PlaintextMetaContent(string: content)
|
||||
contentLabel.configure(content: content)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
// Copyright © 2023 Mastodon gGmbH. All rights reserved.
|
||||
|
||||
import UIKit
|
||||
|
||||
class AboutInstanceTableViewDataSource: UITableViewDiffableDataSource<AboutInstanceSection, AboutInstanceItem> {
|
||||
|
||||
override init(tableView: UITableView, cellProvider: @escaping UITableViewDiffableDataSource<AboutInstanceSection, AboutInstanceItem>.CellProvider) {
|
||||
super.init(tableView: tableView, cellProvider: cellProvider)
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
||||
guard let section = AboutInstanceSection(rawValue: section) else { return nil }
|
||||
|
||||
return section.title.uppercased()
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
// Copyright © 2023 Mastodon gGmbH. All rights reserved.
|
||||
|
||||
import UIKit
|
||||
import MastodonAsset
|
||||
import AlamofireImage
|
||||
|
||||
class AboutInstanceTableHeaderView: UIView {
|
||||
let thumbnailImageView: UIImageView
|
||||
|
||||
init() {
|
||||
thumbnailImageView = UIImageView(image: Asset.Settings.aboutInstancePlaceholder.image)
|
||||
thumbnailImageView.contentMode = .scaleAspectFill
|
||||
thumbnailImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
super.init(frame: .zero)
|
||||
|
||||
addSubview(thumbnailImageView)
|
||||
|
||||
setupConstraints()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
|
||||
|
||||
private func setupConstraints() {
|
||||
let constraints = [
|
||||
thumbnailImageView.topAnchor.constraint(equalTo: topAnchor),
|
||||
thumbnailImageView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
trailingAnchor.constraint(equalTo: thumbnailImageView.trailingAnchor),
|
||||
bottomAnchor.constraint(equalTo: thumbnailImageView.bottomAnchor, constant: 16),
|
||||
]
|
||||
|
||||
NSLayoutConstraint.activate(constraints)
|
||||
}
|
||||
|
||||
func updateImage(with thumbnailURL: URL, completion: (() -> Void)? = nil) {
|
||||
thumbnailImageView.af.setImage(withURL: thumbnailURL, placeholderImage: Asset.Settings.aboutInstancePlaceholder.image, completion: { _ in
|
||||
completion?()
|
||||
})
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
// Copyright © 2023 Mastodon gGmbH. All rights reserved.
|
||||
|
||||
import UIKit
|
||||
|
||||
typealias AdminTableViewCell = SearchResultsProfileTableViewCell
|
@ -0,0 +1,22 @@
|
||||
// Copyright © 2023 Mastodon gGmbH. All rights reserved.
|
||||
|
||||
import UIKit
|
||||
import MastodonAsset
|
||||
import MastodonLocalization
|
||||
|
||||
class ContactAdminTableViewCell: UITableViewCell {
|
||||
|
||||
static let reuseIdentifier = "ContactAdminTableViewCell"
|
||||
|
||||
func configure() {
|
||||
var configuration = defaultContentConfiguration()
|
||||
|
||||
configuration.textProperties.color = Asset.Colors.Brand.blurple.color
|
||||
configuration.image = UIImage(systemName: "envelope")
|
||||
configuration.imageProperties.tintColor = Asset.Colors.Brand.blurple.color
|
||||
configuration.text = L10n.Scene.Settings.ServerDetails.AboutInstance.messageAdmin
|
||||
backgroundColor = .secondarySystemGroupedBackground
|
||||
|
||||
contentConfiguration = configuration
|
||||
}
|
||||
}
|
@ -10,62 +10,78 @@ struct SettingsSection: Hashable {
|
||||
enum SettingsEntry: Hashable {
|
||||
case general
|
||||
case notifications
|
||||
case serverDetails(domain: String)
|
||||
case aboutMastodon
|
||||
case logout(accountName: String)
|
||||
|
||||
var title: String {
|
||||
switch self {
|
||||
case .general:
|
||||
return L10n.Scene.Settings.Overview.general
|
||||
case .notifications:
|
||||
return L10n.Scene.Settings.Overview.notifications
|
||||
case .aboutMastodon:
|
||||
return L10n.Scene.Settings.Overview.aboutMastodon
|
||||
case .logout(let accountName):
|
||||
return L10n.Scene.Settings.Overview.logout(accountName)
|
||||
case .general:
|
||||
return L10n.Scene.Settings.Overview.general
|
||||
case .notifications:
|
||||
return L10n.Scene.Settings.Overview.notifications
|
||||
case .serverDetails(_):
|
||||
return L10n.Scene.Settings.Overview.serverDetails
|
||||
case .aboutMastodon:
|
||||
return L10n.Scene.Settings.Overview.aboutMastodon
|
||||
case .logout(let accountName):
|
||||
return L10n.Scene.Settings.Overview.logout(accountName)
|
||||
}
|
||||
}
|
||||
|
||||
var secondaryTitle: String? {
|
||||
switch self {
|
||||
case .serverDetails(domain: let domain):
|
||||
return domain
|
||||
case .general, .notifications, .aboutMastodon, .logout(_):
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
var accessoryType: UITableViewCell.AccessoryType {
|
||||
switch self {
|
||||
case .general, .notifications, .aboutMastodon, .logout(_):
|
||||
return .disclosureIndicator
|
||||
case .general, .notifications, .serverDetails(_), .aboutMastodon, .logout(_):
|
||||
return .disclosureIndicator
|
||||
}
|
||||
}
|
||||
|
||||
var icon: UIImage? {
|
||||
switch self {
|
||||
case .general:
|
||||
return UIImage(systemName: "gear")
|
||||
case .notifications:
|
||||
return UIImage(systemName: "bell.badge")
|
||||
case .aboutMastodon:
|
||||
return UIImage(systemName: "info.circle.fill")
|
||||
case .logout(_):
|
||||
return nil
|
||||
case .general:
|
||||
return UIImage(systemName: "gear")
|
||||
case .notifications:
|
||||
return UIImage(systemName: "bell.badge")
|
||||
case .serverDetails(_):
|
||||
return UIImage(systemName: "server.rack")
|
||||
case .aboutMastodon:
|
||||
return UIImage(systemName: "info.circle.fill")
|
||||
case .logout(_):
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
var iconBackgroundColor: UIColor? {
|
||||
switch self {
|
||||
case .general:
|
||||
return .systemGray
|
||||
case .notifications:
|
||||
return .systemRed
|
||||
case .aboutMastodon:
|
||||
return .systemPurple
|
||||
case .logout(_):
|
||||
return nil
|
||||
case .general:
|
||||
return .systemGray
|
||||
case .notifications:
|
||||
return .systemRed
|
||||
case .serverDetails(_):
|
||||
return .systemTeal
|
||||
case .aboutMastodon:
|
||||
return .systemPurple
|
||||
case .logout(_):
|
||||
return nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var textColor: UIColor {
|
||||
switch self {
|
||||
case .general, .notifications, .aboutMastodon:
|
||||
return .label
|
||||
case .logout(_):
|
||||
return .red
|
||||
case .general, .notifications, .aboutMastodon, .serverDetails(_):
|
||||
return .label
|
||||
case .logout(_):
|
||||
return .red
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9,7 +9,9 @@ class SettingsTableViewCell: UITableViewCell {
|
||||
let iconImageView: UIImageView
|
||||
let iconImageBackgroundView: UIView
|
||||
let titleLabel: UILabel
|
||||
let secondaryLabel: UILabel
|
||||
|
||||
private let labelStackView: UIStackView
|
||||
private let contentStackView: UIStackView
|
||||
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
@ -21,8 +23,17 @@ class SettingsTableViewCell: UITableViewCell {
|
||||
iconImageBackgroundView.addSubview(iconImageView)
|
||||
|
||||
titleLabel = UILabel()
|
||||
titleLabel.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 17, weight: .regular))
|
||||
secondaryLabel = UILabel()
|
||||
secondaryLabel.font = UIFontMetrics(forTextStyle: .caption1).scaledFont(for: .systemFont(ofSize: 12, weight: .regular))
|
||||
secondaryLabel.textColor = .secondaryLabel
|
||||
|
||||
contentStackView = UIStackView(arrangedSubviews: [iconImageBackgroundView, titleLabel])
|
||||
labelStackView = UIStackView(arrangedSubviews: [titleLabel, secondaryLabel])
|
||||
labelStackView.axis = .vertical
|
||||
labelStackView.spacing = 2
|
||||
labelStackView.alignment = .leading
|
||||
|
||||
contentStackView = UIStackView(arrangedSubviews: [iconImageBackgroundView, labelStackView])
|
||||
contentStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
contentStackView.axis = .horizontal
|
||||
contentStackView.alignment = .center
|
||||
@ -50,8 +61,8 @@ class SettingsTableViewCell: UITableViewCell {
|
||||
iconImageView.centerXAnchor.constraint(equalTo: iconImageBackgroundView.centerXAnchor),
|
||||
iconImageView.widthAnchor.constraint(equalToConstant: 20),
|
||||
|
||||
titleLabel.topAnchor.constraint(greaterThanOrEqualTo: contentView.topAnchor, constant: 12),
|
||||
contentView.bottomAnchor.constraint(greaterThanOrEqualTo: titleLabel.bottomAnchor, constant: 12),
|
||||
labelStackView.topAnchor.constraint(greaterThanOrEqualTo: contentView.topAnchor, constant: 12),
|
||||
contentView.bottomAnchor.constraint(greaterThanOrEqualTo: labelStackView.bottomAnchor, constant: 12),
|
||||
]
|
||||
|
||||
NSLayoutConstraint.activate(constraints)
|
||||
@ -61,6 +72,13 @@ class SettingsTableViewCell: UITableViewCell {
|
||||
titleLabel.textColor = entry.textColor
|
||||
titleLabel.text = entry.title
|
||||
|
||||
if let secondaryTitle = entry.secondaryTitle {
|
||||
secondaryLabel.isHidden = false
|
||||
secondaryLabel.text = secondaryTitle
|
||||
} else {
|
||||
secondaryLabel.isHidden = true
|
||||
}
|
||||
|
||||
if let icon = entry.icon {
|
||||
iconImageView.image = icon
|
||||
iconImageView.tintColor = .white
|
||||
@ -73,7 +91,6 @@ class SettingsTableViewCell: UITableViewCell {
|
||||
iconImageBackgroundView.backgroundColor = entry.iconBackgroundColor
|
||||
|
||||
accessoryType = entry.accessoryType
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,11 +16,11 @@ class SettingsViewController: UIViewController {
|
||||
var tableViewDataSource: UITableViewDiffableDataSource<SettingsSection, SettingsEntry>?
|
||||
let tableView: UITableView
|
||||
|
||||
init(accountName: String) {
|
||||
init(accountName: String, domain: String) {
|
||||
|
||||
sections = [
|
||||
.init(entries: [.general, .notifications]),
|
||||
.init(entries: [.aboutMastodon]),
|
||||
.init(entries: [.serverDetails(domain: domain), .aboutMastodon]),
|
||||
.init(entries: [.logout(accountName: accountName)])
|
||||
]
|
||||
|
||||
|
@ -6,6 +6,7 @@ import MastodonCore
|
||||
import CoreDataStack
|
||||
import MastodonSDK
|
||||
import Combine
|
||||
import MetaTextKit
|
||||
|
||||
protocol SettingsCoordinatorDelegate: AnyObject {
|
||||
func logout(_ settingsCoordinator: SettingsCoordinator)
|
||||
@ -26,15 +27,17 @@ class SettingsCoordinator: NSObject, Coordinator {
|
||||
let appContext: AppContext
|
||||
let authContext: AuthContext
|
||||
var disposeBag = Set<AnyCancellable>()
|
||||
let sceneCoordinator: SceneCoordinator
|
||||
|
||||
init(presentedOn: UIViewController, accountName: String, setting: Setting, appContext: AppContext, authContext: AuthContext) {
|
||||
init(presentedOn: UIViewController, accountName: String, setting: Setting, appContext: AppContext, authContext: AuthContext, sceneCoordinator: SceneCoordinator) {
|
||||
self.presentedOn = presentedOn
|
||||
navigationController = UINavigationController()
|
||||
self.setting = setting
|
||||
self.appContext = appContext
|
||||
self.authContext = authContext
|
||||
self.sceneCoordinator = sceneCoordinator
|
||||
|
||||
settingsViewController = SettingsViewController(accountName: accountName)
|
||||
settingsViewController = SettingsViewController(accountName: accountName, domain: authContext.mastodonAuthenticationBox.domain)
|
||||
}
|
||||
|
||||
func start() {
|
||||
@ -65,8 +68,29 @@ extension SettingsCoordinator: SettingsViewControllerDelegate {
|
||||
let notificationViewController = NotificationSettingsViewController(currentSetting: currentSetting, notificationsEnabled: notificationsEnabled)
|
||||
notificationViewController.delegate = self
|
||||
|
||||
self.navigationController.pushViewController(notificationViewController, animated: true)
|
||||
navigationController.pushViewController(notificationViewController, animated: true)
|
||||
case .serverDetails(let domain):
|
||||
let serverDetailsViewController = ServerDetailsViewController(domain: domain)
|
||||
serverDetailsViewController.delegate = self
|
||||
|
||||
appContext.apiService.instanceV2(domain: domain)
|
||||
.sink { _ in
|
||||
|
||||
} receiveValue: { content in
|
||||
serverDetailsViewController.update(with: content.value)
|
||||
}
|
||||
.store(in: &disposeBag)
|
||||
|
||||
appContext.apiService.extendedDescription(domain: domain)
|
||||
.sink { _ in
|
||||
|
||||
} receiveValue: { content in
|
||||
serverDetailsViewController.updateFooter(with: content.value)
|
||||
}
|
||||
.store(in: &disposeBag)
|
||||
|
||||
|
||||
navigationController.pushViewController(serverDetailsViewController, animated: true)
|
||||
case .aboutMastodon:
|
||||
let aboutViewController = AboutViewController()
|
||||
aboutViewController.delegate = self
|
||||
@ -135,6 +159,8 @@ extension SettingsCoordinator: NotificationSettingsViewControllerDelegate {
|
||||
|
||||
guard viewModel.updated else { return }
|
||||
|
||||
//Show spinner?
|
||||
|
||||
let authenticationBox = authContext.mastodonAuthenticationBox
|
||||
guard let subscription = setting.activeSubscription,
|
||||
setting.domain == authenticationBox.domain,
|
||||
@ -168,16 +194,10 @@ extension SettingsCoordinator: NotificationSettingsViewControllerDelegate {
|
||||
})
|
||||
.store(in: &disposeBag)
|
||||
}
|
||||
|
||||
|
||||
func showNotificationSettings(_ viewController: UIViewController) {
|
||||
if #available(iOS 16.0, *) {
|
||||
if let url = URL(string: UIApplication.openNotificationSettingsURLString) {
|
||||
UIApplication.shared.open(url)
|
||||
}
|
||||
} else {
|
||||
if let url = URL(string: UIApplication.openSettingsURLString) {
|
||||
UIApplication.shared.open(url)
|
||||
}
|
||||
if let url = URL(string: UIApplication.openNotificationSettingsURLString) {
|
||||
UIApplication.shared.open(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -189,3 +209,58 @@ extension SettingsCoordinator: PolicySelectionViewControllerDelegate {
|
||||
try? self.appContext.managedObjectContext.save()
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - ServerDetailsViewControllerDelegate
|
||||
extension SettingsCoordinator: ServerDetailsViewControllerDelegate {
|
||||
|
||||
}
|
||||
|
||||
extension SettingsCoordinator: AboutInstanceViewControllerDelegate {
|
||||
@MainActor func showAdminAccount(_ viewController: AboutInstanceViewController, account: Mastodon.Entity.Account) {
|
||||
Task {
|
||||
let user = try await appContext.apiService.fetchUser(username: account.username, domain: authContext.mastodonAuthenticationBox.domain, authenticationBox: authContext.mastodonAuthenticationBox)
|
||||
|
||||
let profileViewModel = ProfileViewModel(context: appContext, authContext: authContext, optionalMastodonUser: user)
|
||||
|
||||
_ = await MainActor.run {
|
||||
sceneCoordinator.present(scene: .profile(viewModel: profileViewModel), transition: .show)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func sendEmailToAdmin(_ viewController: AboutInstanceViewController, emailAddress: String) {
|
||||
if let emailUrl = URL(string: "mailto:\(emailAddress)"), UIApplication.shared.canOpenURL(emailUrl) {
|
||||
UIApplication.shared.open(emailUrl)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension SettingsCoordinator: InstanceRulesViewControllerDelegate {
|
||||
|
||||
}
|
||||
|
||||
extension SettingsCoordinator: MetaLabelDelegate {
|
||||
@MainActor
|
||||
func metaLabel(_ metaLabel: MetaLabel, didSelectMeta meta: Meta) {
|
||||
switch meta {
|
||||
case .url(_, _, let url, _):
|
||||
guard let url = URL(string: url) else { return }
|
||||
_ = sceneCoordinator.present(scene: .safari(url: url), from: nil, transition: .safariPresent(animated: true, completion: nil))
|
||||
case .mention(_, _, let userInfo):
|
||||
guard let href = userInfo?["href"] as? String,
|
||||
let url = URL(string: href) else { return }
|
||||
_ = sceneCoordinator.present(scene: .safari(url: url), from: nil, transition: .safariPresent(animated: true, completion: nil))
|
||||
case .hashtag(_, let hashtag, _):
|
||||
let hashtagTimelineViewModel = HashtagTimelineViewModel(context: appContext, authContext: authContext, hashtag: hashtag)
|
||||
_ = sceneCoordinator.present(scene: .hashtagTimeline(viewModel: hashtagTimelineViewModel), from: nil, transition: .show)
|
||||
case .email(let email, _):
|
||||
if let emailUrl = URL(string: "mailto:\(email)"), UIApplication.shared.canOpenURL(emailUrl) {
|
||||
UIApplication.shared.open(emailUrl)
|
||||
}
|
||||
case .emoji:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,239 +0,0 @@
|
||||
{
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "alamofire",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/Alamofire/Alamofire.git",
|
||||
"state" : {
|
||||
"revision" : "8dd85aee02e39dd280c75eef88ffdb86eed4b07b",
|
||||
"version" : "5.6.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "alamofireimage",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/Alamofire/AlamofireImage.git",
|
||||
"state" : {
|
||||
"revision" : "98cbb00ce0ec5fc8e52a5b50a6bfc08d3e5aee10",
|
||||
"version" : "4.2.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "commonoslog",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/MainasuK/CommonOSLog",
|
||||
"state" : {
|
||||
"revision" : "c121624a30698e9886efe38aebb36ff51c01b6c2",
|
||||
"version" : "0.1.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "faviconfinder",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/will-lumley/FaviconFinder.git",
|
||||
"state" : {
|
||||
"revision" : "1f74844f77f79b95c0bb0130b3a87d4f340e6d3a",
|
||||
"version" : "3.3.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "flanimatedimage",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/Flipboard/FLAnimatedImage.git",
|
||||
"state" : {
|
||||
"revision" : "d4f07b6f164d53c1212c3e54d6460738b1981e9f",
|
||||
"version" : "1.0.17"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "fpsindicator",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/MainasuK/FPSIndicator.git",
|
||||
"state" : {
|
||||
"revision" : "e4a5067ccd5293b024c767f09e51056afd4a4796",
|
||||
"version" : "1.1.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "fuzi",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/cezheng/Fuzi.git",
|
||||
"state" : {
|
||||
"revision" : "f08c8323da21e985f3772610753bcfc652c2103f",
|
||||
"version" : "3.1.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "keychainaccess",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/kishikawakatsumi/KeychainAccess.git",
|
||||
"state" : {
|
||||
"revision" : "84e546727d66f1adc5439debad16270d0fdd04e7",
|
||||
"version" : "4.2.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "metatextkit",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/TwidereProject/MetaTextKit.git",
|
||||
"state" : {
|
||||
"revision" : "dcd5255d6930c2fab408dc8562c577547e477624",
|
||||
"version" : "2.2.5"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "nextlevelsessionexporter",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/NextLevel/NextLevelSessionExporter.git",
|
||||
"state" : {
|
||||
"revision" : "b6c0cce1aa37fe1547d694f958fac3c3524b74da",
|
||||
"version" : "0.4.6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "nuke",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/kean/Nuke.git",
|
||||
"state" : {
|
||||
"revision" : "a002b7fd786f2df2ed4333fe73a9727499fd9d97",
|
||||
"version" : "10.11.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "nuke-flanimatedimage-plugin",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/kean/Nuke-FLAnimatedImage-Plugin.git",
|
||||
"state" : {
|
||||
"revision" : "b59c346a7d536336db3b0f12c72c6e53ee709e16",
|
||||
"version" : "8.0.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "pageboy",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/uias/Pageboy",
|
||||
"state" : {
|
||||
"revision" : "af8fa81788b893205e1ff42ddd88c5b0b315d7c5",
|
||||
"version" : "3.7.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "panmodal",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/slackhq/PanModal.git",
|
||||
"state" : {
|
||||
"revision" : "b012aecb6b67a8e46369227f893c12544846613f",
|
||||
"version" : "1.2.7"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "sdwebimage",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/SDWebImage/SDWebImage.git",
|
||||
"state" : {
|
||||
"revision" : "9248fe561a2a153916fb9597e3af4434784c6d32",
|
||||
"version" : "5.13.4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "stripes",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/eneko/Stripes.git",
|
||||
"state" : {
|
||||
"revision" : "d533fd44b8043a3abbf523e733599173d6f98c11",
|
||||
"version" : "0.2.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-collections",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-collections.git",
|
||||
"state" : {
|
||||
"revision" : "f504716c27d2e5d4144fa4794b12129301d17729",
|
||||
"version" : "1.0.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-nio",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-nio.git",
|
||||
"state" : {
|
||||
"revision" : "546610d52b19be3e19935e0880bb06b9c03f5cef",
|
||||
"version" : "1.14.4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-nio-zlib-support",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-nio-zlib-support.git",
|
||||
"state" : {
|
||||
"revision" : "37760e9a52030bb9011972c5213c3350fa9d41fd",
|
||||
"version" : "1.0.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swiftsoup",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/scinfu/SwiftSoup.git",
|
||||
"state" : {
|
||||
"revision" : "6778575285177365cbad3e5b8a72f2a20583cfec",
|
||||
"version" : "2.4.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swiftui-introspect",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/siteline/SwiftUI-Introspect.git",
|
||||
"state" : {
|
||||
"revision" : "f2616860a41f9d9932da412a8978fec79c06fe24",
|
||||
"version" : "0.1.4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "tabbarpager",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/TwidereProject/TabBarPager.git",
|
||||
"state" : {
|
||||
"revision" : "488aa66d157a648901b61721212c0dec23d27ee5",
|
||||
"version" : "0.1.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "tabman",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/uias/Tabman",
|
||||
"state" : {
|
||||
"revision" : "4a4f7c755b875ffd4f9ef10d67a67883669d2465",
|
||||
"version" : "2.13.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "tocropviewcontroller",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/TimOliver/TOCropViewController.git",
|
||||
"state" : {
|
||||
"revision" : "d0470491f56e734731bbf77991944c0dfdee3e0e",
|
||||
"version" : "2.6.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "uihostingconfigurationbackport",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/woxtu/UIHostingConfigurationBackport.git",
|
||||
"state" : {
|
||||
"revision" : "6091f2d38faa4b24fc2ca0389c651e2f666624a3",
|
||||
"version" : "0.1.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "uitextview-placeholder",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/MainasuK/UITextView-Placeholder.git",
|
||||
"state" : {
|
||||
"revision" : "20f513ded04a040cdf5467f0891849b1763ede3b",
|
||||
"version" : "1.4.1"
|
||||
}
|
||||
}
|
||||
],
|
||||
"version" : 2
|
||||
}
|
@ -18,7 +18,7 @@ let package = Package(
|
||||
name: "MastodonSDK",
|
||||
defaultLocalization: "en",
|
||||
platforms: [
|
||||
.iOS(.v15),
|
||||
.iOS(.v16),
|
||||
],
|
||||
products: [
|
||||
// Static Library
|
||||
@ -42,7 +42,6 @@ let package = Package(
|
||||
.package(url: "https://github.com/apple/swift-collections.git", from: "1.0.3"),
|
||||
.package(url: "https://github.com/apple/swift-nio.git", from: "2.0.0"),
|
||||
.package(url: "https://github.com/Flipboard/FLAnimatedImage.git", from: "1.0.0"),
|
||||
.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/slackhq/PanModal.git", from: "1.2.7"),
|
||||
@ -54,6 +53,7 @@ let package = Package(
|
||||
.package(url: "https://github.com/SDWebImage/SDWebImage.git", from: "5.12.0"),
|
||||
.package(url: "https://github.com/eneko/Stripes.git", from: "0.2.0"),
|
||||
.package(url: "https://github.com/NextLevel/NextLevelSessionExporter.git", from: "0.4.6"),
|
||||
.package(url: "https://github.com/xmartlabs/XLPagerTabStrip.git", from: "9.1.0"),
|
||||
],
|
||||
targets: [
|
||||
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
||||
@ -126,6 +126,8 @@ let package = Package(
|
||||
.product(name: "PanModal", package: "PanModal"),
|
||||
.product(name: "Stripes", package: "Stripes"),
|
||||
.product(name: "NextLevelSessionExporter", package: "NextLevelSessionExporter"),
|
||||
.product(name: "SDWebImage", package: "SDWebImage"),
|
||||
.product(name: "XLPagerTabStrip", package: "XLPagerTabStrip"),
|
||||
]
|
||||
),
|
||||
.testTarget(
|
||||
|
@ -1,17 +1,15 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "dark.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "dark@2x.png",
|
||||
"filename" : "about_instance_placeholder@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "dark@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
After Width: | Height: | Size: 68 KiB |
@ -1,23 +0,0 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "automatic.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "automatic@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "automatic@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 97 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 95 KiB |
@ -1,23 +0,0 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "light.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "light@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "light@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 96 KiB |
@ -219,9 +219,7 @@ public enum Asset {
|
||||
}
|
||||
}
|
||||
public enum Settings {
|
||||
public static let automatic = ImageAsset(name: "Settings/automatic")
|
||||
public static let dark = ImageAsset(name: "Settings/dark")
|
||||
public static let light = ImageAsset(name: "Settings/light")
|
||||
public static let aboutInstancePlaceholder = ImageAsset(name: "Settings/about_instance_placeholder")
|
||||
}
|
||||
public enum Theme {
|
||||
public enum System {
|
||||
|
@ -24,4 +24,8 @@ extension APIService {
|
||||
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.V2.Instance>, Error> {
|
||||
return Mastodon.API.V2.Instance.instance(session: session, domain: domain)
|
||||
}
|
||||
|
||||
public func extendedDescription(domain: String) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.ExtendedDescription>, Error> {
|
||||
return Mastodon.API.Instance.extendedDescription(session: session, domain: domain)
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
import VisionKit
|
||||
|
||||
@available(iOS 16.0, *)
|
||||
extension ImageAnalyzer {
|
||||
public static let shared = ImageAnalyzer()
|
||||
}
|
||||
|
@ -1418,7 +1418,7 @@ public enum L10n {
|
||||
public enum Settings {
|
||||
public enum AboutMastodon {
|
||||
/// Clear Media Storage
|
||||
public static let cleaerMediaStorage = L10n.tr("Localizable", "Scene.Settings.AboutMastodon.CleaerMediaStorage", fallback: "Clear Media Storage")
|
||||
public static let clearMediaStorage = L10n.tr("Localizable", "Scene.Settings.AboutMastodon.ClearMediaStorage", fallback: "Clear Media Storage")
|
||||
/// Contribute to Mastodon
|
||||
public static let contributeToMastodon = L10n.tr("Localizable", "Scene.Settings.AboutMastodon.ContributeToMastodon", fallback: "Contribute to Mastodon")
|
||||
/// Even More Settings
|
||||
@ -1509,6 +1509,8 @@ public enum L10n {
|
||||
}
|
||||
/// Notifications
|
||||
public static let notifications = L10n.tr("Localizable", "Scene.Settings.Overview.Notifications", fallback: "Notifications")
|
||||
/// Server Details
|
||||
public static let serverDetails = L10n.tr("Localizable", "Scene.Settings.Overview.ServerDetails", fallback: "Server Details")
|
||||
/// Support Mastodon
|
||||
public static let supportMastodon = L10n.tr("Localizable", "Scene.Settings.Overview.SupportMastodon", fallback: "Support Mastodon")
|
||||
/// Settings
|
||||
@ -1592,6 +1594,20 @@ public enum L10n {
|
||||
public static let title = L10n.tr("Localizable", "Scene.Settings.Section.SpicyZone.Title", fallback: "The Spicy Zone")
|
||||
}
|
||||
}
|
||||
public enum ServerDetails {
|
||||
/// About
|
||||
public static let about = L10n.tr("Localizable", "Scene.Settings.ServerDetails.About", fallback: "About")
|
||||
/// Rules
|
||||
public static let rules = L10n.tr("Localizable", "Scene.Settings.ServerDetails.Rules", fallback: "Rules")
|
||||
public enum AboutInstance {
|
||||
/// A legal notice
|
||||
public static let legalNotice = L10n.tr("Localizable", "Scene.Settings.ServerDetails.AboutInstance.LegalNotice", fallback: "A legal notice")
|
||||
/// Message Admin
|
||||
public static let messageAdmin = L10n.tr("Localizable", "Scene.Settings.ServerDetails.AboutInstance.MessageAdmin", fallback: "Message Admin")
|
||||
/// Administrator
|
||||
public static let title = L10n.tr("Localizable", "Scene.Settings.ServerDetails.AboutInstance.Title", fallback: "Administrator")
|
||||
}
|
||||
}
|
||||
}
|
||||
public enum SuggestionAccount {
|
||||
/// Follow all
|
||||
|
@ -527,6 +527,7 @@ uploaded to Mastodon.";
|
||||
"Scene.Settings.Overview.General" = "General";
|
||||
"Scene.Settings.Overview.Notifications" = "Notifications";
|
||||
"Scene.Settings.Overview.SupportMastodon" = "Support Mastodon";
|
||||
"Scene.Settings.Overview.ServerDetails" = "Server Details";
|
||||
"Scene.Settings.Overview.AboutMastodon" = "About Mastodon";
|
||||
"Scene.Settings.Overview.Logout" = "Logout %@";
|
||||
|
||||
@ -534,7 +535,13 @@ uploaded to Mastodon.";
|
||||
"Scene.Settings.AboutMastodon.MoreSettings" = "Even More Settings";
|
||||
"Scene.Settings.AboutMastodon.ContributeToMastodon" = "Contribute to Mastodon";
|
||||
"Scene.Settings.AboutMastodon.PrivacyPolicy" = "Privacy Policy";
|
||||
"Scene.Settings.AboutMastodon.CleaerMediaStorage" = "Clear Media Storage";
|
||||
"Scene.Settings.AboutMastodon.ClearMediaStorage" = "Clear Media Storage";
|
||||
|
||||
"Scene.Settings.ServerDetails.About" = "About";
|
||||
"Scene.Settings.ServerDetails.Rules" = "Rules";
|
||||
"Scene.Settings.ServerDetails.AboutInstance.Title" = "Administrator";
|
||||
"Scene.Settings.ServerDetails.AboutInstance.MessageAdmin" = "Message Admin";
|
||||
"Scene.Settings.ServerDetails.AboutInstance.LegalNotice" = "A legal notice";
|
||||
|
||||
"Scene.Settings.General.Title" = "General";
|
||||
"Scene.Settings.General.Appearance.SectionTitle" = "Appearance";
|
||||
|
@ -527,6 +527,7 @@ uploaded to Mastodon.";
|
||||
"Scene.Settings.Overview.General" = "General";
|
||||
"Scene.Settings.Overview.Notifications" = "Notifications";
|
||||
"Scene.Settings.Overview.SupportMastodon" = "Support Mastodon";
|
||||
"Scene.Settings.Overview.ServerDetails" = "Server Details";
|
||||
"Scene.Settings.Overview.AboutMastodon" = "About Mastodon";
|
||||
"Scene.Settings.Overview.Logout" = "Logout %@";
|
||||
|
||||
@ -534,7 +535,13 @@ uploaded to Mastodon.";
|
||||
"Scene.Settings.AboutMastodon.MoreSettings" = "Even More Settings";
|
||||
"Scene.Settings.AboutMastodon.ContributeToMastodon" = "Contribute to Mastodon";
|
||||
"Scene.Settings.AboutMastodon.PrivacyPolicy" = "Privacy Policy";
|
||||
"Scene.Settings.AboutMastodon.CleaerMediaStorage" = "Clear Media Storage";
|
||||
"Scene.Settings.AboutMastodon.ClearMediaStorage" = "Clear Media Storage";
|
||||
|
||||
"Scene.Settings.ServerDetails.About" = "About";
|
||||
"Scene.Settings.ServerDetails.Rules" = "Rules";
|
||||
"Scene.Settings.ServerDetails.AboutInstance.Title" = "Administrator";
|
||||
"Scene.Settings.ServerDetails.AboutInstance.MessageAdmin" = "Message Admin";
|
||||
"Scene.Settings.ServerDetails.AboutInstance.LegalNotice" = "A legal notice";
|
||||
|
||||
"Scene.Settings.General.Title" = "General";
|
||||
"Scene.Settings.General.Appearance.SectionTitle" = "Appearance";
|
||||
|
@ -30,11 +30,7 @@ extension Mastodon.API.Instance {
|
||||
session: URLSession,
|
||||
domain: String
|
||||
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Instance>, Error> {
|
||||
let request = Mastodon.API.get(
|
||||
url: instanceEndpointURL(domain: domain),
|
||||
query: nil,
|
||||
authorization: nil
|
||||
)
|
||||
let request = Mastodon.API.get(url: instanceEndpointURL(domain: domain))
|
||||
return session.dataTaskPublisher(for: request)
|
||||
.tryMap { data, response in
|
||||
let value: Mastodon.Entity.Instance
|
||||
@ -53,5 +49,27 @@ extension Mastodon.API.Instance {
|
||||
}
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
|
||||
static func extendedDescriptionEndpointURL(domain: String) -> URL {
|
||||
return Mastodon.API.endpointURL(domain: domain).appendingPathComponent("instance").appendingPathComponent("extended_description")
|
||||
}
|
||||
|
||||
/// Extended description of the server
|
||||
///
|
||||
/// - Returns: A ``MastodonSDK.Mastodon.Entity.ExtendedDescription``
|
||||
///
|
||||
/// ## Reference:
|
||||
/// [Document](https://docs.joinmastodon.org/methods/instance/#extended_description)
|
||||
public static func extendedDescription(
|
||||
session: URLSession,
|
||||
domain: String
|
||||
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.ExtendedDescription>, Error> {
|
||||
let request = Mastodon.API.get(url: extendedDescriptionEndpointURL(domain: domain))
|
||||
return session.dataTaskPublisher(for: request)
|
||||
.tryMap { data, response in
|
||||
let value = try Mastodon.API.decode(type: Mastodon.Entity.ExtendedDescription.self, from: data, response: response)
|
||||
return Mastodon.Response.Content(value: value, response: response)
|
||||
}
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,19 @@
|
||||
// Copyright © 2023 Mastodon gGmbH. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
|
||||
extension Mastodon.Entity {
|
||||
/// Extended description of the server
|
||||
|
||||
/// ## Reference:
|
||||
/// [Document](https://docs.joinmastodon.org/entities/ExtendedDescription/)
|
||||
public struct ExtendedDescription: Codable {
|
||||
public let updatedAt: Date
|
||||
public let content: String
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case updatedAt = "updated_at"
|
||||
case content
|
||||
}
|
||||
}
|
||||
}
|
@ -10,12 +10,11 @@ extension Mastodon.Entity.V2 {
|
||||
/// # Reference
|
||||
/// [Document](https://docs.joinmastodon.org/entities/instance/)
|
||||
public struct Instance: Codable {
|
||||
|
||||
|
||||
public let domain: String?
|
||||
public let title: String
|
||||
public let description: String
|
||||
public let shortDescription: String?
|
||||
public let email: String?
|
||||
public let version: String?
|
||||
public let languages: [String]? // (ISO 639 Part 1-5 language codes)
|
||||
public let registrations: Mastodon.Entity.V2.Instance.Registrations?
|
||||
@ -25,7 +24,7 @@ extension Mastodon.Entity.V2 {
|
||||
public let statistics: Mastodon.Entity.Instance.Statistics?
|
||||
|
||||
public let thumbnail: Thumbnail?
|
||||
public let contactAccount: Mastodon.Entity.Account?
|
||||
public let contact: Mastodon.Entity.V2.Instance.Contact?
|
||||
public let rules: [Mastodon.Entity.Instance.Rule]?
|
||||
|
||||
// https://github.com/mastodon/mastodon/pull/16485
|
||||
@ -36,7 +35,7 @@ extension Mastodon.Entity.V2 {
|
||||
self.title = domain
|
||||
self.description = ""
|
||||
self.shortDescription = nil
|
||||
self.email = ""
|
||||
self.contact = nil
|
||||
self.version = nil
|
||||
self.languages = nil
|
||||
self.registrations = nil
|
||||
@ -45,7 +44,6 @@ extension Mastodon.Entity.V2 {
|
||||
self.urls = nil
|
||||
self.statistics = nil
|
||||
self.thumbnail = nil
|
||||
self.contactAccount = nil
|
||||
self.rules = nil
|
||||
self.configuration = nil
|
||||
}
|
||||
@ -55,7 +53,6 @@ extension Mastodon.Entity.V2 {
|
||||
case title
|
||||
case description
|
||||
case shortDescription = "short_description"
|
||||
case email
|
||||
case version
|
||||
case languages
|
||||
case registrations
|
||||
@ -65,7 +62,7 @@ extension Mastodon.Entity.V2 {
|
||||
case statistics = "stats"
|
||||
|
||||
case thumbnail
|
||||
case contactAccount = "contact_account"
|
||||
case contact
|
||||
case rules
|
||||
|
||||
case configuration
|
||||
@ -106,3 +103,10 @@ extension Mastodon.Entity.V2.Instance {
|
||||
public let url: String?
|
||||
}
|
||||
}
|
||||
|
||||
extension Mastodon.Entity.V2.Instance {
|
||||
public struct Contact: Codable {
|
||||
public let email: String?
|
||||
public let account: Mastodon.Entity.Account?
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ extension MetaLabel {
|
||||
case accountListUsername
|
||||
case sidebarHeadline(isSelected: Bool)
|
||||
case sidebarSubheadline(isSelected: Bool)
|
||||
case aboutInstance
|
||||
}
|
||||
|
||||
public convenience init(style: Style) {
|
||||
@ -129,6 +130,10 @@ extension MetaLabel {
|
||||
case .sidebarSubheadline(let isSelected):
|
||||
font = UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 13, weight: .regular), maximumPointSize: 18)
|
||||
textColor = isSelected ? .white : Asset.Colors.Label.secondary.color
|
||||
case .aboutInstance:
|
||||
font = UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 17, weight: .regular))
|
||||
textColor = .label
|
||||
paragraphStyle.paragraphSpacing = 0
|
||||
}
|
||||
|
||||
self.font = font
|
||||
|
@ -44,45 +44,15 @@ public struct PollOptionRow: View {
|
||||
viewModel.textField?.becomeFirstResponder()
|
||||
}
|
||||
|
||||
if #available(iOS 16.0, *) {
|
||||
field.accessibilityActions {
|
||||
if let moveUp {
|
||||
Button(L10n.Scene.Compose.Poll.moveUp, action: moveUp)
|
||||
}
|
||||
if let moveDown {
|
||||
Button(L10n.Scene.Compose.Poll.moveDown, action: moveDown)
|
||||
}
|
||||
if let removeOption {
|
||||
Button(L10n.Scene.Compose.Poll.removeOption, action: removeOption)
|
||||
}
|
||||
field.accessibilityActions {
|
||||
if let moveUp {
|
||||
Button(L10n.Scene.Compose.Poll.moveUp, action: moveUp)
|
||||
}
|
||||
} else {
|
||||
switch (moveUp, moveDown, removeOption) {
|
||||
case let (.some(up), .some(down), .some(remove)):
|
||||
field
|
||||
.accessibilityAction(named: L10n.Scene.Compose.Poll.moveUp, up)
|
||||
.accessibilityAction(named: L10n.Scene.Compose.Poll.moveDown, down)
|
||||
.accessibilityAction(named: L10n.Scene.Compose.Poll.removeOption, remove)
|
||||
case let (.some(up), .some(down), .none):
|
||||
field
|
||||
.accessibilityAction(named: L10n.Scene.Compose.Poll.moveUp, up)
|
||||
.accessibilityAction(named: L10n.Scene.Compose.Poll.moveDown, down)
|
||||
case let (.some(up), .none, .some(remove)):
|
||||
field
|
||||
.accessibilityAction(named: L10n.Scene.Compose.Poll.moveUp, up)
|
||||
.accessibilityAction(named: L10n.Scene.Compose.Poll.removeOption, remove)
|
||||
case let (.some(up), .none, .none):
|
||||
field.accessibilityAction(named: L10n.Scene.Compose.Poll.moveUp, up)
|
||||
case let (.none, .some(down), .some(remove)):
|
||||
field
|
||||
.accessibilityAction(named: L10n.Scene.Compose.Poll.moveDown, down)
|
||||
.accessibilityAction(named: L10n.Scene.Compose.Poll.removeOption, remove)
|
||||
case let (.none, .some(down), .none):
|
||||
field.accessibilityAction(named: L10n.Scene.Compose.Poll.moveDown, down)
|
||||
case let (.none, .none, .some(remove)):
|
||||
field.accessibilityAction(named: L10n.Scene.Compose.Poll.removeOption, remove)
|
||||
case (.none, .none, .none):
|
||||
field
|
||||
if let moveDown {
|
||||
Button(L10n.Scene.Compose.Poll.moveDown, action: moveDown)
|
||||
}
|
||||
if let removeOption {
|
||||
Button(L10n.Scene.Compose.Poll.removeOption, action: removeOption)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -113,13 +113,7 @@ struct ComposeContentToolbarView: View {
|
||||
showingLanguagePicker = true
|
||||
}
|
||||
} label: {
|
||||
let font: SwiftUI.Font = {
|
||||
if #available(iOS 16, *) {
|
||||
return .system(size: 11, weight: .semibold).width(viewModel.language.count == 3 ? .compressed : .standard)
|
||||
} else {
|
||||
return .system(size: 11, weight: .semibold)
|
||||
}
|
||||
}()
|
||||
let font = SwiftUI.Font.system(size: 11, weight: .semibold).width(viewModel.language.count == 3 ? .compressed : .standard)
|
||||
|
||||
Text(viewModel.language)
|
||||
.font(font)
|
||||
|
@ -37,15 +37,9 @@ struct LanguagePicker: View {
|
||||
return Text("")
|
||||
}()
|
||||
Button(action: { onSelect(lang.id) }) {
|
||||
if #available(iOS 16.0, *) {
|
||||
ViewThatFits(in: .horizontal) {
|
||||
HStack(spacing: 0) { endonym; Text(" "); exonym }
|
||||
VStack(alignment: .leading) { endonym; exonym }
|
||||
}
|
||||
} else {
|
||||
// less optimal because if you’re using an LTR language, RTL languages
|
||||
// will read as “ ([exonym])[endonym]” (and vice versa in RTL locales)
|
||||
Text("\(endonym)\(exonym)")
|
||||
ViewThatFits(in: .horizontal) {
|
||||
HStack(spacing: 0) { endonym; Text(" "); exonym }
|
||||
VStack(alignment: .leading) { endonym; exonym }
|
||||
}
|
||||
}
|
||||
.tint(.primary)
|
||||
|
@ -163,7 +163,7 @@ public class CondensedUserView: UIView {
|
||||
}
|
||||
}
|
||||
|
||||
public func configure(with account: Mastodon.Entity.Account) {
|
||||
public func configure(with account: Mastodon.Entity.Account, showFollowers: Bool = true) {
|
||||
let displayNameMetaContent: MetaContent
|
||||
do {
|
||||
let content = MastodonContent(content: account.displayNameWithFallback, emojis: account.emojis?.asDictionary ?? [:])
|
||||
@ -174,10 +174,16 @@ public class CondensedUserView: UIView {
|
||||
|
||||
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))])
|
||||
)
|
||||
|
||||
if showFollowers {
|
||||
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))])
|
||||
)
|
||||
followersLabel.isHidden = false
|
||||
} else {
|
||||
followersLabel.isHidden = false
|
||||
}
|
||||
|
||||
avatarImageView.setImage(url: account.avatarImageURL())
|
||||
|
||||
|
@ -328,13 +328,8 @@ extension StatusView.ViewModel {
|
||||
|
||||
let paragraphStyle = statusView.contentMetaText.paragraphStyle
|
||||
if let language = language {
|
||||
if #available(iOS 16, *) {
|
||||
let direction = Locale.Language(identifier: language).characterDirection
|
||||
paragraphStyle.alignment = direction == .rightToLeft ? .right : .left
|
||||
} else {
|
||||
let direction = Locale.characterDirection(forLanguage: language)
|
||||
paragraphStyle.alignment = direction == .rightToLeft ? .right : .left
|
||||
};
|
||||
let direction = Locale.Language(identifier: language).characterDirection
|
||||
paragraphStyle.alignment = direction == .rightToLeft ? .right : .left
|
||||
} else {
|
||||
paragraphStyle.alignment = .natural
|
||||
}
|
||||
|
5
Podfile
@ -7,11 +7,6 @@ target 'Mastodon' do
|
||||
# Comment the next line if you don't want to use dynamic frameworks
|
||||
use_frameworks!
|
||||
|
||||
# Pods for Mastodon
|
||||
|
||||
# UI
|
||||
pod 'XLPagerTabStrip', '~> 9.0.0'
|
||||
|
||||
# misc
|
||||
pod 'SwiftGen', '~> 6.6.2'
|
||||
pod 'Kanna', '~> 5.2.2'
|
||||
|
@ -4,27 +4,23 @@ PODS:
|
||||
- Sourcery/CLI-Only (= 1.9.2)
|
||||
- Sourcery/CLI-Only (1.9.2)
|
||||
- SwiftGen (6.6.2)
|
||||
- XLPagerTabStrip (9.0.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
- Kanna (~> 5.2.2)
|
||||
- Sourcery (~> 1.9)
|
||||
- SwiftGen (~> 6.6.2)
|
||||
- XLPagerTabStrip (~> 9.0.0)
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- Kanna
|
||||
- Sourcery
|
||||
- SwiftGen
|
||||
- XLPagerTabStrip
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Kanna: 01cfbddc127f5ff0963692f285fcbc8a9d62d234
|
||||
Sourcery: 179539341c2261068528cd15a31837b7238fd901
|
||||
SwiftGen: 1366a7f71aeef49954ca5a63ba4bef6b0f24138c
|
||||
XLPagerTabStrip: 61c57fd61f611ee5f01ff1495ad6fbee8bf496c5
|
||||
|
||||
PODFILE CHECKSUM: 8c962b3cbb4c225f1e57fb2e4ca03d1f22c45e5e
|
||||
PODFILE CHECKSUM: 597c21d7aa08efec996048577c3c4fbeffbb6305
|
||||
|
||||
COCOAPODS: 1.12.1
|
||||
COCOAPODS: 1.13.0
|
||||
|
@ -2,14 +2,14 @@
|
||||
|
||||
[![CI](https://github.com/mastodon/mastodon-ios/actions/workflows/main.yml/badge.svg)](https://github.com/mastodon/mastodon-ios/actions/workflows/main.yml) [![Crowdin](https://badges.crowdin.net/mastodon-for-ios/localized.svg)](https://crowdin.com/project/mastodon-for-ios)
|
||||
|
||||
|
||||
<a href="https://apps.apple.com/us/app/mastodon-for-iphone/id1571998974?itsct=apps_box_badge&itscg=30200" style="display: inline-block; overflow: hidden; border-top-left-radius: 13px; border-top-right-radius: 13px; border-bottom-right-radius: 13px; border-bottom-left-radius: 13px; width: 250px; height: 83px;"><img src="https://tools.applemediaservices.com/api/badges/download-on-the-app-store/black/en-us?size=250x83&releaseDate=1627603200&h=72b0c8495c2c0af1291efef280c4c2c1" alt="Download on the App Store" style="border-top-left-radius: 13px; border-top-right-radius: 13px; border-bottom-right-radius: 13px; border-bottom-left-radius: 13px; width: 250px; height: 83px;"></a>
|
||||
|
||||
## Introduction
|
||||
|
||||
This is the repository for the official iOS App for Mastodon. You can install it from the App Store now. You can build the app from source and file bug report here.
|
||||
This is the repository for the official iOS App for Mastodon. You can install it from the App Store now. You can build the app from source and file bug report here.
|
||||
|
||||
Read this blog post for this app to learn more.
|
||||
|
||||
Read this blog post for this app to learn more.
|
||||
> [Developing an official iOS app for Mastodon](https://blog.joinmastodon.org/2021/02/developing-an-official-ios-app-for-mastodon/)
|
||||
|
||||
## Getting Started
|
||||
@ -17,6 +17,7 @@ Read this blog post for this app to learn more.
|
||||
- Read the setup guide [here](./Documentation/Setup.md)
|
||||
- About [contributing](./Documentation/CONTRIBUTING.md)
|
||||
- [Documentation folder](./Documentation/)
|
||||
- [App Store Deployment](./Documentation/Deployment.md)
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
|
@ -54,10 +54,7 @@ struct FollowersCountEntry: TimelineEntry {
|
||||
|
||||
struct FollowersCountWidget: Widget {
|
||||
private var availableFamilies: [WidgetFamily] {
|
||||
if #available(iOS 16, *) {
|
||||
return [.systemSmall, .accessoryRectangular, .accessoryCircular]
|
||||
}
|
||||
return [.systemSmall]
|
||||
return [.systemSmall, .accessoryRectangular, .accessoryCircular]
|
||||
}
|
||||
|
||||
var body: some WidgetConfiguration {
|
||||
|
@ -148,9 +148,7 @@ struct FollowersCountWidgetView: View {
|
||||
|
||||
private func viewForAccessoryCircular(_ account :FollowersEntryAccountable) -> some View {
|
||||
ZStack {
|
||||
if #available(iOS 16, *) {
|
||||
AccessoryWidgetBackground()
|
||||
}
|
||||
AccessoryWidgetBackground()
|
||||
VStack {
|
||||
Image("BrandIcon")
|
||||
|
||||
|
@ -146,11 +146,7 @@ struct HashtagWidgetTimelineEntry: TimelineEntry {
|
||||
struct HashtagWidget: Widget {
|
||||
|
||||
private var availableFamilies: [WidgetFamily] {
|
||||
if #available(iOS 16, *) {
|
||||
return [.systemMedium, .systemLarge, .accessoryRectangular]
|
||||
} else {
|
||||
return [.systemMedium, .systemLarge]
|
||||
}
|
||||
return [.systemMedium, .systemLarge, .accessoryRectangular]
|
||||
}
|
||||
|
||||
var body: some WidgetConfiguration {
|
||||
|
2
fastlane/Appfile
Normal file
@ -0,0 +1,2 @@
|
||||
app_identifier("org.joinmastodon.app")
|
||||
team_id("5Z4GVSS33P")
|
3
fastlane/Deliverfile
Normal file
@ -0,0 +1,3 @@
|
||||
force true
|
||||
app_identifier "org.joinmastodon.app"
|
||||
precheck_include_in_app_purchases false
|
80
fastlane/Fastfile
Normal file
@ -0,0 +1,80 @@
|
||||
opt_out_usage
|
||||
default_platform(:ios)
|
||||
|
||||
$appName = "Mastodon"
|
||||
|
||||
platform :ios do
|
||||
before_all do |lane|
|
||||
$bundle_id = "org.joinmastodon.app"
|
||||
$all_bundle_ids = [
|
||||
$bundle_id,
|
||||
"org.joinmastodon.app.MastodonIntent",
|
||||
"org.joinmastodon.app.NotificationService",
|
||||
"org.joinmastodon.app.ShareActionExtension",
|
||||
"org.joinmastodon.app.OpenInActionExtension",
|
||||
"org.joinmastodon.app.WidgetExtension"
|
||||
]
|
||||
|
||||
lanes_for_building = [:deploy_appstore]
|
||||
|
||||
if lanes_for_building.include?(lane)
|
||||
app_store_connect_api_key(
|
||||
key_id: ENV["ITC_KEY_ID"],
|
||||
issuer_id: ENV["ITC_ISSUER_ID"],
|
||||
key_content: ENV["ITC_KEY"],
|
||||
duration: 1200,
|
||||
in_house: false
|
||||
)
|
||||
ensure_git_status_clean
|
||||
$version_number = get_version_number_from_xcodeproj(target: $appName)
|
||||
$build_number = get_build_number()
|
||||
increment_build_number_in_xcodeproj(
|
||||
xcodeproj: "#{$appName}.xcodeproj",
|
||||
build_number: $build_number
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
desc "Update certificates"
|
||||
lane :update_certificates do
|
||||
match(type: "development", app_identifier: $all_bundle_ids, force_for_new_devices: true)
|
||||
match(type: "appstore", app_identifier: $all_bundle_ids, force_for_new_devices: false)
|
||||
end
|
||||
|
||||
desc "Update devices"
|
||||
lane :update_devices do
|
||||
register_devices(devices_file: "./fastlane/devices.txt")
|
||||
end
|
||||
|
||||
lane :build_only do
|
||||
xcodebuild(
|
||||
clean: true,
|
||||
scheme: "Mastodon",
|
||||
workspace: "Mastodon.xcworkspace"
|
||||
)
|
||||
end
|
||||
|
||||
desc " Build and deploy the App to App Store Connect & TestFlight"
|
||||
lane :deploy_appstore do
|
||||
|
||||
if is_ci
|
||||
create_keychain(name: "temp_keychain", password: "temp_123456", default_keychain: true, unlock: true, timeout: 3600, lock_when_sleeps: false)
|
||||
match(type: "appstore", app_identifier: $all_bundle_ids, force_for_new_devices: true, readonly: true, keychain_name: "temp_keychain", keychain_password: "temp_123456")
|
||||
else
|
||||
match(type: "appstore", app_identifier: $all_bundle_ids, force_for_new_devices: true, readonly: false)
|
||||
end
|
||||
|
||||
gym(workspace: "#{$appName}.xcworkspace",
|
||||
scheme: "#{$appName}",
|
||||
clean: true,
|
||||
export_method: "app-store",
|
||||
export_xcargs: "-allowProvisioningUpdates")
|
||||
deliver(app_identifier: $bundle_id, skip_screenshots: true, skip_metadata: true)
|
||||
|
||||
sh("echo \"GITHUB_TAG_NAME=#{$version_number}-#{$build_number}\" >> $GITHUB_ENV")
|
||||
end
|
||||
end
|
||||
|
||||
def get_build_number
|
||||
sh("git rev-list --count HEAD").chomp
|
||||
end
|
14
fastlane/Matchfile
Normal file
@ -0,0 +1,14 @@
|
||||
git_url("git@github.com:mastodon/mastodon-ios-match.git")
|
||||
storage_mode("git")
|
||||
git_branch("main")
|
||||
type("appstore") # The default type, can be: appstore, adhoc, enterprise or development
|
||||
|
||||
app_identifier([
|
||||
"org.joinmastodon.app",
|
||||
"org.joinmastodon.app.MastodonIntent",
|
||||
"org.joinmastodon.app.NotificationService",
|
||||
"org.joinmastodon.app.ShareActionExtension",
|
||||
"org.joinmastodon.app.OpenInActionExtension",
|
||||
"org.joinmastodon.app.WidgetExtension"
|
||||
])
|
||||
# username("fastlane@joinmastodon.org")
|
5
fastlane/Pluginfile
Normal file
@ -0,0 +1,5 @@
|
||||
# Autogenerated by fastlane
|
||||
#
|
||||
# Ensure this file is checked in to source control!
|
||||
|
||||
gem 'fastlane-plugin-versioning'
|
56
fastlane/README.md
Normal file
@ -0,0 +1,56 @@
|
||||
fastlane documentation
|
||||
----
|
||||
|
||||
# Installation
|
||||
|
||||
Make sure you have the latest version of the Xcode command line tools installed:
|
||||
|
||||
```sh
|
||||
xcode-select --install
|
||||
```
|
||||
|
||||
For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)
|
||||
|
||||
# Available Actions
|
||||
|
||||
## iOS
|
||||
|
||||
### ios update_certificates
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane ios update_certificates
|
||||
```
|
||||
|
||||
Update certificates
|
||||
|
||||
### ios update_devices
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane ios update_devices
|
||||
```
|
||||
|
||||
Update devices
|
||||
|
||||
### ios build_only
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane ios build_only
|
||||
```
|
||||
|
||||
|
||||
|
||||
### ios deploy_appstore
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane ios deploy_appstore
|
||||
```
|
||||
|
||||
Build and deploy the App to App Store Connect & TestFlight
|
||||
|
||||
----
|
||||
|
||||
This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
|
||||
|
||||
More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).
|
||||
|
||||
The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
|
2
fastlane/devices.txt.example
Normal file
@ -0,0 +1,2 @@
|
||||
Device ID Device Name Device Platform
|
||||
00000000-0000000000000000 Your-Device-Name ios
|