Compare commits
No commits in common. "develop" and "2024.2-121" have entirely different histories.
develop
...
2024.2-121
|
@ -1,157 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<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:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
sodipodi:docname="Tusker.svg"
|
||||
inkscape:version="1.0beta2 (2b71d25, 2019-12-03)"
|
||||
inkscape:export-ydpi="11.52"
|
||||
inkscape:export-xdpi="11.52"
|
||||
inkscape:export-filename="/Users/shadowfacts/Desktop/60x60@2x.png"
|
||||
id="svg8"
|
||||
version="1.1"
|
||||
viewBox="0 0 264.58333 264.58333"
|
||||
height="1000"
|
||||
width="1000">
|
||||
<defs
|
||||
id="defs2">
|
||||
<inkscape:path-effect
|
||||
bendpath1-nodetypes="cc"
|
||||
bendpath4="M 27.271345,85.808468 V 178.94843"
|
||||
bendpath3="M 27.271345,178.94843 H 242.39013"
|
||||
bendpath2="M 242.39013,85.808468 V 178.94843"
|
||||
bendpath1="M 26.897168,85.995557 242.39013,85.808468"
|
||||
xx="true"
|
||||
yy="true"
|
||||
lpeversion="1"
|
||||
is_visible="true"
|
||||
id="path-effect1345"
|
||||
effect="envelope" />
|
||||
<inkscape:path-effect
|
||||
allow_transforms="true"
|
||||
css_properties=""
|
||||
attributes=""
|
||||
method="d"
|
||||
linkeditem=""
|
||||
lpeversion="1"
|
||||
is_visible="true"
|
||||
id="path-effect38"
|
||||
effect="clone_original" />
|
||||
<inkscape:path-effect
|
||||
scale_y_rel="false"
|
||||
prop_scale="1"
|
||||
strokepath="M0,0 L1,0"
|
||||
endpoint_spacing_variation="0;1"
|
||||
endpoint_edge_variation="0;1"
|
||||
startpoint_spacing_variation="0;1"
|
||||
startpoint_edge_variation="0;1"
|
||||
count="5"
|
||||
lpeversion="1"
|
||||
is_visible="true"
|
||||
id="path-effect32"
|
||||
effect="curvestitching" />
|
||||
<filter
|
||||
height="1.3500000000000001"
|
||||
width="1.2"
|
||||
id="filter1277"
|
||||
inkscape:label="Drop Shadow"
|
||||
style="color-interpolation-filters:sRGB;">
|
||||
<feFlood
|
||||
id="feFlood1267"
|
||||
result="flood"
|
||||
flood-color="rgb(0,0,0)"
|
||||
flood-opacity="0.321569" />
|
||||
<feComposite
|
||||
id="feComposite1269"
|
||||
result="composite1"
|
||||
operator="in"
|
||||
in2="SourceGraphic"
|
||||
in="flood" />
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur1271"
|
||||
result="blur"
|
||||
stdDeviation="5"
|
||||
in="composite1" />
|
||||
<feOffset
|
||||
id="feOffset1273"
|
||||
result="offset"
|
||||
dy="5"
|
||||
dx="-2.5" />
|
||||
<feComposite
|
||||
id="feComposite1275"
|
||||
result="composite2"
|
||||
operator="over"
|
||||
in2="offset"
|
||||
in="SourceGraphic" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:window-y="23"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-height="1395"
|
||||
inkscape:window-width="1902"
|
||||
units="px"
|
||||
showgrid="false"
|
||||
inkscape:document-rotation="0"
|
||||
inkscape:current-layer="layer2"
|
||||
inkscape:document-units="px"
|
||||
inkscape:cy="496.39379"
|
||||
inkscape:cx="442.66632"
|
||||
inkscape:zoom="1.4142136"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#ffffff"
|
||||
id="base" />
|
||||
<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 2"
|
||||
id="layer2"
|
||||
inkscape:groupmode="layer">
|
||||
<rect
|
||||
y="-0.14500916"
|
||||
x="-0.14500916"
|
||||
height="264.87335"
|
||||
width="264.87335"
|
||||
id="rect865"
|
||||
style="fill:#75e04e;fill-opacity:1;stroke:#75e04e;stroke-width:0.239149;stroke-opacity:1" />
|
||||
</g>
|
||||
<g
|
||||
style="display:none"
|
||||
id="layer1"
|
||||
inkscape:groupmode="layer"
|
||||
inkscape:label="Layer 1">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 63.595661,96.781172 c 2.610557,8.549728 11.109144,14.261728 18.221441,19.677268 14.285995,10.87784 30.777538,19.16253 47.836068,24.76819 12.08516,3.97134 24.9714,5.89737 37.69211,5.9756 11.75058,0.0723 23.533,-2.04773 34.88282,-5.09124 8.49997,-2.27931 17.13306,-4.99674 24.52676,-9.76937 5.59427,-3.6111 11.35542,-7.93448 14.37737,-13.86775 0.73693,-1.44688 2.00968,-3.90176 0.67356,-4.82442 -4.90929,-3.39011 -10.18592,6.31619 -15.70026,8.59349 -8.68681,3.58745 -17.81526,6.26681 -27.07782,7.85916 -11.94219,2.05301 -24.25018,3.46797 -36.29097,2.10779 -12.7013,-1.4348 -25.14557,-5.50493 -36.82103,-10.70737 -8.48127,-3.77914 -16.22058,-9.14294 -23.66896,-14.68689 C 96.49438,102.53405 91.950513,96.75601 86.13513,92.560411 82.533585,89.96202 79.028923,86.323649 74.610572,85.8754 c -3.438589,-0.34885 -7.602338,0.653715 -9.831133,3.295317 -1.655568,1.962204 -1.933509,5.155042 -1.183778,7.610455 z m -36.276154,1.911751 c 1.000129,9.935377 9.068818,18.042637 15.683118,25.523487 13.285704,15.02628 29.55205,27.69127 47.022482,37.54435 12.376983,6.98044 26.073563,11.90937 39.996973,14.7475 13.12015,2.67439 26.76072,2.8433 40.12178,1.96426 10.02366,-0.65947 20.39718,-1.4876 29.64741,-5.40445 6.55654,-2.77625 13.10939,-6.72368 17.37506,-12.42454 1.08663,-1.45223 3.06381,-3.85048 1.78759,-5.13927 -4.73249,-4.77911 -12.53753,5.06785 -19.12154,6.4416 -10.27704,2.1443 -20.88256,2.99026 -31.37744,2.71972 -13.53101,-0.3488 -27.32398,-1.47627 -40.22043,-5.58617 -13.6039,-4.33535 -26.35283,-11.50217 -38.013078,-19.74231 -8.470214,-5.98579 -15.782756,-13.54635 -22.737346,-21.24101 -5.371021,-5.94258 -9.092383,-13.26181 -14.551151,-19.123884 -3.38068,-3.630455 -6.428954,-8.379273 -11.172348,-9.831658 -3.691559,-1.130322 -8.47165,-0.937751 -11.488322,1.47159 -2.240814,1.789682 -3.239987,5.227417 -2.952758,8.080785 z"
|
||||
style="fill:#f9f7f3;fill-opacity:1;stroke:#d0c1a2;stroke-width:0.565786px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter1277)"
|
||||
id="path28" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:label="Layer 1 copy"
|
||||
inkscape:groupmode="layer"
|
||||
id="g1343">
|
||||
<path
|
||||
id="path1341"
|
||||
style="fill:#f9f7f3;fill-opacity:1;stroke:#d0c1a2;stroke-width:0.56578600000000001px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 63.595661,96.781172 c 2.610557,8.549728 11.109144,14.261728 18.221441,19.677268 14.285995,10.87784 30.777538,19.16253 47.836068,24.76819 12.08516,3.97134 24.9714,5.89737 37.69211,5.9756 11.75058,0.0723 23.533,-2.04773 34.88282,-5.09124 8.49997,-2.27931 17.13306,-4.99674 24.52676,-9.76937 5.59427,-3.6111 11.35542,-7.93448 14.37737,-13.86775 0.73693,-1.44688 2.00968,-3.90176 0.67356,-4.82442 -4.90929,-3.39011 -10.18592,6.31619 -15.70026,8.59349 -8.68681,3.58745 -17.81526,6.26681 -27.07782,7.85916 -11.94219,2.05301 -24.25018,3.46797 -36.29097,2.10779 -12.7013,-1.4348 -25.14557,-5.50493 -36.82103,-10.70737 -8.48127,-3.77914 -16.22058,-9.14294 -23.66896,-14.68689 C 96.49438,102.53405 91.950513,96.75601 86.13513,92.560411 82.533585,89.96202 79.028923,86.323649 74.610572,85.8754 c -3.438589,-0.34885 -7.602338,0.653715 -9.831133,3.295317 -1.655568,1.962204 -1.933509,5.155042 -1.183778,7.610455 z m -36.276154,1.911751 c 1.000129,9.935377 9.068818,18.042637 15.683118,25.523487 13.285704,15.02628 29.55205,27.69127 47.022482,37.54435 12.376983,6.98044 26.073563,11.90937 39.996973,14.7475 13.12015,2.67439 26.76072,2.8433 40.12178,1.96426 10.02366,-0.65947 20.39718,-1.4876 29.64741,-5.40445 6.55654,-2.77625 13.10939,-6.72368 17.37506,-12.42454 1.08663,-1.45223 3.06381,-3.85048 1.78759,-5.13927 -4.73249,-4.77911 -12.53753,5.06785 -19.12154,6.4416 -10.27704,2.1443 -20.88256,2.99026 -31.37744,2.71972 -13.53101,-0.3488 -27.32398,-1.47627 -40.22043,-5.58617 -13.6039,-4.33535 -26.35283,-11.50217 -38.013078,-19.74231 -8.470214,-5.98579 -15.782756,-13.54635 -22.737346,-21.24101 -5.371021,-5.94258 -9.092383,-13.26181 -14.551151,-19.123884 -3.38068,-3.630455 -6.428954,-8.379273 -11.172348,-9.831658 -3.691559,-1.130322 -8.47165,-0.937751 -11.488322,1.47159 -2.240814,1.789682 -3.239987,5.227417 -2.952758,8.080785 z" />
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 8.1 KiB |
|
@ -1,153 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
sodipodi:docname="Tusker transparent.svg"
|
||||
inkscape:version="1.3.2 (091e20e, 2023-11-25)"
|
||||
inkscape:export-ydpi="98.304001"
|
||||
inkscape:export-xdpi="98.304001"
|
||||
inkscape:export-filename="../Desktop/1024x1024-dark@1x.png"
|
||||
id="svg8"
|
||||
version="1.1"
|
||||
viewBox="0 0 264.58333 264.58333"
|
||||
height="1000"
|
||||
width="1000"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs2">
|
||||
<inkscape:path-effect
|
||||
bendpath1-nodetypes="cc"
|
||||
bendpath4="M 27.271345,85.808468 V 178.94843"
|
||||
bendpath3="M 27.271345,178.94843 H 242.39013"
|
||||
bendpath2="M 242.39013,85.808468 V 178.94843"
|
||||
bendpath1="M 26.897168,85.995557 242.39013,85.808468"
|
||||
xx="true"
|
||||
yy="true"
|
||||
lpeversion="1"
|
||||
is_visible="true"
|
||||
id="path-effect1345"
|
||||
effect="envelope" />
|
||||
<inkscape:path-effect
|
||||
allow_transforms="true"
|
||||
css_properties=""
|
||||
attributes=""
|
||||
method="d"
|
||||
linkeditem=""
|
||||
lpeversion="1"
|
||||
is_visible="true"
|
||||
id="path-effect38"
|
||||
effect="clone_original" />
|
||||
<inkscape:path-effect
|
||||
scale_y_rel="false"
|
||||
prop_scale="1"
|
||||
strokepath="M0,0 L1,0"
|
||||
endpoint_spacing_variation="0;1"
|
||||
endpoint_edge_variation="0;1"
|
||||
startpoint_spacing_variation="0;1"
|
||||
startpoint_edge_variation="0;1"
|
||||
count="5"
|
||||
lpeversion="1"
|
||||
is_visible="true"
|
||||
id="path-effect32"
|
||||
effect="curvestitching" />
|
||||
<filter
|
||||
height="1.317445"
|
||||
width="1.1258237"
|
||||
id="filter1277"
|
||||
inkscape:label="Drop Shadow"
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
x="-0.068723437"
|
||||
y="-0.1318855">
|
||||
<feFlood
|
||||
id="feFlood1267"
|
||||
result="flood"
|
||||
flood-color="rgb(0,0,0)"
|
||||
flood-opacity="0.321569" />
|
||||
<feComposite
|
||||
id="feComposite1269"
|
||||
result="composite1"
|
||||
operator="in"
|
||||
in2="SourceGraphic"
|
||||
in="flood" />
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur1271"
|
||||
result="blur"
|
||||
stdDeviation="5"
|
||||
in="composite1" />
|
||||
<feOffset
|
||||
id="feOffset1273"
|
||||
result="offset"
|
||||
dy="5"
|
||||
dx="-2.5" />
|
||||
<feComposite
|
||||
id="feComposite1275"
|
||||
result="composite2"
|
||||
operator="over"
|
||||
in2="offset"
|
||||
in="SourceGraphic" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:window-y="25"
|
||||
inkscape:window-x="1280"
|
||||
inkscape:window-height="1387"
|
||||
inkscape:window-width="1280"
|
||||
units="px"
|
||||
showgrid="false"
|
||||
inkscape:document-rotation="0"
|
||||
inkscape:current-layer="layer2"
|
||||
inkscape:document-units="px"
|
||||
inkscape:cy="404.46507"
|
||||
inkscape:cx="442.29528"
|
||||
inkscape:zoom="1.4142136"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#ffffff"
|
||||
id="base"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1" />
|
||||
<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" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 2"
|
||||
id="layer2"
|
||||
inkscape:groupmode="layer" />
|
||||
<g
|
||||
style="display:none"
|
||||
id="layer1"
|
||||
inkscape:groupmode="layer"
|
||||
inkscape:label="Layer 1">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 63.595661,96.781172 c 2.610557,8.549728 11.109144,14.261728 18.221441,19.677268 14.285995,10.87784 30.777538,19.16253 47.836068,24.76819 12.08516,3.97134 24.9714,5.89737 37.69211,5.9756 11.75058,0.0723 23.533,-2.04773 34.88282,-5.09124 8.49997,-2.27931 17.13306,-4.99674 24.52676,-9.76937 5.59427,-3.6111 11.35542,-7.93448 14.37737,-13.86775 0.73693,-1.44688 2.00968,-3.90176 0.67356,-4.82442 -4.90929,-3.39011 -10.18592,6.31619 -15.70026,8.59349 -8.68681,3.58745 -17.81526,6.26681 -27.07782,7.85916 -11.94219,2.05301 -24.25018,3.46797 -36.29097,2.10779 -12.7013,-1.4348 -25.14557,-5.50493 -36.82103,-10.70737 -8.48127,-3.77914 -16.22058,-9.14294 -23.66896,-14.68689 C 96.49438,102.53405 91.950513,96.75601 86.13513,92.560411 82.533585,89.96202 79.028923,86.323649 74.610572,85.8754 c -3.438589,-0.34885 -7.602338,0.653715 -9.831133,3.295317 -1.655568,1.962204 -1.933509,5.155042 -1.183778,7.610455 z m -36.276154,1.911751 c 1.000129,9.935377 9.068818,18.042637 15.683118,25.523487 13.285704,15.02628 29.55205,27.69127 47.022482,37.54435 12.376983,6.98044 26.073563,11.90937 39.996973,14.7475 13.12015,2.67439 26.76072,2.8433 40.12178,1.96426 10.02366,-0.65947 20.39718,-1.4876 29.64741,-5.40445 6.55654,-2.77625 13.10939,-6.72368 17.37506,-12.42454 1.08663,-1.45223 3.06381,-3.85048 1.78759,-5.13927 -4.73249,-4.77911 -12.53753,5.06785 -19.12154,6.4416 -10.27704,2.1443 -20.88256,2.99026 -31.37744,2.71972 -13.53101,-0.3488 -27.32398,-1.47627 -40.22043,-5.58617 -13.6039,-4.33535 -26.35283,-11.50217 -38.013078,-19.74231 -8.470214,-5.98579 -15.782756,-13.54635 -22.737346,-21.24101 -5.371021,-5.94258 -9.092383,-13.26181 -14.551151,-19.123884 -3.38068,-3.630455 -6.428954,-8.379273 -11.172348,-9.831658 -3.691559,-1.130322 -8.47165,-0.937751 -11.488322,1.47159 -2.240814,1.789682 -3.239987,5.227417 -2.952758,8.080785 z"
|
||||
style="fill:#f9f7f3;fill-opacity:1;stroke:#d0c1a2;stroke-width:0.565786px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter1277)"
|
||||
id="path28" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:label="Layer 1 copy"
|
||||
inkscape:groupmode="layer"
|
||||
id="g1343">
|
||||
<path
|
||||
id="path1341"
|
||||
style="fill:#75e04e;fill-opacity:1;stroke:#74e04d;stroke-width:0.565786px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 63.595661,96.781172 c 2.610557,8.549728 11.109144,14.261728 18.221441,19.677268 14.285995,10.87784 30.777538,19.16253 47.836068,24.76819 12.08516,3.97134 24.9714,5.89737 37.69211,5.9756 11.75058,0.0723 23.533,-2.04773 34.88282,-5.09124 8.49997,-2.27931 17.13306,-4.99674 24.52676,-9.76937 5.59427,-3.6111 11.35542,-7.93448 14.37737,-13.86775 0.73693,-1.44688 2.00968,-3.90176 0.67356,-4.82442 -4.90929,-3.39011 -10.18592,6.31619 -15.70026,8.59349 -8.68681,3.58745 -17.81526,6.26681 -27.07782,7.85916 -11.94219,2.05301 -24.25018,3.46797 -36.29097,2.10779 -12.7013,-1.4348 -25.14557,-5.50493 -36.82103,-10.70737 -8.48127,-3.77914 -16.22058,-9.14294 -23.66896,-14.68689 C 96.49438,102.53405 91.950513,96.75601 86.13513,92.560411 82.533585,89.96202 79.028923,86.323649 74.610572,85.8754 c -3.438589,-0.34885 -7.602338,0.653715 -9.831133,3.295317 -1.655568,1.962204 -1.933509,5.155042 -1.183778,7.610455 z m -36.276154,1.911751 c 1.000129,9.935377 9.068818,18.042637 15.683118,25.523487 13.285704,15.02628 29.55205,27.69127 47.022482,37.54435 12.376983,6.98044 26.073563,11.90937 39.996973,14.7475 13.12015,2.67439 26.76072,2.8433 40.12178,1.96426 10.02366,-0.65947 20.39718,-1.4876 29.64741,-5.40445 6.55654,-2.77625 13.10939,-6.72368 17.37506,-12.42454 1.08663,-1.45223 3.06381,-3.85048 1.78759,-5.13927 -4.73249,-4.77911 -12.53753,5.06785 -19.12154,6.4416 -10.27704,2.1443 -20.88256,2.99026 -31.37744,2.71972 -13.53101,-0.3488 -27.32398,-1.47627 -40.22043,-5.58617 -13.6039,-4.33535 -26.35283,-11.50217 -38.013078,-19.74231 -8.470214,-5.98579 -15.782756,-13.54635 -22.737346,-21.24101 -5.371021,-5.94258 -9.092383,-13.26181 -14.551151,-19.123884 -3.38068,-3.630455 -6.428954,-8.379273 -11.172348,-9.831658 -3.691559,-1.130322 -8.47165,-0.937751 -11.488322,1.47159 -2.240814,1.789682 -3.239987,5.227417 -2.952758,8.080785 z" />
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 7.9 KiB |
|
@ -1,162 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
sodipodi:docname="Tusker.svg"
|
||||
inkscape:version="1.3.2 (091e20e, 2023-11-25)"
|
||||
inkscape:export-ydpi="98.304001"
|
||||
inkscape:export-xdpi="98.304001"
|
||||
inkscape:export-filename="../Desktop/1024x1024@1x.png"
|
||||
id="svg8"
|
||||
version="1.1"
|
||||
viewBox="0 0 264.58333 264.58333"
|
||||
height="1000"
|
||||
width="1000"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs2">
|
||||
<inkscape:path-effect
|
||||
bendpath1-nodetypes="cc"
|
||||
bendpath4="M 27.271345,85.808468 V 178.94843"
|
||||
bendpath3="M 27.271345,178.94843 H 242.39013"
|
||||
bendpath2="M 242.39013,85.808468 V 178.94843"
|
||||
bendpath1="M 26.897168,85.995557 242.39013,85.808468"
|
||||
xx="true"
|
||||
yy="true"
|
||||
lpeversion="1"
|
||||
is_visible="true"
|
||||
id="path-effect1345"
|
||||
effect="envelope" />
|
||||
<inkscape:path-effect
|
||||
allow_transforms="true"
|
||||
css_properties=""
|
||||
attributes=""
|
||||
method="d"
|
||||
linkeditem=""
|
||||
lpeversion="1"
|
||||
is_visible="true"
|
||||
id="path-effect38"
|
||||
effect="clone_original" />
|
||||
<inkscape:path-effect
|
||||
scale_y_rel="false"
|
||||
prop_scale="1"
|
||||
strokepath="M0,0 L1,0"
|
||||
endpoint_spacing_variation="0;1"
|
||||
endpoint_edge_variation="0;1"
|
||||
startpoint_spacing_variation="0;1"
|
||||
startpoint_edge_variation="0;1"
|
||||
count="5"
|
||||
lpeversion="1"
|
||||
is_visible="true"
|
||||
id="path-effect32"
|
||||
effect="curvestitching" />
|
||||
<filter
|
||||
height="1.317445"
|
||||
width="1.1258237"
|
||||
id="filter1277"
|
||||
inkscape:label="Drop Shadow"
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
x="-0.068723437"
|
||||
y="-0.1318855">
|
||||
<feFlood
|
||||
id="feFlood1267"
|
||||
result="flood"
|
||||
flood-color="rgb(0,0,0)"
|
||||
flood-opacity="0.321569" />
|
||||
<feComposite
|
||||
id="feComposite1269"
|
||||
result="composite1"
|
||||
operator="in"
|
||||
in2="SourceGraphic"
|
||||
in="flood" />
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur1271"
|
||||
result="blur"
|
||||
stdDeviation="5"
|
||||
in="composite1" />
|
||||
<feOffset
|
||||
id="feOffset1273"
|
||||
result="offset"
|
||||
dy="5"
|
||||
dx="-2.5" />
|
||||
<feComposite
|
||||
id="feComposite1275"
|
||||
result="composite2"
|
||||
operator="over"
|
||||
in2="offset"
|
||||
in="SourceGraphic" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:window-y="25"
|
||||
inkscape:window-x="1280"
|
||||
inkscape:window-height="1387"
|
||||
inkscape:window-width="1280"
|
||||
units="px"
|
||||
showgrid="false"
|
||||
inkscape:document-rotation="0"
|
||||
inkscape:current-layer="layer2"
|
||||
inkscape:document-units="px"
|
||||
inkscape:cy="496.38895"
|
||||
inkscape:cx="442.29528"
|
||||
inkscape:zoom="1.4142136"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#ffffff"
|
||||
id="base"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1" />
|
||||
<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 />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 2"
|
||||
id="layer2"
|
||||
inkscape:groupmode="layer">
|
||||
<rect
|
||||
y="-0.14500916"
|
||||
x="-0.14500916"
|
||||
height="264.87335"
|
||||
width="264.87335"
|
||||
id="rect865"
|
||||
style="fill:#75e04e;fill-opacity:1;stroke:#75e04e;stroke-width:0.239149;stroke-opacity:1" />
|
||||
</g>
|
||||
<g
|
||||
style="display:none"
|
||||
id="layer1"
|
||||
inkscape:groupmode="layer"
|
||||
inkscape:label="Layer 1">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 63.595661,96.781172 c 2.610557,8.549728 11.109144,14.261728 18.221441,19.677268 14.285995,10.87784 30.777538,19.16253 47.836068,24.76819 12.08516,3.97134 24.9714,5.89737 37.69211,5.9756 11.75058,0.0723 23.533,-2.04773 34.88282,-5.09124 8.49997,-2.27931 17.13306,-4.99674 24.52676,-9.76937 5.59427,-3.6111 11.35542,-7.93448 14.37737,-13.86775 0.73693,-1.44688 2.00968,-3.90176 0.67356,-4.82442 -4.90929,-3.39011 -10.18592,6.31619 -15.70026,8.59349 -8.68681,3.58745 -17.81526,6.26681 -27.07782,7.85916 -11.94219,2.05301 -24.25018,3.46797 -36.29097,2.10779 -12.7013,-1.4348 -25.14557,-5.50493 -36.82103,-10.70737 -8.48127,-3.77914 -16.22058,-9.14294 -23.66896,-14.68689 C 96.49438,102.53405 91.950513,96.75601 86.13513,92.560411 82.533585,89.96202 79.028923,86.323649 74.610572,85.8754 c -3.438589,-0.34885 -7.602338,0.653715 -9.831133,3.295317 -1.655568,1.962204 -1.933509,5.155042 -1.183778,7.610455 z m -36.276154,1.911751 c 1.000129,9.935377 9.068818,18.042637 15.683118,25.523487 13.285704,15.02628 29.55205,27.69127 47.022482,37.54435 12.376983,6.98044 26.073563,11.90937 39.996973,14.7475 13.12015,2.67439 26.76072,2.8433 40.12178,1.96426 10.02366,-0.65947 20.39718,-1.4876 29.64741,-5.40445 6.55654,-2.77625 13.10939,-6.72368 17.37506,-12.42454 1.08663,-1.45223 3.06381,-3.85048 1.78759,-5.13927 -4.73249,-4.77911 -12.53753,5.06785 -19.12154,6.4416 -10.27704,2.1443 -20.88256,2.99026 -31.37744,2.71972 -13.53101,-0.3488 -27.32398,-1.47627 -40.22043,-5.58617 -13.6039,-4.33535 -26.35283,-11.50217 -38.013078,-19.74231 -8.470214,-5.98579 -15.782756,-13.54635 -22.737346,-21.24101 -5.371021,-5.94258 -9.092383,-13.26181 -14.551151,-19.123884 -3.38068,-3.630455 -6.428954,-8.379273 -11.172348,-9.831658 -3.691559,-1.130322 -8.47165,-0.937751 -11.488322,1.47159 -2.240814,1.789682 -3.239987,5.227417 -2.952758,8.080785 z"
|
||||
style="fill:#f9f7f3;fill-opacity:1;stroke:#d0c1a2;stroke-width:0.565786px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter1277)"
|
||||
id="path28" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:label="Layer 1 copy"
|
||||
inkscape:groupmode="layer"
|
||||
id="g1343">
|
||||
<path
|
||||
id="path1341"
|
||||
style="fill:#f9f7f3;fill-opacity:1;stroke:#d0c1a2;stroke-width:0.56578600000000001px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter1277)"
|
||||
d="m 63.595661,96.781172 c 2.610557,8.549728 11.109144,14.261728 18.221441,19.677268 14.285995,10.87784 30.777538,19.16253 47.836068,24.76819 12.08516,3.97134 24.9714,5.89737 37.69211,5.9756 11.75058,0.0723 23.533,-2.04773 34.88282,-5.09124 8.49997,-2.27931 17.13306,-4.99674 24.52676,-9.76937 5.59427,-3.6111 11.35542,-7.93448 14.37737,-13.86775 0.73693,-1.44688 2.00968,-3.90176 0.67356,-4.82442 -4.90929,-3.39011 -10.18592,6.31619 -15.70026,8.59349 -8.68681,3.58745 -17.81526,6.26681 -27.07782,7.85916 -11.94219,2.05301 -24.25018,3.46797 -36.29097,2.10779 -12.7013,-1.4348 -25.14557,-5.50493 -36.82103,-10.70737 -8.48127,-3.77914 -16.22058,-9.14294 -23.66896,-14.68689 C 96.49438,102.53405 91.950513,96.75601 86.13513,92.560411 82.533585,89.96202 79.028923,86.323649 74.610572,85.8754 c -3.438589,-0.34885 -7.602338,0.653715 -9.831133,3.295317 -1.655568,1.962204 -1.933509,5.155042 -1.183778,7.610455 z m -36.276154,1.911751 c 1.000129,9.935377 9.068818,18.042637 15.683118,25.523487 13.285704,15.02628 29.55205,27.69127 47.022482,37.54435 12.376983,6.98044 26.073563,11.90937 39.996973,14.7475 13.12015,2.67439 26.76072,2.8433 40.12178,1.96426 10.02366,-0.65947 20.39718,-1.4876 29.64741,-5.40445 6.55654,-2.77625 13.10939,-6.72368 17.37506,-12.42454 1.08663,-1.45223 3.06381,-3.85048 1.78759,-5.13927 -4.73249,-4.77911 -12.53753,5.06785 -19.12154,6.4416 -10.27704,2.1443 -20.88256,2.99026 -31.37744,2.71972 -13.53101,-0.3488 -27.32398,-1.47627 -40.22043,-5.58617 -13.6039,-4.33535 -26.35283,-11.50217 -38.013078,-19.74231 -8.470214,-5.98579 -15.782756,-13.54635 -22.737346,-21.24101 -5.371021,-5.94258 -9.092383,-13.26181 -14.551151,-19.123884 -3.38068,-3.630455 -6.428954,-8.379273 -11.172348,-9.831658 -3.691559,-1.130322 -8.47165,-0.937751 -11.488322,1.47159 -2.240814,1.789682 -3.239987,5.227417 -2.952758,8.080785 z" />
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 8.2 KiB |
|
@ -1,66 +1,3 @@
|
|||
## 2024.4
|
||||
This release introduces support for iOS 18, including a new sidebar/tab bar on iPad, as well as bugfixes and improvements.
|
||||
|
||||
Features/Improvements:
|
||||
- Import image description when adding attachments from Photos if possible
|
||||
- iPadOS 18: New floating sidebar/tab bar
|
||||
|
||||
Bugfixes:
|
||||
- Fix crash when viewing profiles in certain circumstances
|
||||
- Fix video controls in attachment gallery not auto-hiding
|
||||
- Fix crash if hashtag search results includes duplicates
|
||||
- Fix "no content" text not being removed from list timeline after refreshing
|
||||
- macOS: Fix video controls overlay being positioned incorrectly when Reduce Motion is on
|
||||
- macOS: Fix reselecting current item not navigating back
|
||||
|
||||
## 2024.3
|
||||
This update includes a number of bugfixes and performance improvements. See below for a list of fixes.
|
||||
|
||||
Bugfixes:
|
||||
- Fix an issue displaying rich text in certain cases
|
||||
- Fix crash when video attachment finishes playing
|
||||
- Fix video attachment thumbnails being flipped on Compose screen
|
||||
- Fix profile header images being blurry
|
||||
- Fix crash when opening push notifications in certain circumstances
|
||||
- Fix certain links in profile fields not being tappable
|
||||
- Fix gifv playback pausing audio from other apps
|
||||
- Fix gifv playback being paused when returning from background
|
||||
- Fix badges on gifv attachments not appearing
|
||||
- Fix excessive network traffic when opening profile pages
|
||||
- Fix controls visibility not matching across attachment gallery pages
|
||||
- Fix add hashtag/instance pinned timeline sheet in Customize Timelines dismissing instantly
|
||||
- Fix Dynamic Type not applying to status content
|
||||
- Fix mention/status push notifications not showing CW
|
||||
- Fix sensitive attachment thumbnails being shown in push notifications
|
||||
- Fix profile moved overlay visual and VoiceOver issues
|
||||
- Fix opening Mastodon remote status links
|
||||
- Fix reply author avatar on Compose screen not being pinned to top when scrolling while typing
|
||||
- Pleroma/Akkoma: Fix editing attachment descriptions not working
|
||||
- Pixelfed/Firefish: Fix error loading certain accounts
|
||||
- Pixelfed: Fix error loading relationships and follow/block/etc. actions
|
||||
- iPadOS: Fix pointer interactions throughout the app
|
||||
- iPadOS: Fix multiple close buttons being added in multi-column interface
|
||||
- iPadOS: Fix Cmd+1/etc. removing columns when returning to previous tab
|
||||
- iPadOS: Fix multi-column interface not animating for some actions
|
||||
- iPadOS: Fix selecting search results always adding new column
|
||||
|
||||
## 2024.2
|
||||
This release introduces push notifications as well as an enhanced multi-column interface on iPadOS!
|
||||
|
||||
Features/Improvements:
|
||||
- Push notifications
|
||||
- Add post preview to Appearance preferences
|
||||
- Show instance announcements in Notifications tab
|
||||
- Add subscription option to Tip Jar
|
||||
- iPadOS: Multi-column navigation
|
||||
- Pleroma/Akkoma: Emoji reaction notifications
|
||||
|
||||
Bugfixes:
|
||||
- Fix fetching server info on some instances
|
||||
- Fix attachment captions not displaying while loading in gallery
|
||||
- macOS: Remove in-app Safari preferences
|
||||
- Pleroma: Handle posts with missing creation date
|
||||
|
||||
## 2024.1
|
||||
This update includes a significant improvements for the attachment gallery and displaying rich text posts. See below for a full list of improvements and fixes.
|
||||
|
||||
|
|
122
CHANGELOG.md
|
@ -1,127 +1,5 @@
|
|||
# Changelog
|
||||
|
||||
## 2024.4 (136)
|
||||
Features/Improvements:
|
||||
- Import image description when adding attachments from Photos if possible
|
||||
- Reorganize toolbar buttons when adding saved hashtag
|
||||
- Show errors when loading video in attachment gallery fails
|
||||
|
||||
Bugfixes:
|
||||
- Fix crash when viewing profiles in certain circumstances
|
||||
- Fix profile tab switching animation getting stuck
|
||||
- Fix video controls in attachment gallery not auto-hiding
|
||||
- Pleroma: Fix error when loading polls in some circumstances
|
||||
- iPadOS 18: Fix incorrect two-column layout when closing sidebar
|
||||
- macOS: Fix video controls overlay being positioned incorrectly when Reduce Motion is on
|
||||
- macOS: Fix reselecting current item not navigating back
|
||||
|
||||
## 2024.4 (135)
|
||||
Features/Improvements:
|
||||
- iOS 18: New floating sidebar/tab bar
|
||||
|
||||
Bugfixes:
|
||||
- Fix crash when hashtag search results include duplicates
|
||||
- Fix "no content" text not being removed from list timeline after refreshing
|
||||
|
||||
## 2024.3 (133)
|
||||
- Add additional info to Tip Jar
|
||||
|
||||
## 2024.3 (132)
|
||||
- Add ToS nag before signing in
|
||||
|
||||
## 2024.3 (131)
|
||||
Bugfixes:
|
||||
- Fix Cmd+3 not correctly switching to Explore tab
|
||||
|
||||
## 2024.3 (130)
|
||||
Bugfixes:
|
||||
- Fix reply author avatar on Compose screen not being pinned to top when scrolling while typing
|
||||
- Fix crash when dragging between buttons in reblog confirmation alert
|
||||
- Fix potential crash when displaying search results
|
||||
- Mac: Fix Post button not displaying on Compose screen
|
||||
|
||||
## 2024.3 (129)
|
||||
Bugfixes:
|
||||
- Fix excessive network traffic on profile pages
|
||||
- Fix attachment gallery controls visibility not being synced between pages
|
||||
- Fix video attachments not restarting when play pressed while at ends
|
||||
- Fix profile field text being misaligned
|
||||
- Fix at sign in timeline statuses usernames sometimes clipping
|
||||
- Fix add hashtag/instance to Pinned Timelines sheets dismissing immediately when opened
|
||||
- Fix for display name being replaced with incorrect user in certain circumstances
|
||||
- Fix profile moved overlay view appearing behind avatar/header
|
||||
- Fix profile moved view accessibility with VoiceOver
|
||||
- Fix mention/status push notifications not showing content warning
|
||||
- Fix sensitive attachment thumbnails being shown in push notifications
|
||||
- Fix Dynamic Type not applying to status content
|
||||
- Fix expand all option in Conversation not transferring when opening ancestors
|
||||
- Fix not being able to resolve remote Mastodon status links in Conversation screen
|
||||
- Fix status indicator icons overlapping thread links when Dynamic Type is enabled
|
||||
|
||||
## 2024.3 (128)
|
||||
Bugfixes:
|
||||
- Fix selecting poll option playing too much haptic feedback
|
||||
- Fix crash when displaying HTML in certain posts
|
||||
- Fix gifv playback pausing audio from other apps
|
||||
- Fix gifv playback not resuming after returning from background
|
||||
- Fix attachment badges not appearing on gifvs
|
||||
- iPadOS: Fix poll options not having pointer hover effects
|
||||
- iPadOS: Fix haptic feedback not working on new Magic Keyboard
|
||||
- iPadOS: Fix scrubbing video with pointer not letting you click to select position
|
||||
- iPadOS: Fix multi-column navigation not animating when replacing multiple columns
|
||||
|
||||
## 2024.3 (127)
|
||||
Bugfixes:
|
||||
- Fix Remove Suggestion context menu action missing from Suggested Accounts screen
|
||||
- Fix profile header images being blurry
|
||||
- Fix dismissing gallery when presented from sheet
|
||||
- Fix potential crash in multi-column interface
|
||||
- Fix crash when opening push notification while sheet presented
|
||||
- Fix being able to block your own domain
|
||||
- Fix links in profile fields with other text not being interactable
|
||||
- Fix excessive CPU use immediately after app launch
|
||||
- Fix timeline failing to load when one status is malformed
|
||||
- iPadOS: Fix pointer interactions on conversation main status action buttons
|
||||
- iPadOS: Fix multiple close buttons being added in multi-column interface
|
||||
- iPadOS: Fix Cmd+1/etc. resetting navigation state when returning to previous column
|
||||
- iPadOS: Fix previous sidebar selection losing navigation state in some circumstances
|
||||
- iPadOS: Fix profile followers/following buttons not having pointer effect
|
||||
- iPadOS: Fix search token suggestions not having pointer effect
|
||||
- iPadOS: Fix conversation thread links appearing above avatar during pointer effect
|
||||
- iPadOS: Fix multi-column interface not animating scroll when replacing subsequent columns
|
||||
- iPadOS: Fix not being able to select text on conversation main status by double-clicking with cursor
|
||||
- iPadOS: Fix selecting search result always pushing new column rather than replacing
|
||||
- Pixelfed/Firefish: Fix error loading accounts in some circumstances
|
||||
- Pixelfed: Fix loading relationships and follow/block/etc. actions not working
|
||||
|
||||
## 2024.3 (126)
|
||||
Bugfixes:
|
||||
- Fix an issue displaying post HTML in certain edge cases
|
||||
- Fix crash when video attachment playback ends
|
||||
- Fix excessive CPU usage when scrubbing video attachment
|
||||
- Fix video attachment thubmnails being flipped on Compose screen
|
||||
- Pleroma: Fix editing attachment descriptions not working
|
||||
|
||||
## 2024.2 (124)
|
||||
Features/Improvements:
|
||||
- Add subscription option to Tip Jar
|
||||
|
||||
Bugfixes:
|
||||
- Fix attachment captions not displaying while loading in gallery
|
||||
- Fix tapping follow request push notification not working
|
||||
- Pleroma: Handle posts with missing creation dates
|
||||
|
||||
## 2024.2 (122)
|
||||
Features/Improvements:
|
||||
- Show instance announcements in Notifications
|
||||
- Pleroma/Akkoma: Display emoji reactions in Notifications
|
||||
- Pleroma/Akkoma: Add push notifications for emoji reactions
|
||||
|
||||
Bugfixes:
|
||||
- Fix issue fetching server info on some instances
|
||||
- Fix Preferences background color not updating after changing Pure Black Dark Mode
|
||||
- Fix push subscription settings background using incorrect color with Pure Black Dark Mode off
|
||||
|
||||
## 2024.2 (121)
|
||||
This build introduces a new multi-column navigation mode on iPad. You can revert to the old mode under Preferences -> Appearance.
|
||||
|
||||
|
|
|
@ -15,13 +15,9 @@ import Pachyderm
|
|||
import Intents
|
||||
import HTMLStreamer
|
||||
import WebURL
|
||||
import UIKit
|
||||
import TuskerPreferences
|
||||
|
||||
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "NotificationService")
|
||||
|
||||
private let emojiRegex = try! NSRegularExpression(pattern: ":(\\w+):", options: [])
|
||||
|
||||
class NotificationService: UNNotificationServiceExtension {
|
||||
|
||||
private static let textConverter = TextConverter(configuration: .init(insertNewlines: false), callbacks: HTMLCallbacks.self)
|
||||
|
@ -67,7 +63,6 @@ class NotificationService: UNNotificationServiceExtension {
|
|||
mutableContent.body = notification.body
|
||||
mutableContent.userInfo["notificationID"] = notification.notificationID
|
||||
mutableContent.userInfo["accountID"] = accountID
|
||||
mutableContent.targetContentIdentifier = accountID
|
||||
|
||||
let task = Task {
|
||||
await updateNotificationContent(mutableContent, account: account, push: notification)
|
||||
|
@ -114,24 +109,13 @@ class NotificationService: UNNotificationServiceExtension {
|
|||
kindStr = "📊 Poll finished"
|
||||
case .update:
|
||||
kindStr = "✏️ Edited"
|
||||
case .emojiReaction:
|
||||
if let emoji = notification.emoji {
|
||||
kindStr = "\(emoji) Reacted"
|
||||
} else {
|
||||
kindStr = nil
|
||||
}
|
||||
default:
|
||||
kindStr = nil
|
||||
}
|
||||
|
||||
let notificationContent: String?
|
||||
if let status = notification.status {
|
||||
if notification.kind == .mention || notification.kind == .status,
|
||||
!status.spoilerText.isEmpty {
|
||||
notificationContent = "⚠️ \(status.spoilerText)"
|
||||
} else {
|
||||
notificationContent = NotificationService.textConverter.convert(html: status.content)
|
||||
}
|
||||
} else if notification.kind == .follow || notification.kind == .followRequest {
|
||||
notificationContent = nil
|
||||
} else {
|
||||
|
@ -144,9 +128,7 @@ class NotificationService: UNNotificationServiceExtension {
|
|||
// We deliberately don't include attachments for other types of notifications that have statuses (favs, etc.)
|
||||
// because we risk just fetching the same thing a bunch of times for many senders.
|
||||
if notification.kind == .mention || notification.kind == .status || notification.kind == .update,
|
||||
let status = notification.status,
|
||||
!status.sensitive,
|
||||
let attachment = status.attachments.first {
|
||||
let attachment = notification.status?.attachments.first {
|
||||
let url = attachment.previewURL ?? attachment.url
|
||||
attachmentDataTask = Task {
|
||||
do {
|
||||
|
@ -229,33 +211,8 @@ class NotificationService: UNNotificationServiceExtension {
|
|||
}
|
||||
|
||||
let updatedContent: UNMutableNotificationContent
|
||||
|
||||
let contentProviding: any UNNotificationContentProviding
|
||||
if #available(iOS 18.0, visionOS 2.0, *),
|
||||
await Preferences.shared.hasFeatureFlag(.pushNotifCustomEmoji) {
|
||||
let attributedString = NSMutableAttributedString(string: content.body)
|
||||
|
||||
for match in emojiRegex.matches(in: content.body, range: NSRange(location: 0, length: content.body.utf16.count)).reversed() {
|
||||
let emojiName = (content.body as NSString).substring(with: match.range(at: 1))
|
||||
guard let emoji = notification.status?.emojis.first(where: { $0.shortcode == emojiName }),
|
||||
let url = URL(emoji.url),
|
||||
let (data, _) = try? await URLSession.shared.data(from: url),
|
||||
let image = UIImage(data: data) else {
|
||||
continue
|
||||
}
|
||||
let attachment = NSTextAttachment(image: image)
|
||||
let attachmentStr = NSAttributedString(attachment: attachment)
|
||||
attributedString.replaceCharacters(in: match.range, with: attachmentStr)
|
||||
}
|
||||
|
||||
let attributedCtx = UNNotificationAttributedMessageContext(sendMessageIntent: intent, attributedContent: attributedString)
|
||||
contentProviding = attributedCtx
|
||||
} else {
|
||||
contentProviding = intent
|
||||
}
|
||||
|
||||
do {
|
||||
let newContent = try content.updating(from: contentProviding)
|
||||
let newContent = try content.updating(from: intent)
|
||||
if let newMutableContent = newContent.mutableCopy() as? UNMutableNotificationContent {
|
||||
pendingRequest?.0 = newMutableContent
|
||||
updatedContent = newMutableContent
|
||||
|
@ -371,13 +328,14 @@ private struct HTMLCallbacks: HTMLConversionCallbacks {
|
|||
// Converting WebURL to URL is a small but non-trivial expense (since it works by
|
||||
// serializing the WebURL as a string and then having Foundation parse it again),
|
||||
// so, if available, use the system parser which doesn't require another round trip.
|
||||
if let url = try? URL.ParseStrategy().parse(string) {
|
||||
if #available(iOS 16.0, macOS 13.0, *),
|
||||
let url = try? URL.ParseStrategy().parse(string) {
|
||||
url
|
||||
} else if let web = WebURL(string),
|
||||
let url = URL(web) {
|
||||
url
|
||||
} else {
|
||||
nil
|
||||
URL(string: string)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,8 +24,6 @@
|
|||
<dict>
|
||||
<key>NSExtensionAttributes</key>
|
||||
<dict>
|
||||
<key>NSExtensionServiceRoleType</key>
|
||||
<string>NSExtensionServiceRoleTypeViewer</string>
|
||||
<key>NSExtensionActivationRule</key>
|
||||
<dict>
|
||||
<key>NSExtensionActivationSupportsAttachmentsWithMinCount</key>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// swift-tools-version: 6.0
|
||||
// swift-tools-version: 5.7
|
||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||
|
||||
import PackageDescription
|
||||
|
@ -6,7 +6,7 @@ import PackageDescription
|
|||
let package = Package(
|
||||
name: "ComposeUI",
|
||||
platforms: [
|
||||
.iOS(.v16),
|
||||
.iOS(.v15),
|
||||
],
|
||||
products: [
|
||||
// Products define the executables and libraries a package produces, and make them visible to other packages.
|
||||
|
@ -26,15 +26,9 @@ let package = Package(
|
|||
// Targets can depend on other targets in this package, and on products in packages this package depends on.
|
||||
.target(
|
||||
name: "ComposeUI",
|
||||
dependencies: ["Pachyderm", "InstanceFeatures", "TuskerComponents", "MatchedGeometryPresentation"],
|
||||
swiftSettings: [
|
||||
.swiftLanguageMode(.v5)
|
||||
]),
|
||||
dependencies: ["Pachyderm", "InstanceFeatures", "TuskerComponents", "MatchedGeometryPresentation"]),
|
||||
.testTarget(
|
||||
name: "ComposeUITests",
|
||||
dependencies: ["ComposeUI"],
|
||||
swiftSettings: [
|
||||
.swiftLanguageMode(.v5)
|
||||
]),
|
||||
dependencies: ["ComposeUI"]),
|
||||
]
|
||||
)
|
||||
|
|
|
@ -156,7 +156,7 @@ class AttachmentRowController: ViewController {
|
|||
Button(role: .destructive, action: controller.removeAttachment) {
|
||||
Label("Delete", systemImage: "trash")
|
||||
}
|
||||
} preview: {
|
||||
} previewIfAvailable: {
|
||||
ControllerView(controller: { controller.thumbnailController })
|
||||
}
|
||||
|
||||
|
@ -221,3 +221,16 @@ extension AttachmentRowController {
|
|||
case allowEntry, recognizingText
|
||||
}
|
||||
}
|
||||
|
||||
private extension View {
|
||||
@available(iOS, obsoleted: 16.0)
|
||||
@available(visionOS 1.0, *)
|
||||
@ViewBuilder
|
||||
func contextMenu<M: View, P: View>(@ViewBuilder menuItems: () -> M, @ViewBuilder previewIfAvailable preview: () -> P) -> some View {
|
||||
if #available(iOS 16.0, *) {
|
||||
self.contextMenu(menuItems: menuItems, preview: preview)
|
||||
} else {
|
||||
self.contextMenu(menuItems: menuItems)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,6 @@ class AttachmentThumbnailController: ViewController {
|
|||
case .video, .gifv:
|
||||
let asset = AVURLAsset(url: url)
|
||||
let imageGenerator = AVAssetImageGenerator(asset: asset)
|
||||
imageGenerator.appliesPreferredTrackTransform = true
|
||||
#if os(visionOS)
|
||||
#warning("Use async AVAssetImageGenerator.image(at:)")
|
||||
#else
|
||||
|
@ -92,7 +91,6 @@ class AttachmentThumbnailController: ViewController {
|
|||
if type.conforms(to: .movie) {
|
||||
let asset = AVURLAsset(url: url)
|
||||
let imageGenerator = AVAssetImageGenerator(asset: asset)
|
||||
imageGenerator.appliesPreferredTrackTransform = true
|
||||
#if os(visionOS)
|
||||
#warning("Use async AVAssetImageGenerator.image(at:)")
|
||||
#else
|
||||
|
|
|
@ -214,6 +214,44 @@ fileprivate extension View {
|
|||
self
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS, obsoleted: 16.0)
|
||||
@ViewBuilder
|
||||
func sheetOrPopover(isPresented: Binding<Bool>, @ViewBuilder content: @escaping () -> some View) -> some View {
|
||||
if #available(iOS 16.0, *) {
|
||||
self.modifier(SheetOrPopover(isPresented: isPresented, view: content))
|
||||
} else {
|
||||
self.popover(isPresented: isPresented, content: content)
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS, obsoleted: 16.0)
|
||||
@ViewBuilder
|
||||
func withSheetDetentsIfAvailable() -> some View {
|
||||
if #available(iOS 16.0, *) {
|
||||
self
|
||||
.presentationDetents([.medium, .large])
|
||||
.presentationDragIndicator(.visible)
|
||||
} else {
|
||||
self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 16.0, *)
|
||||
fileprivate struct SheetOrPopover<V: View>: ViewModifier {
|
||||
@Binding var isPresented: Bool
|
||||
@ViewBuilder let view: () -> V
|
||||
|
||||
@Environment(\.horizontalSizeClass) var sizeClass
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
if sizeClass == .compact {
|
||||
content.sheet(isPresented: $isPresented, content: view)
|
||||
} else {
|
||||
content.popover(isPresented: $isPresented, content: view)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@available(visionOS 1.0, *)
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
import SwiftUI
|
||||
import Pachyderm
|
||||
import Combine
|
||||
import TuskerComponents
|
||||
|
||||
class AutocompleteEmojisController: ViewController {
|
||||
unowned let composeController: ComposeController
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
import SwiftUI
|
||||
import Combine
|
||||
import Pachyderm
|
||||
import TuskerComponents
|
||||
|
||||
class AutocompleteHashtagsController: ViewController {
|
||||
unowned let composeController: ComposeController
|
||||
|
|
|
@ -125,7 +125,9 @@ public final class ComposeController: ViewController {
|
|||
self.toolbarController = ToolbarController(parent: self)
|
||||
self.attachmentsListController = AttachmentsListController(parent: self)
|
||||
|
||||
if #available(iOS 16.0, *) {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(currentInputModeChanged), name: UITextInputMode.currentInputModeDidChangeNotification, object: nil)
|
||||
}
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(managedObjectsDidChange), name: .NSManagedObjectContextObjectsDidChange, object: DraftsPersistentContainer.shared.viewContext)
|
||||
}
|
||||
|
||||
|
@ -322,17 +324,16 @@ public final class ComposeController: ViewController {
|
|||
ControllerView(controller: { controller.toolbarController })
|
||||
#endif
|
||||
}
|
||||
#if !os(visionOS)
|
||||
// on iPadOS15, the toolbar ends up below the keyboard's toolbar without this
|
||||
.padding(.bottom, keyboardInset)
|
||||
#endif
|
||||
.transition(.move(edge: .bottom))
|
||||
}
|
||||
}
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .cancellationAction) { cancelButton }
|
||||
#if targetEnvironment(macCatalyst)
|
||||
ToolbarItem(placement: .topBarTrailing) { draftsButton }
|
||||
ToolbarItem(placement: .confirmationAction) { postButton }
|
||||
#else
|
||||
ToolbarItem(placement: .confirmationAction) { postOrDraftsButton }
|
||||
#endif
|
||||
#if os(visionOS)
|
||||
ToolbarItem(placement: .bottomOrnament) {
|
||||
ControllerView(controller: { controller.toolbarController })
|
||||
|
@ -430,7 +431,7 @@ public final class ComposeController: ViewController {
|
|||
}
|
||||
.listStyle(.plain)
|
||||
#if !os(visionOS)
|
||||
.scrollDismissesKeyboard(.interactively)
|
||||
.scrollDismissesKeyboardInteractivelyIfAvailable()
|
||||
#endif
|
||||
.disabled(controller.isPosting)
|
||||
}
|
||||
|
@ -460,26 +461,43 @@ public final class ComposeController: ViewController {
|
|||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var postOrDraftsButton: some View {
|
||||
if draft.hasContent || draft.editedStatusID != nil || !controller.config.allowSwitchingDrafts {
|
||||
postButton
|
||||
} else {
|
||||
draftsButton
|
||||
}
|
||||
}
|
||||
|
||||
private var draftsButton: some View {
|
||||
Button(action: controller.showDrafts) {
|
||||
Text("Drafts")
|
||||
}
|
||||
}
|
||||
|
||||
private var postButton: some View {
|
||||
if draft.hasContent || draft.editedStatusID != nil || !controller.config.allowSwitchingDrafts {
|
||||
Button(action: controller.postStatus) {
|
||||
Text(draft.editedStatusID == nil ? "Post" : "Edit")
|
||||
}
|
||||
.keyboardShortcut(.return, modifiers: .command)
|
||||
.disabled(!controller.postButtonEnabled)
|
||||
} else {
|
||||
Button(action: controller.showDrafts) {
|
||||
Text("Drafts")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !os(visionOS)
|
||||
@available(iOS, obsoleted: 16.0)
|
||||
private var keyboardInset: CGFloat {
|
||||
if #unavailable(iOS 16.0),
|
||||
UIDevice.current.userInterfaceIdiom == .pad,
|
||||
keyboardReader.isVisible {
|
||||
return ToolbarController.height
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
private extension View {
|
||||
@available(iOS, obsoleted: 16.0)
|
||||
@ViewBuilder
|
||||
func scrollDismissesKeyboardInteractivelyIfAvailable() -> some View {
|
||||
if #available(iOS 16.0, *) {
|
||||
self.scrollDismissesKeyboard(.interactively)
|
||||
} else {
|
||||
self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,11 +51,14 @@ class FocusedAttachmentController: ViewController {
|
|||
.onAppear {
|
||||
player.play()
|
||||
}
|
||||
} else {
|
||||
} else if #available(iOS 16.0, *) {
|
||||
ZoomableScrollView {
|
||||
attachmentView
|
||||
.matchedGeometryDestination(id: attachment.id)
|
||||
}
|
||||
} else {
|
||||
attachmentView
|
||||
.matchedGeometryDestination(id: attachment.id)
|
||||
}
|
||||
|
||||
Spacer(minLength: 0)
|
||||
|
|
|
@ -96,7 +96,7 @@ class PollController: ViewController {
|
|||
.onMove(perform: controller.moveOptions)
|
||||
}
|
||||
.listStyle(.plain)
|
||||
.scrollDisabled(true)
|
||||
.scrollDisabledIfAvailable(true)
|
||||
.frame(height: 44 * CGFloat(poll.options.count))
|
||||
|
||||
Button(action: controller.addOption) {
|
||||
|
|
|
@ -66,7 +66,7 @@ class ToolbarController: ViewController {
|
|||
}
|
||||
})
|
||||
}
|
||||
.scrollDisabled(realWidth ?? 0 <= minWidth ?? 0)
|
||||
.scrollDisabledIfAvailable(realWidth ?? 0 <= minWidth ?? 0)
|
||||
.frame(height: ToolbarController.height)
|
||||
.frame(maxWidth: .infinity)
|
||||
.background(.regularMaterial, ignoresSafeAreaEdges: [.bottom, .leading, .trailing])
|
||||
|
@ -122,7 +122,8 @@ class ToolbarController: ViewController {
|
|||
|
||||
Spacer()
|
||||
|
||||
if composeController.mastodonController.instanceFeatures.createStatusWithLanguage {
|
||||
if #available(iOS 16.0, *),
|
||||
composeController.mastodonController.instanceFeatures.createStatusWithLanguage {
|
||||
LanguagePicker(draftLanguage: $draft.language, hasChangedSelection: $composeController.hasChangedLanguageSelection)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -167,23 +167,11 @@ extension DraftAttachment: NSItemProviderReading {
|
|||
type = .png
|
||||
}
|
||||
|
||||
// Read the caption from the image itself, if there is one.
|
||||
let caption: String
|
||||
if let source = CGImageSourceCreateWithData(data as CFData, [kCGImageSourceTypeIdentifierHint: typeIdentifier as CFString] as CFDictionary),
|
||||
let properties = CGImageSourceCopyPropertiesAtIndex(source, 0, nil) as? [String: Any],
|
||||
// This is the dictionary for TIFF properties, but it's present for other image types too
|
||||
let tiffProperties = properties[kCGImagePropertyTIFFDictionary as String] as? [String: Any],
|
||||
let imageDescription = tiffProperties[kCGImagePropertyTIFFImageDescription as String] as? String {
|
||||
caption = imageDescription
|
||||
} else {
|
||||
caption = ""
|
||||
}
|
||||
|
||||
let attachment = DraftAttachment(entity: DraftsPersistentContainer.shared.persistentStoreCoordinator.managedObjectModel.entitiesByName["DraftAttachment"]!, insertInto: nil)
|
||||
attachment.id = UUID()
|
||||
attachment.fileURL = try writeDataToFile(data, id: attachment.id, type: type)
|
||||
attachment.fileType = type.identifier
|
||||
attachment.attachmentDescription = caption
|
||||
attachment.attachmentDescription = ""
|
||||
return attachment
|
||||
}
|
||||
|
||||
|
|
|
@ -16,8 +16,6 @@ public class DraftsPersistentContainer: NSPersistentContainer {
|
|||
|
||||
public static let shared = DraftsPersistentContainer()
|
||||
|
||||
public static var captureError: ((any Error) -> Void)?
|
||||
|
||||
private static let managedObjectModel: NSManagedObjectModel = {
|
||||
let url = Bundle.module.url(forResource: "Drafts", withExtension: "momd")!
|
||||
return NSManagedObjectModel(contentsOf: url)!
|
||||
|
@ -41,7 +39,6 @@ public class DraftsPersistentContainer: NSPersistentContainer {
|
|||
|
||||
loadPersistentStores { _, error in
|
||||
if let error {
|
||||
DraftsPersistentContainer.captureError?(error)
|
||||
fatalError("Loading persistent store: \(error)")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// FuzzyMatcher.swift
|
||||
// TuskerComponents
|
||||
// ComposeUI
|
||||
//
|
||||
// Created by Shadowfacts on 10/10/20.
|
||||
// Copyright © 2020 Shadowfacts. All rights reserved.
|
||||
|
@ -8,7 +8,7 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
public struct FuzzyMatcher {
|
||||
struct FuzzyMatcher {
|
||||
|
||||
private init() {}
|
||||
|
||||
|
@ -21,7 +21,7 @@ public struct FuzzyMatcher {
|
|||
/// +2 points for every char in `pattern` that occurs in `str` sequentially
|
||||
/// -2 points for every char in `pattern` that does not occur in `str` sequentially
|
||||
/// -1 point for every char in `str` skipped between matching chars from the `pattern`
|
||||
public static func match(pattern: String, str: String) -> (matched: Bool, score: Int) {
|
||||
static func match(pattern: String, str: String) -> (matched: Bool, score: Int) {
|
||||
let pattern = pattern.lowercased()
|
||||
let str = str.lowercased()
|
||||
|
|
@ -10,6 +10,7 @@
|
|||
import UIKit
|
||||
import Combine
|
||||
|
||||
@available(iOS, obsoleted: 16.0)
|
||||
class KeyboardReader: ObservableObject {
|
||||
// @Published var isVisible = false
|
||||
@Published var keyboardHeight: CGFloat = 0
|
||||
|
|
|
@ -39,7 +39,6 @@ extension TextViewCaretScrolling {
|
|||
|
||||
let animator = UIViewPropertyAnimator(duration: 0.2, curve: .easeInOut) {
|
||||
scrollView.scrollRectToVisible(rectToMakeVisible, animated: false)
|
||||
scrollView.layoutIfNeeded()
|
||||
}
|
||||
self.caretScrollPositionAnimator = animator
|
||||
animator.startAnimation()
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// View+ForwardsCompat.swift
|
||||
// ComposeUI
|
||||
//
|
||||
// Created by Shadowfacts on 3/25/23.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
extension View {
|
||||
#if os(visionOS)
|
||||
func scrollDisabledIfAvailable(_ disabled: Bool) -> some View {
|
||||
self.scrollDisabled(disabled)
|
||||
}
|
||||
#else
|
||||
@available(iOS, obsoleted: 16.0)
|
||||
@ViewBuilder
|
||||
func scrollDisabledIfAvailable(_ disabled: Bool) -> some View {
|
||||
if #available(iOS 16.0, *) {
|
||||
self.scrollDisabled(disabled)
|
||||
} else {
|
||||
self
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -76,15 +76,13 @@ struct ReplyStatusView: View {
|
|||
// once you scroll past the in-reply-to-content, the bottom of the avatar should be pinned to the bottom of the content
|
||||
offset = min(offset, maxOffset)
|
||||
|
||||
return AvatarContainerRepresentable(offset: offset) {
|
||||
AvatarImageView(
|
||||
return AvatarImageView(
|
||||
url: status.account.avatar,
|
||||
size: 50,
|
||||
style: controller.config.avatarStyle,
|
||||
fetchAvatar: controller.fetchAvatar
|
||||
)
|
||||
}
|
||||
.frame(width: 50, height: 50)
|
||||
.offset(x: 0, y: offset)
|
||||
.accessibilityHidden(true)
|
||||
}
|
||||
|
||||
|
@ -96,39 +94,3 @@ private struct DisplayNameHeightPrefKey: PreferenceKey {
|
|||
value = nextValue()
|
||||
}
|
||||
}
|
||||
|
||||
// This whole dance is necessary so that the offset can be animatable from
|
||||
// UIKit animations, like TextViewCaretScrolling.
|
||||
private struct AvatarContainerRepresentable<Content: View>: UIViewControllerRepresentable {
|
||||
let offset: CGFloat
|
||||
@ViewBuilder let content: Content
|
||||
|
||||
func makeUIViewController(context: Context) -> Controller {
|
||||
Controller(host: UIHostingController(rootView: content))
|
||||
}
|
||||
|
||||
func updateUIViewController(_ uiViewController: Controller, context: Context) {
|
||||
uiViewController.host.rootView = content
|
||||
uiViewController.host.view.transform = CGAffineTransform(translationX: 0, y: offset)
|
||||
}
|
||||
|
||||
// This extra layer is necessary because applying a transform to the
|
||||
// representable's VC's view doesn't seem to have an effect.
|
||||
class Controller: UIViewController {
|
||||
let host: UIHostingController<Content>
|
||||
|
||||
init(host: UIHostingController<Content>) {
|
||||
self.host = host
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
addChild(host)
|
||||
host.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||
view.addSubview(host.view)
|
||||
host.view.frame = view.bounds
|
||||
host.didMove(toParent: self)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// swift-tools-version: 6.0
|
||||
// swift-tools-version: 5.7
|
||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||
|
||||
import PackageDescription
|
||||
|
@ -6,7 +6,7 @@ import PackageDescription
|
|||
let package = Package(
|
||||
name: "Duckable",
|
||||
platforms: [
|
||||
.iOS(.v16),
|
||||
.iOS(.v15),
|
||||
],
|
||||
products: [
|
||||
// Products define the executables and libraries a package produces, and make them visible to other packages.
|
||||
|
@ -23,10 +23,7 @@ let package = Package(
|
|||
// Targets can depend on other targets in this package, and on products in packages this package depends on.
|
||||
.target(
|
||||
name: "Duckable",
|
||||
dependencies: [],
|
||||
swiftSettings: [
|
||||
.swiftLanguageMode(.v5)
|
||||
]),
|
||||
dependencies: []),
|
||||
// .testTarget(
|
||||
// name: "DuckableTests",
|
||||
// dependencies: ["Duckable"]),
|
||||
|
|
|
@ -33,11 +33,11 @@ public enum DuckAttemptAction {
|
|||
|
||||
extension UIViewController {
|
||||
@available(iOS 16.0, *)
|
||||
public func presentDuckable(_ viewController: DuckableViewController, animated: Bool, isDucked: Bool = false, completion: (() -> Void)? = nil) -> Bool {
|
||||
public func presentDuckable(_ viewController: DuckableViewController, animated: Bool, isDucked: Bool = false) -> Bool {
|
||||
var cur: UIViewController? = self
|
||||
while let vc = cur {
|
||||
if let container = vc as? DuckableContainerViewController {
|
||||
container._presentDuckable(viewController, animated: animated, isDucked: isDucked, completion: completion)
|
||||
container.presentDuckable(viewController, animated: animated, isDucked: isDucked, completion: nil)
|
||||
return true
|
||||
} else {
|
||||
cur = vc.parent
|
||||
|
|
|
@ -58,7 +58,7 @@ public class DuckableContainerViewController: UIViewController {
|
|||
])
|
||||
}
|
||||
|
||||
func _presentDuckable(_ viewController: DuckableViewController, animated: Bool, isDucked: Bool, completion: (() -> Void)?) {
|
||||
func presentDuckable(_ viewController: DuckableViewController, animated: Bool, isDucked: Bool, completion: (() -> Void)?) {
|
||||
guard case .idle = state else {
|
||||
if animated,
|
||||
case .ducked(_, placeholder: let placeholder) = state {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// swift-tools-version: 6.0
|
||||
// swift-tools-version: 5.10
|
||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||
|
||||
import PackageDescription
|
||||
|
@ -6,7 +6,7 @@ import PackageDescription
|
|||
let package = Package(
|
||||
name: "GalleryVC",
|
||||
platforms: [
|
||||
.iOS(.v16),
|
||||
.iOS(.v15),
|
||||
],
|
||||
products: [
|
||||
// Products define the executables and libraries a package produces, making them visible to other packages.
|
||||
|
@ -18,15 +18,9 @@ let package = Package(
|
|||
// Targets are the basic building blocks of a package, defining a module or a test suite.
|
||||
// Targets can depend on other targets in this package and products from dependencies.
|
||||
.target(
|
||||
name: "GalleryVC",
|
||||
swiftSettings: [
|
||||
.swiftLanguageMode(.v5)
|
||||
]),
|
||||
name: "GalleryVC"),
|
||||
.testTarget(
|
||||
name: "GalleryVCTests",
|
||||
dependencies: ["GalleryVC"],
|
||||
swiftSettings: [
|
||||
.swiftLanguageMode(.v5)
|
||||
]),
|
||||
dependencies: ["GalleryVC"]),
|
||||
]
|
||||
)
|
||||
|
|
|
@ -17,7 +17,7 @@ public protocol GalleryContentViewController: UIViewController {
|
|||
var bottomControlsAccessoryViewController: UIViewController? { get }
|
||||
var canAnimateFromSourceView: Bool { get }
|
||||
|
||||
func setControlsVisible(_ visible: Bool, animated: Bool, dueToUserInteraction: Bool)
|
||||
func setControlsVisible(_ visible: Bool, animated: Bool)
|
||||
func galleryContentDidAppear()
|
||||
func galleryContentWillDisappear()
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ public extension GalleryContentViewController {
|
|||
true
|
||||
}
|
||||
|
||||
func setControlsVisible(_ visible: Bool, animated: Bool, dueToUserInteraction: Bool) {
|
||||
func setControlsVisible(_ visible: Bool, animated: Bool) {
|
||||
}
|
||||
|
||||
func galleryContentDidAppear() {
|
||||
|
|
|
@ -52,22 +52,15 @@ class GalleryDismissAnimationController: NSObject, UIViewControllerAnimatedTrans
|
|||
appliedSourceToDestTransform = false
|
||||
}
|
||||
|
||||
// Moving `to.view` to the container is necessary when the presenting VC (i.e., `to`)
|
||||
// is in the window's root presentation.
|
||||
// But it breaks when the gallery is presented from a sheet-presented VC--in which case
|
||||
// `to.view` is already in the view hierarchy at this point; and adding it to the
|
||||
// container causees it to be removed when the transition completes.
|
||||
if to.view.superview == nil {
|
||||
to.view.frame = container.bounds
|
||||
container.addSubview(to.view)
|
||||
}
|
||||
|
||||
from.view.frame = container.bounds
|
||||
container.addSubview(from.view)
|
||||
|
||||
let content = itemViewController.takeContent()
|
||||
content.view.translatesAutoresizingMaskIntoConstraints = true
|
||||
content.view.layer.masksToBounds = true
|
||||
|
||||
container.addSubview(to.view)
|
||||
container.addSubview(from.view)
|
||||
container.addSubview(content.view)
|
||||
|
||||
content.view.frame = destFrameInContainer
|
||||
|
@ -106,7 +99,7 @@ class GalleryDismissAnimationController: NSObject, UIViewControllerAnimatedTrans
|
|||
content.view.frame = sourceFrameInContainer
|
||||
content.view.layer.opacity = 0
|
||||
|
||||
itemViewController.setControlsVisible(false, animated: false, dueToUserInteraction: false)
|
||||
itemViewController.setControlsVisible(false, animated: false)
|
||||
}
|
||||
|
||||
animator.addCompletion { _ in
|
||||
|
|
|
@ -42,7 +42,7 @@ class GalleryDismissInteraction: NSObject {
|
|||
|
||||
origControlsVisible = viewController.currentItemViewController.controlsVisible
|
||||
if origControlsVisible! {
|
||||
viewController.currentItemViewController.setControlsVisible(false, animated: true, dueToUserInteraction: false)
|
||||
viewController.currentItemViewController.setControlsVisible(false, animated: true)
|
||||
}
|
||||
|
||||
case .changed:
|
||||
|
|
|
@ -44,7 +44,6 @@ class GalleryItemViewController: UIViewController {
|
|||
private(set) var scrollAndZoomEnabled = true
|
||||
|
||||
private var scrollViewSizeForLastZoomScaleUpdate: CGSize?
|
||||
|
||||
override var prefersHomeIndicatorAutoHidden: Bool {
|
||||
return !controlsVisible
|
||||
}
|
||||
|
@ -81,10 +80,10 @@ class GalleryItemViewController: UIViewController {
|
|||
overlayVC.view.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.addSubview(overlayVC.view)
|
||||
NSLayoutConstraint.activate([
|
||||
overlayVC.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||
overlayVC.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
||||
overlayVC.view.topAnchor.constraint(equalTo: view.topAnchor),
|
||||
overlayVC.view.bottomAnchor.constraint(equalTo: view.bottomAnchor),
|
||||
overlayVC.view.leadingAnchor.constraint(equalTo: content.view.leadingAnchor),
|
||||
overlayVC.view.trailingAnchor.constraint(equalTo: content.view.trailingAnchor),
|
||||
overlayVC.view.topAnchor.constraint(equalTo: content.view.topAnchor),
|
||||
overlayVC.view.bottomAnchor.constraint(equalTo: content.view.bottomAnchor),
|
||||
])
|
||||
}
|
||||
|
||||
|
@ -213,7 +212,7 @@ class GalleryItemViewController: UIViewController {
|
|||
|
||||
updateZoomScale(resetZoom: false)
|
||||
// Ensure the transform is correct if the controls are hidden
|
||||
setControlsVisible(controlsVisible, animated: false, dueToUserInteraction: false)
|
||||
setControlsVisible(controlsVisible, animated: false)
|
||||
|
||||
updateTopControlsInsets()
|
||||
}
|
||||
|
@ -228,8 +227,6 @@ class GalleryItemViewController: UIViewController {
|
|||
updateZoomScale(resetZoom: true)
|
||||
}
|
||||
centerContent()
|
||||
// Ensure the transform is correct if the controls are hidden and their size changed.
|
||||
setControlsVisible(controlsVisible, animated: false, dueToUserInteraction: false)
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
|
@ -250,7 +247,7 @@ class GalleryItemViewController: UIViewController {
|
|||
func addContent() {
|
||||
content.loadViewIfNeeded()
|
||||
|
||||
content.setControlsVisible(controlsVisible, animated: false, dueToUserInteraction: false)
|
||||
content.setControlsVisible(controlsVisible, animated: false)
|
||||
|
||||
content.view.translatesAutoresizingMaskIntoConstraints = false
|
||||
if content.parent != self {
|
||||
|
@ -290,18 +287,16 @@ class GalleryItemViewController: UIViewController {
|
|||
content.view.layoutIfNeeded()
|
||||
}
|
||||
|
||||
func setControlsVisible(_ visible: Bool, animated: Bool, dueToUserInteraction: Bool) {
|
||||
func setControlsVisible(_ visible: Bool, animated: Bool) {
|
||||
controlsVisible = visible
|
||||
|
||||
guard let topControlsView,
|
||||
let bottomControlsView else {
|
||||
return
|
||||
}
|
||||
|
||||
func updateControlsViews() {
|
||||
topControlsView.transform = CGAffineTransform(translationX: 0, y: visible ? 0 : -topControlsView.bounds.height)
|
||||
bottomControlsView.transform = CGAffineTransform(translationX: 0, y: visible ? 0 : bottomControlsView.bounds.height)
|
||||
content.setControlsVisible(visible, animated: animated, dueToUserInteraction: dueToUserInteraction)
|
||||
content.setControlsVisible(visible, animated: animated)
|
||||
}
|
||||
if animated {
|
||||
let animator = UIViewPropertyAnimator(duration: 0.2, timingParameters: UISpringTimingParameters())
|
||||
|
@ -378,6 +373,9 @@ class GalleryItemViewController: UIViewController {
|
|||
47, // iPhone 12, 12 Pro, 12 Pro Max, 13, 13 Pro, 13 Pro Max, 14, 14 Plus
|
||||
50, // iPhone 12 mini, 13 mini
|
||||
]
|
||||
let islandDeviceTopInsets: [CGFloat] = [
|
||||
59, // iPhone 14 Pro, 14 Pro Max, 15 Pro, 15 Pro Max
|
||||
]
|
||||
if notchedDeviceTopInsets.contains(view.safeAreaInsets.top) {
|
||||
// the notch width is not the same for the iPhones 13,
|
||||
// but what we actually want is the same offset from the edges
|
||||
|
@ -387,18 +385,16 @@ class GalleryItemViewController: UIViewController {
|
|||
let offset = (earWidth - (shareButton.imageView?.bounds.width ?? 0)) / 2
|
||||
shareButtonLeadingConstraint.constant = offset
|
||||
closeButtonTrailingConstraint.constant = offset
|
||||
} else if view.safeAreaInsets.top == 0 {
|
||||
// square corner devices
|
||||
shareButtonLeadingConstraint.constant = 8
|
||||
shareButtonTopConstraint.constant = 8
|
||||
closeButtonTrailingConstraint.constant = 8
|
||||
closeButtonTopConstraint.constant = 8
|
||||
} else {
|
||||
// dynamic island devices
|
||||
} else if islandDeviceTopInsets.contains(view.safeAreaInsets.top) {
|
||||
shareButtonLeadingConstraint.constant = 24
|
||||
shareButtonTopConstraint.constant = 24
|
||||
closeButtonTrailingConstraint.constant = 24
|
||||
closeButtonTopConstraint.constant = 24
|
||||
} else {
|
||||
shareButtonLeadingConstraint.constant = 8
|
||||
shareButtonTopConstraint.constant = 8
|
||||
closeButtonTrailingConstraint.constant = 8
|
||||
closeButtonTopConstraint.constant = 8
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -428,7 +424,7 @@ class GalleryItemViewController: UIViewController {
|
|||
scrollView.zoomScale > scrollView.minimumZoomScale {
|
||||
animateZoomOut()
|
||||
} else {
|
||||
setControlsVisible(!controlsVisible, animated: true, dueToUserInteraction: true)
|
||||
setControlsVisible(!controlsVisible, animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -530,7 +526,7 @@ extension GalleryItemViewController: GalleryContentViewControllerContainer {
|
|||
}
|
||||
|
||||
func setGalleryControlsVisible(_ visible: Bool, animated: Bool) {
|
||||
setControlsVisible(visible, animated: animated, dueToUserInteraction: false)
|
||||
setControlsVisible(visible, animated: animated)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -545,9 +541,9 @@ extension GalleryItemViewController: UIScrollViewDelegate {
|
|||
|
||||
func scrollViewDidZoom(_ scrollView: UIScrollView) {
|
||||
if scrollView.zoomScale <= scrollView.minimumZoomScale {
|
||||
setControlsVisible(true, animated: true, dueToUserInteraction: true)
|
||||
setControlsVisible(true, animated: true)
|
||||
} else {
|
||||
setControlsVisible(false, animated: true, dueToUserInteraction: true)
|
||||
setControlsVisible(false, animated: true)
|
||||
}
|
||||
|
||||
centerContent()
|
||||
|
|
|
@ -75,7 +75,7 @@ class GalleryPresentationAnimationController: NSObject, UIViewControllerAnimated
|
|||
container.layoutIfNeeded()
|
||||
|
||||
// This needs to take place after the layout, so that the transform is correct.
|
||||
itemViewController.setControlsVisible(false, animated: false, dueToUserInteraction: false)
|
||||
itemViewController.setControlsVisible(false, animated: false)
|
||||
|
||||
let duration = self.transitionDuration(using: transitionContext)
|
||||
// rougly equivalent to duration: 0.35, bounce: 0.3
|
||||
|
@ -90,7 +90,7 @@ class GalleryPresentationAnimationController: NSObject, UIViewControllerAnimated
|
|||
content.view.frame = destFrameInContainer
|
||||
content.view.layer.opacity = 1
|
||||
|
||||
itemViewController.setControlsVisible(true, animated: false, dueToUserInteraction: false)
|
||||
itemViewController.setControlsVisible(true, animated: false)
|
||||
|
||||
if let sourceToDestTransform {
|
||||
self.sourceView.transform = sourceToDestTransform
|
||||
|
|
|
@ -125,8 +125,6 @@ extension GalleryViewController: UIPageViewControllerDataSource {
|
|||
extension GalleryViewController: UIPageViewControllerDelegate {
|
||||
public func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
|
||||
currentItemViewController.content.galleryContentWillDisappear()
|
||||
let new = pendingViewControllers[0] as! GalleryItemViewController
|
||||
new.setControlsVisible(currentItemViewController.controlsVisible, animated: false, dueToUserInteraction: false)
|
||||
}
|
||||
|
||||
public func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
|
||||
|
@ -154,21 +152,14 @@ extension GalleryViewController: GalleryItemViewControllerDelegate {
|
|||
|
||||
extension GalleryViewController: UIViewControllerTransitioningDelegate {
|
||||
public func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
|
||||
#if os(visionOS)
|
||||
return nil
|
||||
#else
|
||||
if let sourceView = galleryDataSource.galleryContentTransitionSourceView(forItemAt: initialItemIndex) {
|
||||
return GalleryPresentationAnimationController(sourceView: sourceView)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
|
||||
#if os(visionOS)
|
||||
return nil
|
||||
#else
|
||||
if let sourceView = galleryDataSource.galleryContentTransitionSourceView(forItemAt: currentItemViewController.itemIndex) {
|
||||
let translation: CGPoint?
|
||||
let velocity: CGPoint?
|
||||
|
@ -184,6 +175,5 @@ extension GalleryViewController: UIViewControllerTransitioningDelegate {
|
|||
} else {
|
||||
return nil
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// swift-tools-version: 6.0
|
||||
// swift-tools-version: 5.7
|
||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||
|
||||
import PackageDescription
|
||||
|
@ -6,7 +6,7 @@ import PackageDescription
|
|||
let package = Package(
|
||||
name: "InstanceFeatures",
|
||||
platforms: [
|
||||
.iOS(.v16),
|
||||
.iOS(.v15),
|
||||
],
|
||||
products: [
|
||||
// Products define the executables and libraries a package produces, and make them visible to other packages.
|
||||
|
@ -23,15 +23,9 @@ let package = Package(
|
|||
// Targets can depend on other targets in this package, and on products in packages this package depends on.
|
||||
.target(
|
||||
name: "InstanceFeatures",
|
||||
dependencies: ["Pachyderm"],
|
||||
swiftSettings: [
|
||||
.swiftLanguageMode(.v5)
|
||||
]),
|
||||
dependencies: ["Pachyderm"]),
|
||||
.testTarget(
|
||||
name: "InstanceFeaturesTests",
|
||||
dependencies: ["InstanceFeatures"],
|
||||
swiftSettings: [
|
||||
.swiftLanguageMode(.v5)
|
||||
]),
|
||||
dependencies: ["InstanceFeatures"]),
|
||||
]
|
||||
)
|
||||
|
|
|
@ -157,7 +157,7 @@ public final class InstanceFeatures: ObservableObject {
|
|||
}
|
||||
|
||||
public var needsEditAttachmentsInSeparateRequest: Bool {
|
||||
instanceType.isPleroma
|
||||
instanceType.isPleroma(.akkoma(nil))
|
||||
}
|
||||
|
||||
public var composeDirectStatuses: Bool {
|
||||
|
@ -209,26 +209,6 @@ public final class InstanceFeatures: ObservableObject {
|
|||
}
|
||||
}
|
||||
|
||||
public var instanceAnnouncements: Bool {
|
||||
hasMastodonVersion(3, 1, 0)
|
||||
}
|
||||
|
||||
public var emojiReactionNotifications: Bool {
|
||||
instanceType.isPleroma
|
||||
}
|
||||
|
||||
public var muteNotifications: Bool {
|
||||
!instanceType.isPixelfed
|
||||
}
|
||||
|
||||
public var blockDomains: Bool {
|
||||
!instanceType.isPixelfed
|
||||
}
|
||||
|
||||
public var hideReblogs: Bool {
|
||||
!instanceType.isPixelfed
|
||||
}
|
||||
|
||||
public init() {
|
||||
}
|
||||
|
||||
|
@ -350,14 +330,6 @@ extension InstanceFeatures {
|
|||
return false
|
||||
}
|
||||
}
|
||||
|
||||
var isPixelfed: Bool {
|
||||
if case .pixelfed = self {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@_spi(InstanceType) public enum MastodonType {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// swift-tools-version: 6.0
|
||||
// swift-tools-version: 5.8
|
||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||
|
||||
import PackageDescription
|
||||
|
@ -6,7 +6,7 @@ import PackageDescription
|
|||
let package = Package(
|
||||
name: "MatchedGeometryPresentation",
|
||||
platforms: [
|
||||
.iOS(.v16),
|
||||
.iOS(.v15),
|
||||
],
|
||||
products: [
|
||||
// Products define the executables and libraries a package produces, making them visible to other packages.
|
||||
|
@ -18,10 +18,7 @@ let package = Package(
|
|||
// Targets are the basic building blocks of a package, defining a module or a test suite.
|
||||
// Targets can depend on other targets in this package and products from dependencies.
|
||||
.target(
|
||||
name: "MatchedGeometryPresentation",
|
||||
swiftSettings: [
|
||||
.swiftLanguageMode(.v5)
|
||||
]),
|
||||
name: "MatchedGeometryPresentation"),
|
||||
// .testTarget(
|
||||
// name: "MatchedGeometryPresentationTests",
|
||||
// dependencies: ["MatchedGeometryPresentation"]),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// swift-tools-version: 6.0
|
||||
// swift-tools-version: 5.6
|
||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||
|
||||
import PackageDescription
|
||||
|
@ -6,7 +6,7 @@ import PackageDescription
|
|||
let package = Package(
|
||||
name: "Pachyderm",
|
||||
platforms: [
|
||||
.iOS(.v16),
|
||||
.iOS(.v15),
|
||||
],
|
||||
products: [
|
||||
// Products define the executables and libraries a package produces, and make them visible to other packages.
|
||||
|
@ -16,7 +16,7 @@ let package = Package(
|
|||
],
|
||||
dependencies: [
|
||||
// Dependencies declare other packages that this package depends on.
|
||||
.package(url: "https://github.com/karwa/swift-url.git", exact: "0.4.2"),
|
||||
.package(url: "https://github.com/karwa/swift-url.git", branch: "main"),
|
||||
],
|
||||
targets: [
|
||||
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
||||
|
@ -26,15 +26,9 @@ let package = Package(
|
|||
dependencies: [
|
||||
.product(name: "WebURL", package: "swift-url"),
|
||||
.product(name: "WebURLFoundationExtras", package: "swift-url"),
|
||||
],
|
||||
swiftSettings: [
|
||||
.swiftLanguageMode(.v5)
|
||||
]),
|
||||
.testTarget(
|
||||
name: "PachydermTests",
|
||||
dependencies: ["Pachyderm"],
|
||||
swiftSettings: [
|
||||
.swiftLanguageMode(.v5)
|
||||
]),
|
||||
dependencies: ["Pachyderm"]),
|
||||
]
|
||||
)
|
||||
|
|
|
@ -42,7 +42,7 @@ public struct Client: Sendable {
|
|||
} else if let date = iso8601.date(from: str) {
|
||||
return date
|
||||
} else {
|
||||
throw DecodingError.typeMismatch(Date.self, .init(codingPath: container.codingPath, debugDescription: "unexpected date format: \(str)"))
|
||||
throw DecodingError.typeMismatch(Date.self, .init(codingPath: container.codingPath, debugDescription: "unexpected date format"))
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -204,8 +204,8 @@ public struct Client: Sendable {
|
|||
return Request<Account>(method: .get, path: "/api/v1/accounts/verify_credentials")
|
||||
}
|
||||
|
||||
public static func getFavourites(range: RequestRange = .default) -> Request<[TryDecode<Status>]> {
|
||||
var request = Request<[TryDecode<Status>]>(method: .get, path: "/api/v1/favourites")
|
||||
public static func getFavourites(range: RequestRange = .default) -> Request<[Status]> {
|
||||
var request = Request<[Status]>(method: .get, path: "/api/v1/favourites")
|
||||
request.range = range
|
||||
return request
|
||||
}
|
||||
|
@ -456,13 +456,14 @@ public struct Client: Sendable {
|
|||
}
|
||||
|
||||
// MARK: - Timelines
|
||||
public static func getStatuses(timeline: Timeline, range: RequestRange = .default) -> Request<[TryDecode<Status>]> {
|
||||
public static func getStatuses(timeline: Timeline, range: RequestRange = .default) -> Request<[Status]> {
|
||||
return timeline.request(range: range)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Bookmarks
|
||||
public static func getBookmarks(range: RequestRange = .default) -> Request<[TryDecode<Status>]> {
|
||||
var request = Request<[TryDecode<Status>]>(method: .get, path: "/api/v1/bookmarks")
|
||||
public static func getBookmarks(range: RequestRange = .default) -> Request<[Status]> {
|
||||
var request = Request<[Status]>(method: .get, path: "/api/v1/bookmarks")
|
||||
request.range = range
|
||||
return request
|
||||
}
|
||||
|
@ -490,7 +491,7 @@ public struct Client: Sendable {
|
|||
return Request<[Hashtag]>(method: .get, path: "/api/v1/trends/tags", queryParameters: parameters)
|
||||
}
|
||||
|
||||
public static func getTrendingStatuses(limit: Int? = nil, offset: Int? = nil) -> Request<[TryDecode<Status>]> {
|
||||
public static func getTrendingStatuses(limit: Int? = nil, offset: Int? = nil) -> Request<[Status]> {
|
||||
var parameters: [Parameter] = []
|
||||
if let limit {
|
||||
parameters.append("limit" => limit)
|
||||
|
|
|
@ -40,9 +40,8 @@ public final class Account: AccountProtocol, Decodable, Sendable {
|
|||
self.displayName = try container.decode(String.self, forKey: .displayName)
|
||||
self.locked = try container.decode(Bool.self, forKey: .locked)
|
||||
self.createdAt = try container.decode(Date.self, forKey: .createdAt)
|
||||
// some instance types (pixelfed, firefish) seem to sometimes send null for these fields, so just fallback to 0
|
||||
self.followersCount = try container.decodeIfPresent(Int.self, forKey: .followersCount) ?? 0
|
||||
self.followingCount = try container.decodeIfPresent(Int.self, forKey: .followingCount) ?? 0
|
||||
self.followersCount = try container.decode(Int.self, forKey: .followersCount)
|
||||
self.followingCount = try container.decode(Int.self, forKey: .followingCount)
|
||||
self.statusesCount = try container.decode(Int.self, forKey: .statusesCount)
|
||||
self.note = try container.decode(String.self, forKey: .note)
|
||||
self.url = try container.decode(URL.self, forKey: .url)
|
||||
|
@ -95,8 +94,8 @@ public final class Account: AccountProtocol, Decodable, Sendable {
|
|||
return request
|
||||
}
|
||||
|
||||
public static func getStatuses(_ accountID: String, range: RequestRange = .default, onlyMedia: Bool? = nil, pinned: Bool? = nil, excludeReplies: Bool? = nil, excludeReblogs: Bool? = nil) -> Request<[TryDecode<Status>]> {
|
||||
var request = Request<[TryDecode<Status>]>(method: .get, path: "/api/v1/accounts/\(accountID)/statuses", queryParameters: [
|
||||
public static func getStatuses(_ accountID: String, range: RequestRange = .default, onlyMedia: Bool? = nil, pinned: Bool? = nil, excludeReplies: Bool? = nil, excludeReblogs: Bool? = nil) -> Request<[Status]> {
|
||||
var request = Request<[Status]>(method: .get, path: "/api/v1/accounts/\(accountID)/statuses", queryParameters: [
|
||||
"only_media" => onlyMedia,
|
||||
"pinned" => pinned,
|
||||
"exclude_replies" => excludeReplies,
|
||||
|
|
|
@ -1,99 +0,0 @@
|
|||
//
|
||||
// Announcement.swift
|
||||
// Pachyderm
|
||||
//
|
||||
// Created by Shadowfacts on 4/16/24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import WebURL
|
||||
|
||||
public struct Announcement: Decodable, Sendable, Hashable, Identifiable {
|
||||
public let id: String
|
||||
public let content: String
|
||||
public let startsAt: Date?
|
||||
public let endsAt: Date?
|
||||
public let allDay: Bool
|
||||
public let publishedAt: Date
|
||||
public let updatedAt: Date
|
||||
public let read: Bool?
|
||||
public let mentions: [Account]
|
||||
public let statuses: [Status]
|
||||
public let tags: [Hashtag]
|
||||
public let emojis: [Emoji]
|
||||
public var reactions: [Reaction]
|
||||
|
||||
public static func all() -> Request<[Announcement]> {
|
||||
return Request(method: .get, path: "/api/v1/announcements")
|
||||
}
|
||||
|
||||
public static func dismiss(id: String) -> Request<Empty> {
|
||||
return Request(method: .post, path: "/api/v1/announcements/\(id)/dismiss")
|
||||
}
|
||||
|
||||
public static func react(id: String, name: String) -> Request<Empty> {
|
||||
return Request(method: .put, path: "/api/v1/announcements/\(id)/reactions/\(name)")
|
||||
}
|
||||
|
||||
public static func unreact(id: String, name: String) -> Request<Empty> {
|
||||
return Request(method: .delete, path: "/api/v1/announcements/\(id)/reactions/\(name)")
|
||||
}
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case id
|
||||
case content
|
||||
case startsAt = "starts_at"
|
||||
case endsAt = "ends_at"
|
||||
case allDay = "all_day"
|
||||
case publishedAt = "published_at"
|
||||
case updatedAt = "updated_at"
|
||||
case read
|
||||
case mentions
|
||||
case statuses
|
||||
case tags
|
||||
case emojis
|
||||
case reactions
|
||||
}
|
||||
}
|
||||
|
||||
extension Announcement {
|
||||
public struct Account: Decodable, Sendable, Hashable {
|
||||
public let id: String
|
||||
public let username: String
|
||||
public let url: WebURL
|
||||
public let acct: String
|
||||
}
|
||||
}
|
||||
|
||||
extension Announcement {
|
||||
public struct Status: Decodable, Sendable, Hashable {
|
||||
public let id: String
|
||||
public let url: WebURL
|
||||
}
|
||||
}
|
||||
|
||||
extension Announcement {
|
||||
public struct Reaction: Decodable, Sendable, Hashable {
|
||||
public let name: String
|
||||
public var count: Int
|
||||
public var me: Bool?
|
||||
public let url: URL?
|
||||
public let staticURL: URL?
|
||||
|
||||
public init(name: String, count: Int, me: Bool?, url: URL?, staticURL: URL?) {
|
||||
self.name = name
|
||||
self.count = count
|
||||
self.me = me
|
||||
self.url = url
|
||||
self.staticURL = staticURL
|
||||
}
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case name
|
||||
case count
|
||||
case me
|
||||
case url
|
||||
case staticURL = "static_url"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -43,13 +43,8 @@ extension Emoji: CustomDebugStringConvertible {
|
|||
}
|
||||
}
|
||||
|
||||
extension Emoji: Equatable, Hashable {
|
||||
extension Emoji: Equatable {
|
||||
public static func ==(lhs: Emoji, rhs: Emoji) -> Bool {
|
||||
return lhs.shortcode == rhs.shortcode && lhs.url == rhs.url
|
||||
}
|
||||
|
||||
public func hash(into hasher: inout Hasher) {
|
||||
hasher.combine(shortcode)
|
||||
hasher.combine(url)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ extension InstanceV2 {
|
|||
public struct Thumbnail: Decodable, Sendable {
|
||||
public let url: String
|
||||
public let blurhash: String?
|
||||
public let versions: ThumbnailVersions?
|
||||
public let versions: ThumbnailVersions
|
||||
}
|
||||
|
||||
public struct ThumbnailVersions: Decodable, Sendable {
|
||||
|
@ -120,6 +120,6 @@ extension InstanceV2 {
|
|||
extension InstanceV2 {
|
||||
public struct Contact: Decodable, Sendable {
|
||||
public let email: String
|
||||
public let account: Account?
|
||||
public let account: Account
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import WebURL
|
||||
|
||||
public struct Notification: Decodable, Sendable {
|
||||
public let id: String
|
||||
|
@ -15,10 +14,6 @@ public struct Notification: Decodable, Sendable {
|
|||
public let createdAt: Date
|
||||
public let account: Account
|
||||
public let status: Status?
|
||||
// Only present for pleroma emoji reactions
|
||||
// Either an emoji or :shortcode: (for akkoma custom emoji reactions)
|
||||
public let emoji: String?
|
||||
public let emojiURL: WebURL?
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
@ -32,8 +27,6 @@ public struct Notification: Decodable, Sendable {
|
|||
self.createdAt = try container.decode(Date.self, forKey: .createdAt)
|
||||
self.account = try container.decode(Account.self, forKey: .account)
|
||||
self.status = try container.decodeIfPresent(Status.self, forKey: .status)
|
||||
self.emoji = try container.decodeIfPresent(String.self, forKey: .emoji)
|
||||
self.emojiURL = try container.decodeIfPresent(WebURL.self, forKey: .emojiURL)
|
||||
}
|
||||
|
||||
public static func dismiss(id notificationID: String) -> Request<Empty> {
|
||||
|
@ -46,8 +39,6 @@ public struct Notification: Decodable, Sendable {
|
|||
case createdAt = "created_at"
|
||||
case account
|
||||
case status
|
||||
case emoji
|
||||
case emojiURL = "emoji_url"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,7 +52,6 @@ extension Notification {
|
|||
case poll
|
||||
case update
|
||||
case status
|
||||
case emojiReaction = "pleroma:emoji_reaction"
|
||||
case unknown
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ public struct Poll: Codable, Sendable {
|
|||
public let votesCount: Int
|
||||
public let votersCount: Int?
|
||||
public let voted: Bool?
|
||||
public let ownVotes: [Int?]?
|
||||
public let ownVotes: [Int]?
|
||||
public let options: [Option]
|
||||
public let emojis: [Emoji]
|
||||
|
||||
|
@ -33,7 +33,7 @@ public struct Poll: Codable, Sendable {
|
|||
self.votesCount = try container.decode(Int.self, forKey: .votesCount)
|
||||
self.votersCount = try container.decodeIfPresent(Int.self, forKey: .votersCount)
|
||||
self.voted = try container.decodeIfPresent(Bool.self, forKey: .voted)
|
||||
self.ownVotes = try container.decodeIfPresent([Int?].self, forKey: .ownVotes)
|
||||
self.ownVotes = try container.decodeIfPresent([Int].self, forKey: .ownVotes)
|
||||
self.options = try container.decode([Poll.Option].self, forKey: .options)
|
||||
self.emojis = try container.decodeIfPresent([Emoji].self, forKey: .emojis) ?? []
|
||||
}
|
||||
|
|
|
@ -44,7 +44,6 @@ public struct PushSubscription: Decodable, Sendable {
|
|||
"data[alerts][favourite]" => alerts.favourite,
|
||||
"data[alerts][poll]" => alerts.poll,
|
||||
"data[alerts][update]" => alerts.update,
|
||||
"data[alerts][pleroma:emoji_reaction]" => alerts.emojiReaction,
|
||||
"data[policy]" => policy.rawValue,
|
||||
]))
|
||||
}
|
||||
|
@ -59,7 +58,6 @@ public struct PushSubscription: Decodable, Sendable {
|
|||
"data[alerts][favourite]" => alerts.favourite,
|
||||
"data[alerts][poll]" => alerts.poll,
|
||||
"data[alerts][update]" => alerts.update,
|
||||
"data[alerts][pleroma:emoji_reaction]" => alerts.emojiReaction,
|
||||
"data[policy]" => policy.rawValue,
|
||||
]))
|
||||
}
|
||||
|
@ -87,19 +85,8 @@ extension PushSubscription {
|
|||
public let favourite: Bool
|
||||
public let poll: Bool
|
||||
public let update: Bool
|
||||
public let emojiReaction: Bool
|
||||
|
||||
public init(
|
||||
mention: Bool,
|
||||
status: Bool,
|
||||
reblog: Bool,
|
||||
follow: Bool,
|
||||
followRequest: Bool,
|
||||
favourite: Bool,
|
||||
poll: Bool,
|
||||
update: Bool,
|
||||
emojiReaction: Bool
|
||||
) {
|
||||
public init(mention: Bool, status: Bool, reblog: Bool, follow: Bool, followRequest: Bool, favourite: Bool, poll: Bool, update: Bool) {
|
||||
self.mention = mention
|
||||
self.status = status
|
||||
self.reblog = reblog
|
||||
|
@ -108,7 +95,6 @@ extension PushSubscription {
|
|||
self.favourite = favourite
|
||||
self.poll = poll
|
||||
self.update = update
|
||||
self.emojiReaction = emojiReaction
|
||||
}
|
||||
|
||||
public init(from decoder: any Decoder) throws {
|
||||
|
@ -124,8 +110,6 @@ extension PushSubscription {
|
|||
self.poll = try container.decode(Bool.self, forKey: PushSubscription.Alerts.CodingKeys.poll)
|
||||
// update added in mastodon 3.5.0
|
||||
self.update = try container.decodeIfPresent(Bool.self, forKey: PushSubscription.Alerts.CodingKeys.update) ?? false
|
||||
// pleroma/akkoma only
|
||||
self.emojiReaction = try container.decodeIfPresent(Bool.self, forKey: .emojiReaction) ?? false
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
|
@ -137,7 +121,6 @@ extension PushSubscription {
|
|||
case favourite
|
||||
case poll
|
||||
case update
|
||||
case emojiReaction = "pleroma:emoji_reaction"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,13 +27,10 @@ public struct Relationship: RelationshipProtocol, Decodable, Sendable {
|
|||
self.followedBy = try container.decode(Bool.self, forKey: .followedBy)
|
||||
self.blocking = try container.decode(Bool.self, forKey: .blocking)
|
||||
self.muting = try container.decode(Bool.self, forKey: .muting)
|
||||
// not supported on pixelfed
|
||||
self.mutingNotifications = try container.decodeIfPresent(Bool.self, forKey: .mutingNotifications) ?? false
|
||||
self.mutingNotifications = try container.decode(Bool.self, forKey: .mutingNotifications)
|
||||
self.followRequested = try container.decode(Bool.self, forKey: .followRequested)
|
||||
// not supported on pixelfed
|
||||
self.domainBlocking = try container.decodeIfPresent(Bool.self, forKey: .domainBlocking) ?? false
|
||||
// not supported on pixelfed
|
||||
self.showingReblogs = try container.decodeIfPresent(Bool.self, forKey: .showingReblogs) ?? true
|
||||
self.domainBlocking = try container.decode(Bool.self, forKey: .domainBlocking)
|
||||
self.showingReblogs = try container.decode(Bool.self, forKey: .showingReblogs)
|
||||
self.endorsed = try container.decodeIfPresent(Bool.self, forKey: .endorsed) ?? false
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import Foundation
|
|||
|
||||
public struct SearchResults: Decodable, Sendable {
|
||||
public let accounts: [Account]
|
||||
public let statuses: [TryDecode<Status>]
|
||||
public let statuses: [Status]
|
||||
public let hashtags: [Hashtag]
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
|
|
|
@ -124,12 +124,6 @@ public final class Status: StatusProtocol, Decodable, Sendable {
|
|||
return request
|
||||
}
|
||||
|
||||
public static func getReactions(_ statusID: String, emoji: String, range: RequestRange = .default) -> Request<[Account]> {
|
||||
var request = Request<[Account]>(method: .get, path: "/api/v1/statuses/\(statusID)/reactions/\(emoji)")
|
||||
request.range = range
|
||||
return request
|
||||
}
|
||||
|
||||
public static func delete(_ statusID: String) -> Request<Empty> {
|
||||
return Request<Empty>(method: .delete, path: "/api/v1/statuses/\(statusID)")
|
||||
}
|
||||
|
|
|
@ -32,8 +32,8 @@ extension Timeline {
|
|||
}
|
||||
}
|
||||
|
||||
func request(range: RequestRange) -> Request<[TryDecode<Status>]> {
|
||||
var request = Request<[TryDecode<Status>]>(method: .get, path: endpoint)
|
||||
func request(range: RequestRange) -> Request<[Status]> {
|
||||
var request: Request<[Status]> = Request<[Status]>(method: .get, path: endpoint)
|
||||
if case .public(true) = self {
|
||||
request.queryParameters.append("local" => true)
|
||||
}
|
||||
|
|
|
@ -7,18 +7,17 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import WebURL
|
||||
|
||||
public struct NotificationGroup: Identifiable, Hashable, Sendable {
|
||||
public private(set) var notifications: [Notification]
|
||||
public let id: String
|
||||
public let kind: Kind
|
||||
public let kind: Notification.Kind
|
||||
|
||||
public init?(notifications: [Notification], kind: Kind) {
|
||||
public init?(notifications: [Notification]) {
|
||||
guard !notifications.isEmpty else { return nil }
|
||||
self.notifications = notifications
|
||||
self.id = notifications.first!.id
|
||||
self.kind = kind
|
||||
self.kind = notifications.first!.kind
|
||||
}
|
||||
|
||||
public static func ==(lhs: NotificationGroup, rhs: NotificationGroup) -> Bool {
|
||||
|
@ -45,61 +44,30 @@ public struct NotificationGroup: Identifiable, Hashable, Sendable {
|
|||
notifications.append(contentsOf: group.notifications)
|
||||
}
|
||||
|
||||
private static func groupKind(for notification: Notification) -> Kind {
|
||||
switch notification.kind {
|
||||
case .mention:
|
||||
return .mention
|
||||
case .reblog:
|
||||
return .reblog
|
||||
case .favourite:
|
||||
return .favourite
|
||||
case .follow:
|
||||
return .follow
|
||||
case .followRequest:
|
||||
return .followRequest
|
||||
case .poll:
|
||||
return .poll
|
||||
case .update:
|
||||
return .update
|
||||
case .status:
|
||||
return .status
|
||||
case .emojiReaction:
|
||||
if let emoji = notification.emoji {
|
||||
return .emojiReaction(emoji, notification.emojiURL)
|
||||
} else {
|
||||
return .unknown
|
||||
}
|
||||
case .unknown:
|
||||
return .unknown
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
public static func createGroups(notifications: [Notification], only allowedTypes: [Notification.Kind]) -> [NotificationGroup] {
|
||||
var groups = [NotificationGroup]()
|
||||
for notification in notifications {
|
||||
let groupKind = groupKind(for: notification)
|
||||
|
||||
if allowedTypes.contains(notification.kind) {
|
||||
if let lastGroup = groups.last, canMerge(notification: notification, kind: groupKind, into: lastGroup) {
|
||||
if let lastGroup = groups.last, canMerge(notification: notification, into: lastGroup) {
|
||||
groups[groups.count - 1].append(notification)
|
||||
continue
|
||||
} else if groups.count >= 2 {
|
||||
let secondToLastGroup = groups[groups.count - 2]
|
||||
if allowedTypes.contains(notification.kind), canMerge(notification: notification, kind: groupKind, into: secondToLastGroup) {
|
||||
if allowedTypes.contains(groups[groups.count - 1].kind), canMerge(notification: notification, into: secondToLastGroup) {
|
||||
groups[groups.count - 2].append(notification)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
groups.append(NotificationGroup(notifications: [notification], kind: groupKind)!)
|
||||
groups.append(NotificationGroup(notifications: [notification])!)
|
||||
}
|
||||
return groups
|
||||
}
|
||||
|
||||
private static func canMerge(notification: Notification, kind: Kind, into group: NotificationGroup) -> Bool {
|
||||
return kind == group.kind && notification.status?.id == group.notifications.first!.status?.id
|
||||
private static func canMerge(notification: Notification, into group: NotificationGroup) -> Bool {
|
||||
return notification.kind == group.kind && notification.status?.id == group.notifications.first!.status?.id
|
||||
}
|
||||
|
||||
public static func mergeGroups(first: [NotificationGroup], second: [NotificationGroup], only allowedTypes: [Notification.Kind]) -> [NotificationGroup] {
|
||||
|
@ -114,21 +82,21 @@ public struct NotificationGroup: Identifiable, Hashable, Sendable {
|
|||
var second = second
|
||||
merged.reserveCapacity(second.count)
|
||||
while let firstGroupFromSecond = second.first,
|
||||
allowedTypes.contains(firstGroupFromSecond.kind.notificationKind) {
|
||||
allowedTypes.contains(firstGroupFromSecond.kind) {
|
||||
|
||||
second.removeFirst()
|
||||
|
||||
guard let lastGroup = merged.last,
|
||||
allowedTypes.contains(lastGroup.kind.notificationKind) else {
|
||||
allowedTypes.contains(lastGroup.kind) else {
|
||||
merged.append(firstGroupFromSecond)
|
||||
break
|
||||
}
|
||||
|
||||
if canMerge(notification: firstGroupFromSecond.notifications.first!, kind: firstGroupFromSecond.kind, into: lastGroup) {
|
||||
if canMerge(notification: firstGroupFromSecond.notifications.first!, into: lastGroup) {
|
||||
merged[merged.count - 1].append(group: firstGroupFromSecond)
|
||||
} else if merged.count >= 2 {
|
||||
let secondToLastGroup = merged[merged.count - 2]
|
||||
if allowedTypes.contains(secondToLastGroup.kind.notificationKind), canMerge(notification: firstGroupFromSecond.notifications.first!, kind: firstGroupFromSecond.kind, into: secondToLastGroup) {
|
||||
if allowedTypes.contains(secondToLastGroup.kind), canMerge(notification: firstGroupFromSecond.notifications.first!, into: secondToLastGroup) {
|
||||
merged[merged.count - 2].append(group: firstGroupFromSecond)
|
||||
} else {
|
||||
merged.append(firstGroupFromSecond)
|
||||
|
@ -141,42 +109,4 @@ public struct NotificationGroup: Identifiable, Hashable, Sendable {
|
|||
return merged
|
||||
}
|
||||
|
||||
public enum Kind: Sendable, Equatable {
|
||||
case mention
|
||||
case reblog
|
||||
case favourite
|
||||
case follow
|
||||
case followRequest
|
||||
case poll
|
||||
case update
|
||||
case status
|
||||
case emojiReaction(String, WebURL?)
|
||||
case unknown
|
||||
|
||||
var notificationKind: Notification.Kind {
|
||||
switch self {
|
||||
case .mention:
|
||||
.mention
|
||||
case .reblog:
|
||||
.reblog
|
||||
case .favourite:
|
||||
.favourite
|
||||
case .follow:
|
||||
.follow
|
||||
case .followRequest:
|
||||
.followRequest
|
||||
case .poll:
|
||||
.poll
|
||||
case .update:
|
||||
.update
|
||||
case .status:
|
||||
.status
|
||||
case .emojiReaction(_, _):
|
||||
.emojiReaction
|
||||
case .unknown:
|
||||
.unknown
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
//
|
||||
// TryDecode.swift
|
||||
// Pachyderm
|
||||
//
|
||||
// Created by Shadowfacts on 6/8/24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public enum TryDecode<T: Decodable>: Decodable {
|
||||
case error(String)
|
||||
case value(T)
|
||||
|
||||
public init(from decoder: any Decoder) throws {
|
||||
do {
|
||||
self = .value(try T(from: decoder))
|
||||
} catch {
|
||||
self = .error(error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
public var value: T? {
|
||||
if case .value(let value) = self {
|
||||
value
|
||||
} else {
|
||||
nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension TryDecode: Sendable where T: Sendable {
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// swift-tools-version: 6.0
|
||||
// swift-tools-version: 5.10
|
||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||
|
||||
import PackageDescription
|
||||
|
@ -6,7 +6,7 @@ import PackageDescription
|
|||
let package = Package(
|
||||
name: "PushNotifications",
|
||||
platforms: [
|
||||
.iOS(.v16),
|
||||
.iOS(.v15),
|
||||
],
|
||||
products: [
|
||||
// Products define the executables and libraries a package produces, making them visible to other packages.
|
||||
|
@ -23,17 +23,10 @@ let package = Package(
|
|||
// Targets can depend on other targets in this package and products from dependencies.
|
||||
.target(
|
||||
name: "PushNotifications",
|
||||
dependencies: ["UserAccounts", "Pachyderm"],
|
||||
swiftSettings: [
|
||||
.swiftLanguageMode(.v5)
|
||||
]
|
||||
dependencies: ["UserAccounts", "Pachyderm"]
|
||||
),
|
||||
.testTarget(
|
||||
name: "PushNotificationsTests",
|
||||
dependencies: ["PushNotifications"],
|
||||
swiftSettings: [
|
||||
.swiftLanguageMode(.v5)
|
||||
]
|
||||
),
|
||||
dependencies: ["PushNotifications"]),
|
||||
]
|
||||
)
|
||||
|
|
|
@ -104,7 +104,6 @@ class PushManagerImpl: _PushManager {
|
|||
self.subscriptions = await AsyncSequenceAdaptor(wrapping: subscriptions).map {
|
||||
let newEndpoint = await self.endpointURL(deviceToken: token, accountID: $0.accountID)
|
||||
guard newEndpoint != $0.endpoint else {
|
||||
PushManager.logger.debug("Skipping update of push subscription with endpoint \($0.endpoint, privacy: .public)")
|
||||
return $0
|
||||
}
|
||||
var copy = $0
|
||||
|
|
|
@ -70,7 +70,6 @@ public struct PushSubscription {
|
|||
public static let favorite = Alerts(rawValue: 1 << 5)
|
||||
public static let poll = Alerts(rawValue: 1 << 6)
|
||||
public static let update = Alerts(rawValue: 1 << 7)
|
||||
public static let emojiReaction = Alerts(rawValue: 1 << 8)
|
||||
|
||||
public let rawValue: Int
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// swift-tools-version: 6.0
|
||||
// swift-tools-version: 5.7
|
||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||
|
||||
import PackageDescription
|
||||
|
@ -6,7 +6,7 @@ import PackageDescription
|
|||
let package = Package(
|
||||
name: "TTTKit",
|
||||
platforms: [
|
||||
.iOS(.v16),
|
||||
.iOS(.v15),
|
||||
],
|
||||
products: [
|
||||
// Products define the executables and libraries a package produces, and make them visible to other packages.
|
||||
|
@ -23,15 +23,9 @@ let package = Package(
|
|||
// Targets can depend on other targets in this package, and on products in packages this package depends on.
|
||||
.target(
|
||||
name: "TTTKit",
|
||||
dependencies: [],
|
||||
swiftSettings: [
|
||||
.swiftLanguageMode(.v5)
|
||||
]),
|
||||
dependencies: []),
|
||||
.testTarget(
|
||||
name: "TTTKitTests",
|
||||
dependencies: ["TTTKit"],
|
||||
swiftSettings: [
|
||||
.swiftLanguageMode(.v5)
|
||||
]),
|
||||
dependencies: ["TTTKit"]),
|
||||
]
|
||||
)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// swift-tools-version: 6.0
|
||||
// swift-tools-version: 5.7
|
||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||
|
||||
import PackageDescription
|
||||
|
@ -6,7 +6,7 @@ import PackageDescription
|
|||
let package = Package(
|
||||
name: "TuskerComponents",
|
||||
platforms: [
|
||||
.iOS(.v16),
|
||||
.iOS(.v15),
|
||||
],
|
||||
products: [
|
||||
// Products define the executables and libraries a package produces, and make them visible to other packages.
|
||||
|
@ -23,10 +23,7 @@ let package = Package(
|
|||
// Targets can depend on other targets in this package, and on products in packages this package depends on.
|
||||
.target(
|
||||
name: "TuskerComponents",
|
||||
dependencies: [],
|
||||
swiftSettings: [
|
||||
.swiftLanguageMode(.v5)
|
||||
]),
|
||||
dependencies: []),
|
||||
// .testTarget(
|
||||
// name: "TuskerComponentsTests",
|
||||
// dependencies: ["TuskerComponents"]),
|
||||
|
|
|
@ -9,14 +9,21 @@ import SwiftUI
|
|||
|
||||
public struct AsyncPicker<V: Hashable, Content: View>: View {
|
||||
let titleKey: LocalizedStringKey
|
||||
#if !os(visionOS)
|
||||
@available(iOS, obsoleted: 16.0, message: "Switch to LabeledContent")
|
||||
let labelHidden: Bool
|
||||
#endif
|
||||
let alignment: Alignment
|
||||
@Binding var value: V
|
||||
let onChange: (V) async -> Bool
|
||||
let content: Content
|
||||
@State private var isLoading = false
|
||||
|
||||
public init(_ titleKey: LocalizedStringKey, alignment: Alignment = .center, value: Binding<V>, onChange: @escaping (V) async -> Bool, @ViewBuilder content: () -> Content) {
|
||||
public init(_ titleKey: LocalizedStringKey, labelHidden: Bool = false, alignment: Alignment = .center, value: Binding<V>, onChange: @escaping (V) async -> Bool, @ViewBuilder content: () -> Content) {
|
||||
self.titleKey = titleKey
|
||||
#if !os(visionOS)
|
||||
self.labelHidden = labelHidden
|
||||
#endif
|
||||
self.alignment = alignment
|
||||
self._value = value
|
||||
self.onChange = onChange
|
||||
|
@ -24,9 +31,25 @@ public struct AsyncPicker<V: Hashable, Content: View>: View {
|
|||
}
|
||||
|
||||
public var body: some View {
|
||||
#if os(visionOS)
|
||||
LabeledContent(titleKey) {
|
||||
picker
|
||||
}
|
||||
#else
|
||||
if #available(iOS 16.0, *) {
|
||||
LabeledContent(titleKey) {
|
||||
picker
|
||||
}
|
||||
} else if labelHidden {
|
||||
picker
|
||||
} else {
|
||||
HStack {
|
||||
Text(titleKey)
|
||||
Spacer()
|
||||
picker
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private var picker: some View {
|
||||
|
|
|
@ -10,19 +10,42 @@ import SwiftUI
|
|||
|
||||
public struct AsyncToggle: View {
|
||||
let titleKey: LocalizedStringKey
|
||||
#if !os(visionOS)
|
||||
@available(iOS, obsoleted: 16.0, message: "Switch to LabeledContent")
|
||||
let labelHidden: Bool
|
||||
#endif
|
||||
@Binding var mode: Mode
|
||||
let onChange: (Bool) async -> Bool
|
||||
|
||||
public init(_ titleKey: LocalizedStringKey, mode: Binding<Mode>, onChange: @escaping (Bool) async -> Bool) {
|
||||
public init(_ titleKey: LocalizedStringKey, labelHidden: Bool = false, mode: Binding<Mode>, onChange: @escaping (Bool) async -> Bool) {
|
||||
self.titleKey = titleKey
|
||||
#if !os(visionOS)
|
||||
self.labelHidden = labelHidden
|
||||
#endif
|
||||
self._mode = mode
|
||||
self.onChange = onChange
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
#if os(visionOS)
|
||||
LabeledContent(titleKey) {
|
||||
toggleOrSpinner
|
||||
}
|
||||
#else
|
||||
if #available(iOS 16.0, *) {
|
||||
LabeledContent(titleKey) {
|
||||
toggleOrSpinner
|
||||
}
|
||||
} else if labelHidden {
|
||||
toggleOrSpinner
|
||||
} else {
|
||||
HStack {
|
||||
Text(titleKey)
|
||||
Spacer()
|
||||
toggleOrSpinner
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
|
|
|
@ -47,7 +47,9 @@ public struct MenuPicker<Value: Hashable>: UIViewRepresentable {
|
|||
|
||||
private func makeConfiguration() -> UIButton.Configuration {
|
||||
var config = UIButton.Configuration.borderless()
|
||||
if #available(iOS 16.0, *) {
|
||||
config.indicator = .popup
|
||||
}
|
||||
if buttonStyle.hasIcon {
|
||||
config.image = selectedOption.image
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// swift-tools-version: 6.0
|
||||
// swift-tools-version: 5.8
|
||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||
|
||||
import PackageDescription
|
||||
|
@ -6,7 +6,7 @@ import PackageDescription
|
|||
let package = Package(
|
||||
name: "TuskerPreferences",
|
||||
platforms: [
|
||||
.iOS(.v16),
|
||||
.iOS(.v15),
|
||||
],
|
||||
products: [
|
||||
// Products define the executables and libraries a package produces, making them visible to other packages.
|
||||
|
@ -22,17 +22,11 @@ let package = Package(
|
|||
// Targets can depend on other targets in this package and products from dependencies.
|
||||
.target(
|
||||
name: "TuskerPreferences",
|
||||
dependencies: ["Pachyderm"],
|
||||
swiftSettings: [
|
||||
.swiftLanguageMode(.v5)
|
||||
]
|
||||
dependencies: ["Pachyderm"]
|
||||
),
|
||||
.testTarget(
|
||||
name: "TuskerPreferencesTests",
|
||||
dependencies: ["TuskerPreferences"],
|
||||
swiftSettings: [
|
||||
.swiftLanguageMode(.v5)
|
||||
]
|
||||
dependencies: ["TuskerPreferences"]
|
||||
)
|
||||
]
|
||||
)
|
||||
|
|
|
@ -74,9 +74,4 @@ extension PreferenceStore {
|
|||
public func hasFeatureFlag(_ flag: FeatureFlag) -> Bool {
|
||||
enabledFeatureFlags.contains(flag)
|
||||
}
|
||||
|
||||
|
||||
public func getValue<Key: PreferenceKey>(preferenceKeyPath: KeyPath<PreferenceStore, PreferencePublisher<Key>>) -> Key.Value {
|
||||
self[keyPath: preferenceKeyPath].preference.wrappedValue
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,5 +9,4 @@ import Foundation
|
|||
|
||||
public enum FeatureFlag: String, Codable {
|
||||
case iPadBrowserNavigation = "ipad-browser-navigation"
|
||||
case pushNotifCustomEmoji = "push-notif-custom-emoji"
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// swift-tools-version: 6.0
|
||||
// swift-tools-version: 5.7
|
||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||
|
||||
import PackageDescription
|
||||
|
@ -6,7 +6,7 @@ import PackageDescription
|
|||
let package = Package(
|
||||
name: "UserAccounts",
|
||||
platforms: [
|
||||
.iOS(.v16),
|
||||
.iOS(.v15),
|
||||
],
|
||||
products: [
|
||||
// Products define the executables and libraries a package produces, and make them visible to other packages.
|
||||
|
@ -23,10 +23,7 @@ let package = Package(
|
|||
// Targets can depend on other targets in this package, and on products in packages this package depends on.
|
||||
.target(
|
||||
name: "UserAccounts",
|
||||
dependencies: ["Pachyderm"],
|
||||
swiftSettings: [
|
||||
.swiftLanguageMode(.v5)
|
||||
]),
|
||||
dependencies: ["Pachyderm"]),
|
||||
// .testTarget(
|
||||
// name: "UserAccountsTests",
|
||||
// dependencies: ["UserAccounts"]),
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
D60E2F2E244248BF005F8713 /* MastodonCachePersistentStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = D60E2F2D244248BF005F8713 /* MastodonCachePersistentStore.swift */; };
|
||||
D6114E0D27F7FEB30080E273 /* TrendingStatusesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6114E0C27F7FEB30080E273 /* TrendingStatusesViewController.swift */; };
|
||||
D6114E1127F899B30080E273 /* TrendingLinksViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6114E1027F899B30080E273 /* TrendingLinksViewController.swift */; };
|
||||
D6187BED2BFA840B00B3A281 /* FollowRequestNotificationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6187BEC2BFA840B00B3A281 /* FollowRequestNotificationViewController.swift */; };
|
||||
D61A45E628DC0F2F002BE511 /* ConfirmLoadMoreCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D61A45E528DC0F2F002BE511 /* ConfirmLoadMoreCollectionViewCell.swift */; };
|
||||
D61A45E828DF477D002BE511 /* LoadingCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D61A45E728DF477D002BE511 /* LoadingCollectionViewCell.swift */; };
|
||||
D61A45EA28DF51EE002BE511 /* TimelineLikeCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D61A45E928DF51EE002BE511 /* TimelineLikeCollectionViewController.swift */; };
|
||||
|
@ -75,9 +74,7 @@
|
|||
D620483423D3801D008A63EF /* LinkTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D620483323D3801D008A63EF /* LinkTextView.swift */; };
|
||||
D620483623D38075008A63EF /* ContentTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D620483523D38075008A63EF /* ContentTextView.swift */; };
|
||||
D620483823D38190008A63EF /* StatusContentTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D620483723D38190008A63EF /* StatusContentTextView.swift */; };
|
||||
D6210D762C0B924F009BB569 /* RemoveProfileSuggestionService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6210D752C0B924F009BB569 /* RemoveProfileSuggestionService.swift */; };
|
||||
D621733328F1D5ED004C7DB1 /* ReblogService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D621733228F1D5ED004C7DB1 /* ReblogService.swift */; };
|
||||
D62220472C7EA8DF003E43B7 /* TuskerPreferences in Frameworks */ = {isa = PBXBuildFile; productRef = D62220462C7EA8DF003E43B7 /* TuskerPreferences */; };
|
||||
D62275A824F1CA2800B82A16 /* ComposeReplyContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62275A724F1CA2800B82A16 /* ComposeReplyContentView.swift */; };
|
||||
D623A53D2635F5590095BD04 /* StatusPollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D623A53C2635F5590095BD04 /* StatusPollView.swift */; };
|
||||
D623A5412635FB3C0095BD04 /* PollOptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D623A5402635FB3C0095BD04 /* PollOptionView.swift */; };
|
||||
|
@ -98,7 +95,7 @@
|
|||
D630C3CA2BC59FF500208903 /* MastodonController+Push.swift in Sources */ = {isa = PBXBuildFile; fileRef = D630C3C92BC59FF500208903 /* MastodonController+Push.swift */; };
|
||||
D630C3CC2BC5FD4600208903 /* GetAuthorizationTokenService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D630C3CB2BC5FD4600208903 /* GetAuthorizationTokenService.swift */; };
|
||||
D630C3D42BC61B6100208903 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D630C3D32BC61B6100208903 /* NotificationService.swift */; };
|
||||
D630C3D82BC61B6100208903 /* NotificationExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = D630C3D12BC61B6000208903 /* NotificationExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
D630C3D82BC61B6100208903 /* NotificationExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = D630C3D12BC61B6000208903 /* NotificationExtension.appex */; platformFilters = (ios, maccatalyst, ); settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
D630C3DF2BC61C4900208903 /* PushNotifications in Frameworks */ = {isa = PBXBuildFile; productRef = D630C3DE2BC61C4900208903 /* PushNotifications */; };
|
||||
D630C3E12BC61C6700208903 /* UserAccounts in Frameworks */ = {isa = PBXBuildFile; productRef = D630C3E02BC61C6700208903 /* UserAccounts */; };
|
||||
D630C3E52BC6313400208903 /* Pachyderm in Frameworks */ = {isa = PBXBuildFile; productRef = D630C3E42BC6313400208903 /* Pachyderm */; };
|
||||
|
@ -130,10 +127,6 @@
|
|||
D646DCD82A07F3500059ECEB /* FollowRequestNotificationCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D646DCD72A07F3500059ECEB /* FollowRequestNotificationCollectionViewCell.swift */; };
|
||||
D646DCDA2A081A2C0059ECEB /* PollFinishedNotificationCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D646DCD92A081A2C0059ECEB /* PollFinishedNotificationCollectionViewCell.swift */; };
|
||||
D646DCDC2A081CF10059ECEB /* StatusUpdatedNotificationCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D646DCDB2A081CF10059ECEB /* StatusUpdatedNotificationCollectionViewCell.swift */; };
|
||||
D64A50462C739DC0009D7193 /* NewMainTabBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64A50452C739DC0009D7193 /* NewMainTabBarViewController.swift */; };
|
||||
D64A50482C739DEA009D7193 /* BaseMainTabBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64A50472C739DEA009D7193 /* BaseMainTabBarViewController.swift */; };
|
||||
D64A50BC2C74F8F4009D7193 /* FindInstanceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64A50BB2C74F8F4009D7193 /* FindInstanceViewController.swift */; };
|
||||
D64A50BE2C752247009D7193 /* AdaptableNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64A50BD2C752247009D7193 /* AdaptableNavigationController.swift */; };
|
||||
D64AAE9126C80DC600FC57FB /* ToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64AAE9026C80DC600FC57FB /* ToastView.swift */; };
|
||||
D64AAE9526C88C5000FC57FB /* ToastableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64AAE9426C88C5000FC57FB /* ToastableViewController.swift */; };
|
||||
D64AAE9726C88DC400FC57FB /* ToastConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64AAE9626C88DC400FC57FB /* ToastConfiguration.swift */; };
|
||||
|
@ -141,6 +134,7 @@
|
|||
D64B96812BC3279D002C8990 /* PrefsAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64B96802BC3279D002C8990 /* PrefsAccountView.swift */; };
|
||||
D64B96842BC3893C002C8990 /* PushSubscriptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64B96832BC3893C002C8990 /* PushSubscriptionView.swift */; };
|
||||
D64D0AB12128D9AE005A6F37 /* OnboardingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64D0AB02128D9AE005A6F37 /* OnboardingViewController.swift */; };
|
||||
D64D8CA92463B494006B0BAA /* MultiThreadDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64D8CA82463B494006B0BAA /* MultiThreadDictionary.swift */; };
|
||||
D651C5B42915B00400236EF6 /* ProfileFieldsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D651C5B32915B00400236EF6 /* ProfileFieldsView.swift */; };
|
||||
D6531DEE246B81C9000F9538 /* GifvPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6531DED246B81C9000F9538 /* GifvPlayerView.swift */; };
|
||||
D6538945214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6538944214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift */; };
|
||||
|
@ -165,6 +159,7 @@
|
|||
D663626C21361C6700C9CBA2 /* Account+Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = D663626B21361C6700C9CBA2 /* Account+Preferences.swift */; };
|
||||
D6674AEA23341F7600E8DF94 /* AppShortcutItems.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6674AE923341F7600E8DF94 /* AppShortcutItems.swift */; };
|
||||
D6676CA527A8D0020052936B /* WebURLFoundationExtras in Frameworks */ = {isa = PBXBuildFile; productRef = D6676CA427A8D0020052936B /* WebURLFoundationExtras */; };
|
||||
D667E5F82135C3040057A976 /* Mastodon+Equatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D667E5F72135C3040057A976 /* Mastodon+Equatable.swift */; };
|
||||
D66A77BB233838DC0058F1EC /* UIFont+Traits.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66A77BA233838DC0058F1EC /* UIFont+Traits.swift */; };
|
||||
D66C900B28DAB7FD00217BF2 /* TimelineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66C900A28DAB7FD00217BF2 /* TimelineViewController.swift */; };
|
||||
D674A50927F9128D00BA03AC /* Pachyderm in Frameworks */ = {isa = PBXBuildFile; productRef = D674A50827F9128D00BA03AC /* Pachyderm */; };
|
||||
|
@ -218,24 +213,20 @@
|
|||
D6934F402BAA19EC002B1C8D /* VideoActivityItemSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6934F3F2BAA19EC002B1C8D /* VideoActivityItemSource.swift */; };
|
||||
D6934F422BAC7D6E002B1C8D /* VideoControlsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6934F412BAC7D6E002B1C8D /* VideoControlsViewController.swift */; };
|
||||
D693A72825CF282E003A14E2 /* TrendingHashtagsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D693A72725CF282E003A14E2 /* TrendingHashtagsViewController.swift */; };
|
||||
D693A72F25CF91C6003A14E2 /* FeaturedProfileCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D693A72D25CF91C6003A14E2 /* FeaturedProfileCollectionViewCell.swift */; };
|
||||
D693A73025CF91C6003A14E2 /* FeaturedProfileCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D693A72E25CF91C6003A14E2 /* FeaturedProfileCollectionViewCell.xib */; };
|
||||
D693DE5723FE1A6A0061E07D /* EnhancedNavigationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D693DE5623FE1A6A0061E07D /* EnhancedNavigationViewController.swift */; };
|
||||
D693DE5923FE24310061E07D /* InteractivePushTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = D693DE5823FE24300061E07D /* InteractivePushTransition.swift */; };
|
||||
D6945C2F23AC47C3005C403C /* SavedDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6945C2E23AC47C3005C403C /* SavedDataManager.swift */; };
|
||||
D6945C3223AC4D36005C403C /* HashtagTimelineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6945C3123AC4D36005C403C /* HashtagTimelineViewController.swift */; };
|
||||
D6945C3423AC6431005C403C /* AddSavedHashtagViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6945C3323AC6431005C403C /* AddSavedHashtagViewController.swift */; };
|
||||
D6945C3823AC739F005C403C /* InstanceTimelineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6945C3723AC739F005C403C /* InstanceTimelineViewController.swift */; };
|
||||
D6945C3A23AC75E2005C403C /* FindInstanceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6945C3923AC75E2005C403C /* FindInstanceViewController.swift */; };
|
||||
D6958F3D2AA383D90062FE52 /* WidescreenNavigationPrefsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6958F3C2AA383D90062FE52 /* WidescreenNavigationPrefsView.swift */; };
|
||||
D69693F42585941A00F4E116 /* UIWindowSceneDelegate+Close.swift in Sources */ = {isa = PBXBuildFile; fileRef = D69693F32585941A00F4E116 /* UIWindowSceneDelegate+Close.swift */; };
|
||||
D69693FA25859A8000F4E116 /* ComposeSceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D69693F925859A8000F4E116 /* ComposeSceneDelegate.swift */; };
|
||||
D6969E9E240C81B9002843CE /* NSTextAttachment+Emoji.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6969E9D240C81B9002843CE /* NSTextAttachment+Emoji.swift */; };
|
||||
D6969EA0240C8384002843CE /* EmojiLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6969E9F240C8384002843CE /* EmojiLabel.swift */; };
|
||||
D698F4672BD079800054DB14 /* AnnouncementsHostingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D698F4662BD079800054DB14 /* AnnouncementsHostingController.swift */; };
|
||||
D698F4692BD0799F0054DB14 /* AnnouncementsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D698F4682BD0799F0054DB14 /* AnnouncementsView.swift */; };
|
||||
D698F46B2BD079F00054DB14 /* AnnouncementListRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = D698F46A2BD079F00054DB14 /* AnnouncementListRow.swift */; };
|
||||
D698F46D2BD0B8310054DB14 /* AnnouncementsCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = D698F46C2BD0B8310054DB14 /* AnnouncementsCollection.swift */; };
|
||||
D698F46F2BD0B8DF0054DB14 /* AddReactionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D698F46E2BD0B8DF0054DB14 /* AddReactionView.swift */; };
|
||||
D698F4712BD0CBAA0054DB14 /* AnnouncementContentTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D698F4702BD0CBAA0054DB14 /* AnnouncementContentTextView.swift */; };
|
||||
D69F26342C4CDFD300FAF761 /* AccountDisplayAndUserNameLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D69F26332C4CDFD300FAF761 /* AccountDisplayAndUserNameLabel.swift */; };
|
||||
D6A00B1D26379FC900316AD4 /* PollOptionsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A00B1C26379FC900316AD4 /* PollOptionsView.swift */; };
|
||||
D6A3A380295515550036B6EF /* ProfileHeaderButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A3A37F295515550036B6EF /* ProfileHeaderButton.swift */; };
|
||||
D6A3A3822956123A0036B6EF /* TimelinePosition.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A3A3812956123A0036B6EF /* TimelinePosition.swift */; };
|
||||
|
@ -260,7 +251,6 @@
|
|||
D6A6C10F25B62D2400298D0F /* DiskCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A6C10E25B62D2400298D0F /* DiskCache.swift */; };
|
||||
D6A6C11525B62E9700298D0F /* CacheExpiry.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A6C11425B62E9700298D0F /* CacheExpiry.swift */; };
|
||||
D6A6C11B25B63CEE00298D0F /* MemoryCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A6C11A25B63CEE00298D0F /* MemoryCache.swift */; };
|
||||
D6A8D7A52C14DB280007B285 /* PersistentHistoryTokenStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A8D7A42C14DB280007B285 /* PersistentHistoryTokenStore.swift */; };
|
||||
D6AC956723C4347E008C9946 /* MainSceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6AC956623C4347E008C9946 /* MainSceneDelegate.swift */; };
|
||||
D6ADB6E828E8C878009924AB /* PublicTimelineDescriptionCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6ADB6E728E8C878009924AB /* PublicTimelineDescriptionCollectionViewCell.swift */; };
|
||||
D6ADB6EA28E91C30009924AB /* TimelineStatusCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6ADB6E928E91C30009924AB /* TimelineStatusCollectionViewCell.swift */; };
|
||||
|
@ -301,7 +291,6 @@
|
|||
D6C3F5192991F5D60009FCFF /* TimelineJumpButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C3F5182991F5D60009FCFF /* TimelineJumpButton.swift */; };
|
||||
D6C4532D2BCB86AC00E26A0E /* AppearancePrefsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C4532C2BCB86AC00E26A0E /* AppearancePrefsView.swift */; };
|
||||
D6C4532F2BCB873400E26A0E /* MockStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C4532E2BCB873400E26A0E /* MockStatusView.swift */; };
|
||||
D6C453372BCE1CEF00E26A0E /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = D6C4532A2BCAD7F900E26A0E /* PrivacyInfo.xcprivacy */; };
|
||||
D6C693EF216192C2007D6A6D /* TuskerNavigationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693EE216192C2007D6A6D /* TuskerNavigationDelegate.swift */; };
|
||||
D6C693FC2162FE6F007D6A6D /* LoadingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693FB2162FE6F007D6A6D /* LoadingViewController.swift */; };
|
||||
D6C693FE2162FEEA007D6A6D /* UIViewController+Children.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693FD2162FEEA007D6A6D /* UIViewController+Children.swift */; };
|
||||
|
@ -336,7 +325,7 @@
|
|||
D6D79F592A13293200AB2315 /* BackgroundManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D79F582A13293200AB2315 /* BackgroundManager.swift */; };
|
||||
D6D94955298963A900C59229 /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D94954298963A900C59229 /* Colors.swift */; };
|
||||
D6D9498D298CBB4000C59229 /* TrendingStatusCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D9498C298CBB4000C59229 /* TrendingStatusCollectionViewCell.swift */; };
|
||||
D6D9498F298EB79400C59229 /* CopyableLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D9498E298EB79400C59229 /* CopyableLabel.swift */; };
|
||||
D6D9498F298EB79400C59229 /* CopyableLable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D9498E298EB79400C59229 /* CopyableLable.swift */; };
|
||||
D6DD8FFD298495A8002AD3FD /* LogoutService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6DD8FFC298495A8002AD3FD /* LogoutService.swift */; };
|
||||
D6DD8FFF2984D327002AD3FD /* BookmarksViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6DD8FFE2984D327002AD3FD /* BookmarksViewController.swift */; };
|
||||
D6DD996B2998611A0015C962 /* SuggestedProfilesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6DD996A2998611A0015C962 /* SuggestedProfilesViewController.swift */; };
|
||||
|
@ -362,7 +351,6 @@
|
|||
D6EBF01523C55C0900AE061B /* UIApplication+Scenes.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6EBF01423C55C0900AE061B /* UIApplication+Scenes.swift */; };
|
||||
D6EBF01723C55E0D00AE061B /* UISceneSession+MastodonController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6EBF01623C55E0D00AE061B /* UISceneSession+MastodonController.swift */; };
|
||||
D6EE63FB2551F7F60065485C /* StatusCollapseButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6EE63FA2551F7F60065485C /* StatusCollapseButton.swift */; };
|
||||
D6EEDE932C3CF21800E10E51 /* AudioSessionCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6EEDE922C3CF21800E10E51 /* AudioSessionCoordinator.swift */; };
|
||||
D6F0B12B24A3071C001E48C3 /* MainSplitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6F0B12A24A3071C001E48C3 /* MainSplitViewController.swift */; };
|
||||
D6F0B17524A3A1AA001E48C3 /* MainSidebarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6F0B17424A3A1AA001E48C3 /* MainSidebarViewController.swift */; };
|
||||
D6F253CF2AC9F86300806D83 /* SearchTokenSuggestionCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6F253CE2AC9F86300806D83 /* SearchTokenSuggestionCollectionViewCell.swift */; };
|
||||
|
@ -472,7 +460,6 @@
|
|||
D60E2F2D244248BF005F8713 /* MastodonCachePersistentStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonCachePersistentStore.swift; sourceTree = "<group>"; };
|
||||
D6114E0C27F7FEB30080E273 /* TrendingStatusesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrendingStatusesViewController.swift; sourceTree = "<group>"; };
|
||||
D6114E1027F899B30080E273 /* TrendingLinksViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrendingLinksViewController.swift; sourceTree = "<group>"; };
|
||||
D6187BEC2BFA840B00B3A281 /* FollowRequestNotificationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowRequestNotificationViewController.swift; sourceTree = "<group>"; };
|
||||
D61A45E528DC0F2F002BE511 /* ConfirmLoadMoreCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmLoadMoreCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||
D61A45E728DF477D002BE511 /* LoadingCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||
D61A45E928DF51EE002BE511 /* TimelineLikeCollectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineLikeCollectionViewController.swift; sourceTree = "<group>"; };
|
||||
|
@ -510,7 +497,6 @@
|
|||
D620483323D3801D008A63EF /* LinkTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkTextView.swift; sourceTree = "<group>"; };
|
||||
D620483523D38075008A63EF /* ContentTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentTextView.swift; sourceTree = "<group>"; };
|
||||
D620483723D38190008A63EF /* StatusContentTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusContentTextView.swift; sourceTree = "<group>"; };
|
||||
D6210D752C0B924F009BB569 /* RemoveProfileSuggestionService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoveProfileSuggestionService.swift; sourceTree = "<group>"; };
|
||||
D621733228F1D5ED004C7DB1 /* ReblogService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReblogService.swift; sourceTree = "<group>"; };
|
||||
D62275A724F1CA2800B82A16 /* ComposeReplyContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeReplyContentView.swift; sourceTree = "<group>"; };
|
||||
D623A53C2635F5590095BD04 /* StatusPollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusPollView.swift; sourceTree = "<group>"; };
|
||||
|
@ -560,10 +546,6 @@
|
|||
D646DCD72A07F3500059ECEB /* FollowRequestNotificationCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowRequestNotificationCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||
D646DCD92A081A2C0059ECEB /* PollFinishedNotificationCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollFinishedNotificationCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||
D646DCDB2A081CF10059ECEB /* StatusUpdatedNotificationCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusUpdatedNotificationCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||
D64A50452C739DC0009D7193 /* NewMainTabBarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewMainTabBarViewController.swift; sourceTree = "<group>"; };
|
||||
D64A50472C739DEA009D7193 /* BaseMainTabBarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseMainTabBarViewController.swift; sourceTree = "<group>"; };
|
||||
D64A50BB2C74F8F4009D7193 /* FindInstanceViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FindInstanceViewController.swift; sourceTree = "<group>"; };
|
||||
D64A50BD2C752247009D7193 /* AdaptableNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdaptableNavigationController.swift; sourceTree = "<group>"; };
|
||||
D64AAE9026C80DC600FC57FB /* ToastView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastView.swift; sourceTree = "<group>"; };
|
||||
D64AAE9426C88C5000FC57FB /* ToastableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastableViewController.swift; sourceTree = "<group>"; };
|
||||
D64AAE9626C88DC400FC57FB /* ToastConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastConfiguration.swift; sourceTree = "<group>"; };
|
||||
|
@ -571,6 +553,7 @@
|
|||
D64B96802BC3279D002C8990 /* PrefsAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrefsAccountView.swift; sourceTree = "<group>"; };
|
||||
D64B96832BC3893C002C8990 /* PushSubscriptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushSubscriptionView.swift; sourceTree = "<group>"; };
|
||||
D64D0AB02128D9AE005A6F37 /* OnboardingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingViewController.swift; sourceTree = "<group>"; };
|
||||
D64D8CA82463B494006B0BAA /* MultiThreadDictionary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiThreadDictionary.swift; sourceTree = "<group>"; };
|
||||
D651C5B32915B00400236EF6 /* ProfileFieldsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileFieldsView.swift; sourceTree = "<group>"; };
|
||||
D6531DED246B81C9000F9538 /* GifvPlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GifvPlayerView.swift; sourceTree = "<group>"; };
|
||||
D6538944214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewSwipeActionProvider.swift; sourceTree = "<group>"; };
|
||||
|
@ -597,6 +580,7 @@
|
|||
D6620ACD2511A0ED00312CA0 /* StatusStateResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusStateResolver.swift; sourceTree = "<group>"; };
|
||||
D663626B21361C6700C9CBA2 /* Account+Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Account+Preferences.swift"; sourceTree = "<group>"; };
|
||||
D6674AE923341F7600E8DF94 /* AppShortcutItems.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppShortcutItems.swift; sourceTree = "<group>"; };
|
||||
D667E5F72135C3040057A976 /* Mastodon+Equatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Mastodon+Equatable.swift"; sourceTree = "<group>"; };
|
||||
D66A77BA233838DC0058F1EC /* UIFont+Traits.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIFont+Traits.swift"; sourceTree = "<group>"; };
|
||||
D66C900A28DAB7FD00217BF2 /* TimelineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineViewController.swift; sourceTree = "<group>"; };
|
||||
D671A6BE299DA96100A81FEA /* Tusker-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Tusker-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
|
@ -651,24 +635,20 @@
|
|||
D6934F3F2BAA19EC002B1C8D /* VideoActivityItemSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoActivityItemSource.swift; sourceTree = "<group>"; };
|
||||
D6934F412BAC7D6E002B1C8D /* VideoControlsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoControlsViewController.swift; sourceTree = "<group>"; };
|
||||
D693A72725CF282E003A14E2 /* TrendingHashtagsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrendingHashtagsViewController.swift; sourceTree = "<group>"; };
|
||||
D693A72D25CF91C6003A14E2 /* FeaturedProfileCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeaturedProfileCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||
D693A72E25CF91C6003A14E2 /* FeaturedProfileCollectionViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = FeaturedProfileCollectionViewCell.xib; sourceTree = "<group>"; };
|
||||
D693DE5623FE1A6A0061E07D /* EnhancedNavigationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnhancedNavigationViewController.swift; sourceTree = "<group>"; };
|
||||
D693DE5823FE24300061E07D /* InteractivePushTransition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InteractivePushTransition.swift; sourceTree = "<group>"; };
|
||||
D6945C2E23AC47C3005C403C /* SavedDataManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SavedDataManager.swift; sourceTree = "<group>"; };
|
||||
D6945C3123AC4D36005C403C /* HashtagTimelineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashtagTimelineViewController.swift; sourceTree = "<group>"; };
|
||||
D6945C3323AC6431005C403C /* AddSavedHashtagViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddSavedHashtagViewController.swift; sourceTree = "<group>"; };
|
||||
D6945C3723AC739F005C403C /* InstanceTimelineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstanceTimelineViewController.swift; sourceTree = "<group>"; };
|
||||
D6945C3923AC75E2005C403C /* FindInstanceViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = FindInstanceViewController.swift; path = Tusker/Screens/FindInstanceViewController.swift; sourceTree = SOURCE_ROOT; };
|
||||
D6958F3C2AA383D90062FE52 /* WidescreenNavigationPrefsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidescreenNavigationPrefsView.swift; sourceTree = "<group>"; };
|
||||
D69693F32585941A00F4E116 /* UIWindowSceneDelegate+Close.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIWindowSceneDelegate+Close.swift"; sourceTree = "<group>"; };
|
||||
D69693F925859A8000F4E116 /* ComposeSceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeSceneDelegate.swift; sourceTree = "<group>"; };
|
||||
D6969E9D240C81B9002843CE /* NSTextAttachment+Emoji.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSTextAttachment+Emoji.swift"; sourceTree = "<group>"; };
|
||||
D6969E9F240C8384002843CE /* EmojiLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiLabel.swift; sourceTree = "<group>"; };
|
||||
D698F4662BD079800054DB14 /* AnnouncementsHostingController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnnouncementsHostingController.swift; sourceTree = "<group>"; };
|
||||
D698F4682BD0799F0054DB14 /* AnnouncementsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnnouncementsView.swift; sourceTree = "<group>"; };
|
||||
D698F46A2BD079F00054DB14 /* AnnouncementListRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnnouncementListRow.swift; sourceTree = "<group>"; };
|
||||
D698F46C2BD0B8310054DB14 /* AnnouncementsCollection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnnouncementsCollection.swift; sourceTree = "<group>"; };
|
||||
D698F46E2BD0B8DF0054DB14 /* AddReactionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddReactionView.swift; sourceTree = "<group>"; };
|
||||
D698F4702BD0CBAA0054DB14 /* AnnouncementContentTextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnnouncementContentTextView.swift; sourceTree = "<group>"; };
|
||||
D69F26332C4CDFD300FAF761 /* AccountDisplayAndUserNameLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountDisplayAndUserNameLabel.swift; sourceTree = "<group>"; };
|
||||
D6A00B1C26379FC900316AD4 /* PollOptionsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollOptionsView.swift; sourceTree = "<group>"; };
|
||||
D6A3A37F295515550036B6EF /* ProfileHeaderButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileHeaderButton.swift; sourceTree = "<group>"; };
|
||||
D6A3A3812956123A0036B6EF /* TimelinePosition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelinePosition.swift; sourceTree = "<group>"; };
|
||||
|
@ -690,7 +670,6 @@
|
|||
D6A6C10E25B62D2400298D0F /* DiskCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiskCache.swift; sourceTree = "<group>"; };
|
||||
D6A6C11425B62E9700298D0F /* CacheExpiry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CacheExpiry.swift; sourceTree = "<group>"; };
|
||||
D6A6C11A25B63CEE00298D0F /* MemoryCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemoryCache.swift; sourceTree = "<group>"; };
|
||||
D6A8D7A42C14DB280007B285 /* PersistentHistoryTokenStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersistentHistoryTokenStore.swift; sourceTree = "<group>"; };
|
||||
D6A9E04F29F8917500BEDC7E /* MatchedGeometryPresentation */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = MatchedGeometryPresentation; sourceTree = "<group>"; };
|
||||
D6AC956623C4347E008C9946 /* MainSceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainSceneDelegate.swift; sourceTree = "<group>"; };
|
||||
D6ADB6E728E8C878009924AB /* PublicTimelineDescriptionCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublicTimelineDescriptionCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||
|
@ -776,7 +755,7 @@
|
|||
D6D79F582A13293200AB2315 /* BackgroundManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundManager.swift; sourceTree = "<group>"; };
|
||||
D6D94954298963A900C59229 /* Colors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Colors.swift; sourceTree = "<group>"; };
|
||||
D6D9498C298CBB4000C59229 /* TrendingStatusCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrendingStatusCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||
D6D9498E298EB79400C59229 /* CopyableLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CopyableLabel.swift; sourceTree = "<group>"; };
|
||||
D6D9498E298EB79400C59229 /* CopyableLable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CopyableLable.swift; sourceTree = "<group>"; };
|
||||
D6DD8FFC298495A8002AD3FD /* LogoutService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogoutService.swift; sourceTree = "<group>"; };
|
||||
D6DD8FFE2984D327002AD3FD /* BookmarksViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarksViewController.swift; sourceTree = "<group>"; };
|
||||
D6DD996A2998611A0015C962 /* SuggestedProfilesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuggestedProfilesViewController.swift; sourceTree = "<group>"; };
|
||||
|
@ -805,7 +784,6 @@
|
|||
D6EBF01423C55C0900AE061B /* UIApplication+Scenes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIApplication+Scenes.swift"; sourceTree = "<group>"; };
|
||||
D6EBF01623C55E0D00AE061B /* UISceneSession+MastodonController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UISceneSession+MastodonController.swift"; sourceTree = "<group>"; };
|
||||
D6EE63FA2551F7F60065485C /* StatusCollapseButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusCollapseButton.swift; sourceTree = "<group>"; };
|
||||
D6EEDE922C3CF21800E10E51 /* AudioSessionCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioSessionCoordinator.swift; sourceTree = "<group>"; };
|
||||
D6F0B12A24A3071C001E48C3 /* MainSplitViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainSplitViewController.swift; sourceTree = "<group>"; };
|
||||
D6F0B17424A3A1AA001E48C3 /* MainSidebarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainSidebarViewController.swift; sourceTree = "<group>"; };
|
||||
D6F253CE2AC9F86300806D83 /* SearchTokenSuggestionCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchTokenSuggestionCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||
|
@ -827,7 +805,6 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D630C4252BC7845800208903 /* WebURL in Frameworks */,
|
||||
D62220472C7EA8DF003E43B7 /* TuskerPreferences in Frameworks */,
|
||||
D630C4232BC7842C00208903 /* HTMLStreamer in Frameworks */,
|
||||
D630C3E52BC6313400208903 /* Pachyderm in Frameworks */,
|
||||
D630C3DF2BC61C4900208903 /* PushNotifications in Frameworks */,
|
||||
|
@ -977,7 +954,7 @@
|
|||
D68E525C24A3E8F00054355A /* InlineTrendsViewController.swift */,
|
||||
D6945C3323AC6431005C403C /* AddSavedHashtagViewController.swift */,
|
||||
D6093F9A25BDD4B9004811E6 /* HashtagSearchResultsViewController.swift */,
|
||||
D64A50BB2C74F8F4009D7193 /* FindInstanceViewController.swift */,
|
||||
D6945C3923AC75E2005C403C /* FindInstanceViewController.swift */,
|
||||
D6114E0C27F7FEB30080E273 /* TrendingStatusesViewController.swift */,
|
||||
D693A72725CF282E003A14E2 /* TrendingHashtagsViewController.swift */,
|
||||
D6114E1027F899B30080E273 /* TrendingLinksViewController.swift */,
|
||||
|
@ -987,6 +964,8 @@
|
|||
D601FA81297EEC3F00A8E8B5 /* SuggestedProfileCardCollectionViewCell.swift */,
|
||||
D601FA82297EEC3F00A8E8B5 /* SuggestedProfileCardCollectionViewCell.xib */,
|
||||
D6BC74852AFC4772000DD603 /* SuggestedProfileCardView.swift */,
|
||||
D693A72D25CF91C6003A14E2 /* FeaturedProfileCollectionViewCell.swift */,
|
||||
D693A72E25CF91C6003A14E2 /* FeaturedProfileCollectionViewCell.xib */,
|
||||
D6C3F4FA299035650009FCFF /* TrendsViewController.swift */,
|
||||
D68329EE299540050026EB24 /* MoreTrendsFooterCollectionViewCell.swift */,
|
||||
D6DD996A2998611A0015C962 /* SuggestedProfilesViewController.swift */,
|
||||
|
@ -1055,7 +1034,6 @@
|
|||
D608470E2A245D1F00C17380 /* ActiveInstance.swift */,
|
||||
D60E2F2D244248BF005F8713 /* MastodonCachePersistentStore.swift */,
|
||||
D6B936702829F72900237D0E /* NSManagedObjectContext+Helpers.swift */,
|
||||
D6A8D7A42C14DB280007B285 /* PersistentHistoryTokenStore.swift */,
|
||||
);
|
||||
path = CoreData;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1076,7 +1054,6 @@
|
|||
children = (
|
||||
D65B4B89297879DE00DABDFB /* Account Follows */,
|
||||
D6A3BC822321F69400FD64D5 /* Account List */,
|
||||
D698F4472BCEE2320054DB14 /* Announcements */,
|
||||
D641C787213DD862004B4513 /* Compose */,
|
||||
D641C785213DD83B004B4513 /* Conversation */,
|
||||
D6F2E960249E772F005846BB /* Crash Reporter */,
|
||||
|
@ -1122,9 +1099,7 @@
|
|||
D6FF985F255C717400845181 /* AccountSwitchingContainerViewController.swift */,
|
||||
D6BEA246291A0F2D002F4D01 /* Duckable+Root.swift */,
|
||||
D6F0B12A24A3071C001E48C3 /* MainSplitViewController.swift */,
|
||||
D64A50472C739DEA009D7193 /* BaseMainTabBarViewController.swift */,
|
||||
04DACE8B212CB14B009840C4 /* MainTabBarViewController.swift */,
|
||||
D64A50452C739DC0009D7193 /* NewMainTabBarViewController.swift */,
|
||||
D6F0B17424A3A1AA001E48C3 /* MainSidebarViewController.swift */,
|
||||
D6B93666281D937300237D0E /* MainSidebarMyProfileCollectionViewCell.swift */,
|
||||
D68E525A24A3D77E0054355A /* TuskerRootViewController.swift */,
|
||||
|
@ -1175,7 +1150,6 @@
|
|||
D646DCD92A081A2C0059ECEB /* PollFinishedNotificationCollectionViewCell.swift */,
|
||||
D646DCDB2A081CF10059ECEB /* StatusUpdatedNotificationCollectionViewCell.swift */,
|
||||
D68245112BCA1F4000AFB38B /* NotificationLoadingViewController.swift */,
|
||||
D6187BEC2BFA840B00B3A281 /* FollowRequestNotificationViewController.swift */,
|
||||
);
|
||||
path = Notifications;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1322,6 +1296,7 @@
|
|||
D667E5F62135C2ED0057A976 /* Extensions */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D667E5F72135C3040057A976 /* Mastodon+Equatable.swift */,
|
||||
D663626B21361C6700C9CBA2 /* Account+Preferences.swift */,
|
||||
D6F4D79329ECB0AF00351B87 /* UIBackgroundConfiguration+AppColors.swift */,
|
||||
D6333B362137838300CE884A /* AttributedString+Helpers.swift */,
|
||||
|
@ -1374,19 +1349,6 @@
|
|||
path = About;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D698F4472BCEE2320054DB14 /* Announcements */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D698F4662BD079800054DB14 /* AnnouncementsHostingController.swift */,
|
||||
D698F46C2BD0B8310054DB14 /* AnnouncementsCollection.swift */,
|
||||
D698F4682BD0799F0054DB14 /* AnnouncementsView.swift */,
|
||||
D698F46A2BD079F00054DB14 /* AnnouncementListRow.swift */,
|
||||
D698F4702BD0CBAA0054DB14 /* AnnouncementContentTextView.swift */,
|
||||
D698F46E2BD0B8DF0054DB14 /* AddReactionView.swift */,
|
||||
);
|
||||
path = Announcements;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D6A3BC822321F69400FD64D5 /* Account List */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -1481,14 +1443,12 @@
|
|||
D6BED1722126661300F02DA0 /* Views */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D6D79F562A1160B800AB2315 /* AccountDisplayNameLabel.swift */,
|
||||
D6B4A4FE2506B81A000C81C1 /* AccountDisplayNameView.swift */,
|
||||
D69F26332C4CDFD300FAF761 /* AccountDisplayAndUserNameLabel.swift */,
|
||||
D68E6F5E253C9B2D001A1B4C /* BaseEmojiLabel.swift */,
|
||||
D6ADB6EF28ED1F25009924AB /* CachedImageView.swift */,
|
||||
D6895DC328D65342006341DA /* ConfirmReblogStatusPreviewView.swift */,
|
||||
D620483523D38075008A63EF /* ContentTextView.swift */,
|
||||
D6D9498E298EB79400C59229 /* CopyableLabel.swift */,
|
||||
D6D9498E298EB79400C59229 /* CopyableLable.swift */,
|
||||
D6E426B225337C7000C02E1C /* CustomEmojiImageView.swift */,
|
||||
D6969E9F240C8384002843CE /* EmojiLabel.swift */,
|
||||
D61F75B8293C15A000C0B37F /* ZeroHeightCollectionViewCell.swift */,
|
||||
|
@ -1517,6 +1477,7 @@
|
|||
D641C78B213DD92F004B4513 /* Profile Header */,
|
||||
D641C78A213DD926004B4513 /* Status */,
|
||||
D64AAE8F26C80DB600FC57FB /* Toast */,
|
||||
D6D79F562A1160B800AB2315 /* AccountDisplayNameLabel.swift */,
|
||||
);
|
||||
path = Views;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1555,7 +1516,6 @@
|
|||
D6B8DB332182A59300424AF7 /* UIAlertController+Visibility.swift */,
|
||||
D6C693FD2162FEEA007D6A6D /* UIViewController+Children.swift */,
|
||||
D61F759129365C6C00C0B37F /* CollectionViewController.swift */,
|
||||
D64A50BD2C752247009D7193 /* AdaptableNavigationController.swift */,
|
||||
);
|
||||
path = Utilities;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1612,7 +1572,6 @@
|
|||
D691296D2BA75ACF005C58ED /* PrivacyInfo.xcprivacy */,
|
||||
D671A6BE299DA96100A81FEA /* Tusker-Bridging-Header.h */,
|
||||
D6D4DDCF212518A000E1C4BB /* AppDelegate.swift */,
|
||||
D6EEDE922C3CF21800E10E51 /* AudioSessionCoordinator.swift */,
|
||||
D6D79F582A13293200AB2315 /* BackgroundManager.swift */,
|
||||
D69261262BB3BA610023152C /* Box.swift */,
|
||||
D61F75B6293C119700C0B37F /* Filterer.swift */,
|
||||
|
@ -1625,6 +1584,7 @@
|
|||
D6DEBA8C2B6579830008629A /* MainThreadBox.swift */,
|
||||
D6B81F432560390300F6E31D /* MenuController.swift */,
|
||||
D6CF5B842AC7C56F00F15D83 /* MultiColumnCollectionViewLayout.swift */,
|
||||
D64D8CA82463B494006B0BAA /* MultiThreadDictionary.swift */,
|
||||
D6945C2E23AC47C3005C403C /* SavedDataManager.swift */,
|
||||
D61F759E29385AD800C0B37F /* SemiCaseSensitiveComparator.swift */,
|
||||
D6895DE828D962C2006341DA /* TimelineLikeController.swift */,
|
||||
|
@ -1767,7 +1727,6 @@
|
|||
D6DD8FFC298495A8002AD3FD /* LogoutService.swift */,
|
||||
D6D79F252A0C8D2700AB2315 /* FetchStatusSourceService.swift */,
|
||||
D630C3CB2BC5FD4600208903 /* GetAuthorizationTokenService.swift */,
|
||||
D6210D752C0B924F009BB569 /* RemoveProfileSuggestionService.swift */,
|
||||
);
|
||||
path = API;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1794,7 +1753,6 @@
|
|||
D630C3E42BC6313400208903 /* Pachyderm */,
|
||||
D630C4222BC7842C00208903 /* HTMLStreamer */,
|
||||
D630C4242BC7845800208903 /* WebURL */,
|
||||
D62220462C7EA8DF003E43B7 /* TuskerPreferences */,
|
||||
);
|
||||
productName = NotificationExtension;
|
||||
productReference = D630C3D12BC61B6000208903 /* NotificationExtension.appex */;
|
||||
|
@ -1996,7 +1954,6 @@
|
|||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D6C453372BCE1CEF00E26A0E /* PrivacyInfo.xcprivacy in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -2014,6 +1971,7 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D6E77D0D286E6B7300D8B732 /* TrendingLinkCardCollectionViewCell.xib in Resources */,
|
||||
D693A73025CF91C6003A14E2 /* FeaturedProfileCollectionViewCell.xib in Resources */,
|
||||
D61AC1D9232EA42D00C54D2D /* InstanceTableViewCell.xib in Resources */,
|
||||
D691296E2BA75ADF005C58ED /* PrivacyInfo.xcprivacy in Resources */,
|
||||
D6412B0B24B0D4C600F5412E /* ProfileHeaderView.xib in Resources */,
|
||||
|
@ -2140,7 +2098,6 @@
|
|||
D61F75A5293ABD6F00C0B37F /* EditFilterView.swift in Sources */,
|
||||
D6BC9DB1232C61BC002CA326 /* NotificationsPageViewController.swift in Sources */,
|
||||
D6ADB6EC28EA73CB009924AB /* StatusContentContainer.swift in Sources */,
|
||||
D64A50462C739DC0009D7193 /* NewMainTabBarViewController.swift in Sources */,
|
||||
D6969E9E240C81B9002843CE /* NSTextAttachment+Emoji.swift in Sources */,
|
||||
D6D79F532A0FFE3200AB2315 /* ToggleableButton.swift in Sources */,
|
||||
D6BC9DB3232D4C07002CA326 /* WellnessPrefsView.swift in Sources */,
|
||||
|
@ -2153,7 +2110,6 @@
|
|||
D61F759B29384F9C00C0B37F /* FilterMO.swift in Sources */,
|
||||
D68FEC4F232C5BC300C84F23 /* SegmentedPageViewController.swift in Sources */,
|
||||
D6934F342BA8D65A002B1C8D /* ImageGalleryDataSource.swift in Sources */,
|
||||
D6EEDE932C3CF21800E10E51 /* AudioSessionCoordinator.swift in Sources */,
|
||||
D6C4532D2BCB86AC00E26A0E /* AppearancePrefsView.swift in Sources */,
|
||||
D64AAE9126C80DC600FC57FB /* ToastView.swift in Sources */,
|
||||
D6BC74862AFC4772000DD603 /* SuggestedProfileCardView.swift in Sources */,
|
||||
|
@ -2173,7 +2129,6 @@
|
|||
D6934F3C2BAA0F80002B1C8D /* VideoGalleryContentViewController.swift in Sources */,
|
||||
D6F6A552291F098700F496A8 /* RenameListService.swift in Sources */,
|
||||
D62D2426217ABF63005076CC /* UserActivityType.swift in Sources */,
|
||||
D698F46B2BD079F00054DB14 /* AnnouncementListRow.swift in Sources */,
|
||||
D6AC956723C4347E008C9946 /* MainSceneDelegate.swift in Sources */,
|
||||
D6311C5025B3765B00B27539 /* ImageDataCache.swift in Sources */,
|
||||
D6934F362BA8E020002B1C8D /* GifvGalleryContentViewController.swift in Sources */,
|
||||
|
@ -2193,7 +2148,6 @@
|
|||
D6934F322BA7E43E002B1C8D /* LoadingGalleryContentViewController.swift in Sources */,
|
||||
D68E525B24A3D77E0054355A /* TuskerRootViewController.swift in Sources */,
|
||||
D62D2422217AA7E1005076CC /* UserActivityManager.swift in Sources */,
|
||||
D64A50482C739DEA009D7193 /* BaseMainTabBarViewController.swift in Sources */,
|
||||
D68A76E329524D2A001DA1B3 /* ListMO.swift in Sources */,
|
||||
D63CC70C2910AADB000E19DE /* TuskerSceneDelegate.swift in Sources */,
|
||||
D61F759D2938574B00C0B37F /* FilterRow.swift in Sources */,
|
||||
|
@ -2205,14 +2159,13 @@
|
|||
D62D2424217ABF3F005076CC /* NSUserActivity+Extensions.swift in Sources */,
|
||||
D6E77D0F286F773900D8B732 /* SplitNavigationController.swift in Sources */,
|
||||
D6B30E09254BAF63009CAEE5 /* ImageGrayscalifier.swift in Sources */,
|
||||
D698F4692BD0799F0054DB14 /* AnnouncementsView.swift in Sources */,
|
||||
D6A6C10F25B62D2400298D0F /* DiskCache.swift in Sources */,
|
||||
D6C3F4F9298EDBF20009FCFF /* ConversationTree.swift in Sources */,
|
||||
D698F46F2BD0B8DF0054DB14 /* AddReactionView.swift in Sources */,
|
||||
D6B81F3C2560365300F6E31D /* RefreshableViewController.swift in Sources */,
|
||||
D6674AEA23341F7600E8DF94 /* AppShortcutItems.swift in Sources */,
|
||||
D6DD8FFF2984D327002AD3FD /* BookmarksViewController.swift in Sources */,
|
||||
D646DCD22A06F2510059ECEB /* NotificationsCollectionViewController.swift in Sources */,
|
||||
D667E5F82135C3040057A976 /* Mastodon+Equatable.swift in Sources */,
|
||||
D6B4A4FF2506B81A000C81C1 /* AccountDisplayNameView.swift in Sources */,
|
||||
D63D8DF42850FE7A008D95E1 /* ViewTags.swift in Sources */,
|
||||
D630C3CC2BC5FD4600208903 /* GetAuthorizationTokenService.swift in Sources */,
|
||||
|
@ -2233,10 +2186,8 @@
|
|||
D691772E29AA5D420054D7EF /* UserActivityHandlingContext.swift in Sources */,
|
||||
04ED00B121481ED800567C53 /* SteppedProgressView.swift in Sources */,
|
||||
D6A6C11B25B63CEE00298D0F /* MemoryCache.swift in Sources */,
|
||||
D64A50BC2C74F8F4009D7193 /* FindInstanceViewController.swift in Sources */,
|
||||
D6114E0D27F7FEB30080E273 /* TrendingStatusesViewController.swift in Sources */,
|
||||
D6BC9DDA232D8BE5002CA326 /* SearchResultsViewController.swift in Sources */,
|
||||
D698F4672BD079800054DB14 /* AnnouncementsHostingController.swift in Sources */,
|
||||
D61ABEF628EE74D400B29151 /* StatusCollectionViewCell.swift in Sources */,
|
||||
D65B4B6629773AE600DABDFB /* DeleteStatusService.swift in Sources */,
|
||||
D61DC84628F498F200B82C6E /* Logging.swift in Sources */,
|
||||
|
@ -2251,8 +2202,8 @@
|
|||
D65A261D2BC39399005EB5D8 /* PushInstanceSettingsView.swift in Sources */,
|
||||
D65C6BF525478A9C00A6E89C /* BackgroundableViewController.swift in Sources */,
|
||||
D61DC84D28F500D200B82C6E /* ProfileViewController.swift in Sources */,
|
||||
D6187BED2BFA840B00B3A281 /* FollowRequestNotificationViewController.swift in Sources */,
|
||||
D600891F29848DE2005B4D00 /* AddInstancePinnedTimelineView.swift in Sources */,
|
||||
D693A72F25CF91C6003A14E2 /* FeaturedProfileCollectionViewCell.swift in Sources */,
|
||||
D627943223A5466600D38C68 /* SelectableTableViewCell.swift in Sources */,
|
||||
D64B96812BC3279D002C8990 /* PrefsAccountView.swift in Sources */,
|
||||
D6EAE0DB2550CC8A002DB0AC /* FocusableTextField.swift in Sources */,
|
||||
|
@ -2272,6 +2223,7 @@
|
|||
D63CC7102911F1E4000E19DE /* UIScrollView+Top.swift in Sources */,
|
||||
D6F6A557291F4F1600F496A8 /* MuteAccountView.swift in Sources */,
|
||||
D65B4B8B297879E900DABDFB /* AccountFollowsViewController.swift in Sources */,
|
||||
D6945C3A23AC75E2005C403C /* FindInstanceViewController.swift in Sources */,
|
||||
D65B4B6429771EFF00DABDFB /* ConversationViewController.swift in Sources */,
|
||||
D68E6F59253C9969001A1B4C /* MultiSourceEmojiLabel.swift in Sources */,
|
||||
D6EBF01523C55C0900AE061B /* UIApplication+Scenes.swift in Sources */,
|
||||
|
@ -2303,7 +2255,7 @@
|
|||
D61ABEFE28F1C92600B29151 /* FavoriteService.swift in Sources */,
|
||||
D61F75AB293AF11400C0B37F /* FilterKeywordMO.swift in Sources */,
|
||||
D65B4B5A29720AB000DABDFB /* ReportStatusView.swift in Sources */,
|
||||
D6D9498F298EB79400C59229 /* CopyableLabel.swift in Sources */,
|
||||
D6D9498F298EB79400C59229 /* CopyableLable.swift in Sources */,
|
||||
D6333B792139AEFD00CE884A /* Date+TimeAgo.swift in Sources */,
|
||||
D6D706A029466649000827ED /* ScrollingSegmentedControl.swift in Sources */,
|
||||
D686BBE324FBF8110068E6AA /* WrappedProgressView.swift in Sources */,
|
||||
|
@ -2340,7 +2292,6 @@
|
|||
D6C693FE2162FEEA007D6A6D /* UIViewController+Children.swift in Sources */,
|
||||
D61A45EA28DF51EE002BE511 /* TimelineLikeCollectionViewController.swift in Sources */,
|
||||
D64D0AB12128D9AE005A6F37 /* OnboardingViewController.swift in Sources */,
|
||||
D64A50BE2C752247009D7193 /* AdaptableNavigationController.swift in Sources */,
|
||||
D6934F302BA7AF91002B1C8D /* ImageGalleryContentViewController.swift in Sources */,
|
||||
D6934F3E2BAA19D5002B1C8D /* ImageActivityItemSource.swift in Sources */,
|
||||
D67C1795266D57D10070F250 /* FastAccountSwitcherIndicatorView.swift in Sources */,
|
||||
|
@ -2360,7 +2311,6 @@
|
|||
D65B4B542971F71D00DABDFB /* EditedReport.swift in Sources */,
|
||||
D62D67C52A97D8CD00167EE2 /* MultiColumnNavigationController.swift in Sources */,
|
||||
D6A6C11525B62E9700298D0F /* CacheExpiry.swift in Sources */,
|
||||
D69F26342C4CDFD300FAF761 /* AccountDisplayAndUserNameLabel.swift in Sources */,
|
||||
D67C57AF21E28EAD00C3118B /* Array+Uniques.swift in Sources */,
|
||||
D68A76F129539116001DA1B3 /* FlipView.swift in Sources */,
|
||||
D6945C3223AC4D36005C403C /* HashtagTimelineViewController.swift in Sources */,
|
||||
|
@ -2373,10 +2323,8 @@
|
|||
D693A72825CF282E003A14E2 /* TrendingHashtagsViewController.swift in Sources */,
|
||||
D621733328F1D5ED004C7DB1 /* ReblogService.swift in Sources */,
|
||||
D62275A824F1CA2800B82A16 /* ComposeReplyContentView.swift in Sources */,
|
||||
D698F46D2BD0B8310054DB14 /* AnnouncementsCollection.swift in Sources */,
|
||||
D61F75AF293AF50C00C0B37F /* EditedFilter.swift in Sources */,
|
||||
D691771929A7B8820054D7EF /* ProfileHeaderMovedOverlayView.swift in Sources */,
|
||||
D6210D762C0B924F009BB569 /* RemoveProfileSuggestionService.swift in Sources */,
|
||||
D61F75B9293C15A000C0B37F /* ZeroHeightCollectionViewCell.swift in Sources */,
|
||||
D68232F72464F4FD00325FB8 /* ComposeDrawingViewController.swift in Sources */,
|
||||
04586B4122B2FFB10021BD04 /* PreferencesView.swift in Sources */,
|
||||
|
@ -2387,6 +2335,7 @@
|
|||
D62E9987279D094F00C26176 /* StatusMetaIndicatorsView.swift in Sources */,
|
||||
D6BEA247291A0F2D002F4D01 /* Duckable+Root.swift in Sources */,
|
||||
D6C1B2082545D1EC00DAAA66 /* StatusCardView.swift in Sources */,
|
||||
D64D8CA92463B494006B0BAA /* MultiThreadDictionary.swift in Sources */,
|
||||
D630C3CA2BC59FF500208903 /* MastodonController+Push.swift in Sources */,
|
||||
D6F6A554291F0D9600F496A8 /* DeleteListService.swift in Sources */,
|
||||
D68E6F5F253C9B2D001A1B4C /* BaseEmojiLabel.swift in Sources */,
|
||||
|
@ -2418,11 +2367,9 @@
|
|||
D6934F2E2BA7AEF9002B1C8D /* StatusAttachmentsGalleryDataSource.swift in Sources */,
|
||||
D623A543263634100095BD04 /* PollOptionCheckboxView.swift in Sources */,
|
||||
D6C4532F2BCB873400E26A0E /* MockStatusView.swift in Sources */,
|
||||
D698F4712BD0CBAA0054DB14 /* AnnouncementContentTextView.swift in Sources */,
|
||||
D68A76E829527884001DA1B3 /* PinnedTimelinesView.swift in Sources */,
|
||||
D690797324A4EF9700023A34 /* UIBezierPath+Helpers.swift in Sources */,
|
||||
D6D12B5A292D684600D528E1 /* AccountListViewController.swift in Sources */,
|
||||
D6A8D7A52C14DB280007B285 /* PersistentHistoryTokenStore.swift in Sources */,
|
||||
D693DE5723FE1A6A0061E07D /* EnhancedNavigationViewController.swift in Sources */,
|
||||
D646DCDC2A081CF10059ECEB /* StatusUpdatedNotificationCollectionViewCell.swift in Sources */,
|
||||
);
|
||||
|
@ -2543,7 +2490,6 @@
|
|||
INFOPLIST_FILE = NotificationExtension/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = NotificationExtension;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Shadowfacts. All rights reserved.";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
@ -2576,7 +2522,6 @@
|
|||
INFOPLIST_FILE = NotificationExtension/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = NotificationExtension;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Shadowfacts. All rights reserved.";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
@ -2608,7 +2553,6 @@
|
|||
INFOPLIST_FILE = NotificationExtension/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = NotificationExtension;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2024 Shadowfacts. All rights reserved.";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
@ -2690,8 +2634,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
"ASSETCATALOG_COMPILER_APPICON_NAME[sdk=*]" = AppIcon;
|
||||
"ASSETCATALOG_COMPILER_APPICON_NAME[sdk=xros*]" = "AppIcon-vision";
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Tusker/Tusker.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
|
@ -2699,7 +2642,6 @@
|
|||
CURRENT_PROJECT_VERSION = "$(CURRENT_PROJECT_VERSION)";
|
||||
INFOPLIST_FILE = Tusker/Info.plist;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
@ -2743,7 +2685,7 @@
|
|||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
INFOPLIST_FILE = TuskerUITests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
@ -2766,7 +2708,6 @@
|
|||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = "$(CURRENT_PROJECT_VERSION)";
|
||||
INFOPLIST_FILE = OpenInTusker/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
@ -2794,7 +2735,6 @@
|
|||
INFOPLIST_FILE = ShareExtension/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = ShareExtension;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 Shadowfacts. All rights reserved.";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
@ -2823,7 +2763,6 @@
|
|||
INFOPLIST_FILE = ShareExtension/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = ShareExtension;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 Shadowfacts. All rights reserved.";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
@ -2852,7 +2791,6 @@
|
|||
INFOPLIST_FILE = ShareExtension/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = ShareExtension;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 Shadowfacts. All rights reserved.";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
@ -2999,8 +2937,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
"ASSETCATALOG_COMPILER_APPICON_NAME[sdk=*]" = AppIcon;
|
||||
"ASSETCATALOG_COMPILER_APPICON_NAME[sdk=xros*]" = "AppIcon-vision";
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Tusker/Tusker.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
|
@ -3008,7 +2945,6 @@
|
|||
CURRENT_PROJECT_VERSION = "$(CURRENT_PROJECT_VERSION)";
|
||||
INFOPLIST_FILE = Tusker/Info.plist;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
@ -3032,8 +2968,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
"ASSETCATALOG_COMPILER_APPICON_NAME[sdk=*]" = AppIcon;
|
||||
"ASSETCATALOG_COMPILER_APPICON_NAME[sdk=xros*]" = AppIcon;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Tusker/Tusker.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
|
@ -3041,7 +2976,6 @@
|
|||
CURRENT_PROJECT_VERSION = "$(CURRENT_PROJECT_VERSION)";
|
||||
INFOPLIST_FILE = Tusker/Info.plist;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
@ -3106,7 +3040,7 @@
|
|||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
INFOPLIST_FILE = TuskerUITests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
@ -3126,7 +3060,7 @@
|
|||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
INFOPLIST_FILE = TuskerUITests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
@ -3149,7 +3083,6 @@
|
|||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = "$(CURRENT_PROJECT_VERSION)";
|
||||
INFOPLIST_FILE = OpenInTusker/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
@ -3174,7 +3107,6 @@
|
|||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = "$(CURRENT_PROJECT_VERSION)";
|
||||
INFOPLIST_FILE = OpenInTusker/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
@ -3271,7 +3203,7 @@
|
|||
repositoryURL = "https://git.shadowfacts.net/shadowfacts/HTMLStreamer.git";
|
||||
requirement = {
|
||||
kind = exactVersion;
|
||||
version = 0.3.0;
|
||||
version = 0.2.3;
|
||||
};
|
||||
};
|
||||
D63CC700290EC0B8000E19DE /* XCRemoteSwiftPackageReference "sentry-cocoa" */ = {
|
||||
|
@ -3279,7 +3211,7 @@
|
|||
repositoryURL = "https://github.com/getsentry/sentry-cocoa.git";
|
||||
requirement = {
|
||||
kind = upToNextMinorVersion;
|
||||
minimumVersion = 8.33.0;
|
||||
minimumVersion = 8.21.0;
|
||||
};
|
||||
};
|
||||
D6552365289870790048A653 /* XCRemoteSwiftPackageReference "ScreenCorners" */ = {
|
||||
|
@ -3294,8 +3226,8 @@
|
|||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/karwa/swift-url";
|
||||
requirement = {
|
||||
kind = exactVersion;
|
||||
version = 0.4.2;
|
||||
branch = main;
|
||||
kind = branch;
|
||||
};
|
||||
};
|
||||
/* End XCRemoteSwiftPackageReference section */
|
||||
|
@ -3310,10 +3242,6 @@
|
|||
isa = XCSwiftPackageProductDependency;
|
||||
productName = Pachyderm;
|
||||
};
|
||||
D62220462C7EA8DF003E43B7 /* TuskerPreferences */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = TuskerPreferences;
|
||||
};
|
||||
D630C3C72BC43AFD00208903 /* PushNotifications */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = PushNotifications;
|
||||
|
|
|
@ -58,8 +58,7 @@ private extension Pachyderm.PushSubscription.Alerts {
|
|||
followRequest: alerts.contains(.followRequest),
|
||||
favourite: alerts.contains(.favorite),
|
||||
poll: alerts.contains(.poll),
|
||||
update: alerts.contains(.update),
|
||||
emojiReaction: alerts.contains(.emojiReaction)
|
||||
update: alerts.contains(.update)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
//
|
||||
// RemoveProfileSuggestionService.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 6/1/24.
|
||||
// Copyright © 2024 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Pachyderm
|
||||
|
||||
@MainActor
|
||||
class RemoveProfileSuggestionService {
|
||||
private let accountID: String
|
||||
private let mastodonController: MastodonController
|
||||
private let presenter: any TuskerNavigationDelegate
|
||||
private let completionHandler: @MainActor () -> Void
|
||||
|
||||
init(accountID: String, mastodonController: MastodonController, presenter: any TuskerNavigationDelegate, completionHandler: @MainActor @escaping () -> Void) {
|
||||
self.accountID = accountID
|
||||
self.mastodonController = mastodonController
|
||||
self.presenter = presenter
|
||||
self.completionHandler = completionHandler
|
||||
}
|
||||
|
||||
func run() async {
|
||||
let req = Suggestion.remove(accountID: accountID)
|
||||
do {
|
||||
_ = try await mastodonController.run(req)
|
||||
completionHandler()
|
||||
} catch {
|
||||
let config = ToastConfiguration(from: error, with: "Error Removing Suggestion", in: presenter) { toast in
|
||||
toast.dismissToast(animated: true)
|
||||
await self.run()
|
||||
}
|
||||
self.presenter.showToast(configuration: config, animated: true)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -56,9 +56,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||
|
||||
// make sure the persistent container is initialized on the main thread
|
||||
// otherwise initializing it on the background thread can deadlock with accessing it on the main thread elsewhere
|
||||
#if canImport(Sentry)
|
||||
DraftsPersistentContainer.captureError = { SentrySDK.capture(error: $0) }
|
||||
#endif
|
||||
_ = DraftsPersistentContainer.shared
|
||||
|
||||
DispatchQueue.global(qos: .userInitiated).async {
|
||||
|
@ -110,8 +107,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||
// we don't care about events like battery, keyboard show/hide
|
||||
options.enableAutoBreadcrumbTracking = false
|
||||
options.enableUserInteractionTracing = false
|
||||
options.profilesSampleRate = nil
|
||||
options.tracesSampleRate = nil
|
||||
|
||||
options.beforeSend = { event in
|
||||
// just no, why would anyone need this information
|
||||
|
@ -190,8 +185,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||
let mastodonController = MastodonController.getForAccount(account)
|
||||
do {
|
||||
let result = try await mastodonController.updatePushSubscription(subscription: $0)
|
||||
PushManager.logger.info("Updated push subscription \(result.id, privacy: .public) on \(mastodonController.instanceURL) with endpoint \($0.endpoint, privacy: .public)")
|
||||
PushManager.logger.debug("New push subscription: \(String(describing: result))")
|
||||
PushManager.logger.debug("Updated push subscription \(result.id) on \(mastodonController.instanceURL)")
|
||||
return true
|
||||
} catch {
|
||||
PushManager.logger.error("Error updating push subscription: \(String(describing: error))")
|
||||
|
@ -292,25 +286,16 @@ extension AppDelegate: UNUserNotificationCenterDelegate {
|
|||
let rootViewController = delegate.rootViewController {
|
||||
let mastodonController = MastodonController.getForAccount(account)
|
||||
|
||||
// if the scene is already active, then we animate things
|
||||
let animated = scene.activationState == .foregroundActive
|
||||
// if the scene is already active, then we animate the account switching if necessary
|
||||
delegate.activateAccount(account, animated: scene.activationState == .foregroundActive)
|
||||
|
||||
delegate.activateAccount(account, animated: animated)
|
||||
|
||||
rootViewController.runNavigation(animated: animated) { navigation in
|
||||
navigation.select(route: .notifications)
|
||||
rootViewController.select(route: .notifications, animated: false)
|
||||
let vc = NotificationLoadingViewController(notificationID: notificationID, mastodonController: mastodonController)
|
||||
navigation.push(viewController: vc)
|
||||
}
|
||||
rootViewController.getNavigationController().pushViewController(vc, animated: false)
|
||||
} else {
|
||||
let activity = UserActivityManager.showNotificationActivity(id: notificationID, accountID: accountID)
|
||||
if #available(iOS 17.0, *) {
|
||||
let request = UISceneSessionActivationRequest(userActivity: activity)
|
||||
UIApplication.shared.activateSceneSession(for: request)
|
||||
} else {
|
||||
UIApplication.shared.requestSceneSessionActivation(nil, userActivity: activity, options: nil)
|
||||
}
|
||||
}
|
||||
completionHandler()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "back.png",
|
||||
"idiom" : "vision",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 6.4 KiB |
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"layers" : [
|
||||
{
|
||||
"filename" : "Front.solidimagestacklayer"
|
||||
},
|
||||
{
|
||||
"filename" : "Back.solidimagestacklayer"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "front.png",
|
||||
"idiom" : "vision",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 44 KiB |
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 123 KiB |
Before Width: | Height: | Size: 723 B |
Before Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 580 B |
After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 968 B After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1022 B |
Before Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 917 B |
After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 4.9 KiB |