mirror of
https://github.com/Ranchero-Software/NetNewsWire
synced 2025-08-12 06:26:36 +00:00
Move Account folder into Settings folder.
This commit is contained in:
810
iOS/Settings/Account/Account.storyboard
Normal file
810
iOS/Settings/Account/Account.storyboard
Normal file
@@ -0,0 +1,810 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
|
||||
<capability name="Named colors" minToolsVersion="9.0"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Modal Navigation Controller-->
|
||||
<scene sceneID="98f-PW-S1C">
|
||||
<objects>
|
||||
<navigationController storyboardIdentifier="LocalAccountNavigationViewController" id="TMY-HB-vAu" customClass="ModalNavigationController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="p8g-7e-3f4">
|
||||
<rect key="frame" x="0.0" y="48" width="414" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</navigationBar>
|
||||
<connections>
|
||||
<segue destination="vi3-jb-8XS" kind="relationship" relationship="rootViewController" id="dIe-7d-ZQX"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="6sV-68-OXu" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1880" y="-528"/>
|
||||
</scene>
|
||||
<!--Modal Navigation Controller-->
|
||||
<scene sceneID="6i4-ho-e4F">
|
||||
<objects>
|
||||
<navigationController storyboardIdentifier="FeedbinAccountNavigationViewController" id="sFg-MZ-PqJ" customClass="ModalNavigationController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="wq6-np-tNn">
|
||||
<rect key="frame" x="0.0" y="48" width="414" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</navigationBar>
|
||||
<connections>
|
||||
<segue destination="ECy-jg-Kyc" kind="relationship" relationship="rootViewController" id="usT-8C-GGf"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Lfz-4s-0Vn" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="3177" y="-528"/>
|
||||
</scene>
|
||||
<!--On My Device-->
|
||||
<scene sceneID="J93-FN-Yey">
|
||||
<objects>
|
||||
<tableViewController id="vi3-jb-8XS" customClass="LocalAccountViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="insetGrouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="YLa-nM-G7t">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<view key="tableFooterView" contentMode="scaleToFill" id="Vxr-5V-V6R">
|
||||
<rect key="frame" x="0.0" y="159" width="414" height="150"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Local accounts do not sync your feeds across devices." textAlignment="center" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5ce-ZL-glQ">
|
||||
<rect key="frame" x="20" y="8" width="373" height="14.5"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption1"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" systemColor="systemGroupedBackgroundColor"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="5ce-ZL-glQ" secondAttribute="trailing" constant="21" id="YLV-d0-1us"/>
|
||||
<constraint firstItem="5ce-ZL-glQ" firstAttribute="leading" secondItem="Vxr-5V-V6R" secondAttribute="leading" constant="20" symbolic="YES" id="dmE-Zi-5FR"/>
|
||||
<constraint firstItem="5ce-ZL-glQ" firstAttribute="top" secondItem="Vxr-5V-V6R" secondAttribute="top" constant="8" id="z4G-hO-VUE"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<sections>
|
||||
<tableViewSection id="TfM-Jc-Fr0">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="uFU-j6-qP1">
|
||||
<rect key="frame" x="20" y="18" width="374" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="uFU-j6-qP1" id="fr4-mL-3Yf">
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Name" textAlignment="natural" adjustsFontForContentSizeCategory="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="Yl1-R6-xZi">
|
||||
<rect key="frame" x="20" y="11" width="334" height="22"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<textInputTraits key="textInputTraits" autocapitalizationType="words"/>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="Yl1-R6-xZi" firstAttribute="leading" secondItem="fr4-mL-3Yf" secondAttribute="leading" constant="20" id="HJ4-VN-e9Y"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Yl1-R6-xZi" secondAttribute="trailing" constant="20" id="vbZ-dD-yZM"/>
|
||||
<constraint firstItem="Yl1-R6-xZi" firstAttribute="centerY" secondItem="fr4-mL-3Yf" secondAttribute="centerY" id="zsZ-z6-IFh"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
<tableViewSection id="Sgf-NV-3Di">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="pTk-WJ-j5h" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
|
||||
<rect key="frame" x="20" y="97.5" width="374" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="pTk-WJ-j5h" id="ahe-yz-PGg">
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mQv-3O-Y2d" customClass="VibrantButton" customModule="NetNewsWire" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="-0.5" width="374" height="44.5"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="44" id="EEL-8n-nHO"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<state key="normal" title="Add Account">
|
||||
<color key="titleColor" name="secondaryAccentColor"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="add:" destination="vi3-jb-8XS" eventType="touchUpInside" id="lCb-LW-xZ0"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="mQv-3O-Y2d" firstAttribute="centerY" secondItem="ahe-yz-PGg" secondAttribute="centerY" id="6bl-bA-qYE"/>
|
||||
<constraint firstItem="mQv-3O-Y2d" firstAttribute="leading" secondItem="ahe-yz-PGg" secondAttribute="leading" id="7gZ-8n-bWs"/>
|
||||
<constraint firstAttribute="trailing" secondItem="mQv-3O-Y2d" secondAttribute="trailing" id="FQu-yU-a4k"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
</sections>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="vi3-jb-8XS" id="U1Z-Kw-46j"/>
|
||||
<outlet property="delegate" destination="vi3-jb-8XS" id="4El-ci-jdg"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title="On My Device" id="AOA-LS-PIB">
|
||||
<barButtonItem key="leftBarButtonItem" systemItem="cancel" id="b2H-re-cgN">
|
||||
<connections>
|
||||
<action selector="cancel:" destination="vi3-jb-8XS" id="gRE-sR-r4Z"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
<connections>
|
||||
<outlet property="footerLabel" destination="5ce-ZL-glQ" id="V50-Yc-hD6"/>
|
||||
<outlet property="nameTextField" destination="Yl1-R6-xZi" id="jcl-vI-Rde"/>
|
||||
</connections>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="XJD-sO-MSq" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1879.7101449275365" y="144.64285714285714"/>
|
||||
</scene>
|
||||
<!--Feedbin-->
|
||||
<scene sceneID="IDj-HA-olN">
|
||||
<objects>
|
||||
<tableViewController id="ECy-jg-Kyc" customClass="FeedbinAccountViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="insetGrouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="Y0x-RC-7ln">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<view key="tableFooterView" contentMode="scaleToFill" id="3KO-DU-JXG">
|
||||
<rect key="frame" x="0.0" y="202.5" width="414" height="150"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sgL-0C-JZa">
|
||||
<rect key="frame" x="20" y="8" width="373" height="78.5"/>
|
||||
<string key="text">Sign in to your Feedbin account to sync your feeds across your devices. Your username and password will be encrypted and stored in Keychain.
|
||||
|
||||
Don’t have a Feedbin account?</string>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption1"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Xhf-bK-vzm">
|
||||
<rect key="frame" x="169.5" y="85" width="75" height="27"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption1"/>
|
||||
<state key="normal" title="Sign Up Here"/>
|
||||
<connections>
|
||||
<action selector="signUpWithProvider:" destination="ECy-jg-Kyc" eventType="touchUpInside" id="fIY-hq-q3H"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<color key="backgroundColor" systemColor="systemGroupedBackgroundColor"/>
|
||||
<constraints>
|
||||
<constraint firstItem="sgL-0C-JZa" firstAttribute="top" secondItem="3KO-DU-JXG" secondAttribute="top" constant="8" id="BgR-gH-qHf"/>
|
||||
<constraint firstItem="sgL-0C-JZa" firstAttribute="leading" secondItem="3KO-DU-JXG" secondAttribute="leading" constant="20" symbolic="YES" id="PLI-kz-MMq"/>
|
||||
<constraint firstItem="Xhf-bK-vzm" firstAttribute="top" secondItem="sgL-0C-JZa" secondAttribute="bottom" constant="-1.5" id="R9l-5y-aMr"/>
|
||||
<constraint firstAttribute="trailing" secondItem="sgL-0C-JZa" secondAttribute="trailing" constant="21" id="ddS-HE-f1J"/>
|
||||
<constraint firstItem="Xhf-bK-vzm" firstAttribute="centerX" secondItem="3KO-DU-JXG" secondAttribute="centerX" id="xs6-P4-4Vj"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<sections>
|
||||
<tableViewSection id="xBN-Pb-KAy">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="lsa-Fl-Pc7">
|
||||
<rect key="frame" x="20" y="18" width="374" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="lsa-Fl-Pc7" id="Lpd-D1-1PQ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Email" textAlignment="natural" adjustsFontForContentSizeCategory="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="vJa-NN-yjR">
|
||||
<rect key="frame" x="20" y="11" width="334" height="22"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<textInputTraits key="textInputTraits" spellCheckingType="no" keyboardType="emailAddress" textContentType="username"/>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="vJa-NN-yjR" secondAttribute="trailing" constant="20" id="7xY-Mz-Szf"/>
|
||||
<constraint firstItem="vJa-NN-yjR" firstAttribute="centerY" secondItem="Lpd-D1-1PQ" secondAttribute="centerY" id="E8M-nD-KIN"/>
|
||||
<constraint firstItem="vJa-NN-yjR" firstAttribute="leading" secondItem="Lpd-D1-1PQ" secondAttribute="leading" constant="20" id="Lgm-1L-4xL"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="Hwv-Q0-zT0">
|
||||
<rect key="frame" x="20" y="61.5" width="374" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Hwv-Q0-zT0" id="jIT-5L-d8d">
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Password" textAlignment="natural" adjustsFontForContentSizeCategory="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="YC2-RH-QoV">
|
||||
<rect key="frame" x="20" y="11.5" width="284" height="21"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<textInputTraits key="textInputTraits" secureTextEntry="YES" textContentType="password"/>
|
||||
</textField>
|
||||
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" pointerInteraction="YES" translatesAutoresizingMaskIntoConstraints="NO" id="TfW-wf-V06">
|
||||
<rect key="frame" x="312" y="5.5" width="42" height="33"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<state key="normal" title="Show"/>
|
||||
<connections>
|
||||
<action selector="showHidePassword:" destination="ECy-jg-Kyc" eventType="touchUpInside" id="QcS-lr-SPG"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="TfW-wf-V06" firstAttribute="leading" secondItem="YC2-RH-QoV" secondAttribute="trailing" constant="8" symbolic="YES" id="MHu-Ut-Kox"/>
|
||||
<constraint firstItem="TfW-wf-V06" firstAttribute="centerY" secondItem="jIT-5L-d8d" secondAttribute="centerY" id="O3Y-Jd-n9t"/>
|
||||
<constraint firstItem="YC2-RH-QoV" firstAttribute="leading" secondItem="jIT-5L-d8d" secondAttribute="leading" constant="20" id="W79-WW-Buk"/>
|
||||
<constraint firstItem="YC2-RH-QoV" firstAttribute="centerY" secondItem="jIT-5L-d8d" secondAttribute="centerY" id="iDt-ym-Qjf"/>
|
||||
<constraint firstAttribute="trailing" secondItem="TfW-wf-V06" secondAttribute="trailing" constant="20" symbolic="YES" id="rMZ-af-tPg"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
<tableViewSection id="Kkf-rn-qdv">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="hWd-EN-p7e">
|
||||
<rect key="frame" x="20" y="141" width="374" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="hWd-EN-p7e" id="S8S-1a-vVf">
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="gv7-yG-aE3" customClass="VibrantButton" customModule="NetNewsWire" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="-0.5" width="374" height="44.5"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="44" id="pt0-rn-0JI"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<state key="normal" title="Action">
|
||||
<color key="titleColor" name="secondaryAccentColor"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="action:" destination="ECy-jg-Kyc" eventType="touchUpInside" id="79h-R2-s0C"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="gv7-yG-aE3" firstAttribute="leading" secondItem="S8S-1a-vVf" secondAttribute="leading" id="cbE-1E-Mem"/>
|
||||
<constraint firstAttribute="trailing" secondItem="gv7-yG-aE3" secondAttribute="trailing" id="tQC-jk-evr"/>
|
||||
<constraint firstItem="gv7-yG-aE3" firstAttribute="centerY" secondItem="S8S-1a-vVf" secondAttribute="centerY" id="xSU-R7-XQ8"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
</sections>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="ECy-jg-Kyc" id="hUr-Xx-9Ho"/>
|
||||
<outlet property="delegate" destination="ECy-jg-Kyc" id="DKA-Lp-mNb"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title="Feedbin" id="tYg-9f-kyd">
|
||||
<barButtonItem key="leftBarButtonItem" systemItem="cancel" id="pfF-Of-5NT">
|
||||
<connections>
|
||||
<action selector="cancel:" destination="ECy-jg-Kyc" id="ZKI-gV-ylg"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
<barButtonItem key="rightBarButtonItem" id="Xwp-LO-qff">
|
||||
<view key="customView" contentMode="scaleToFill" id="cn4-b1-uZa">
|
||||
<rect key="frame" x="374" y="12" width="20" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" style="medium" translatesAutoresizingMaskIntoConstraints="NO" id="YvV-hB-lzT">
|
||||
<rect key="frame" x="36" y="6" width="20" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
</activityIndicatorView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</view>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
<connections>
|
||||
<outlet property="actionButton" destination="gv7-yG-aE3" id="ENc-5A-hQc"/>
|
||||
<outlet property="activityIndicator" destination="YvV-hB-lzT" id="n1F-tV-5ZV"/>
|
||||
<outlet property="cancelBarButtonItem" destination="pfF-Of-5NT" id="Zr3-qD-1Yi"/>
|
||||
<outlet property="emailTextField" destination="vJa-NN-yjR" id="nCF-9W-YsF"/>
|
||||
<outlet property="footerLabel" destination="sgL-0C-JZa" id="b6I-Mk-2K3"/>
|
||||
<outlet property="passwordTextField" destination="YC2-RH-QoV" id="qaX-0i-7jq"/>
|
||||
<outlet property="showHideButton" destination="TfW-wf-V06" id="PbL-67-Nrg"/>
|
||||
</connections>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="L24-0i-kyr" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="3177" y="145"/>
|
||||
</scene>
|
||||
<!--Modal Navigation Controller-->
|
||||
<scene sceneID="j4N-ax-exh">
|
||||
<objects>
|
||||
<navigationController storyboardIdentifier="NewsBlurAccountNavigationViewController" id="eE3-pu-HdL" customClass="ModalNavigationController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="Fsp-NG-hoR">
|
||||
<rect key="frame" x="0.0" y="48" width="414" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</navigationBar>
|
||||
<connections>
|
||||
<segue destination="Cge-ND-NpD" kind="relationship" relationship="rootViewController" id="1D5-CN-liN"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="8t3-0U-5vL" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="4562" y="-528"/>
|
||||
</scene>
|
||||
<!--NewsBlur-->
|
||||
<scene sceneID="tfA-kz-P6O">
|
||||
<objects>
|
||||
<tableViewController id="Cge-ND-NpD" customClass="NewsBlurAccountViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="insetGrouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="fLL-7i-HdK">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<view key="tableFooterView" contentMode="scaleToFill" id="mgO-Iq-dEg">
|
||||
<rect key="frame" x="0.0" y="202.5" width="414" height="150"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fal-e8-3BB">
|
||||
<rect key="frame" x="20" y="8" width="373" height="78.5"/>
|
||||
<string key="text">Sign in to your NewsBlur account to sync your feeds across your devices. Your username and password will be encrypted and stored in Keychain.
|
||||
|
||||
Don’t have a NewsBlur account?</string>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption1"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="YhB-G0-eeJ">
|
||||
<rect key="frame" x="169.5" y="85" width="75" height="27"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption1"/>
|
||||
<state key="normal" title="Sign Up Here"/>
|
||||
<connections>
|
||||
<action selector="signUpWithProvider:" destination="Cge-ND-NpD" eventType="touchUpInside" id="Vfz-DD-Kwm"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<color key="backgroundColor" systemColor="systemGroupedBackgroundColor"/>
|
||||
<constraints>
|
||||
<constraint firstItem="YhB-G0-eeJ" firstAttribute="centerX" secondItem="mgO-Iq-dEg" secondAttribute="centerX" id="7r5-l6-NNv"/>
|
||||
<constraint firstItem="fal-e8-3BB" firstAttribute="leading" secondItem="mgO-Iq-dEg" secondAttribute="leading" constant="20" symbolic="YES" id="O4q-GI-2AO"/>
|
||||
<constraint firstItem="YhB-G0-eeJ" firstAttribute="top" secondItem="fal-e8-3BB" secondAttribute="bottom" constant="-1.5" id="UHc-sh-Xq4"/>
|
||||
<constraint firstAttribute="trailing" secondItem="fal-e8-3BB" secondAttribute="trailing" constant="21" id="V0d-ny-GRE"/>
|
||||
<constraint firstItem="fal-e8-3BB" firstAttribute="top" secondItem="mgO-Iq-dEg" secondAttribute="top" constant="8" id="h5B-kg-rZj"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<sections>
|
||||
<tableViewSection id="I5T-12-2jC">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="gAY-Bo-c0L">
|
||||
<rect key="frame" x="20" y="18" width="374" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="gAY-Bo-c0L" id="mqD-6S-DIl">
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Username or Email" textAlignment="natural" adjustsFontForContentSizeCategory="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="S4v-fs-DIO">
|
||||
<rect key="frame" x="20" y="11" width="334" height="22"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<textInputTraits key="textInputTraits" spellCheckingType="no" keyboardType="emailAddress" textContentType="username"/>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="S4v-fs-DIO" secondAttribute="trailing" constant="20" id="Upe-dm-4DP"/>
|
||||
<constraint firstItem="S4v-fs-DIO" firstAttribute="leading" secondItem="mqD-6S-DIl" secondAttribute="leading" constant="20" id="pQc-Fh-6T3"/>
|
||||
<constraint firstItem="S4v-fs-DIO" firstAttribute="centerY" secondItem="mqD-6S-DIl" secondAttribute="centerY" id="s9a-ew-C5W"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="iCK-kn-Au6">
|
||||
<rect key="frame" x="20" y="61.5" width="374" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="iCK-kn-Au6" id="9Ej-wB-9Tr">
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Password" textAlignment="natural" adjustsFontForContentSizeCategory="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="fct-XR-fEa">
|
||||
<rect key="frame" x="20" y="11.5" width="284" height="21"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<textInputTraits key="textInputTraits" secureTextEntry="YES" textContentType="password"/>
|
||||
</textField>
|
||||
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="GY9-nr-jFb">
|
||||
<rect key="frame" x="312" y="5.5" width="42" height="33"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<state key="normal" title="Show"/>
|
||||
<connections>
|
||||
<action selector="showHidePassword:" destination="Cge-ND-NpD" eventType="touchUpInside" id="8JH-LX-URH"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="GY9-nr-jFb" firstAttribute="centerY" secondItem="9Ej-wB-9Tr" secondAttribute="centerY" id="3jf-KC-nd8"/>
|
||||
<constraint firstItem="GY9-nr-jFb" firstAttribute="leading" secondItem="fct-XR-fEa" secondAttribute="trailing" constant="8" symbolic="YES" id="Ibr-pt-eGr"/>
|
||||
<constraint firstAttribute="trailing" secondItem="GY9-nr-jFb" secondAttribute="trailing" constant="20" symbolic="YES" id="mcZ-cl-knP"/>
|
||||
<constraint firstItem="fct-XR-fEa" firstAttribute="leading" secondItem="9Ej-wB-9Tr" secondAttribute="leading" constant="20" id="u5f-tJ-8ce"/>
|
||||
<constraint firstItem="fct-XR-fEa" firstAttribute="centerY" secondItem="9Ej-wB-9Tr" secondAttribute="centerY" id="z5e-jg-0nm"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
<tableViewSection id="L37-iZ-GVj">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="fyQ-K8-byV">
|
||||
<rect key="frame" x="20" y="141" width="374" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="fyQ-K8-byV" id="CtR-ZJ-FG5">
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="E1I-C4-JdL" customClass="VibrantButton" customModule="NetNewsWire" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="-0.5" width="374" height="44.5"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="44" id="yoo-36-msf"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<state key="normal" title="Action">
|
||||
<color key="titleColor" name="secondaryAccentColor"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="action:" destination="Cge-ND-NpD" eventType="touchUpInside" id="YQw-1k-e8G"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="E1I-C4-JdL" firstAttribute="centerY" secondItem="CtR-ZJ-FG5" secondAttribute="centerY" id="2vc-Ys-4Cj"/>
|
||||
<constraint firstAttribute="trailing" secondItem="E1I-C4-JdL" secondAttribute="trailing" id="SLX-wc-QR7"/>
|
||||
<constraint firstItem="E1I-C4-JdL" firstAttribute="leading" secondItem="CtR-ZJ-FG5" secondAttribute="leading" id="Veu-Wo-GSZ"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
</sections>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="Cge-ND-NpD" id="u8B-p4-Vlv"/>
|
||||
<outlet property="delegate" destination="Cge-ND-NpD" id="RIw-V2-EJC"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title="NewsBlur" id="jCQ-pH-6AD">
|
||||
<barButtonItem key="leftBarButtonItem" systemItem="cancel" id="bl6-Y1-wQ8">
|
||||
<connections>
|
||||
<action selector="cancel:" destination="Cge-ND-NpD" id="9zR-LJ-IWk"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
<barButtonItem key="rightBarButtonItem" id="4yi-H0-B9J">
|
||||
<view key="customView" contentMode="scaleToFill" id="8DU-L0-P6c">
|
||||
<rect key="frame" x="374" y="12" width="20" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" style="medium" translatesAutoresizingMaskIntoConstraints="NO" id="HfW-jV-MjK">
|
||||
<rect key="frame" x="36" y="6" width="20" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
</activityIndicatorView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</view>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
<connections>
|
||||
<outlet property="actionButton" destination="E1I-C4-JdL" id="q2T-4o-c8i"/>
|
||||
<outlet property="activityIndicator" destination="HfW-jV-MjK" id="AIV-uG-9uC"/>
|
||||
<outlet property="cancelBarButtonItem" destination="bl6-Y1-wQ8" id="ohR-gW-5J2"/>
|
||||
<outlet property="footerLabel" destination="fal-e8-3BB" id="7Fq-Oz-aEx"/>
|
||||
<outlet property="passwordTextField" destination="fct-XR-fEa" id="fGL-4k-gZ6"/>
|
||||
<outlet property="showHideButton" destination="GY9-nr-jFb" id="1p9-9F-GMY"/>
|
||||
<outlet property="usernameTextField" destination="S4v-fs-DIO" id="B7I-yz-M0T"/>
|
||||
</connections>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="8Ku-6P-yPg" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="4561" y="145"/>
|
||||
</scene>
|
||||
<!--Reader-->
|
||||
<scene sceneID="3fU-9I-RDp">
|
||||
<objects>
|
||||
<tableViewController id="MzG-hS-TpF" customClass="ReaderAPIAccountViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="insetGrouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="bQC-XA-xWP">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<view key="tableFooterView" contentMode="scaleToFill" id="6sa-hD-iAT">
|
||||
<rect key="frame" x="0.0" y="246" width="414" height="150"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7Jj-p8-lYw">
|
||||
<rect key="frame" x="20" y="8" width="373" height="46.5"/>
|
||||
<string key="text">Use your Reader account to sync your feeds across your devices.
|
||||
|
||||
Don’t have a Reader account?</string>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption1"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="3Fq-U4-PS5">
|
||||
<rect key="frame" x="169.5" y="53" width="75" height="27"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption1"/>
|
||||
<state key="normal" title="Sign Up Here"/>
|
||||
<connections>
|
||||
<action selector="signUpWithProvider:" destination="MzG-hS-TpF" eventType="touchUpInside" id="pMC-f8-E4G"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<color key="backgroundColor" systemColor="systemGroupedBackgroundColor"/>
|
||||
<constraints>
|
||||
<constraint firstItem="3Fq-U4-PS5" firstAttribute="top" secondItem="7Jj-p8-lYw" secondAttribute="bottom" constant="-1.5" id="6ma-pw-DSZ"/>
|
||||
<constraint firstItem="7Jj-p8-lYw" firstAttribute="leading" secondItem="6sa-hD-iAT" secondAttribute="leading" constant="20" symbolic="YES" id="CnY-UA-F3a"/>
|
||||
<constraint firstItem="3Fq-U4-PS5" firstAttribute="centerX" secondItem="6sa-hD-iAT" secondAttribute="centerX" id="Rgg-oG-KOZ"/>
|
||||
<constraint firstAttribute="trailing" secondItem="7Jj-p8-lYw" secondAttribute="trailing" constant="21" id="mgT-t6-6c8"/>
|
||||
<constraint firstItem="7Jj-p8-lYw" firstAttribute="top" secondItem="6sa-hD-iAT" secondAttribute="top" constant="8" id="syN-5x-dbM"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<sections>
|
||||
<tableViewSection id="Rju-xt-yUY">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="kW8-SV-Byq">
|
||||
<rect key="frame" x="20" y="18" width="374" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="kW8-SV-Byq" id="4mV-Au-W6t">
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Username or Email" textAlignment="natural" adjustsFontForContentSizeCategory="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="CZg-x8-936">
|
||||
<rect key="frame" x="14" y="11" width="347" height="22"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<textInputTraits key="textInputTraits" spellCheckingType="no" keyboardType="emailAddress" textContentType="username"/>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="CZg-x8-936" secondAttribute="trailing" constant="13" id="7BW-D6-ZAW"/>
|
||||
<constraint firstItem="CZg-x8-936" firstAttribute="centerY" secondItem="4mV-Au-W6t" secondAttribute="centerY" id="Fii-Qu-oXf"/>
|
||||
<constraint firstItem="CZg-x8-936" firstAttribute="leading" secondItem="4mV-Au-W6t" secondAttribute="leading" constant="14" id="MKL-Nm-1Po"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="pNe-n6-tVf">
|
||||
<rect key="frame" x="20" y="61.5" width="374" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="pNe-n6-tVf" id="yQJ-L0-qVZ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Password" textAlignment="natural" adjustsFontForContentSizeCategory="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="KgN-kQ-Cyc">
|
||||
<rect key="frame" x="14" y="11.5" width="294" height="21"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<textInputTraits key="textInputTraits" secureTextEntry="YES" textContentType="password"/>
|
||||
</textField>
|
||||
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="cFF-qt-WLs">
|
||||
<rect key="frame" x="316" y="5.5" width="42" height="33"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<state key="normal" title="Show"/>
|
||||
<connections>
|
||||
<action selector="showHidePassword:" destination="MzG-hS-TpF" eventType="touchUpInside" id="IsF-iJ-oxT"/>
|
||||
<action selector="showHidePassword:" destination="Cge-ND-NpD" eventType="touchUpInside" id="b9p-LX-Wk7"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="cFF-qt-WLs" firstAttribute="leading" secondItem="KgN-kQ-Cyc" secondAttribute="trailing" constant="8" symbolic="YES" id="Cwh-XX-m2G"/>
|
||||
<constraint firstItem="cFF-qt-WLs" firstAttribute="centerY" secondItem="yQJ-L0-qVZ" secondAttribute="centerY" id="GDc-9f-afL"/>
|
||||
<constraint firstAttribute="trailing" secondItem="cFF-qt-WLs" secondAttribute="trailing" constant="16" id="K93-X3-UuK"/>
|
||||
<constraint firstItem="KgN-kQ-Cyc" firstAttribute="centerY" secondItem="yQJ-L0-qVZ" secondAttribute="centerY" id="UpQ-pU-DYv"/>
|
||||
<constraint firstItem="KgN-kQ-Cyc" firstAttribute="leading" secondItem="yQJ-L0-qVZ" secondAttribute="leading" constant="14" id="fam-16-kf6"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="mCx-af-pd3">
|
||||
<rect key="frame" x="20" y="105" width="374" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="mCx-af-pd3" id="o1U-Qv-4gz">
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="API URL" textAlignment="natural" adjustsFontForContentSizeCategory="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="iPv-M2-U8Q">
|
||||
<rect key="frame" x="14" y="11" width="340" height="22"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="URL" smartDashesType="no" smartInsertDeleteType="no" smartQuotesType="no" textContentType="url"/>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="iPv-M2-U8Q" firstAttribute="leading" secondItem="o1U-Qv-4gz" secondAttribute="leading" constant="14" id="4UP-GO-kmh"/>
|
||||
<constraint firstItem="iPv-M2-U8Q" firstAttribute="top" secondItem="o1U-Qv-4gz" secondAttribute="topMargin" id="Gap-aN-LP7"/>
|
||||
<constraint firstItem="iPv-M2-U8Q" firstAttribute="trailing" secondItem="o1U-Qv-4gz" secondAttribute="trailingMargin" id="npR-r8-mpF"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
<tableViewSection id="UWZ-Vu-0Pp">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" rowHeight="43.5" id="d3E-Ds-Thm">
|
||||
<rect key="frame" x="20" y="184.5" width="374" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="d3E-Ds-Thm" id="Frb-uH-Sff">
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="7L9-X7-1Oc">
|
||||
<rect key="frame" x="0.0" y="-0.5" width="374" height="44.5"/>
|
||||
<state key="normal" title="Action"/>
|
||||
<connections>
|
||||
<action selector="action:" destination="MzG-hS-TpF" eventType="touchUpInside" id="d10-4f-ZUn"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="7L9-X7-1Oc" firstAttribute="centerY" secondItem="Frb-uH-Sff" secondAttribute="centerY" id="NVm-XD-zND"/>
|
||||
<constraint firstItem="7L9-X7-1Oc" firstAttribute="centerX" secondItem="Frb-uH-Sff" secondAttribute="centerX" id="YB9-O8-Z15"/>
|
||||
<constraint firstItem="7L9-X7-1Oc" firstAttribute="height" secondItem="Frb-uH-Sff" secondAttribute="height" multiplier="0.689655" constant="13.999999999999996" id="iNV-NE-jhW"/>
|
||||
<constraint firstItem="7L9-X7-1Oc" firstAttribute="width" secondItem="Frb-uH-Sff" secondAttribute="width" multiplier="0.893048" constant="40" id="lfQ-KQ-9nR"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
</sections>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="MzG-hS-TpF" id="QvG-cd-Q3P"/>
|
||||
<outlet property="delegate" destination="MzG-hS-TpF" id="o4Z-RV-8uW"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title="Reader" id="z3N-XM-EXU">
|
||||
<barButtonItem key="leftBarButtonItem" title="Cancel" id="n8H-ai-4Df">
|
||||
<connections>
|
||||
<action selector="cancel:" destination="MzG-hS-TpF" id="a49-Fh-i1S"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
<barButtonItem key="rightBarButtonItem" id="Ih6-jI-jFg">
|
||||
<view key="customView" contentMode="scaleToFill" id="gSl-PT-7DH">
|
||||
<rect key="frame" x="374" y="12" width="20" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" style="medium" translatesAutoresizingMaskIntoConstraints="NO" id="pdn-6v-d9a">
|
||||
<rect key="frame" x="36" y="6" width="20" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
</activityIndicatorView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</view>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
<connections>
|
||||
<outlet property="actionButton" destination="7L9-X7-1Oc" id="VnP-sl-Cmd"/>
|
||||
<outlet property="activityIndicator" destination="pdn-6v-d9a" id="vgt-C6-fy6"/>
|
||||
<outlet property="apiURLTextField" destination="iPv-M2-U8Q" id="8kn-Xk-a8w"/>
|
||||
<outlet property="cancelBarButtonItem" destination="n8H-ai-4Df" id="u86-HH-HYC"/>
|
||||
<outlet property="footerLabel" destination="7Jj-p8-lYw" id="Tqv-qR-WBR"/>
|
||||
<outlet property="passwordTextField" destination="KgN-kQ-Cyc" id="A0K-JL-CEW"/>
|
||||
<outlet property="showHideButton" destination="cFF-qt-WLs" id="AxI-Gl-NdM"/>
|
||||
<outlet property="signUpButton" destination="3Fq-U4-PS5" id="Wuj-5g-vDH"/>
|
||||
<outlet property="usernameTextField" destination="CZg-x8-936" id="nUT-WL-fKD"/>
|
||||
</connections>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Fj8-E0-Aeh" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="5260.8695652173919" y="144.64285714285714"/>
|
||||
</scene>
|
||||
<!--Modal Navigation Controller-->
|
||||
<scene sceneID="gfi-2F-rht">
|
||||
<objects>
|
||||
<navigationController storyboardIdentifier="CloudKitAccountNavigationViewController" id="LhW-Dq-qqj" customClass="ModalNavigationController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="MVG-BZ-ALL">
|
||||
<rect key="frame" x="0.0" y="48" width="414" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</navigationBar>
|
||||
<connections>
|
||||
<segue destination="qj9-Vr-VIU" kind="relationship" relationship="rootViewController" id="n8n-iF-qeC"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="z9f-5I-8GC" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="2533" y="-528"/>
|
||||
</scene>
|
||||
<!--iCloud-->
|
||||
<scene sceneID="ULt-VE-viU">
|
||||
<objects>
|
||||
<tableViewController id="qj9-Vr-VIU" customClass="CloudKitAccountViewController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="insetGrouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="j6U-sh-M9y">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<view key="tableFooterView" contentMode="scaleToFill" id="iYz-ri-yys">
|
||||
<rect key="frame" x="0.0" y="79.5" width="414" height="150"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Your iCloud account syncs your feeds across your Mac and iOS devices" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="aFS-Y0-2MH">
|
||||
<rect key="frame" x="20" y="8" width="373" height="42.5"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="vXG-7q-4qg">
|
||||
<rect key="frame" x="75" y="50.5" width="264" height="30"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleSubhead"/>
|
||||
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
|
||||
<state key="normal" title="iCloud Syncing Limitations & Solutions"/>
|
||||
<connections>
|
||||
<action selector="openLimitationsAndSolutions:" destination="qj9-Vr-VIU" eventType="touchUpInside" id="JZ5-hQ-PLl"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<color key="backgroundColor" systemColor="systemGroupedBackgroundColor"/>
|
||||
<constraints>
|
||||
<constraint firstItem="vXG-7q-4qg" firstAttribute="centerX" secondItem="iYz-ri-yys" secondAttribute="centerX" id="8Pg-BU-zIj"/>
|
||||
<constraint firstItem="aFS-Y0-2MH" firstAttribute="leading" secondItem="iYz-ri-yys" secondAttribute="leading" constant="20" symbolic="YES" id="E97-lo-arw"/>
|
||||
<constraint firstItem="vXG-7q-4qg" firstAttribute="top" secondItem="aFS-Y0-2MH" secondAttribute="bottom" id="TEh-B3-9Ci"/>
|
||||
<constraint firstAttribute="trailing" secondItem="aFS-Y0-2MH" secondAttribute="trailing" constant="21" id="XUo-oQ-MbK"/>
|
||||
<constraint firstItem="aFS-Y0-2MH" firstAttribute="top" secondItem="iYz-ri-yys" secondAttribute="top" constant="8" id="xpj-LW-4l7"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<sections>
|
||||
<tableViewSection id="bGn-Io-KuQ">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="FSY-KL-m3i" customClass="VibrantTableViewCell" customModule="NetNewsWire" customModuleProvider="target">
|
||||
<rect key="frame" x="20" y="18" width="374" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="FSY-KL-m3i" id="ds7-ib-VgJ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="T1S-zH-rIp" customClass="VibrantButton" customModule="NetNewsWire" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="-0.5" width="374" height="44.5"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="44" id="dOv-Gz-h7s"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<state key="normal" title="Use iCloud">
|
||||
<color key="titleColor" name="secondaryAccentColor"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="add:" destination="qj9-Vr-VIU" eventType="touchUpInside" id="kUm-lW-g62"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="T1S-zH-rIp" firstAttribute="leading" secondItem="ds7-ib-VgJ" secondAttribute="leading" id="7F5-Ym-ew3"/>
|
||||
<constraint firstAttribute="trailing" secondItem="T1S-zH-rIp" secondAttribute="trailing" id="ON3-nQ-kd8"/>
|
||||
<constraint firstItem="T1S-zH-rIp" firstAttribute="centerY" secondItem="ds7-ib-VgJ" secondAttribute="centerY" id="dAM-F2-peY"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
</sections>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="qj9-Vr-VIU" id="j7u-Yd-rbe"/>
|
||||
<outlet property="delegate" destination="qj9-Vr-VIU" id="NhE-Pt-JGp"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title="iCloud" id="idp-kp-cGU">
|
||||
<barButtonItem key="leftBarButtonItem" systemItem="cancel" id="hKZ-OI-mTV">
|
||||
<connections>
|
||||
<action selector="cancel:" destination="qj9-Vr-VIU" id="n5q-9M-3ME"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
<connections>
|
||||
<outlet property="footerLabel" destination="aFS-Y0-2MH" id="gDw-R1-HSK"/>
|
||||
</connections>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="weY-OS-9NV" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="2533" y="145"/>
|
||||
</scene>
|
||||
<!--Modal Navigation Controller-->
|
||||
<scene sceneID="JBz-7C-wEc">
|
||||
<objects>
|
||||
<navigationController storyboardIdentifier="ReaderAPIAccountNavigationViewController" id="Son-xT-GLx" customClass="ModalNavigationController" customModule="NetNewsWire" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="sdL-X8-E6K">
|
||||
<rect key="frame" x="0.0" y="48" width="414" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</navigationBar>
|
||||
<connections>
|
||||
<segue destination="MzG-hS-TpF" kind="relationship" relationship="rootViewController" id="gsQ-9o-AMJ"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="vls-xO-YVi" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="5261" y="-528"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<namedColor name="secondaryAccentColor">
|
||||
<color red="0.031372549019607843" green="0.41568627450980394" blue="0.93333333333333335" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</namedColor>
|
||||
<systemColor name="secondaryLabelColor">
|
||||
<color red="0.23529411764705882" green="0.23529411764705882" blue="0.2627450980392157" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemGroupedBackgroundColor">
|
||||
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
||||
72
iOS/Settings/Account/CloudKitAccountViewController.swift
Normal file
72
iOS/Settings/Account/CloudKitAccountViewController.swift
Normal file
@@ -0,0 +1,72 @@
|
||||
//
|
||||
// CloudKitAccountViewController.swift
|
||||
// NetNewsWire-iOS
|
||||
//
|
||||
// Created by Maurice Parker on 3/28/20.
|
||||
// Copyright © 2020 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import SafariServices
|
||||
import Account
|
||||
|
||||
enum CloudKitAccountViewControllerError: LocalizedError {
|
||||
case iCloudDriveMissing
|
||||
|
||||
var errorDescription: String? {
|
||||
return NSLocalizedString("Unable to add iCloud Account. Please make sure you have iCloud and iCloud Drive enabled in System Settings.", comment: "Unable to add iCloud Account.")
|
||||
}
|
||||
}
|
||||
|
||||
final class CloudKitAccountViewController: UITableViewController {
|
||||
|
||||
weak var delegate: AddAccountDismissDelegate?
|
||||
@IBOutlet weak var footerLabel: UILabel!
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
setupFooter()
|
||||
|
||||
tableView.register(ImageHeaderView.self, forHeaderFooterViewReuseIdentifier: "SectionHeader")
|
||||
}
|
||||
|
||||
private func setupFooter() {
|
||||
footerLabel.text = NSLocalizedString("NetNewsWire will use your iCloud account to sync your subscriptions across your Mac and iOS devices.", comment: "iCloud")
|
||||
}
|
||||
|
||||
@IBAction func cancel(_ sender: Any) {
|
||||
dismiss(animated: true, completion: nil)
|
||||
delegate?.dismiss()
|
||||
}
|
||||
|
||||
@IBAction func add(_ sender: Any) {
|
||||
guard FileManager.default.ubiquityIdentityToken != nil else {
|
||||
presentError(CloudKitAccountViewControllerError.iCloudDriveMissing)
|
||||
return
|
||||
}
|
||||
|
||||
_ = AccountManager.shared.createAccount(type: .cloudKit)
|
||||
dismiss(animated: true, completion: nil)
|
||||
delegate?.dismiss()
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
|
||||
return section == 0 ? ImageHeaderView.rowHeight : super.tableView(tableView, heightForHeaderInSection: section)
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
|
||||
if section == 0 {
|
||||
let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "SectionHeader") as! ImageHeaderView
|
||||
headerView.imageView.image = AppImage.account(.cloudKit)
|
||||
return headerView
|
||||
} else {
|
||||
return super.tableView(tableView, viewForHeaderInSection: section)
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func openLimitationsAndSolutions(_ sender: Any) {
|
||||
let vc = SFSafariViewController(url: CloudKitWebDocumentation.limitationsAndSolutionsURL)
|
||||
vc.modalPresentationStyle = .pageSheet
|
||||
present(vc, animated: true)
|
||||
}
|
||||
}
|
||||
187
iOS/Settings/Account/FeedbinAccountViewController.swift
Normal file
187
iOS/Settings/Account/FeedbinAccountViewController.swift
Normal file
@@ -0,0 +1,187 @@
|
||||
//
|
||||
// FeedbinAccountViewController.swift
|
||||
// NetNewsWire-iOS
|
||||
//
|
||||
// Created by Maurice Parker on 5/19/19.
|
||||
// Copyright © 2019 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Account
|
||||
import Secrets
|
||||
import RSWeb
|
||||
import SafariServices
|
||||
|
||||
final class FeedbinAccountViewController: UITableViewController {
|
||||
|
||||
@IBOutlet weak var activityIndicator: UIActivityIndicatorView!
|
||||
@IBOutlet weak var cancelBarButtonItem: UIBarButtonItem!
|
||||
@IBOutlet weak var emailTextField: UITextField!
|
||||
@IBOutlet weak var passwordTextField: UITextField!
|
||||
@IBOutlet weak var showHideButton: UIButton!
|
||||
@IBOutlet weak var actionButton: UIButton!
|
||||
@IBOutlet weak var footerLabel: UILabel!
|
||||
|
||||
weak var account: Account?
|
||||
weak var delegate: AddAccountDismissDelegate?
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
setupFooter()
|
||||
|
||||
activityIndicator.isHidden = true
|
||||
emailTextField.delegate = self
|
||||
passwordTextField.delegate = self
|
||||
|
||||
if let account = account, let credentials = try? account.retrieveCredentials(type: .basic) {
|
||||
actionButton.setTitle(NSLocalizedString("Update Credentials", comment: "Update Credentials"), for: .normal)
|
||||
actionButton.isEnabled = true
|
||||
emailTextField.text = credentials.username
|
||||
passwordTextField.text = credentials.secret
|
||||
} else {
|
||||
actionButton.setTitle(NSLocalizedString("Add Account", comment: "Add Account"), for: .normal)
|
||||
}
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(textDidChange(_:)), name: UITextField.textDidChangeNotification, object: emailTextField)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(textDidChange(_:)), name: UITextField.textDidChangeNotification, object: passwordTextField)
|
||||
|
||||
tableView.register(ImageHeaderView.self, forHeaderFooterViewReuseIdentifier: "SectionHeader")
|
||||
}
|
||||
|
||||
private func setupFooter() {
|
||||
footerLabel.text = NSLocalizedString("Sign in to your Feedbin account and sync your feeds across your devices. Your username and password will be encrypted and stored in Keychain.\n\nDon’t have a Feedbin account?", comment: "Feedbin")
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
|
||||
return section == 0 ? ImageHeaderView.rowHeight : super.tableView(tableView, heightForHeaderInSection: section)
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
|
||||
if section == 0 {
|
||||
let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "SectionHeader") as! ImageHeaderView
|
||||
headerView.imageView.image = AppImage.account(.feedbin)
|
||||
return headerView
|
||||
} else {
|
||||
return super.tableView(tableView, viewForHeaderInSection: section)
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func cancel(_ sender: Any) {
|
||||
dismiss(animated: true, completion: nil)
|
||||
}
|
||||
|
||||
@IBAction func showHidePassword(_ sender: Any) {
|
||||
if passwordTextField.isSecureTextEntry {
|
||||
passwordTextField.isSecureTextEntry = false
|
||||
showHideButton.setTitle("Hide", for: .normal)
|
||||
} else {
|
||||
passwordTextField.isSecureTextEntry = true
|
||||
showHideButton.setTitle("Show", for: .normal)
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func action(_ sender: Any) {
|
||||
guard let email = emailTextField.text, let password = passwordTextField.text else {
|
||||
showError(NSLocalizedString("Username & password required.", comment: "Credentials Error"))
|
||||
return
|
||||
}
|
||||
|
||||
// When you fill in the email address via auto-complete it adds extra whitespace
|
||||
let trimmedEmail = email.trimmingCharacters(in: .whitespaces)
|
||||
|
||||
guard account != nil || !AccountManager.shared.duplicateServiceAccount(type: .feedbin, username: trimmedEmail) else {
|
||||
showError(NSLocalizedString("There is already a Feedbin account with that username created.", comment: "Duplicate Error"))
|
||||
return
|
||||
}
|
||||
|
||||
resignFirstResponder()
|
||||
toggleActivityIndicatorAnimation(visible: true)
|
||||
setNavigationEnabled(to: false)
|
||||
|
||||
let credentials = Credentials(type: .basic, username: trimmedEmail, secret: password)
|
||||
Account.validateCredentials(type: .feedbin, credentials: credentials) { result in
|
||||
self.toggleActivityIndicatorAnimation(visible: false)
|
||||
self.setNavigationEnabled(to: true)
|
||||
|
||||
switch result {
|
||||
case .success(let credentials):
|
||||
if let credentials = credentials {
|
||||
if self.account == nil {
|
||||
self.account = AccountManager.shared.createAccount(type: .feedbin)
|
||||
}
|
||||
|
||||
do {
|
||||
|
||||
do {
|
||||
try self.account?.removeCredentials(type: .basic)
|
||||
} catch {}
|
||||
try self.account?.storeCredentials(credentials)
|
||||
|
||||
self.account?.refreshAll { result in
|
||||
switch result {
|
||||
case .success:
|
||||
break
|
||||
case .failure(let error):
|
||||
self.presentError(error)
|
||||
}
|
||||
}
|
||||
|
||||
self.dismiss(animated: true, completion: nil)
|
||||
self.delegate?.dismiss()
|
||||
} catch {
|
||||
self.showError(NSLocalizedString("Keychain error while storing credentials.", comment: "Credentials Error"))
|
||||
}
|
||||
} else {
|
||||
self.showError(NSLocalizedString("Invalid email/password combination.", comment: "Credentials Error"))
|
||||
}
|
||||
case .failure:
|
||||
self.showError(NSLocalizedString("Network error. Try again later.", comment: "Credentials Error"))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func signUpWithProvider(_ sender: Any) {
|
||||
let url = URL(string: "https://feedbin.com/signup")!
|
||||
let safari = SFSafariViewController(url: url)
|
||||
safari.modalPresentationStyle = .currentContext
|
||||
self.present(safari, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
@objc func textDidChange(_ note: Notification) {
|
||||
actionButton.isEnabled = !(emailTextField.text?.isEmpty ?? false) && !(passwordTextField.text?.isEmpty ?? false)
|
||||
}
|
||||
|
||||
private func showError(_ message: String) {
|
||||
presentError(title: NSLocalizedString("Error", comment: "Credentials Error"), message: message)
|
||||
}
|
||||
|
||||
private func setNavigationEnabled(to value: Bool) {
|
||||
cancelBarButtonItem.isEnabled = value
|
||||
actionButton.isEnabled = value
|
||||
}
|
||||
|
||||
private func toggleActivityIndicatorAnimation(visible value: Bool) {
|
||||
activityIndicator.isHidden = !value
|
||||
if value {
|
||||
activityIndicator.startAnimating()
|
||||
} else {
|
||||
activityIndicator.stopAnimating()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension FeedbinAccountViewController: UITextFieldDelegate {
|
||||
|
||||
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
||||
if textField == emailTextField {
|
||||
passwordTextField.becomeFirstResponder()
|
||||
} else {
|
||||
textField.resignFirstResponder()
|
||||
action(self)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
65
iOS/Settings/Account/LocalAccountViewController.swift
Normal file
65
iOS/Settings/Account/LocalAccountViewController.swift
Normal file
@@ -0,0 +1,65 @@
|
||||
//
|
||||
// LocalAccountViewController.swift
|
||||
// NetNewsWire-iOS
|
||||
//
|
||||
// Created by Maurice Parker on 5/19/19.
|
||||
// Copyright © 2019 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Account
|
||||
|
||||
final class LocalAccountViewController: UITableViewController {
|
||||
|
||||
@IBOutlet weak var nameTextField: UITextField!
|
||||
@IBOutlet weak var footerLabel: UILabel!
|
||||
|
||||
weak var delegate: AddAccountDismissDelegate?
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
setupFooter()
|
||||
navigationItem.title = Account.defaultLocalAccountName
|
||||
nameTextField.delegate = self
|
||||
tableView.register(ImageHeaderView.self, forHeaderFooterViewReuseIdentifier: "SectionHeader")
|
||||
}
|
||||
|
||||
private func setupFooter() {
|
||||
footerLabel.text = NSLocalizedString("Local accounts do not sync your feeds across devices.", comment: "Local")
|
||||
}
|
||||
|
||||
@IBAction func cancel(_ sender: Any) {
|
||||
dismiss(animated: true, completion: nil)
|
||||
}
|
||||
|
||||
@IBAction func add(_ sender: Any) {
|
||||
let account = AccountManager.shared.createAccount(type: .onMyMac)
|
||||
account.name = nameTextField.text
|
||||
dismiss(animated: true, completion: nil)
|
||||
delegate?.dismiss()
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
|
||||
return section == 0 ? ImageHeaderView.rowHeight : super.tableView(tableView, heightForHeaderInSection: section)
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
|
||||
if section == 0 {
|
||||
let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "SectionHeader") as! ImageHeaderView
|
||||
headerView.imageView.image = AppImage.account(.onMyMac)
|
||||
return headerView
|
||||
} else {
|
||||
return super.tableView(tableView, viewForHeaderInSection: section)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension LocalAccountViewController: UITextFieldDelegate {
|
||||
|
||||
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
||||
textField.resignFirstResponder()
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
193
iOS/Settings/Account/NewsBlurAccountViewController.swift
Normal file
193
iOS/Settings/Account/NewsBlurAccountViewController.swift
Normal file
@@ -0,0 +1,193 @@
|
||||
//
|
||||
// NewsBlurAccountViewController.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Anh-Quang Do on 3/9/20.
|
||||
// Copyright (c) 2020 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Account
|
||||
import Secrets
|
||||
import RSWeb
|
||||
import SafariServices
|
||||
|
||||
final class NewsBlurAccountViewController: UITableViewController {
|
||||
|
||||
@IBOutlet weak var activityIndicator: UIActivityIndicatorView!
|
||||
@IBOutlet weak var cancelBarButtonItem: UIBarButtonItem!
|
||||
@IBOutlet weak var usernameTextField: UITextField!
|
||||
@IBOutlet weak var passwordTextField: UITextField!
|
||||
@IBOutlet weak var showHideButton: UIButton!
|
||||
@IBOutlet weak var actionButton: UIButton!
|
||||
@IBOutlet weak var footerLabel: UILabel!
|
||||
|
||||
weak var account: Account?
|
||||
weak var delegate: AddAccountDismissDelegate?
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
setupFooter()
|
||||
activityIndicator.isHidden = true
|
||||
usernameTextField.delegate = self
|
||||
passwordTextField.delegate = self
|
||||
|
||||
if let account = account, let credentials = try? account.retrieveCredentials(type: .newsBlurBasic) {
|
||||
actionButton.setTitle(NSLocalizedString("Update Credentials", comment: "Update Credentials"), for: .normal)
|
||||
actionButton.isEnabled = true
|
||||
usernameTextField.text = credentials.username
|
||||
passwordTextField.text = credentials.secret
|
||||
} else {
|
||||
actionButton.setTitle(NSLocalizedString("Add Account", comment: "Add Account"), for: .normal)
|
||||
}
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(textDidChange(_:)), name: UITextField.textDidChangeNotification, object: usernameTextField)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(textDidChange(_:)), name: UITextField.textDidChangeNotification, object: passwordTextField)
|
||||
|
||||
tableView.register(ImageHeaderView.self, forHeaderFooterViewReuseIdentifier: "SectionHeader")
|
||||
}
|
||||
|
||||
private func setupFooter() {
|
||||
footerLabel.text = NSLocalizedString("Sign in to your NewsBlur account and sync your feeds across your devices. Your username and password will be encrypted and stored in Keychain.\n\nDon’t have a NewsBlur account?", comment: "NewsBlur")
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
|
||||
return section == 0 ? ImageHeaderView.rowHeight : super.tableView(tableView, heightForHeaderInSection: section)
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
|
||||
if section == 0 {
|
||||
let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "SectionHeader") as! ImageHeaderView
|
||||
headerView.imageView.image = AppImage.account(.newsBlur)
|
||||
return headerView
|
||||
} else {
|
||||
return super.tableView(tableView, viewForHeaderInSection: section)
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func cancel(_ sender: Any) {
|
||||
dismiss(animated: true, completion: nil)
|
||||
}
|
||||
|
||||
@IBAction func showHidePassword(_ sender: Any) {
|
||||
if passwordTextField.isSecureTextEntry {
|
||||
passwordTextField.isSecureTextEntry = false
|
||||
showHideButton.setTitle("Hide", for: .normal)
|
||||
} else {
|
||||
passwordTextField.isSecureTextEntry = true
|
||||
showHideButton.setTitle("Show", for: .normal)
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func action(_ sender: Any) {
|
||||
|
||||
guard let username = usernameTextField.text else {
|
||||
showError(NSLocalizedString("Username required.", comment: "Credentials Error"))
|
||||
return
|
||||
}
|
||||
|
||||
// When you fill in the email address via auto-complete it adds extra whitespace
|
||||
let trimmedUsername = username.trimmingCharacters(in: .whitespaces)
|
||||
|
||||
guard account != nil || !AccountManager.shared.duplicateServiceAccount(type: .newsBlur, username: trimmedUsername) else {
|
||||
showError(NSLocalizedString("There is already a NewsBlur account with that username created.", comment: "Duplicate Error"))
|
||||
return
|
||||
}
|
||||
|
||||
let password = passwordTextField.text ?? ""
|
||||
|
||||
startAnimatingActivityIndicator()
|
||||
disableNavigation()
|
||||
|
||||
let basicCredentials = Credentials(type: .newsBlurBasic, username: trimmedUsername, secret: password)
|
||||
Account.validateCredentials(type: .newsBlur, credentials: basicCredentials) { result in
|
||||
|
||||
self.stopAnimatingActivityIndicator()
|
||||
self.enableNavigation()
|
||||
|
||||
switch result {
|
||||
case .success(let sessionCredentials):
|
||||
if let sessionCredentials = sessionCredentials {
|
||||
|
||||
if self.account == nil {
|
||||
self.account = AccountManager.shared.createAccount(type: .newsBlur)
|
||||
}
|
||||
|
||||
do {
|
||||
|
||||
do {
|
||||
try self.account?.removeCredentials(type: .newsBlurBasic)
|
||||
try self.account?.removeCredentials(type: .newsBlurSessionID)
|
||||
} catch {}
|
||||
try self.account?.storeCredentials(basicCredentials)
|
||||
try self.account?.storeCredentials(sessionCredentials)
|
||||
|
||||
self.account?.refreshAll { result in
|
||||
switch result {
|
||||
case .success:
|
||||
break
|
||||
case .failure(let error):
|
||||
self.presentError(error)
|
||||
}
|
||||
}
|
||||
|
||||
self.dismiss(animated: true, completion: nil)
|
||||
self.delegate?.dismiss()
|
||||
} catch {
|
||||
self.showError(NSLocalizedString("Keychain error while storing credentials.", comment: "Credentials Error"))
|
||||
}
|
||||
} else {
|
||||
self.showError(NSLocalizedString("Invalid username/password combination.", comment: "Credentials Error"))
|
||||
}
|
||||
case .failure(let error):
|
||||
self.showError(error.localizedDescription)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func signUpWithProvider(_ sender: Any) {
|
||||
let url = URL(string: "https://newsblur.com")!
|
||||
let safari = SFSafariViewController(url: url)
|
||||
safari.modalPresentationStyle = .currentContext
|
||||
self.present(safari, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
@objc func textDidChange(_ note: Notification) {
|
||||
actionButton.isEnabled = !(usernameTextField.text?.isEmpty ?? false)
|
||||
}
|
||||
|
||||
private func showError(_ message: String) {
|
||||
presentError(title: "Error", message: message)
|
||||
}
|
||||
|
||||
private func enableNavigation() {
|
||||
self.cancelBarButtonItem.isEnabled = true
|
||||
self.actionButton.isEnabled = true
|
||||
}
|
||||
|
||||
private func disableNavigation() {
|
||||
cancelBarButtonItem.isEnabled = false
|
||||
actionButton.isEnabled = false
|
||||
}
|
||||
|
||||
private func startAnimatingActivityIndicator() {
|
||||
activityIndicator.isHidden = false
|
||||
activityIndicator.startAnimating()
|
||||
}
|
||||
|
||||
private func stopAnimatingActivityIndicator() {
|
||||
self.activityIndicator.isHidden = true
|
||||
self.activityIndicator.stopAnimating()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension NewsBlurAccountViewController: UITextFieldDelegate {
|
||||
|
||||
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
||||
textField.resignFirstResponder()
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
317
iOS/Settings/Account/ReaderAPIAccountViewController.swift
Normal file
317
iOS/Settings/Account/ReaderAPIAccountViewController.swift
Normal file
@@ -0,0 +1,317 @@
|
||||
//
|
||||
// ReaderAPIAccountViewController.swift
|
||||
// NetNewsWire-iOS
|
||||
//
|
||||
// Created by Stuart Breckenridge on 25/10/20.
|
||||
// Copyright © 2020 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Account
|
||||
import Secrets
|
||||
import RSWeb
|
||||
import SafariServices
|
||||
|
||||
final class ReaderAPIAccountViewController: UITableViewController {
|
||||
|
||||
@IBOutlet weak var activityIndicator: UIActivityIndicatorView!
|
||||
@IBOutlet weak var cancelBarButtonItem: UIBarButtonItem!
|
||||
@IBOutlet weak var usernameTextField: UITextField!
|
||||
@IBOutlet weak var passwordTextField: UITextField!
|
||||
@IBOutlet weak var apiURLTextField: UITextField!
|
||||
@IBOutlet weak var showHideButton: UIButton!
|
||||
@IBOutlet weak var actionButton: UIButton!
|
||||
@IBOutlet weak var footerLabel: UILabel!
|
||||
@IBOutlet weak var signUpButton: UIButton!
|
||||
|
||||
weak var account: Account?
|
||||
var accountType: AccountType?
|
||||
weak var delegate: AddAccountDismissDelegate?
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
setupFooter()
|
||||
|
||||
activityIndicator.isHidden = true
|
||||
usernameTextField.delegate = self
|
||||
passwordTextField.delegate = self
|
||||
|
||||
if let unwrappedAccount = account,
|
||||
let credentials = try? retrieveCredentialsForAccount(for: unwrappedAccount) {
|
||||
actionButton.setTitle(NSLocalizedString("Update Credentials", comment: "Update Credentials"), for: .normal)
|
||||
actionButton.isEnabled = true
|
||||
usernameTextField.text = credentials.username
|
||||
passwordTextField.text = credentials.secret
|
||||
} else {
|
||||
actionButton.setTitle(NSLocalizedString("Add Account", comment: "Add Account"), for: .normal)
|
||||
}
|
||||
|
||||
if let unwrappedAccountType = accountType {
|
||||
switch unwrappedAccountType {
|
||||
case .freshRSS:
|
||||
title = NSLocalizedString("FreshRSS", comment: "FreshRSS")
|
||||
apiURLTextField.placeholder = NSLocalizedString("API URL: fresh.rss.net/api/greader.php", comment: "FreshRSS API Helper")
|
||||
case .inoreader:
|
||||
title = NSLocalizedString("InoReader", comment: "InoReader")
|
||||
case .bazQux:
|
||||
title = NSLocalizedString("BazQux", comment: "BazQux")
|
||||
case .theOldReader:
|
||||
title = NSLocalizedString("The Old Reader", comment: "The Old Reader")
|
||||
default:
|
||||
title = ""
|
||||
}
|
||||
}
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(textDidChange(_:)), name: UITextField.textDidChangeNotification, object: usernameTextField)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(textDidChange(_:)), name: UITextField.textDidChangeNotification, object: passwordTextField)
|
||||
|
||||
tableView.register(ImageHeaderView.self, forHeaderFooterViewReuseIdentifier: "SectionHeader")
|
||||
|
||||
}
|
||||
|
||||
private func setupFooter() {
|
||||
switch accountType {
|
||||
case .bazQux:
|
||||
footerLabel.text = NSLocalizedString("Sign in to your BazQux account and sync your feeds across your devices. Your username and password will be encrypted and stored in Keychain.\n\nDon’t have a BazQux account?", comment: "BazQux")
|
||||
signUpButton.setTitle(NSLocalizedString("Sign Up Here", comment: "BazQux SignUp"), for: .normal)
|
||||
case .inoreader:
|
||||
footerLabel.text = NSLocalizedString("Sign in to your InoReader account and sync your feeds across your devices. Your username and password will be encrypted and stored in Keychain.\n\nDon’t have an InoReader account?", comment: "InoReader")
|
||||
signUpButton.setTitle(NSLocalizedString("Sign Up Here", comment: "InoReader SignUp"), for: .normal)
|
||||
case .theOldReader:
|
||||
footerLabel.text = NSLocalizedString("Sign in to your The Old Reader account and sync your feeds across your devices. Your username and password will be encrypted and stored in Keychain.\n\nDon’t have a The Old Reader account?", comment: "TOR")
|
||||
signUpButton.setTitle(NSLocalizedString("Sign Up Here", comment: "TOR SignUp"), for: .normal)
|
||||
case .freshRSS:
|
||||
footerLabel.text = NSLocalizedString("Sign in to your FreshRSS instance and sync your feeds across your devices. Your username and password will be encrypted and stored in Keychain.\n\nDon’t have an FreshRSS instance?", comment: "FreshRSS")
|
||||
signUpButton.setTitle(NSLocalizedString("Find Out More", comment: "FreshRSS SignUp"), for: .normal)
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
|
||||
return section == 0 ? ImageHeaderView.rowHeight : super.tableView(tableView, heightForHeaderInSection: section)
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
|
||||
if section == 0 {
|
||||
let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "SectionHeader") as! ImageHeaderView
|
||||
headerView.imageView.image = headerViewImage()
|
||||
return headerView
|
||||
} else {
|
||||
return super.tableView(tableView, viewForHeaderInSection: section)
|
||||
}
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
switch section {
|
||||
case 0:
|
||||
switch accountType {
|
||||
case .freshRSS:
|
||||
return 3
|
||||
default:
|
||||
return 2
|
||||
}
|
||||
default:
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func cancel(_ sender: Any) {
|
||||
dismiss(animated: true, completion: nil)
|
||||
}
|
||||
|
||||
@IBAction func showHidePassword(_ sender: Any) {
|
||||
if passwordTextField.isSecureTextEntry {
|
||||
passwordTextField.isSecureTextEntry = false
|
||||
showHideButton.setTitle("Hide", for: .normal)
|
||||
} else {
|
||||
passwordTextField.isSecureTextEntry = true
|
||||
showHideButton.setTitle("Show", for: .normal)
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func action(_ sender: Any) {
|
||||
guard validateDataEntry(), let type = accountType else {
|
||||
return
|
||||
}
|
||||
|
||||
let username = usernameTextField.text!
|
||||
let password = passwordTextField.text!
|
||||
let url = apiURL()!
|
||||
|
||||
// When you fill in the email address via auto-complete it adds extra whitespace
|
||||
let trimmedUsername = username.trimmingCharacters(in: .whitespaces)
|
||||
|
||||
guard account != nil || !AccountManager.shared.duplicateServiceAccount(type: type, username: trimmedUsername) else {
|
||||
showError(NSLocalizedString("There is already an account of that type with that username created.", comment: "Duplicate Error"))
|
||||
return
|
||||
}
|
||||
|
||||
startAnimatingActivityIndicator()
|
||||
disableNavigation()
|
||||
|
||||
let credentials = Credentials(type: .readerBasic, username: trimmedUsername, secret: password)
|
||||
Account.validateCredentials(type: type, credentials: credentials, endpoint: url) { result in
|
||||
|
||||
self.stopAnimatingActivityIndicator()
|
||||
self.enableNavigation()
|
||||
|
||||
switch result {
|
||||
case .success(let validatedCredentials):
|
||||
if let validatedCredentials = validatedCredentials {
|
||||
|
||||
if self.account == nil {
|
||||
self.account = AccountManager.shared.createAccount(type: type)
|
||||
}
|
||||
|
||||
do {
|
||||
self.account?.endpointURL = url
|
||||
|
||||
try? self.account?.removeCredentials(type: .readerBasic)
|
||||
try? self.account?.removeCredentials(type: .readerAPIKey)
|
||||
try self.account?.storeCredentials(credentials)
|
||||
try self.account?.storeCredentials(validatedCredentials)
|
||||
|
||||
self.dismiss(animated: true, completion: nil)
|
||||
|
||||
self.account?.refreshAll { result in
|
||||
switch result {
|
||||
case .success:
|
||||
break
|
||||
case .failure(let error):
|
||||
self.showError(NSLocalizedString(error.localizedDescription, comment: "Account Refresh Error"))
|
||||
}
|
||||
}
|
||||
|
||||
self.delegate?.dismiss()
|
||||
} catch {
|
||||
self.showError(NSLocalizedString("Keychain error while storing credentials.", comment: "Credentials Error"))
|
||||
}
|
||||
} else {
|
||||
self.showError(NSLocalizedString("Invalid username/password combination.", comment: "Credentials Error"))
|
||||
}
|
||||
case .failure(let error):
|
||||
self.showError(error.localizedDescription)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private func retrieveCredentialsForAccount(for account: Account) throws -> Credentials? {
|
||||
switch accountType {
|
||||
case .bazQux, .inoreader, .theOldReader, .freshRSS:
|
||||
return try account.retrieveCredentials(type: .readerBasic)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
private func headerViewImage() -> UIImage? {
|
||||
if let accountType = accountType {
|
||||
switch accountType {
|
||||
case .bazQux:
|
||||
return AppImage.account(.bazQux)
|
||||
case .inoreader:
|
||||
return AppImage.account(.inoreader)
|
||||
case .theOldReader:
|
||||
return AppImage.account(.theOldReader)
|
||||
case .freshRSS:
|
||||
return AppImage.account(.freshRSS)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
private func validateDataEntry() -> Bool {
|
||||
switch accountType {
|
||||
case .freshRSS:
|
||||
if !usernameTextField.hasText || !passwordTextField.hasText || !apiURLTextField.hasText {
|
||||
showError(NSLocalizedString("Username, password, and API URL are required.", comment: "Credentials Error"))
|
||||
return false
|
||||
}
|
||||
guard URL(string: apiURLTextField.text!) != nil else {
|
||||
showError(NSLocalizedString("Invalid API URL.", comment: "Invalid API URL"))
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if !usernameTextField.hasText || !passwordTextField.hasText {
|
||||
showError(NSLocalizedString("Username and password are required.", comment: "Credentials Error"))
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@IBAction func signUpWithProvider(_ sender: Any) {
|
||||
var url: URL!
|
||||
switch accountType {
|
||||
case .bazQux:
|
||||
url = URL(string: "https://bazqux.com")!
|
||||
case .inoreader:
|
||||
url = URL(string: "https://www.inoreader.com")!
|
||||
case .theOldReader:
|
||||
url = URL(string: "https://theoldreader.com")!
|
||||
case .freshRSS:
|
||||
url = URL(string: "https://freshrss.org")!
|
||||
default:
|
||||
return
|
||||
}
|
||||
let safari = SFSafariViewController(url: url)
|
||||
safari.modalPresentationStyle = .currentContext
|
||||
self.present(safari, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
private func apiURL() -> URL? {
|
||||
switch accountType {
|
||||
case .freshRSS:
|
||||
return URL(string: apiURLTextField.text!)!
|
||||
case .inoreader:
|
||||
return URL(string: ReaderAPIVariant.inoreader.host)!
|
||||
case .bazQux:
|
||||
return URL(string: ReaderAPIVariant.bazQux.host)!
|
||||
case .theOldReader:
|
||||
return URL(string: ReaderAPIVariant.theOldReader.host)!
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@objc func textDidChange(_ note: Notification) {
|
||||
actionButton.isEnabled = !(usernameTextField.text?.isEmpty ?? false)
|
||||
}
|
||||
|
||||
private func showError(_ message: String) {
|
||||
presentError(title: "Error", message: message)
|
||||
}
|
||||
|
||||
private func enableNavigation() {
|
||||
self.cancelBarButtonItem.isEnabled = true
|
||||
self.actionButton.isEnabled = true
|
||||
}
|
||||
|
||||
private func disableNavigation() {
|
||||
cancelBarButtonItem.isEnabled = false
|
||||
actionButton.isEnabled = false
|
||||
}
|
||||
|
||||
private func startAnimatingActivityIndicator() {
|
||||
activityIndicator.isHidden = false
|
||||
activityIndicator.startAnimating()
|
||||
}
|
||||
|
||||
private func stopAnimatingActivityIndicator() {
|
||||
self.activityIndicator.isHidden = true
|
||||
self.activityIndicator.stopAnimating()
|
||||
}
|
||||
}
|
||||
|
||||
extension ReaderAPIAccountViewController: UITextFieldDelegate {
|
||||
|
||||
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
||||
textField.resignFirstResponder()
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user