Compare commits

..

5 Commits

Author SHA1 Message Date
Shadowfacts 787dc9f24f
Fix crash decoding statuses sent from certain applications
If an application provides its URL as an empty string, decoding it would
cause throw an error because Foundation's URL class does not accept
empty strings. Instead, during parsing, consume the invalid URL and
replace it with a `nil` app URL.
2020-01-04 23:13:55 -05:00
Shadowfacts ad09e36907
Show follow requsts in notifications w/ accept/reject buttons
Closes #64
2020-01-04 23:13:23 -05:00
Shadowfacts c31916d67e
Remove references to old images 2020-01-04 23:04:45 -05:00
Shadowfacts 05cc3fd6d9
Add pinning/unpinning statuses
Closes #69
2020-01-04 19:31:35 -05:00
Shadowfacts b70256c525
Remove old icons 2020-01-04 19:22:16 -05:00
38 changed files with 397 additions and 1163 deletions

View File

@ -1,91 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg4592"
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
sodipodi:docname="Download.svg">
<defs
id="defs4586" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="166.13768"
inkscape:cy="136.01503"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="2560"
inkscape:window-height="1395"
inkscape:window-x="1920"
inkscape:window-y="1"
inkscape:window-maximized="1" />
<metadata
id="metadata4589">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.7641871;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect5166"
width="100"
height="10"
x="-45"
y="302"
ry="4.9918189" />
<rect
transform="matrix(-0.70710679,-0.70710677,-0.70710679,0.70710677,0,0)"
ry="4.4665961"
y="199.22142"
x="-214.47757"
height="8.9331923"
width="66.99894"
id="rect5164"
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.46821165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
transform="matrix(0,1,1,0,0,0)"
ry="4.4665961"
y="0"
x="212"
height="8.9331923"
width="85"
id="rect5168"
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.78008413;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.46821189;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect5162"
width="66.99894"
height="8.9331923"
x="141.1559"
y="205.54411"
ry="4.4665961"
transform="matrix(-0.70710679,0.70710677,0.70710679,0.70710677,0,0)" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -1,73 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg1007"
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
sodipodi:docname="Favorite.svg">
<defs
id="defs1001" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.98994949"
inkscape:cx="293.05888"
inkscape:cy="341.92599"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="2560"
inkscape:window-height="1395"
inkscape:window-x="1920"
inkscape:window-y="1"
inkscape:window-maximized="1" />
<metadata
id="metadata1004">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
sodipodi:type="star"
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.64583325;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill"
id="path1571"
sodipodi:sides="5"
sodipodi:cx="68.784126"
sodipodi:cy="238.46798"
sodipodi:r1="72.331841"
sodipodi:r2="30.379374"
sodipodi:arg1="0.94281504"
sodipodi:arg2="1.5711336"
inkscape:flatsided="false"
inkscape:rounded="0"
inkscape:randomized="0"
d="M 111.27998,297.00001 68.77388,268.84736 26.248805,296.97133 39.888461,247.84598 -6.6077817e-8,216.09302 50.935869,213.88454 68.80852,166.13615 l 17.840442,47.76043 50.934368,2.24284 -39.90987,31.72605 z"
inkscape:transform-center-x="-0.0075377331"
inkscape:transform-center-y="-6.8999101" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -1,78 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg5214"
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
sodipodi:docname="Link.svg">
<defs
id="defs5208" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.8"
inkscape:cx="166.9267"
inkscape:cy="23.876042"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="2560"
inkscape:window-height="1395"
inkscape:window-x="1920"
inkscape:window-y="1"
inkscape:window-maximized="1" />
<metadata
id="metadata5211">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<ellipse
cy="308.6665"
cx="68.333336"
id="circle5763"
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:9;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
rx="24.99999"
ry="25.000156" />
<circle
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:9;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path5218"
cx="28.333334"
cy="268.66666"
r="25" />
<rect
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:3.61034346;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect5767"
width="65"
height="12.5"
x="206.42897"
y="164.74048"
ry="6.25"
transform="rotate(45)" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -1,84 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="80"
height="40"
viewBox="0 0 21.166666 10.583334"
version="1.1"
id="svg1623"
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
sodipodi:docname="More.svg">
<defs
id="defs1617" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.6"
inkscape:cx="83.737701"
inkscape:cy="47.564201"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="2560"
inkscape:window-height="1395"
inkscape:window-x="1920"
inkscape:window-y="1"
inkscape:window-maximized="1"
units="px" />
<metadata
id="metadata1620">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-286.41665)">
<rect
style="fill:#000000;fill-opacity:0;stroke:none;stroke-width:2.73260474;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill"
id="rect2326"
width="21.166668"
height="10.583334"
x="6.9388939e-18"
y="286.41666" />
<circle
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.15993595;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill"
id="path2187"
cx="2.6458333"
cy="291.70831"
r="2.6458333" />
<circle
cy="291.70831"
cx="-10.583333"
id="circle2189"
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.15993595;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill"
transform="scale(-1,1)"
r="2.6458333" />
<circle
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.15993595;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill"
id="circle2191"
cx="18.520834"
cy="291.70831"
r="2.6458333" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -1,115 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="793.70081"
height="1122.5197"
viewBox="0 0 210 297"
version="1.1"
id="svg886"
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
sodipodi:docname="Reblog.svg"
enable-background="new">
<defs
id="defs880">
<filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter2010">
<feBlend
inkscape:collect="always"
mode="multiply"
in2="BackgroundImage"
id="feBlend2012" />
</filter>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.12"
inkscape:cx="426.6819"
inkscape:cy="222.48454"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
inkscape:snap-bbox="true"
inkscape:bbox-paths="true"
inkscape:bbox-nodes="true"
inkscape:snap-bbox-edge-midpoints="true"
inkscape:snap-bbox-midpoints="true"
showguides="true"
inkscape:guide-bbox="true"
inkscape:window-width="2560"
inkscape:window-height="1395"
inkscape:window-x="1920"
inkscape:window-y="1"
inkscape:window-maximized="1"
inkscape:lockguides="false"
inkscape:pagecheckerboard="false">
<sodipodi:guide
position="100.46678,110.57587"
orientation="0,1"
id="guide1767"
inkscape:locked="false" />
<sodipodi:guide
position="39.817226,99.415325"
orientation="1,0"
id="guide1773"
inkscape:locked="false" />
<sodipodi:guide
position="107.95499,89.359277"
orientation="0,1"
id="guide1987"
inkscape:locked="false" />
<sodipodi:guide
position="79.634452,79.589293"
orientation="-0.70563567,-0.70857484"
id="guide1999"
inkscape:locked="false" />
<sodipodi:guide
position="70.763562,8.6713087"
orientation="0,1"
id="guide904"
inkscape:locked="false" />
</sodipodi:namedview>
<metadata
id="metadata883">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
style="opacity:0.92000002;filter:url(#filter2010)">
<path
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:4.54638195;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill"
d="m 159.65664,296.99998 39.81721,-39.65184 h -29.05972 v -49.56596 h -0.005 c 0.003,0 0.005,-0.003 0.005,-0.005 V 186.4343 c 0,-0.003 -0.002,-0.005 -0.005,-0.005 h -54.66849 c -8e-4,0 -0.001,-0.003 -0.003,-0.003 H 75.53562 l 21.441585,21.35219 h 18.756475 c 7.9e-4,0 7.9e-4,0.003 0.002,0.003 h 33.16389 v 49.56617 h -29.05973 z"
id="path1592"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path1716"
d="M 39.817206,177.75866 0,217.4105 h 29.059724 v 49.56596 h 0.0047 c -0.0026,0 -0.0047,0.003 -0.0047,0.005 v 21.34288 c 0,0.003 0.0021,0.005 0.0047,0.005 h 54.668491 c 7.93e-4,0 0.0013,0.003 0.0026,0.003 H 123.93823 L 102.49665,266.97932 H 83.740169 c -7.94e-4,0 -7.94e-4,-0.003 -0.0016,-0.003 H 50.574691 V 217.4105 h 29.059724 z"
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:4.54638195;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -1,78 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="793.70081"
height="1122.5197"
viewBox="0 0 210 297"
version="1.1"
id="svg8"
sodipodi:docname="Reply.svg"
inkscape:version="0.92.2 5c3e80d, 2017-08-06">
<defs
id="defs2">
<inkscape:path-effect
effect="powerstroke"
id="path-effect821"
is_visible="true"
offset_points="0,0.13229166"
sort_points="true"
interpolator_type="CubicBezierJohan"
interpolator_beta="0.2"
start_linecap_type="zerowidth"
linejoin_type="extrp_arc"
miter_limit="4"
end_linecap_type="zerowidth" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="134.7614"
inkscape:cy="56.711221"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
inkscape:measure-start="46.669,115.435"
inkscape:measure-end="64.166,149.577"
inkscape:window-width="2560"
inkscape:window-height="1395"
inkscape:window-x="1920"
inkscape:window-y="1"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.26310158px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 0.20308372,275.78816 20.85866428,-18.46405 -4.77e-4,14.33185 c 0,0 41.110218,1.57695 31.919391,25.03042 2.746954,-16.26972 -31.82696,-14.6095 -31.82696,-14.6095 l -0.184082,14.75226 z"
id="path825"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -29,12 +29,12 @@ public class Account: Decodable {
public let fields: [Field]? public let fields: [Field]?
public let bot: Bool? public let bot: Bool?
public static func authorizeFollowRequest(_ account: Account) -> Request<Empty> { public static func authorizeFollowRequest(_ account: Account) -> Request<Relationship> {
return Request<Empty>(method: .post, path: "/api/v1/follow_requests/\(account.id)/authorize") return Request<Relationship>(method: .post, path: "/api/v1/follow_requests/\(account.id)/authorize")
} }
public static func rejectFollowRequest(_ account: Account) -> Request<Empty> { public static func rejectFollowRequest(_ account: Account) -> Request<Relationship> {
return Request<Empty>(method: .post, path: "/api/v1/follow_requests/\(account.id)/reject") return Request<Relationship>(method: .post, path: "/api/v1/follow_requests/\(account.id)/reject")
} }
public static func removeFromFollowRequests(_ account: Account) -> Request<Empty> { public static func removeFromFollowRequests(_ account: Account) -> Request<Empty> {

View File

@ -12,6 +12,19 @@ public class Application: Decodable {
public let name: String public let name: String
public let website: URL? public let website: URL?
public required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.name = try container.decode(String.self, forKey: .name)
if let websiteStr = try container.decodeIfPresent(String.self, forKey: .website),
let url = URL(string: websiteStr) {
self.website = url
} else {
self.website = nil
}
}
private enum CodingKeys: String, CodingKey { private enum CodingKeys: String, CodingKey {
case name case name
case website case website

View File

@ -36,6 +36,7 @@ extension Notification {
case reblog case reblog
case favourite case favourite
case follow case follow
case followRequest = "follow_request"
} }
} }

View File

@ -114,6 +114,10 @@
D646C958213B367000269FB5 /* LargeImageShrinkAnimationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D646C957213B367000269FB5 /* LargeImageShrinkAnimationController.swift */; }; D646C958213B367000269FB5 /* LargeImageShrinkAnimationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D646C957213B367000269FB5 /* LargeImageShrinkAnimationController.swift */; };
D646C95A213B5D0500269FB5 /* LargeImageInteractionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D646C959213B5D0500269FB5 /* LargeImageInteractionController.swift */; }; D646C95A213B5D0500269FB5 /* LargeImageInteractionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D646C959213B5D0500269FB5 /* LargeImageInteractionController.swift */; };
D64BC18623C1253A000D0238 /* AssetPreviewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64BC18523C1253A000D0238 /* AssetPreviewViewController.swift */; }; D64BC18623C1253A000D0238 /* AssetPreviewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64BC18523C1253A000D0238 /* AssetPreviewViewController.swift */; };
D64BC18823C1640A000D0238 /* PinStatusActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64BC18723C1640A000D0238 /* PinStatusActivity.swift */; };
D64BC18A23C16487000D0238 /* UnpinStatusActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64BC18923C16487000D0238 /* UnpinStatusActivity.swift */; };
D64BC18F23C18B9D000D0238 /* FollowRequestNotificationTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64BC18D23C18B9D000D0238 /* FollowRequestNotificationTableViewCell.swift */; };
D64BC19023C18B9D000D0238 /* FollowRequestNotificationTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D64BC18E23C18B9D000D0238 /* FollowRequestNotificationTableViewCell.xib */; };
D64D0AAD2128D88B005A6F37 /* LocalData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64D0AAC2128D88B005A6F37 /* LocalData.swift */; }; D64D0AAD2128D88B005A6F37 /* LocalData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64D0AAC2128D88B005A6F37 /* LocalData.swift */; };
D64D0AB12128D9AE005A6F37 /* OnboardingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64D0AB02128D9AE005A6F37 /* OnboardingViewController.swift */; }; D64D0AB12128D9AE005A6F37 /* OnboardingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64D0AB02128D9AE005A6F37 /* OnboardingViewController.swift */; };
D64F80E2215875CC00BEF393 /* XCBActionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64F80E1215875CC00BEF393 /* XCBActionType.swift */; }; D64F80E2215875CC00BEF393 /* XCBActionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64F80E1215875CC00BEF393 /* XCBActionType.swift */; };
@ -380,6 +384,10 @@
D646C957213B367000269FB5 /* LargeImageShrinkAnimationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LargeImageShrinkAnimationController.swift; sourceTree = "<group>"; }; D646C957213B367000269FB5 /* LargeImageShrinkAnimationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LargeImageShrinkAnimationController.swift; sourceTree = "<group>"; };
D646C959213B5D0500269FB5 /* LargeImageInteractionController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LargeImageInteractionController.swift; sourceTree = "<group>"; }; D646C959213B5D0500269FB5 /* LargeImageInteractionController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LargeImageInteractionController.swift; sourceTree = "<group>"; };
D64BC18523C1253A000D0238 /* AssetPreviewViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetPreviewViewController.swift; sourceTree = "<group>"; }; D64BC18523C1253A000D0238 /* AssetPreviewViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetPreviewViewController.swift; sourceTree = "<group>"; };
D64BC18723C1640A000D0238 /* PinStatusActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PinStatusActivity.swift; sourceTree = "<group>"; };
D64BC18923C16487000D0238 /* UnpinStatusActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnpinStatusActivity.swift; sourceTree = "<group>"; };
D64BC18D23C18B9D000D0238 /* FollowRequestNotificationTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowRequestNotificationTableViewCell.swift; sourceTree = "<group>"; };
D64BC18E23C18B9D000D0238 /* FollowRequestNotificationTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = FollowRequestNotificationTableViewCell.xib; sourceTree = "<group>"; };
D64D0AAC2128D88B005A6F37 /* LocalData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalData.swift; sourceTree = "<group>"; }; D64D0AAC2128D88B005A6F37 /* LocalData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalData.swift; sourceTree = "<group>"; };
D64D0AB02128D9AE005A6F37 /* OnboardingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingViewController.swift; sourceTree = "<group>"; }; D64D0AB02128D9AE005A6F37 /* OnboardingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingViewController.swift; sourceTree = "<group>"; };
D64F80E1215875CC00BEF393 /* XCBActionType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCBActionType.swift; sourceTree = "<group>"; }; D64F80E1215875CC00BEF393 /* XCBActionType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCBActionType.swift; sourceTree = "<group>"; };
@ -703,6 +711,8 @@
D627943423A5525100D38C68 /* StatusActivity.swift */, D627943423A5525100D38C68 /* StatusActivity.swift */,
D627943623A552C200D38C68 /* BookmarkStatusActivity.swift */, D627943623A552C200D38C68 /* BookmarkStatusActivity.swift */,
D627943823A553B600D38C68 /* UnbookmarkStatusActivity.swift */, D627943823A553B600D38C68 /* UnbookmarkStatusActivity.swift */,
D64BC18723C1640A000D0238 /* PinStatusActivity.swift */,
D64BC18923C16487000D0238 /* UnpinStatusActivity.swift */,
); );
path = "Status Activities"; path = "Status Activities";
sourceTree = "<group>"; sourceTree = "<group>";
@ -900,6 +910,8 @@
D6A3BC7B232195C600FD64D5 /* ActionNotificationGroupTableViewCell.xib */, D6A3BC7B232195C600FD64D5 /* ActionNotificationGroupTableViewCell.xib */,
D6A3BC7E2321B7E600FD64D5 /* FollowNotificationGroupTableViewCell.swift */, D6A3BC7E2321B7E600FD64D5 /* FollowNotificationGroupTableViewCell.swift */,
D6A3BC7F2321B7E600FD64D5 /* FollowNotificationGroupTableViewCell.xib */, D6A3BC7F2321B7E600FD64D5 /* FollowNotificationGroupTableViewCell.xib */,
D64BC18D23C18B9D000D0238 /* FollowRequestNotificationTableViewCell.swift */,
D64BC18E23C18B9D000D0238 /* FollowRequestNotificationTableViewCell.xib */,
); );
path = Notifications; path = Notifications;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1476,6 +1488,7 @@
D626493323BD751600612E6E /* ShowCameraCollectionViewCell.xib in Resources */, D626493323BD751600612E6E /* ShowCameraCollectionViewCell.xib in Resources */,
D626493D23C1000300612E6E /* AlbumTableViewCell.xib in Resources */, D626493D23C1000300612E6E /* AlbumTableViewCell.xib in Resources */,
D627944723A6AC9300D38C68 /* BasicTableViewCell.xib in Resources */, D627944723A6AC9300D38C68 /* BasicTableViewCell.xib in Resources */,
D64BC19023C18B9D000D0238 /* FollowRequestNotificationTableViewCell.xib in Resources */,
D67C57B221E28FAD00C3118B /* ComposeStatusReplyView.xib in Resources */, D67C57B221E28FAD00C3118B /* ComposeStatusReplyView.xib in Resources */,
0411610122B442870030A9B7 /* AttachmentViewController.xib in Resources */, 0411610122B442870030A9B7 /* AttachmentViewController.xib in Resources */,
D6A3BC812321B7E600FD64D5 /* FollowNotificationGroupTableViewCell.xib in Resources */, D6A3BC812321B7E600FD64D5 /* FollowNotificationGroupTableViewCell.xib in Resources */,
@ -1608,6 +1621,7 @@
D6BC9DB3232D4C07002CA326 /* WellnessPrefsView.swift in Sources */, D6BC9DB3232D4C07002CA326 /* WellnessPrefsView.swift in Sources */,
D6D58DF922074B74009C8DD9 /* LinkLabel.swift in Sources */, D6D58DF922074B74009C8DD9 /* LinkLabel.swift in Sources */,
0454DDAF22B462EF00B8BB8E /* GalleryExpandAnimationController.swift in Sources */, 0454DDAF22B462EF00B8BB8E /* GalleryExpandAnimationController.swift in Sources */,
D64BC18F23C18B9D000D0238 /* FollowRequestNotificationTableViewCell.swift in Sources */,
D6A3BC8A2321F79B00FD64D5 /* AccountTableViewCell.swift in Sources */, D6A3BC8A2321F79B00FD64D5 /* AccountTableViewCell.swift in Sources */,
D66A77BB233838DC0058F1EC /* UIFont+Traits.swift in Sources */, D66A77BB233838DC0058F1EC /* UIFont+Traits.swift in Sources */,
D68FEC4F232C5BC300C84F23 /* SegmentedPageViewController.swift in Sources */, D68FEC4F232C5BC300C84F23 /* SegmentedPageViewController.swift in Sources */,
@ -1633,6 +1647,7 @@
D62D2424217ABF3F005076CC /* NSUserActivity+Extensions.swift in Sources */, D62D2424217ABF3F005076CC /* NSUserActivity+Extensions.swift in Sources */,
D646C958213B367000269FB5 /* LargeImageShrinkAnimationController.swift in Sources */, D646C958213B367000269FB5 /* LargeImageShrinkAnimationController.swift in Sources */,
D6A3BC852321F6C100FD64D5 /* AccountListTableViewController.swift in Sources */, D6A3BC852321F6C100FD64D5 /* AccountListTableViewController.swift in Sources */,
D64BC18823C1640A000D0238 /* PinStatusActivity.swift in Sources */,
D6674AEA23341F7600E8DF94 /* AppShortcutItems.swift in Sources */, D6674AEA23341F7600E8DF94 /* AppShortcutItems.swift in Sources */,
D646C956213B365700269FB5 /* LargeImageExpandAnimationController.swift in Sources */, D646C956213B365700269FB5 /* LargeImageExpandAnimationController.swift in Sources */,
0454DDB122B467AA00B8BB8E /* GalleryShrinkAnimationController.swift in Sources */, 0454DDB122B467AA00B8BB8E /* GalleryShrinkAnimationController.swift in Sources */,
@ -1702,6 +1717,7 @@
D667E5EB21349EF80057A976 /* ProfileHeaderTableViewCell.swift in Sources */, D667E5EB21349EF80057A976 /* ProfileHeaderTableViewCell.swift in Sources */,
04D14BB022B34A2800642648 /* GalleryViewController.swift in Sources */, 04D14BB022B34A2800642648 /* GalleryViewController.swift in Sources */,
D641C773213CAA25004B4513 /* NotificationsTableViewController.swift in Sources */, D641C773213CAA25004B4513 /* NotificationsTableViewController.swift in Sources */,
D64BC18A23C16487000D0238 /* UnpinStatusActivity.swift in Sources */,
D6757A7C2157E01900721E32 /* XCBManager.swift in Sources */, D6757A7C2157E01900721E32 /* XCBManager.swift in Sources */,
D6F1F84D2193B56E00F5FE67 /* Cache.swift in Sources */, D6F1F84D2193B56E00F5FE67 /* Cache.swift in Sources */,
0427037C22B316B9000D31B6 /* SilentActionPrefs.swift in Sources */, 0427037C22B316B9000D31B6 /* SilentActionPrefs.swift in Sources */,

View File

@ -0,0 +1,39 @@
//
// PinStatusActivity.swift
// Tusker
//
// Created by Shadowfacts on 1/4/20.
// Copyright © 2020 Shadowfacts. All rights reserved.
//
import UIKit
import Pachyderm
class PinStatusActivity: StatusActivity {
override var activityType: UIActivity.ActivityType? {
return .pinStatus
}
override var activityTitle: String? {
return NSLocalizedString("Pin", comment: "pin status activity title")
}
override var activityImage: UIImage? {
return UIImage(systemName: "pin")
}
override func perform() {
guard let status = status else { return }
let request = Status.pin(status)
MastodonController.client.run(request) { (response) in
if case let .success(status, _) = response {
MastodonCache.add(status: status)
} else {
// todo: display error message
UINotificationFeedbackGenerator().notificationOccurred(.error)
fatalError()
}
}
}
}

View File

@ -0,0 +1,39 @@
//
// UnpinStatusActivity.swift
// Tusker
//
// Created by Shadowfacts on 1/4/20.
// Copyright © 2020 Shadowfacts. All rights reserved.
//
import UIKit
import Pachyderm
class UnpinStatusActivity: StatusActivity {
override var activityType: UIActivity.ActivityType? {
return .unpinStatus
}
override var activityTitle: String? {
return NSLocalizedString("Unpin", comment: "unpin status activity title")
}
override var activityImage: UIImage? {
return UIImage(systemName: "pin.slash")
}
override func perform() {
guard let status = status else { return }
let request = Status.unpin(status)
MastodonController.client.run(request) { (response) in
if case let .success(status, _) = response {
MastodonCache.add(status: status)
} else {
// todo: display error message
UINotificationFeedbackGenerator().notificationOccurred(.error)
fatalError()
}
}
}
}

View File

@ -20,5 +20,7 @@ extension UIActivity.ActivityType {
// Status // Status
static let bookmarkStatus = UIActivity.ActivityType("\(Bundle.main.bundleIdentifier!).bookmark_status") static let bookmarkStatus = UIActivity.ActivityType("\(Bundle.main.bundleIdentifier!).bookmark_status")
static let unbookmarkStatus = UIActivity.ActivityType("\(Bundle.main.bundleIdentifier!).unbookmark_status") static let unbookmarkStatus = UIActivity.ActivityType("\(Bundle.main.bundleIdentifier!).unbookmark_status")
static let pinStatus = UIActivity.ActivityType("\(Bundle.main.bundleIdentifier!).pin_status")
static let unpinStatus = UIActivity.ActivityType("\(Bundle.main.bundleIdentifier!).unpin_status")
} }

View File

@ -1,69 +0,0 @@
%PDF-1.5
%µí®û
3 0 obj
<< /Length 4 0 R
/Filter /FlateDecode
>>
stream
xœ]KÂ0 D÷>…/€‰óÏ18ªÔ²( àþI[uQM:Ïs_àp<ï ¯w‡Û"qŽè#y×ð‰\#¥ÔлHÙEÜ#怞û;¥®¹Ä¦Å™À"Ëü”§5œô¸ÊkD†e‰1¿à(` ­”{àÂjÅF…“
)|8{ð8,‡£¨8ÂIŒ h >þYW=˜ÅŸs<C5B8>J •Ž'̉!ŽÚ* TJ;µku]ääÒ=ûj—®º²Ý`çNMÊÊÈàLo°+Üà ¹
endstream
endobj
4 0 obj
206
endobj
2 0 obj
<<
/ExtGState <<
/a0 << /CA 1 /ca 1 >>
>>
>>
endobj
5 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 208.76799 208.76799 ]
/Contents 3 0 R
/Group <<
/Type /Group
/S /Transparency
/I true
/CS /DeviceRGB
>>
/Resources 2 0 R
>>
endobj
1 0 obj
<< /Type /Pages
/Kids [ 5 0 R ]
/Count 1
>>
endobj
6 0 obj
<< /Creator (cairo 1.14.8 (http://cairographics.org))
/Producer (cairo 1.14.8 (http://cairographics.org))
>>
endobj
7 0 obj
<< /Type /Catalog
/Pages 1 0 R
>>
endobj
xref
0 8
0000000000 65535 f
0000000618 00000 n
0000000320 00000 n
0000000015 00000 n
0000000298 00000 n
0000000392 00000 n
0000000683 00000 n
0000000810 00000 n
trailer
<< /Size 8
/Root 7 0 R
/Info 6 0 R
>>
startxref
862
%%EOF

View File

@ -1,25 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "Close.pdf",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "template",
"preserves-vector-representation" : true
}
}

View File

@ -1,25 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "Download.pdf",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "template",
"preserves-vector-representation" : true
}
}

View File

@ -1,69 +0,0 @@
%PDF-1.5
%µí®û
3 0 obj
<< /Length 4 0 R
/Filter /FlateDecode
>>
stream
xœ}RKnC1Üû¾@¨ÁàÏ1z„êIIÉ¢íý¥Â³<C382>ÕDªÞ†™7†áóR´ïûß>R¼ýd@nd®ñ©tÈXq<>T+ Ð"¨eà"R‡gž.ñpf&¾;Q4/yºKòRK~IAŸ éÅœŽ0­ÿÇ µÔ]Ãéb¦ÿtôÅçK“We:`k±ØV*Ô®<C394>[Éxö <0A> ˆšºvÈÐÔÂT[=«¼
Hå…JiÅÕ… <E280A6>Í35Œ\€²Íó…Èã‡z¢ºáp;õš@Ì·DAEßÐduÉÃênŒà©a<C2A9><61>¶(ÒµÓ-·ÀÚÍ×$¸¦63PR[Zö°°m±ªCv<43>´ýù„3ýáÄt`«ß”ÎgÜguÖt|¸)W Ïa§xêóÇKï×@ZªöxŒ=Õº†fóÐS#ŸóDs SöÆVÿ]*ï¥R±ãñ3¹‡Ó<E280A1>9Y‡äxžÙz1 [Š³ß)É™+lâ©GÅkß×ð~dˆÎÉ
endstream
endobj
4 0 obj
395
endobj
2 0 obj
<<
/ExtGState <<
/a0 << /CA 1 /ca 1 >>
>>
>>
endobj
5 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 283.464569 283.464569 ]
/Contents 3 0 R
/Group <<
/Type /Group
/S /Transparency
/I true
/CS /DeviceRGB
>>
/Resources 2 0 R
>>
endobj
1 0 obj
<< /Type /Pages
/Kids [ 5 0 R ]
/Count 1
>>
endobj
6 0 obj
<< /Creator (cairo 1.14.8 (http://cairographics.org))
/Producer (cairo 1.14.8 (http://cairographics.org))
>>
endobj
7 0 obj
<< /Type /Catalog
/Pages 1 0 R
>>
endobj
xref
0 8
0000000000 65535 f
0000000809 00000 n
0000000509 00000 n
0000000015 00000 n
0000000487 00000 n
0000000581 00000 n
0000000874 00000 n
0000001001 00000 n
trailer
<< /Size 8
/Root 7 0 R
/Info 6 0 R
>>
startxref
1053
%%EOF

View File

@ -1,25 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "Favorite.pdf",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "template",
"preserves-vector-representation" : true
}
}

View File

@ -1,25 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "Link.pdf",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "template",
"preserves-vector-representation" : true
}
}

View File

@ -1,70 +0,0 @@
%PDF-1.5
%µí®û
3 0 obj
<< /Length 4 0 R
/Filter /FlateDecode
>>
stream
xœ}RËN1 ¼û+ü˜Ø›‡ýHH
BôP8ðû8ízÛnZ­œqfœqœ$ßý ^?'|û)T˜|ïÖÿx|ÂD _ ãî<>÷«DU1Ëû¤6ÒV<C392>­QJŠ[ŒŒL•8ŸÄ3pG.cÅp¤È<C2A4>ð" Ò~Ì imQ"ò°PƒØ/Š-‡Í%Öþ:¾ÿÑÝnàŸëà)«¢NždçGE¨U9ÆsbÀŽy,2œ©•Sýβø ŠpF€}]$ŽÕ¹¥ÑÿE;£ýÃóùzC3šÌNcô);¯ UÒ2á'
3•ZQ<EFBFBD>ÌŸWÀ¦Ô& :`cj¶7è÷\ÝJÍ^À§ªÕ_¦,°yXØ-Óä¶ÏFÔOŸÖä;ìv­a +>ï:³ÃlGeuOÉ\žÑ„²{ž!¬›·qÑï+làuÛ¥>
endstream
endobj
4 0 obj
330
endobj
2 0 obj
<<
/ExtGState <<
/a0 << /CA 1 /ca 1 >>
>>
>>
endobj
5 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 280.629913 280.629944 ]
/Contents 3 0 R
/Group <<
/Type /Group
/S /Transparency
/I true
/CS /DeviceRGB
>>
/Resources 2 0 R
>>
endobj
1 0 obj
<< /Type /Pages
/Kids [ 5 0 R ]
/Count 1
>>
endobj
6 0 obj
<< /Creator (cairo 1.14.8 (http://cairographics.org))
/Producer (cairo 1.14.8 (http://cairographics.org))
>>
endobj
7 0 obj
<< /Type /Catalog
/Pages 1 0 R
>>
endobj
xref
0 8
0000000000 65535 f
0000000744 00000 n
0000000444 00000 n
0000000015 00000 n
0000000422 00000 n
0000000516 00000 n
0000000809 00000 n
0000000936 00000 n
trailer
<< /Size 8
/Root 7 0 R
/Info 6 0 R
>>
startxref
988
%%EOF

View File

@ -1,25 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "More.pdf",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "template",
"preserves-vector-representation" : true
}
}

View File

@ -1,69 +0,0 @@
%PDF-1.5
%µí®û
3 0 obj
<< /Length 4 0 R
/Filter /FlateDecode
>>
stream
xœEP[à ûÏ)r¡í1v„ ©ÝO?¶Ý_ ˆRœÖØ?@(ë{áãExý 2öçW¤°ó<C2B0>1†Z"n<>çn˜Cî¿“óHî49ŽKã¤d—4—ÓIL”ŒÃ¶á{8Á)·‡Mb=D1“§)*¢ß¶E˜A
‡—±U´KX.ÓÕiøfÙV¢* Tg\gQœfSeŸU•™¬˜déáÌÇxjÁiõeª:U/+y&ÏqÂþŠÓX`
endstream
endobj
4 0 obj
187
endobj
2 0 obj
<<
/ExtGState <<
/a0 << /CA 1 /ca 1 >>
>>
>>
endobj
5 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 60 30 ]
/Contents 3 0 R
/Group <<
/Type /Group
/S /Transparency
/I true
/CS /DeviceRGB
>>
/Resources 2 0 R
>>
endobj
1 0 obj
<< /Type /Pages
/Kids [ 5 0 R ]
/Count 1
>>
endobj
6 0 obj
<< /Creator (cairo 1.14.8 (http://cairographics.org))
/Producer (cairo 1.14.8 (http://cairographics.org))
>>
endobj
7 0 obj
<< /Type /Catalog
/Pages 1 0 R
>>
endobj
xref
0 8
0000000000 65535 f
0000000585 00000 n
0000000301 00000 n
0000000015 00000 n
0000000279 00000 n
0000000373 00000 n
0000000650 00000 n
0000000777 00000 n
trailer
<< /Size 8
/Root 7 0 R
/Info 6 0 R
>>
startxref
829
%%EOF

View File

@ -1,25 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "Reblog.pdf",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "template",
"preserves-vector-representation" : true
}
}

Binary file not shown.

View File

@ -1,24 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "Remove.pdf",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"preserves-vector-representation" : true
}
}

View File

@ -1,68 +0,0 @@
%PDF-1.5
%µí®û
3 0 obj
<< /Length 4 0 R
/Filter /FlateDecode
>>
stream
xœePËN1 ¼û+æ0Žóò^{©„Ä¡\´¨­=ý}œlV° +rÆž;¹’ Åç ÷¯‚Ó´xÚ£rÆÍÛ~ÞéùÂ7JxÄÕMu×J1̪…Í"°—pÁÀE8 &D®yUôûàÏ ì‘~ú}^¥Ôá²ñcxþ·÷‡ñþ3Á¼ªÈ•UÔ¹”rŠ”ÈqòU”«NŽ³±XA¨œ:>Ó_‡c«$K]cæ×h¶îYÂâ™Ë¢èØgVº§ï9<7G:Ð7~s[O
endstream
endobj
4 0 obj
226
endobj
2 0 obj
<<
/ExtGState <<
/a0 << /CA 1 /ca 1 >>
>>
>>
endobj
5 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 80.631668 80.631668 ]
/Contents 3 0 R
/Group <<
/Type /Group
/S /Transparency
/I true
/CS /DeviceRGB
>>
/Resources 2 0 R
>>
endobj
1 0 obj
<< /Type /Pages
/Kids [ 5 0 R ]
/Count 1
>>
endobj
6 0 obj
<< /Creator (cairo 1.14.8 (http://cairographics.org))
/Producer (cairo 1.14.8 (http://cairographics.org))
>>
endobj
7 0 obj
<< /Type /Catalog
/Pages 1 0 R
>>
endobj
xref
0 8
0000000000 65535 f
0000000638 00000 n
0000000340 00000 n
0000000015 00000 n
0000000318 00000 n
0000000412 00000 n
0000000703 00000 n
0000000830 00000 n
trailer
<< /Size 8
/Root 7 0 R
/Info 6 0 R
>>
startxref
882
%%EOF

View File

@ -1,25 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "Reply.pdf",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "template",
"preserves-vector-representation" : true
}
}

View File

@ -1,69 +0,0 @@
%PDF-1.5
%µí®û
3 0 obj
<< /Length 4 0 R
/Filter /FlateDecode
>>
stream
xœeŽ=
BA „û=Å\À˜d³?imÁB[±<>'<^ß]ÑB%„ä2L®<4C>Ñë6b~`Œ÷7o—`**MYµ>‡Ý¾iŒc0¬q…¼g}ˆD*\5)†)0%H$WLHN¹-LU+.4!Kñ<4B>¥dwX"× ‰I¬¶%㌡)…<r&­ÞíQ˜Üõ†ŽÝÓ½U4´°Óïs lÂ&<ô
endstream
endobj
4 0 obj
165
endobj
2 0 obj
<<
/ExtGState <<
/a0 << /CA 1 /ca 1 >>
>>
>>
endobj
5 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 154.310501 113.708252 ]
/Contents 3 0 R
/Group <<
/Type /Group
/S /Transparency
/I true
/CS /DeviceRGB
>>
/Resources 2 0 R
>>
endobj
1 0 obj
<< /Type /Pages
/Kids [ 5 0 R ]
/Count 1
>>
endobj
6 0 obj
<< /Creator (cairo 1.14.8 (http://cairographics.org))
/Producer (cairo 1.14.8 (http://cairographics.org))
>>
endobj
7 0 obj
<< /Type /Catalog
/Pages 1 0 R
>>
endobj
xref
0 8
0000000000 65535 f
0000000579 00000 n
0000000279 00000 n
0000000015 00000 n
0000000257 00000 n
0000000351 00000 n
0000000644 00000 n
0000000771 00000 n
trailer
<< /Size 8
/Root 7 0 R
/Info 6 0 R
>>
startxref
823
%%EOF

View File

@ -12,7 +12,9 @@ import Pachyderm
extension Account { extension Account {
var realDisplayName: String { var realDisplayName: String {
if Preferences.shared.hideCustomEmojiInUsernames { if displayName.isEmpty {
return username
} else if Preferences.shared.hideCustomEmojiInUsernames {
return stripCustomEmoji(from: displayName) return stripCustomEmoji(from: displayName)
} else { } else {
return displayName return displayName

View File

@ -14,6 +14,7 @@ class NotificationsTableViewController: EnhancedTableViewController {
private let statusCell = "statusCell" private let statusCell = "statusCell"
private let actionGroupCell = "actionGroupCell" private let actionGroupCell = "actionGroupCell"
private let followGroupCell = "followGroupCell" private let followGroupCell = "followGroupCell"
private let followRequestCell = "followRequestCell"
let excludedTypes: [Pachyderm.Notification.Kind] let excludedTypes: [Pachyderm.Notification.Kind]
let groupTypes = [Notification.Kind.favourite, .reblog, .follow] let groupTypes = [Notification.Kind.favourite, .reblog, .follow]
@ -48,9 +49,10 @@ class NotificationsTableViewController: EnhancedTableViewController {
tableView.rowHeight = UITableView.automaticDimension tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 140 tableView.estimatedRowHeight = 140
tableView.register(UINib(nibName: "TimelineStatusTableViewCell", bundle: nil), forCellReuseIdentifier: statusCell) tableView.register(UINib(nibName: "TimelineStatusTableViewCell", bundle: .main), forCellReuseIdentifier: statusCell)
tableView.register(UINib(nibName: "ActionNotificationGroupTableViewCell", bundle: nil), forCellReuseIdentifier: actionGroupCell) tableView.register(UINib(nibName: "ActionNotificationGroupTableViewCell", bundle: .main), forCellReuseIdentifier: actionGroupCell)
tableView.register(UINib(nibName: "FollowNotificationGroupTableViewCell", bundle: nil), forCellReuseIdentifier: followGroupCell) tableView.register(UINib(nibName: "FollowNotificationGroupTableViewCell", bundle: .main), forCellReuseIdentifier: followGroupCell)
tableView.register(UINib(nibName: "FollowRequestNotificationTableViewCell", bundle: .main), forCellReuseIdentifier: followRequestCell)
tableView.prefetchDataSource = self tableView.prefetchDataSource = self
@ -102,10 +104,17 @@ class NotificationsTableViewController: EnhancedTableViewController {
return cell return cell
case .follow: case .follow:
guard let cell = tableView.dequeueReusableCell(withIdentifier: "followGroupCell", for: indexPath) as? FollowNotificationGroupTableViewCell else { fatalError() } guard let cell = tableView.dequeueReusableCell(withIdentifier: followGroupCell, for: indexPath) as? FollowNotificationGroupTableViewCell else { fatalError() }
cell.updateUI(group: group) cell.updateUI(group: group)
cell.delegate = self cell.delegate = self
return cell return cell
case .followRequest:
guard let notification = MastodonCache.notification(for: group.notificationIDs.first!),
let cell = tableView.dequeueReusableCell(withIdentifier: followRequestCell, for: indexPath) as? FollowRequestNotificationTableViewCell else { fatalError() }
cell.updateUI(notification: notification)
cell.delegate = self
return cell
} }
} }

View File

@ -11,19 +11,6 @@ import Pachyderm
class TimelineTableViewController: EnhancedTableViewController { class TimelineTableViewController: EnhancedTableViewController {
lazy var favoriteActionImage: UIImage = UIGraphicsImageRenderer(size: CGSize(width: 30 * 137/131, height: 30)).image { _ in
UIImage(named: "Favorite")!.draw(in: CGRect(x: 0, y: 0, width: 30 * 137/131, height: 30))
}
lazy var reblogActionImage: UIImage = UIGraphicsImageRenderer(size: CGSize(width: 30 * 927/558, height: 30)).image { _ in
UIImage(named: "Reblog")!.draw(in: CGRect(x: 0, y: 0, width: 30 * 927/558, height: 30))
}
lazy var replyActionImage: UIImage = UIGraphicsImageRenderer(size: CGSize(width: 30 * 205/151, height: 30)).image { _ in
UIImage(named: "Reply")!.draw(in: CGRect(x: 0, y: 0, width: 30 * 205/151, height: 30))
}
lazy var moreActionImage: UIImage = UIGraphicsImageRenderer(size: CGSize(width: 30 * 2/1, height: 30)).image { _ in
UIImage(named: "More")!.draw(in: CGRect(x: 0, y: 0, width: 30 * 2/1, height: 30))
}
var timeline: Timeline! var timeline: Timeline!
var timelineSegments: [[(id: String, state: StatusState)]] = [] { var timelineSegments: [[(id: String, state: StatusState)]] = [] {

View File

@ -200,6 +200,11 @@ extension TuskerNavigationDelegate where Self: UIViewController {
customActivites.insert(bookmarked ? UnbookmarkStatusActivity() : BookmarkStatusActivity(), at: 0) customActivites.insert(bookmarked ? UnbookmarkStatusActivity() : BookmarkStatusActivity(), at: 0)
} }
if status.account == MastodonController.account,
let pinned = status.pinned {
customActivites.insert(pinned ? UnpinStatusActivity() : PinStatusActivity(), at: 1)
}
let activityController = UIActivityViewController(activityItems: [url, status], applicationActivities: customActivites) let activityController = UIActivityViewController(activityItems: [url, status], applicationActivities: customActivites)
activityController.completionWithItemsHandler = OpenInSafariActivity.completionHandler(viewController: self, url: url) activityController.completionWithItemsHandler = OpenInSafariActivity.completionHandler(viewController: self, url: url)
return activityController return activityController

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/> <device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies> <dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15703"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/> <capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14868" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait" appearance="light"/> <device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies> <dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14824"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/> <capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
@ -26,7 +26,9 @@
<constraint firstAttribute="height" constant="22" id="dyG-5Y-91s"/> <constraint firstAttribute="height" constant="22" id="dyG-5Y-91s"/>
<constraint firstAttribute="width" constant="22" id="sWQ-3z-Z5r"/> <constraint firstAttribute="width" constant="22" id="sWQ-3z-Z5r"/>
</constraints> </constraints>
<state key="normal" image="Remove"/> <state key="normal" image="xmark.circle.fill" catalog="system">
<preferredSymbolConfiguration key="preferredSymbolConfiguration" scale="large"/>
</state>
<connections> <connections>
<action selector="removePressed:" destination="iN0-l3-epB" eventType="touchUpInside" id="aor-Cq-YjJ"/> <action selector="removePressed:" destination="iN0-l3-epB" eventType="touchUpInside" id="aor-Cq-YjJ"/>
</connections> </connections>
@ -48,7 +50,7 @@
</label> </label>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0h4-wv-2R8"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0h4-wv-2R8">
<rect key="frame" x="0.0" y="0.0" width="375" height="1"/> <rect key="frame" x="0.0" y="0.0" width="375" height="1"/>
<color key="backgroundColor" systemColor="separatorColor" red="0.23529411764705882" green="0.23529411764705882" blue="0.2627450980392157" alpha="0.28999999999999998" colorSpace="custom" customColorSpace="sRGB"/> <color key="backgroundColor" systemColor="separatorColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.28999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="1" id="aQa-2T-uYY"/> <constraint firstAttribute="height" constant="1" id="aQa-2T-uYY"/>
</constraints> </constraints>
@ -83,6 +85,6 @@
</view> </view>
</objects> </objects>
<resources> <resources>
<image name="Remove" width="81" height="81"/> <image name="xmark.circle.fill" catalog="system" width="64" height="60"/>
</resources> </resources>
</document> </document>

View File

@ -0,0 +1,142 @@
//
// FollowRequestNotificationTableViewCell.swift
// Tusker
//
// Created by Shadowfacts on 1/4/20.
// Copyright © 2020 Shadowfacts. All rights reserved.
//
import UIKit
import Pachyderm
class FollowRequestNotificationTableViewCell: UITableViewCell {
var delegate: TuskerNavigationDelegate?
@IBOutlet weak var stackView: UIStackView!
@IBOutlet weak var avatarImageView: UIImageView!
@IBOutlet weak var timestampLabel: UILabel!
@IBOutlet weak var actionLabel: UILabel!
@IBOutlet weak var actionButtonsStackView: UIStackView!
@IBOutlet weak var acceptButton: UIButton!
@IBOutlet weak var rejectButton: UIButton!
var notification: Pachyderm.Notification?
var account: Account!
var updateTimestampWorkItem: DispatchWorkItem?
override func awakeFromNib() {
super.awakeFromNib()
avatarImageView.layer.masksToBounds = true
NotificationCenter.default.addObserver(self, selector: #selector(updateUIForPreferences), name: .preferencesChanged, object: nil)
updateUIForPreferences()
}
@objc func updateUIForPreferences() {
avatarImageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadiusFraction * 30
}
func updateUI(notification: Pachyderm.Notification) {
self.notification = notification
updateUI(account: notification.account)
updateTimestamp()
}
func updateUI(account: Account) {
self.account = account
actionLabel.text = "Request to follow from \(account.realDisplayName)"
ImageCache.avatars.get(account.avatar) { (data) in
guard self.account == account, let data = data, let image = UIImage(data: data) else { return }
DispatchQueue.main.async {
self.avatarImageView.image = image
}
}
}
func updateTimestamp() {
guard let notification = notification else { return }
timestampLabel.text = notification.createdAt.timeAgoString()
let delay: DispatchTimeInterval?
switch notification.createdAt.timeAgo().1 {
case .second:
delay = .seconds(10)
case .minute:
delay = .seconds(60)
default:
delay = nil
}
if let delay = delay {
updateTimestampWorkItem = DispatchWorkItem(block: self.updateTimestamp)
DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: updateTimestampWorkItem!)
} else {
updateTimestampWorkItem = nil
}
}
override func prepareForReuse() {
super.prepareForReuse()
updateTimestampWorkItem?.cancel()
updateTimestampWorkItem = nil
}
// MARK: - Interaction
@IBAction func rejectButtonPressed() {
let request = Account.rejectFollowRequest(account)
MastodonController.client.run(request) { (response) in
guard case let .success(relationship, _) = response else { fatalError() }
MastodonCache.add(relationship: relationship)
DispatchQueue.main.async {
UINotificationFeedbackGenerator().notificationOccurred(.success)
self.actionButtonsStackView.isHidden = true
let label = UILabel()
label.textAlignment = .center
label.font = .boldSystemFont(ofSize: 17)
label.text = NSLocalizedString("Rejected", comment: "rejected follow request label")
self.stackView.addArrangedSubview(label)
}
}
}
@IBAction func acceptButtonPressed() {
let request = Account.authorizeFollowRequest(account)
MastodonController.client.run(request) { (response) in
guard case let .success(relationship, _) = response else { fatalError() }
MastodonCache.add(relationship: relationship)
DispatchQueue.main.async {
UINotificationFeedbackGenerator().notificationOccurred(.success)
self.actionButtonsStackView.isHidden = true
let label = UILabel()
label.textAlignment = .center
label.font = .boldSystemFont(ofSize: 17)
label.text = NSLocalizedString("Accepted", comment: "accepted follow request label")
self.stackView.addArrangedSubview(label)
}
}
}
}
extension FollowRequestNotificationTableViewCell: SelectableTableViewCell {
func didSelectCell() {
delegate?.selected(account: account.id)
}
}
extension FollowRequestNotificationTableViewCell: MenuPreviewProvider {
var navigationDelegate: TuskerNavigationDelegate? { return delegate }
func getPreviewProviders(for location: CGPoint, sourceViewController: UIViewController) -> PreviewProviders? {
return (content: {
return ProfileTableViewController(accountID: self.account.id)
}, actions: {
return []
})
}
}

View File

@ -0,0 +1,109 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15702" 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="15704"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="107" id="Pcu-ap-Xqf" customClass="FollowRequestNotificationTableViewCell" customModule="Tusker" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="320" height="107"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Pcu-ap-Xqf" id="Ulr-P8-MK9">
<rect key="frame" x="0.0" y="0.0" width="320" height="107"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="Cth-1T-Km3">
<rect key="frame" x="74" y="11" width="230" height="85"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="G6v-p7-JbC">
<rect key="frame" x="0.0" y="0.0" width="230" height="30"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="0j2-g5-Y0W">
<rect key="frame" x="0.0" y="0.0" width="30" height="30"/>
<constraints>
<constraint firstAttribute="width" secondItem="0j2-g5-Y0W" secondAttribute="height" multiplier="1:1" id="05S-TD-ePl"/>
<constraint firstAttribute="height" constant="30" id="KCp-Zt-Cm6"/>
</constraints>
</imageView>
<view contentMode="scaleToFill" horizontalHuggingPriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="9WN-Ql-DDL">
<rect key="frame" x="30" y="0.0" width="175.5" height="30"/>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" text="2m" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Saq-P5-oVH">
<rect key="frame" x="205.5" y="0.0" width="24.5" height="30"/>
<fontDescription key="fontDescription" type="system" weight="light" pointSize="17"/>
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Request to follow by Person 1" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="aM6-C6-9QH">
<rect key="frame" x="0.0" y="34" width="230" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" translatesAutoresizingMaskIntoConstraints="NO" id="20F-2n-eQx">
<rect key="frame" x="0.0" y="58.5" width="230" height="26.5"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="CMQ-TI-X9k">
<rect key="frame" x="0.0" y="0.0" width="115" height="26.5"/>
<state key="normal" image="checkmark.circle.fill" catalog="system">
<preferredSymbolConfiguration key="preferredSymbolConfiguration" configurationType="pointSize" pointSize="22"/>
</state>
<connections>
<action selector="acceptButtonPressed" destination="Pcu-ap-Xqf" eventType="touchUpInside" id="hGw-3d-RNi"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="7MW-rY-m5l">
<rect key="frame" x="115" y="0.0" width="115" height="26.5"/>
<state key="normal" image="xmark.circle.fill" catalog="system">
<preferredSymbolConfiguration key="preferredSymbolConfiguration" configurationType="pointSize" pointSize="22"/>
</state>
<connections>
<action selector="rejectButtonPressed" destination="Pcu-ap-Xqf" eventType="touchUpInside" id="EP6-Bg-3nC"/>
</connections>
</button>
</subviews>
</stackView>
</subviews>
</stackView>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="person.fill" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="1qX-LD-7ZK">
<rect key="frame" x="36" y="12.5" width="30" height="27"/>
<constraints>
<constraint firstAttribute="height" constant="30" id="UDV-Vb-1bn"/>
<constraint firstAttribute="width" constant="30" id="d5A-cf-hFe"/>
</constraints>
</imageView>
</subviews>
<constraints>
<constraint firstAttribute="trailingMargin" secondItem="Cth-1T-Km3" secondAttribute="trailing" id="9Zn-8U-6HF"/>
<constraint firstItem="Cth-1T-Km3" firstAttribute="top" secondItem="Ulr-P8-MK9" secondAttribute="topMargin" id="EIi-sE-AkN"/>
<constraint firstItem="1qX-LD-7ZK" firstAttribute="top" secondItem="Ulr-P8-MK9" secondAttribute="topMargin" id="GUW-Xm-fLN"/>
<constraint firstItem="Cth-1T-Km3" firstAttribute="leading" secondItem="Ulr-P8-MK9" secondAttribute="leadingMargin" constant="58" id="QvY-68-add"/>
<constraint firstAttribute="bottomMargin" secondItem="Cth-1T-Km3" secondAttribute="bottom" id="aje-GB-qn6"/>
<constraint firstItem="Cth-1T-Km3" firstAttribute="leading" secondItem="1qX-LD-7ZK" secondAttribute="trailing" constant="8" id="qnO-DF-3wu"/>
</constraints>
</tableViewCellContentView>
<viewLayoutGuide key="safeArea" id="ctM-Hq-1Oz"/>
<connections>
<outlet property="acceptButton" destination="CMQ-TI-X9k" id="xL1-MG-SHi"/>
<outlet property="actionButtonsStackView" destination="20F-2n-eQx" id="Uaj-3F-N05"/>
<outlet property="actionLabel" destination="aM6-C6-9QH" id="UfY-EF-7Ya"/>
<outlet property="avatarImageView" destination="0j2-g5-Y0W" id="3Qj-5q-e73"/>
<outlet property="rejectButton" destination="7MW-rY-m5l" id="ZeH-FG-T7M"/>
<outlet property="stackView" destination="Cth-1T-Km3" id="Elz-8v-AFa"/>
<outlet property="timestampLabel" destination="Saq-P5-oVH" id="d6F-HV-HXs"/>
</connections>
<point key="canvasLocation" x="131.8840579710145" y="174.44196428571428"/>
</tableViewCell>
</objects>
<resources>
<image name="checkmark.circle.fill" catalog="system" width="64" height="60"/>
<image name="person.fill" catalog="system" width="64" height="60"/>
<image name="xmark.circle.fill" catalog="system" width="64" height="60"/>
</resources>
</document>