Allow tabs to be enabled/disabled and reordered
This commit is contained in:
parent
0f37843a5b
commit
57b4e67cc2
@ -57,6 +57,9 @@
|
||||
D6109A0D214599E100432DC2 /* RequestRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6109A0C214599E100432DC2 /* RequestRange.swift */; };
|
||||
D6109A0F21459B6900432DC2 /* Pagination.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6109A0E21459B6900432DC2 /* Pagination.swift */; };
|
||||
D6109A11214607D500432DC2 /* Timeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6109A10214607D500432DC2 /* Timeline.swift */; };
|
||||
D621544821682A9D0003D87D /* TabsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D621544721682A9D0003D87D /* TabsTableViewController.swift */; };
|
||||
D621544B21682AD30003D87D /* TabTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D621544A21682AD30003D87D /* TabTableViewCell.swift */; };
|
||||
D621544D21682AD90003D87D /* TabTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D621544C21682AD90003D87D /* TabTableViewCell.xib */; };
|
||||
D6333B372137838300CE884A /* AttributedString+Trim.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6333B362137838300CE884A /* AttributedString+Trim.swift */; };
|
||||
D6333B772138D94E00CE884A /* ComposeMediaView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6333B762138D94E00CE884A /* ComposeMediaView.swift */; };
|
||||
D6333B792139AEFD00CE884A /* Date+TimeAgo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6333B782139AEFD00CE884A /* Date+TimeAgo.swift */; };
|
||||
@ -103,6 +106,7 @@
|
||||
D6757A822157E8FA00721E32 /* XCBSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6757A812157E8FA00721E32 /* XCBSession.swift */; };
|
||||
D679C09F215850EF00DA27FE /* XCBActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D679C09E215850EF00DA27FE /* XCBActions.swift */; };
|
||||
D67E0513216438A7000E0927 /* AppearanceTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D67E0512216438A7000E0927 /* AppearanceTableViewController.swift */; };
|
||||
D67E051521643C77000E0927 /* Tab.swift in Sources */ = {isa = PBXBuildFile; fileRef = D67E051421643C77000E0927 /* Tab.swift */; };
|
||||
D6BED170212663DA00F02DA0 /* SwiftSoup.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D6BED16E212663DA00F02DA0 /* SwiftSoup.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
D6BED174212667E900F02DA0 /* StatusTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6BED173212667E900F02DA0 /* StatusTableViewCell.swift */; };
|
||||
D6C693CA2161253F007D6A6D /* SilentActionPermissionsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693C92161253F007D6A6D /* SilentActionPermissionsTableViewController.swift */; };
|
||||
@ -241,6 +245,9 @@
|
||||
D6109A0C214599E100432DC2 /* RequestRange.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestRange.swift; sourceTree = "<group>"; };
|
||||
D6109A0E21459B6900432DC2 /* Pagination.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Pagination.swift; sourceTree = "<group>"; };
|
||||
D6109A10214607D500432DC2 /* Timeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Timeline.swift; sourceTree = "<group>"; };
|
||||
D621544721682A9D0003D87D /* TabsTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsTableViewController.swift; sourceTree = "<group>"; };
|
||||
D621544A21682AD30003D87D /* TabTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabTableViewCell.swift; sourceTree = "<group>"; };
|
||||
D621544C21682AD90003D87D /* TabTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TabTableViewCell.xib; sourceTree = "<group>"; };
|
||||
D6333B362137838300CE884A /* AttributedString+Trim.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AttributedString+Trim.swift"; sourceTree = "<group>"; };
|
||||
D6333B762138D94E00CE884A /* ComposeMediaView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeMediaView.swift; sourceTree = "<group>"; };
|
||||
D6333B782139AEFD00CE884A /* Date+TimeAgo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Date+TimeAgo.swift"; sourceTree = "<group>"; };
|
||||
@ -286,6 +293,7 @@
|
||||
D6757A812157E8FA00721E32 /* XCBSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCBSession.swift; sourceTree = "<group>"; };
|
||||
D679C09E215850EF00DA27FE /* XCBActions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCBActions.swift; sourceTree = "<group>"; };
|
||||
D67E0512216438A7000E0927 /* AppearanceTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppearanceTableViewController.swift; sourceTree = "<group>"; };
|
||||
D67E051421643C77000E0927 /* Tab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tab.swift; sourceTree = "<group>"; };
|
||||
D6BED16E212663DA00F02DA0 /* SwiftSoup.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SwiftSoup.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D6BED173212667E900F02DA0 /* StatusTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusTableViewCell.swift; sourceTree = "<group>"; };
|
||||
D6C693C92161253F007D6A6D /* SilentActionPermissionsTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SilentActionPermissionsTableViewController.swift; sourceTree = "<group>"; };
|
||||
@ -464,6 +472,15 @@
|
||||
path = Model;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D621544921682AC60003D87D /* Tab */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D621544C21682AD90003D87D /* TabTableViewCell.xib */,
|
||||
D621544A21682AD30003D87D /* TabTableViewCell.swift */,
|
||||
);
|
||||
path = Tab;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D641C780213DD7C4004B4513 /* Screens */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -558,8 +575,9 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D663626521360DD700C9CBA2 /* Preferences.storyboard */,
|
||||
D67E0512216438A7000E0927 /* AppearanceTableViewController.swift */,
|
||||
D663626721360E2C00C9CBA2 /* PreferencesTableViewController.swift */,
|
||||
D67E0512216438A7000E0927 /* AppearanceTableViewController.swift */,
|
||||
D621544721682A9D0003D87D /* TabsTableViewController.swift */,
|
||||
D641C78E213DF2AA004B4513 /* VisibilityTableViewController.swift */,
|
||||
D6C693C92161253F007D6A6D /* SilentActionPermissionsTableViewController.swift */,
|
||||
);
|
||||
@ -620,6 +638,7 @@
|
||||
D663626121360B1900C9CBA2 /* Preferences.swift */,
|
||||
D663626321360D2300C9CBA2 /* AvatarStyle.swift */,
|
||||
D66362692136163000C9CBA2 /* PreferencesAdaptive.swift */,
|
||||
D67E051421643C77000E0927 /* Tab.swift */,
|
||||
);
|
||||
path = Preferences;
|
||||
sourceTree = "<group>";
|
||||
@ -653,6 +672,7 @@
|
||||
D6BED1722126661300F02DA0 /* Views */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D621544921682AC60003D87D /* Tab */,
|
||||
04496BD621625361001F1B23 /* ContentLabel.swift */,
|
||||
D6C693F82162E4DB007D6A6D /* StatusContentLabel.swift */,
|
||||
D6C94D882139E6EC00CB5196 /* AttachmentView.swift */,
|
||||
@ -995,6 +1015,7 @@
|
||||
D641C771213CA9EC004B4513 /* Notifications.storyboard in Resources */,
|
||||
D663626621360DD700C9CBA2 /* Preferences.storyboard in Resources */,
|
||||
D667E5E12134937B0057A976 /* StatusTableViewCell.xib in Resources */,
|
||||
D621544D21682AD90003D87D /* TabTableViewCell.xib in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -1085,9 +1106,11 @@
|
||||
D6F953F021251A2900CF0F2B /* MastodonController.swift in Sources */,
|
||||
D66362712136338600C9CBA2 /* ComposeViewController.swift in Sources */,
|
||||
D6028B9B2150811100F223B9 /* MastodonCache.swift in Sources */,
|
||||
D67E051521643C77000E0927 /* Tab.swift in Sources */,
|
||||
D646C958213B367000269FB5 /* LargeImageShrinkAnimationController.swift in Sources */,
|
||||
D646C956213B365700269FB5 /* LargeImageExpandAnimationController.swift in Sources */,
|
||||
D667E5F82135C3040057A976 /* Mastodon+Equatable.swift in Sources */,
|
||||
D621544B21682AD30003D87D /* TabTableViewCell.swift in Sources */,
|
||||
04DACE8E212CC7CC009840C4 /* ImageCache.swift in Sources */,
|
||||
D6333B772138D94E00CE884A /* ComposeMediaView.swift in Sources */,
|
||||
04ED00B121481ED800567C53 /* SteppedProgressView.swift in Sources */,
|
||||
@ -1102,6 +1125,7 @@
|
||||
D6434EB3215B1856001A919A /* XCBRequest.swift in Sources */,
|
||||
D663626221360B1900C9CBA2 /* Preferences.swift in Sources */,
|
||||
D6333B792139AEFD00CE884A /* Date+TimeAgo.swift in Sources */,
|
||||
D621544821682A9D0003D87D /* TabsTableViewController.swift in Sources */,
|
||||
D641C78F213DF2AA004B4513 /* VisibilityTableViewController.swift in Sources */,
|
||||
D641C77F213DC78A004B4513 /* InlineTextAttachment.swift in Sources */,
|
||||
04496BD721625361001F1B23 /* ContentLabel.swift in Sources */,
|
||||
|
@ -31,16 +31,29 @@ class Preferences: Codable {
|
||||
return Preferences()
|
||||
}
|
||||
|
||||
private init() {}
|
||||
|
||||
// MARK: - Appearance
|
||||
var showRepliesInProfiles = false
|
||||
|
||||
var avatarStyle = AvatarStyle.roundRect
|
||||
|
||||
var hideCustomEmojiInUsernames = false
|
||||
var tabs: [Tab: Int] = [.home: 0, .notifications: 1, .local: -1, .federated: 2, .myProfile: 3, .preferences: 4]
|
||||
|
||||
var defaultPostVisibility = Status.Visibility.public
|
||||
|
||||
// MARK: - Advanced
|
||||
var silentActions: [String: Permission] = [:]
|
||||
|
||||
// MARK: - Utility Methods
|
||||
func tabIndex(_ tab: Tab) -> Int {
|
||||
if let index = tabs[tab] {
|
||||
return index
|
||||
} else {
|
||||
tabs[tab] = -1
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension Preferences {
|
||||
|
35
Tusker/Preferences/Tab.swift
Normal file
35
Tusker/Preferences/Tab.swift
Normal file
@ -0,0 +1,35 @@
|
||||
//
|
||||
// Tab.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 10/2/18.
|
||||
// Copyright © 2018 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum Tab: String, Codable, CaseIterable {
|
||||
case home
|
||||
case federated
|
||||
case local
|
||||
case myProfile
|
||||
case notifications
|
||||
case preferences
|
||||
|
||||
var humanName: String {
|
||||
switch self {
|
||||
case .home:
|
||||
return "Home"
|
||||
case .federated:
|
||||
return "Federated"
|
||||
case .local:
|
||||
return "Local"
|
||||
case .myProfile:
|
||||
return "My Profile"
|
||||
case .notifications:
|
||||
return "Notifications"
|
||||
case .preferences:
|
||||
return "Preferences"
|
||||
}
|
||||
}
|
||||
}
|
@ -13,35 +13,49 @@ class MainTabBarViewController: UITabBarController {
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
let home = TimelineTableViewController.create(for: .home)
|
||||
|
||||
let federated = TimelineTableViewController.create(for: .public(local: false))
|
||||
|
||||
let local = TimelineTableViewController.create(for: .public(local: true))
|
||||
|
||||
let ownProfile = ProfileTableViewController.createForPending()
|
||||
ownProfile.title = "My Profile"
|
||||
|
||||
let notifications = NotificationsTableViewController.create()
|
||||
|
||||
let preferences = PreferencesTableViewController.create()
|
||||
|
||||
viewControllers = [
|
||||
navigationController(for: home),
|
||||
navigationController(for: federated),
|
||||
navigationController(for: local),
|
||||
navigationController(for: ownProfile),
|
||||
notifications,
|
||||
preferences
|
||||
]
|
||||
|
||||
MastodonController.getOwnAccount { (account) in
|
||||
ownProfile.accountID = account.id
|
||||
updateTabs(animated: false)
|
||||
}
|
||||
|
||||
func updateTabs(animated: Bool) {
|
||||
let currentTabs = Preferences.shared.tabs.filter { $1 >= 0 }.sorted { $1.1 > $0.1 }.map { $0.key }
|
||||
let viewControllers: [UIViewController] = currentTabs.map { (tab) in
|
||||
if tab == .preferences, let preferences = selectedViewController {
|
||||
return preferences
|
||||
} else {
|
||||
return embedInNavigationController(createVC(for: tab))
|
||||
}
|
||||
}
|
||||
setViewControllers(viewControllers, animated: animated)
|
||||
}
|
||||
|
||||
func createVC(for tab: Tab) -> UIViewController {
|
||||
switch tab {
|
||||
case .home:
|
||||
return TimelineTableViewController.create(for: .home)
|
||||
case .federated:
|
||||
return TimelineTableViewController.create(for: .public(local: false))
|
||||
case .local:
|
||||
return TimelineTableViewController.create(for: .public(local: true))
|
||||
case .myProfile:
|
||||
let myProfile = ProfileTableViewController.createForPending()
|
||||
myProfile.title = "My Profile"
|
||||
MastodonController.getOwnAccount { (account) in
|
||||
myProfile.accountID = account.id
|
||||
}
|
||||
return myProfile
|
||||
case .notifications:
|
||||
return NotificationsTableViewController.create()
|
||||
case .preferences:
|
||||
return PreferencesTableViewController.create()
|
||||
}
|
||||
}
|
||||
|
||||
func navigationController(for vc: UIViewController) -> UINavigationController {
|
||||
return UINavigationController(rootViewController: vc)
|
||||
func embedInNavigationController(_ vc: UIViewController) -> UINavigationController {
|
||||
if let vc = vc as? UINavigationController {
|
||||
return vc
|
||||
} else {
|
||||
return UINavigationController(rootViewController: vc)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,10 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.15" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="VJJ-jC-9g8">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.23.1" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="VJJ-jC-9g8">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.9"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.16.1"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
@ -44,22 +44,22 @@
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
<tableViewSection id="1m2-cM-16u">
|
||||
<tableViewSection id="QnL-PI-wDE">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" id="8Y3-if-FhA">
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="blue" accessoryType="disclosureIndicator" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" id="RwH-Ti-TH8">
|
||||
<rect key="frame" x="0.0" y="115" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="8Y3-if-FhA" id="ZpZ-BB-0Ti">
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="RwH-Ti-TH8" id="NJF-ED-5cF">
|
||||
<rect key="frame" x="0.0" y="0.0" width="341" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Default post visibility" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VIi-n0-FBN">
|
||||
<rect key="frame" x="16" y="11.5" width="159" height="21"/>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Default Post Visibility" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="iEj-dZ-E4F">
|
||||
<rect key="frame" x="16" y="11.5" width="162" height="21"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Public" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="RXt-HZ-X6X">
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Public" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="se3-JR-wRN">
|
||||
<rect key="frame" x="294" y="11.5" width="47" height="21"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
@ -67,28 +67,28 @@
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="VIi-n0-FBN" firstAttribute="centerY" secondItem="ZpZ-BB-0Ti" secondAttribute="centerY" id="7qF-Va-DIX"/>
|
||||
<constraint firstAttribute="trailing" secondItem="RXt-HZ-X6X" secondAttribute="trailing" id="8Y3-1J-Y5y"/>
|
||||
<constraint firstItem="RXt-HZ-X6X" firstAttribute="centerY" secondItem="ZpZ-BB-0Ti" secondAttribute="centerY" id="8vB-O3-3p8"/>
|
||||
<constraint firstItem="VIi-n0-FBN" firstAttribute="leading" secondItem="ZpZ-BB-0Ti" secondAttribute="leadingMargin" id="y3v-9l-ECZ"/>
|
||||
<constraint firstItem="se3-JR-wRN" firstAttribute="centerY" secondItem="NJF-ED-5cF" secondAttribute="centerY" id="GGU-6Y-NSR"/>
|
||||
<constraint firstItem="iEj-dZ-E4F" firstAttribute="leading" secondItem="NJF-ED-5cF" secondAttribute="leadingMargin" id="X5l-TE-I3w"/>
|
||||
<constraint firstAttribute="trailing" secondItem="se3-JR-wRN" secondAttribute="trailing" id="eeH-Zb-ZS9"/>
|
||||
<constraint firstItem="iEj-dZ-E4F" firstAttribute="centerY" secondItem="NJF-ED-5cF" secondAttribute="centerY" id="rak-B9-rwy"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
<segue destination="50Z-Q7-qIn" kind="show" id="Nns-Fe-keu"/>
|
||||
<segue destination="50Z-Q7-qIn" kind="show" id="uHj-Vc-3uZ"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
<tableViewSection id="QnL-PI-wDE">
|
||||
<tableViewSection id="5L1-9T-nha">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="blue" accessoryType="disclosureIndicator" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" id="RwH-Ti-TH8">
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="blue" accessoryType="disclosureIndicator" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" id="eQh-JA-eyx">
|
||||
<rect key="frame" x="0.0" y="195" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="RwH-Ti-TH8" id="NJF-ED-5cF">
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="eQh-JA-eyx" id="2y5-gN-4xJ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="341" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Advanced" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="iEj-dZ-E4F">
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Advanced" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="SWr-6T-ZL5">
|
||||
<rect key="frame" x="16" y="11.5" width="77" height="21"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
@ -96,12 +96,12 @@
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="iEj-dZ-E4F" firstAttribute="leading" secondItem="NJF-ED-5cF" secondAttribute="leadingMargin" id="X5l-TE-I3w"/>
|
||||
<constraint firstItem="iEj-dZ-E4F" firstAttribute="centerY" secondItem="NJF-ED-5cF" secondAttribute="centerY" id="rak-B9-rwy"/>
|
||||
<constraint firstItem="SWr-6T-ZL5" firstAttribute="leading" secondItem="2y5-gN-4xJ" secondAttribute="leadingMargin" id="1hJ-fj-Llf"/>
|
||||
<constraint firstItem="SWr-6T-ZL5" firstAttribute="centerY" secondItem="2y5-gN-4xJ" secondAttribute="centerY" id="Qao-fy-t0w"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
<segue destination="3mv-l7-6We" kind="show" id="LGp-xW-KyG"/>
|
||||
<segue destination="3mv-l7-6We" kind="show" id="v4C-bk-CFc"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
@ -114,7 +114,7 @@
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title="Preferences" id="dN7-yl-voz"/>
|
||||
<connections>
|
||||
<outlet property="defaultPostVisibilityLabel" destination="RXt-HZ-X6X" id="KEB-sg-UNE"/>
|
||||
<outlet property="defaultPostVisibilityLabel" destination="se3-JR-wRN" id="YQM-H1-DBK"/>
|
||||
</connections>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="GBL-Cz-yNZ" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
@ -130,10 +130,10 @@
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
|
||||
<sections>
|
||||
<tableViewSection id="gwC-db-0ec">
|
||||
<tableViewSection headerTitle="Display" id="gwC-db-0ec">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" id="cSJ-mP-CMQ">
|
||||
<rect key="frame" x="0.0" y="35" width="375" height="44"/>
|
||||
<rect key="frame" x="0.0" y="55.5" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="cSJ-mP-CMQ" id="K0u-vm-1cA">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
|
||||
@ -162,7 +162,7 @@
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" id="KRM-HM-H3l">
|
||||
<rect key="frame" x="0.0" y="79" width="375" height="44"/>
|
||||
<rect key="frame" x="0.0" y="99.5" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="KRM-HM-H3l" id="1OA-09-UkD">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
|
||||
@ -190,7 +190,7 @@
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" id="KoZ-lA-gof">
|
||||
<rect key="frame" x="0.0" y="123" width="375" height="44"/>
|
||||
<rect key="frame" x="0.0" y="143.5" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="KoZ-lA-gof" id="ZiQ-kq-AHv">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
|
||||
@ -219,6 +219,33 @@
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
<tableViewSection headerTitle="Interaction" id="2hR-aI-CRP">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" id="11q-UM-f40">
|
||||
<rect key="frame" x="0.0" y="243.5" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="11q-UM-f40" id="Tp5-hX-pc3">
|
||||
<rect key="frame" x="0.0" y="0.0" width="341" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Tabs" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="BdH-U9-Vcz">
|
||||
<rect key="frame" x="16" y="11.5" width="37" height="21"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="BdH-U9-Vcz" firstAttribute="centerY" secondItem="Tp5-hX-pc3" secondAttribute="centerY" id="OfE-gk-aMJ"/>
|
||||
<constraint firstItem="BdH-U9-Vcz" firstAttribute="leading" secondItem="Tp5-hX-pc3" secondAttribute="leadingMargin" id="dVK-2S-b6A"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
<segue destination="JJN-aw-37c" kind="show" id="6oX-43-R1z"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
</sections>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="oM9-mi-wRc" id="ubt-jB-z6P"/>
|
||||
@ -234,7 +261,26 @@
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Rkj-gt-dSt" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="18" y="537"/>
|
||||
<point key="canvasLocation" x="2" y="535"/>
|
||||
</scene>
|
||||
<!--Tabs-->
|
||||
<scene sceneID="D4Y-D0-S4g">
|
||||
<objects>
|
||||
<tableViewController id="JJN-aw-37c" customClass="TabsTableViewController" customModule="Tusker" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="M8r-EE-Z7d">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="JJN-aw-37c" id="dC9-LA-KZy"/>
|
||||
<outlet property="delegate" destination="JJN-aw-37c" id="6Zp-me-GOX"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title="Tabs" id="GwP-CQ-WwZ"/>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="8dk-2n-9cx" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1" y="1243"/>
|
||||
</scene>
|
||||
<!--Default Post Visibility-->
|
||||
<scene sceneID="z9g-ND-zkU">
|
||||
@ -273,7 +319,7 @@
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="JNY-yb-Efi" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="825" y="537"/>
|
||||
<point key="canvasLocation" x="825" y="535"/>
|
||||
</scene>
|
||||
<!--Advanced-->
|
||||
<scene sceneID="xgj-Fx-53j">
|
||||
@ -321,7 +367,7 @@
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="4wC-Hp-AZk" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1612" y="538"/>
|
||||
<point key="canvasLocation" x="1612" y="536"/>
|
||||
</scene>
|
||||
<!--Silent Actions-->
|
||||
<scene sceneID="Vyy-sh-Tca">
|
||||
|
92
Tusker/Screens/Preferences/TabsTableViewController.swift
Normal file
92
Tusker/Screens/Preferences/TabsTableViewController.swift
Normal file
@ -0,0 +1,92 @@
|
||||
//
|
||||
// TabsTableViewController.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 10/5/18.
|
||||
// Copyright © 2018 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class TabsTableViewController: UITableViewController {
|
||||
|
||||
var tabs: [(Tab, Bool)] = []
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
tableView.register(UINib(nibName: "TabTableViewCell", bundle: nil), forCellReuseIdentifier: "tabCell")
|
||||
|
||||
tabs = Preferences.shared.tabs.filter { $0.value >= 0 }.sorted(by: { $0.value < $1.value }).map { ($0.key, true) }
|
||||
tabs.append(contentsOf: Preferences.shared.tabs.filter { $0.value == -1 }.map { ($0.key, false) })
|
||||
|
||||
tableView.setEditing(true, animated: false)
|
||||
}
|
||||
|
||||
func updatePreferences() {
|
||||
var dict = [Tab: Int]()
|
||||
var maxIndex = 0
|
||||
for (tab, enabled) in tabs {
|
||||
if enabled {
|
||||
dict[tab] = maxIndex
|
||||
maxIndex += 1
|
||||
} else {
|
||||
dict[tab] = -1
|
||||
}
|
||||
}
|
||||
Preferences.shared.tabs = dict
|
||||
|
||||
guard let tabBarController = tabBarController as? MainTabBarViewController else { fatalError("Tab bar controller should be of type MainTabBarViewController") }
|
||||
tabBarController.updateTabs(animated: true)
|
||||
}
|
||||
|
||||
// MARK: - Table view data source
|
||||
|
||||
override func numberOfSections(in tableView: UITableView) -> Int {
|
||||
return 1
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return tabs.count
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
guard let cell = tableView.dequeueReusableCell(withIdentifier: "tabCell", for: indexPath) as? TabTableViewCell else { fatalError() }
|
||||
|
||||
let (tab, _) = tabs[indexPath.row]
|
||||
cell.updateUI(for: tab)
|
||||
cell.delegate = self
|
||||
|
||||
return cell
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
|
||||
return .none
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
|
||||
let tab = tabs.remove(at: sourceIndexPath.row)
|
||||
tabs.insert(tab, at: destinationIndexPath.row)
|
||||
updatePreferences()
|
||||
}
|
||||
|
||||
/*
|
||||
// MARK: - Navigation
|
||||
|
||||
// In a storyboard-based application, you will often want to do a little preparation before navigation
|
||||
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
||||
// Get the new view controller using segue.destination.
|
||||
// Pass the selected object to the new view controller.
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
extension TabsTableViewController: TabTableViewCellDelegate {
|
||||
func setEnabled(tab: Tab, enabled: Bool) {
|
||||
let index = tabs.firstIndex(where: { $0.0 == tab })!
|
||||
tabs[index] = (tab, enabled)
|
||||
updatePreferences()
|
||||
}
|
||||
}
|
||||
|
47
Tusker/Views/Tab/TabTableViewCell.swift
Normal file
47
Tusker/Views/Tab/TabTableViewCell.swift
Normal file
@ -0,0 +1,47 @@
|
||||
//
|
||||
// TabTableViewCell.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 10/5/18.
|
||||
// Copyright © 2018 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
protocol TabTableViewCellDelegate {
|
||||
func setEnabled(tab: Tab, enabled: Bool)
|
||||
}
|
||||
|
||||
class TabTableViewCell: UITableViewCell {
|
||||
|
||||
var delegate: TabTableViewCellDelegate?
|
||||
|
||||
@IBOutlet weak var nameLabel: UILabel!
|
||||
@IBOutlet weak var enabledSwitch: UISwitch!
|
||||
|
||||
var tab: Tab!
|
||||
|
||||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
|
||||
// compensate for inset created by table view editing mode even when no delete control shown
|
||||
nameLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: -20).isActive = true
|
||||
}
|
||||
|
||||
override func setSelected(_ selected: Bool, animated: Bool) {
|
||||
super.setSelected(selected, animated: animated)
|
||||
}
|
||||
|
||||
func updateUI(for tab: Tab) {
|
||||
self.tab = tab
|
||||
|
||||
enabledSwitch.isEnabled = tab != .preferences
|
||||
enabledSwitch.setOn(Preferences.shared.tabIndex(tab) >= 0, animated: false)
|
||||
nameLabel.text = tab.humanName
|
||||
}
|
||||
|
||||
@IBAction func enabledSwitchChanged(_ sender: Any) {
|
||||
delegate?.setEnabled(tab: tab, enabled: enabledSwitch.isOn)
|
||||
}
|
||||
|
||||
}
|
47
Tusker/Views/Tab/TabTableViewCell.xib
Normal file
47
Tusker/Views/Tab/TabTableViewCell.xib
Normal file
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.23.1" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.16.1"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" id="TY9-GT-fyh" customClass="TabTableViewCell" customModule="Tusker" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="TY9-GT-fyh" id="5RM-4m-Lba">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dsQ-ir-jly">
|
||||
<rect key="frame" x="16" y="11.5" width="45" height="21"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="gxP-eh-ANw">
|
||||
<rect key="frame" x="308" y="6.5" width="51" height="31"/>
|
||||
<connections>
|
||||
<action selector="enabledSwitchChanged:" destination="TY9-GT-fyh" eventType="valueChanged" id="MdE-f1-w07"/>
|
||||
</connections>
|
||||
</switch>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="dsQ-ir-jly" firstAttribute="centerY" secondItem="5RM-4m-Lba" secondAttribute="centerY" id="Azd-iZ-FmM"/>
|
||||
<constraint firstItem="gxP-eh-ANw" firstAttribute="centerY" secondItem="5RM-4m-Lba" secondAttribute="centerY" id="Ch4-Gf-4q2"/>
|
||||
<constraint firstItem="dsQ-ir-jly" firstAttribute="leading" secondItem="5RM-4m-Lba" secondAttribute="leadingMargin" placeholder="YES" id="HIe-Qg-Jkj"/>
|
||||
<constraint firstAttribute="trailing" secondItem="gxP-eh-ANw" secondAttribute="trailing" constant="18" id="P7D-Pk-13h"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
<outlet property="enabledSwitch" destination="gxP-eh-ANw" id="BP3-g2-HIV"/>
|
||||
<outlet property="nameLabel" destination="dsQ-ir-jly" id="G9F-tK-Xi3"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="-369" y="89"/>
|
||||
</tableViewCell>
|
||||
</objects>
|
||||
</document>
|
Loading…
x
Reference in New Issue
Block a user