mirror of
https://github.com/anultravioletaurora/Jellify.git
synced 2026-01-07 14:19:57 -06:00
Quick Connect optimization
This commit is contained in:
BIN
assets/icons/teal-icon.png
Normal file
BIN
assets/icons/teal-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 89 KiB |
@@ -1,407 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="300mm"
|
||||
height="300mm"
|
||||
viewBox="0 0 300 300"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="JellifyFinalGradientTealPurpleFinal.svg"
|
||||
inkscape:version="1.4.2 (f4327f4, 2025-05-13)"
|
||||
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"><sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:zoom="0.70710678"
|
||||
inkscape:cx="444.06306"
|
||||
inkscape:cy="514.06663"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1361"
|
||||
inkscape:window-x="-9"
|
||||
inkscape:window-y="-9"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg1"
|
||||
showgrid="false" /><defs
|
||||
id="defs1"><linearGradient
|
||||
id="linearGradient1"
|
||||
inkscape:collect="always"><stop
|
||||
style="stop-color:#00dbb9;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop2" /><stop
|
||||
style="stop-color:#7317ff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop1" /></linearGradient><inkscape:path-effect
|
||||
effect="mirror_symmetry"
|
||||
start_point="36.829795,103.65226"
|
||||
end_point="163.35938,103.65226"
|
||||
center_point="100.09459,103.65226"
|
||||
id="path-effect27"
|
||||
is_visible="true"
|
||||
lpeversion="1.2"
|
||||
lpesatellites=""
|
||||
mode="Y"
|
||||
discard_orig_path="false"
|
||||
fuse_paths="false"
|
||||
oposite_fuse="false"
|
||||
split_items="true"
|
||||
split_open="false"
|
||||
link_styles="false" /><inkscape:path-effect
|
||||
effect="mirror_symmetry"
|
||||
start_point="0,150"
|
||||
end_point="300,150"
|
||||
center_point="150,150"
|
||||
id="path-effect26"
|
||||
is_visible="true"
|
||||
lpeversion="1.2"
|
||||
lpesatellites=""
|
||||
mode="horizontal"
|
||||
discard_orig_path="false"
|
||||
fuse_paths="false"
|
||||
oposite_fuse="false"
|
||||
split_items="false"
|
||||
split_open="false"
|
||||
link_styles="false" /><inkscape:path-effect
|
||||
effect="powerstroke"
|
||||
message=""
|
||||
id="path-effect25"
|
||||
is_visible="true"
|
||||
lpeversion="1.3"
|
||||
scale_width="1"
|
||||
interpolator_type="CentripetalCatmullRom"
|
||||
interpolator_beta="0.2"
|
||||
start_linecap_type="zerowidth"
|
||||
end_linecap_type="zerowidth"
|
||||
offset_points="1,2.5"
|
||||
linejoin_type="round"
|
||||
miter_limit="4"
|
||||
not_jump="false"
|
||||
sort_points="true" /><inkscape:path-effect
|
||||
effect="mirror_symmetry"
|
||||
start_point="0,150"
|
||||
end_point="300,150"
|
||||
center_point="150,150"
|
||||
id="path-effect24"
|
||||
is_visible="true"
|
||||
lpeversion="1.2"
|
||||
lpesatellites=""
|
||||
mode="horizontal"
|
||||
discard_orig_path="false"
|
||||
fuse_paths="false"
|
||||
oposite_fuse="false"
|
||||
split_items="false"
|
||||
split_open="false"
|
||||
link_styles="false" /><inkscape:path-effect
|
||||
effect="powerstroke"
|
||||
message=""
|
||||
id="path-effect23"
|
||||
is_visible="true"
|
||||
lpeversion="1.3"
|
||||
scale_width="1"
|
||||
interpolator_type="CentripetalCatmullRom"
|
||||
interpolator_beta="0.2"
|
||||
start_linecap_type="butt"
|
||||
end_linecap_type="zerowidth"
|
||||
offset_points="0.28721364,1.9659181 | 1.0065447,1.3281153 | 1.7656209,0.14729167"
|
||||
linejoin_type="round"
|
||||
miter_limit="4"
|
||||
not_jump="false"
|
||||
sort_points="true" /><inkscape:path-effect
|
||||
effect="powerstroke"
|
||||
message=""
|
||||
id="path-effect22"
|
||||
is_visible="true"
|
||||
lpeversion="1.3"
|
||||
scale_width="1"
|
||||
interpolator_type="CentripetalCatmullRom"
|
||||
interpolator_beta="0.2"
|
||||
start_linecap_type="zerowidth"
|
||||
end_linecap_type="round"
|
||||
offset_points="0.021811409,4.5200294 | 2.9894369,3.0532151 | 4.0214422,4.3410551"
|
||||
linejoin_type="round"
|
||||
miter_limit="4"
|
||||
not_jump="false"
|
||||
sort_points="true" /><inkscape:path-effect
|
||||
effect="powerstroke"
|
||||
message=""
|
||||
id="path-effect21"
|
||||
is_visible="true"
|
||||
lpeversion="1.3"
|
||||
scale_width="1"
|
||||
interpolator_type="CentripetalCatmullRom"
|
||||
interpolator_beta="0.2"
|
||||
start_linecap_type="zerowidth"
|
||||
end_linecap_type="round"
|
||||
offset_points="0,3.0010829 | 1.5006767,3.0586652 | 2.7911139,4.8447845"
|
||||
linejoin_type="round"
|
||||
miter_limit="4"
|
||||
not_jump="false"
|
||||
sort_points="true" /><inkscape:path-effect
|
||||
effect="powerstroke"
|
||||
message=""
|
||||
id="path-effect20"
|
||||
is_visible="true"
|
||||
lpeversion="1.3"
|
||||
scale_width="1"
|
||||
interpolator_type="CentripetalCatmullRom"
|
||||
interpolator_beta="0.2"
|
||||
start_linecap_type="zerowidth"
|
||||
end_linecap_type="round"
|
||||
offset_points="0.065755614,3.9759006 | 2.5006233,4.1433183 | 4.7821816,4.2678689"
|
||||
linejoin_type="round"
|
||||
miter_limit="4"
|
||||
not_jump="false"
|
||||
sort_points="true" /><inkscape:path-effect
|
||||
effect="powerstroke"
|
||||
message=""
|
||||
id="path-effect19"
|
||||
is_visible="true"
|
||||
lpeversion="1.3"
|
||||
scale_width="1"
|
||||
interpolator_type="CentripetalCatmullRom"
|
||||
interpolator_beta="0.2"
|
||||
start_linecap_type="zerowidth"
|
||||
end_linecap_type="round"
|
||||
offset_points="0.046321001,3.1112262 | 1.5105021,3.3915097 | 3.5871741,4.0865502"
|
||||
linejoin_type="round"
|
||||
miter_limit="4"
|
||||
not_jump="false"
|
||||
sort_points="true" /><inkscape:path-effect
|
||||
effect="powerstroke"
|
||||
message=""
|
||||
id="path-effect18"
|
||||
is_visible="true"
|
||||
lpeversion="1.3"
|
||||
scale_width="1"
|
||||
interpolator_type="CentripetalCatmullRom"
|
||||
interpolator_beta="0.2"
|
||||
start_linecap_type="zerowidth"
|
||||
end_linecap_type="zerowidth"
|
||||
offset_points="0.2,2.5 | 1,2.5 | 1.8,2.5"
|
||||
linejoin_type="round"
|
||||
miter_limit="4"
|
||||
not_jump="false"
|
||||
sort_points="true" /><inkscape:path-effect
|
||||
effect="powerstroke"
|
||||
message=""
|
||||
id="path-effect17"
|
||||
is_visible="true"
|
||||
lpeversion="1.3"
|
||||
scale_width="1"
|
||||
interpolator_type="CentripetalCatmullRom"
|
||||
interpolator_beta="0.2"
|
||||
start_linecap_type="zerowidth"
|
||||
end_linecap_type="zerowidth"
|
||||
offset_points="0.69542096,1.5137821 | 1.999296,4.5220552 | 3.574709,1.3221339"
|
||||
linejoin_type="round"
|
||||
miter_limit="4"
|
||||
not_jump="false"
|
||||
sort_points="true" /><inkscape:path-effect
|
||||
effect="powerstroke"
|
||||
message=""
|
||||
id="path-effect16"
|
||||
is_visible="true"
|
||||
lpeversion="1.3"
|
||||
scale_width="1"
|
||||
interpolator_type="CentripetalCatmullRom"
|
||||
interpolator_beta="0.2"
|
||||
start_linecap_type="zerowidth"
|
||||
end_linecap_type="zerowidth"
|
||||
offset_points="0.2,2.5 | 1.0010114,5.1044674 | 1.8,2.5"
|
||||
linejoin_type="round"
|
||||
miter_limit="4"
|
||||
not_jump="false"
|
||||
sort_points="true" /><inkscape:path-effect
|
||||
effect="powerstroke"
|
||||
message=""
|
||||
id="path-effect14"
|
||||
is_visible="true"
|
||||
lpeversion="1.3"
|
||||
scale_width="1"
|
||||
interpolator_type="CentripetalCatmullRom"
|
||||
interpolator_beta="0.2"
|
||||
start_linecap_type="zerowidth"
|
||||
end_linecap_type="butt"
|
||||
offset_points="0.34651289,2.842816 | 1,5.8779234 | 0.20052903,2.327192"
|
||||
linejoin_type="round"
|
||||
miter_limit="4"
|
||||
not_jump="false"
|
||||
sort_points="true" /><inkscape:path-effect
|
||||
effect="mirror_symmetry"
|
||||
start_point="0,150"
|
||||
end_point="300,150"
|
||||
center_point="150,150"
|
||||
id="path-effect8"
|
||||
is_visible="true"
|
||||
lpeversion="1.2"
|
||||
lpesatellites=""
|
||||
mode="horizontal"
|
||||
discard_orig_path="false"
|
||||
fuse_paths="false"
|
||||
oposite_fuse="false"
|
||||
split_items="false"
|
||||
split_open="false"
|
||||
link_styles="false" /><inkscape:path-effect
|
||||
effect="mirror_symmetry"
|
||||
start_point="0,150"
|
||||
end_point="300,150"
|
||||
center_point="150,150"
|
||||
id="path-effect7"
|
||||
is_visible="true"
|
||||
lpeversion="1.2"
|
||||
lpesatellites=""
|
||||
mode="horizontal"
|
||||
discard_orig_path="false"
|
||||
fuse_paths="false"
|
||||
oposite_fuse="false"
|
||||
split_items="false"
|
||||
split_open="false"
|
||||
link_styles="false" /><inkscape:path-effect
|
||||
effect="mirror_symmetry"
|
||||
start_point="14.80014,150"
|
||||
end_point="276.48117,150"
|
||||
center_point="145.64065,150"
|
||||
id="path-effect4"
|
||||
is_visible="true"
|
||||
lpeversion="1.2"
|
||||
lpesatellites=""
|
||||
mode="horizontal"
|
||||
discard_orig_path="false"
|
||||
fuse_paths="false"
|
||||
oposite_fuse="false"
|
||||
split_items="false"
|
||||
split_open="false"
|
||||
link_styles="false" /><inkscape:path-effect
|
||||
effect="mirror_symmetry"
|
||||
start_point="0,150"
|
||||
end_point="300,150"
|
||||
center_point="150,150"
|
||||
id="path-effect1"
|
||||
is_visible="true"
|
||||
lpeversion="1.2"
|
||||
lpesatellites=""
|
||||
mode="horizontal"
|
||||
discard_orig_path="false"
|
||||
fuse_paths="false"
|
||||
oposite_fuse="false"
|
||||
split_items="false"
|
||||
split_open="false"
|
||||
link_styles="false" /><inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect15"
|
||||
is_visible="true"
|
||||
lpeversion="1" /><inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect13"
|
||||
is_visible="true"
|
||||
lpeversion="1" /><inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect12"
|
||||
is_visible="true"
|
||||
lpeversion="1" /><inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect11"
|
||||
is_visible="true"
|
||||
lpeversion="1" /><inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect10"
|
||||
is_visible="true"
|
||||
lpeversion="1" /><inkscape:path-effect
|
||||
effect="mirror_symmetry"
|
||||
start_point="0,150"
|
||||
end_point="300,150"
|
||||
center_point="150,150"
|
||||
id="path-effect9"
|
||||
is_visible="true"
|
||||
lpeversion="1.2"
|
||||
lpesatellites=""
|
||||
mode="horizontal"
|
||||
discard_orig_path="false"
|
||||
fuse_paths="false"
|
||||
oposite_fuse="false"
|
||||
split_items="false"
|
||||
split_open="false"
|
||||
link_styles="false" /><inkscape:path-effect
|
||||
effect="mirror_symmetry"
|
||||
start_point="14.80014,150"
|
||||
end_point="276.48117,150"
|
||||
center_point="145.64065,150"
|
||||
id="path-effect5"
|
||||
is_visible="true"
|
||||
lpeversion="1.2"
|
||||
lpesatellites=""
|
||||
mode="horizontal"
|
||||
discard_orig_path="false"
|
||||
fuse_paths="false"
|
||||
oposite_fuse="false"
|
||||
split_items="false"
|
||||
split_open="false"
|
||||
link_styles="false" /><inkscape:path-effect
|
||||
effect="mirror_symmetry"
|
||||
start_point="0,150"
|
||||
end_point="300,150"
|
||||
center_point="150,150"
|
||||
id="path-effect3"
|
||||
is_visible="true"
|
||||
lpeversion="1.2"
|
||||
lpesatellites=""
|
||||
mode="horizontal"
|
||||
discard_orig_path="false"
|
||||
fuse_paths="false"
|
||||
oposite_fuse="false"
|
||||
split_items="false"
|
||||
split_open="false"
|
||||
link_styles="false" /><inkscape:path-effect
|
||||
effect="mirror_symmetry"
|
||||
start_point="0,150"
|
||||
end_point="300,150"
|
||||
center_point="150,150"
|
||||
id="path-effect2"
|
||||
is_visible="true"
|
||||
lpeversion="1.2"
|
||||
lpesatellites=""
|
||||
mode="horizontal"
|
||||
discard_orig_path="false"
|
||||
fuse_paths="false"
|
||||
oposite_fuse="false"
|
||||
split_items="false"
|
||||
split_open="false"
|
||||
link_styles="false" /><inkscape:path-effect
|
||||
effect="mirror_symmetry"
|
||||
start_point="0,150"
|
||||
end_point="300,150"
|
||||
center_point="150,150"
|
||||
id="path-effect6"
|
||||
is_visible="true"
|
||||
lpeversion="1.2"
|
||||
lpesatellites=""
|
||||
mode="horizontal"
|
||||
discard_orig_path="false"
|
||||
fuse_paths="false"
|
||||
oposite_fuse="false"
|
||||
split_items="false"
|
||||
split_open="false"
|
||||
link_styles="false" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient1"
|
||||
id="linearGradient2"
|
||||
x1="76.596825"
|
||||
y1="82.716858"
|
||||
x2="233.49379"
|
||||
y2="239.61383"
|
||||
gradientUnits="userSpaceOnUse" /></defs><path
|
||||
id="path6"
|
||||
style="display:inline;fill:url(#linearGradient2);fill-rule:nonzero;stroke:none;stroke-width:5.66499;stroke-linecap:round"
|
||||
d="M 139.3269,45.768783 C 126.88229,45.706148 95.328135,48.241638 71.292289,73.203284 61.843322,83.016179 47.31339,102.04964 44.663424,128.3317 c -6.621328,65.66952 47.193245,92.9287 65.103006,70.99929 -32.613971,12.4543 -59.632157,-25.84645 -53.371939,-68.86298 3.10699,-21.34941 15.9332,-37.938267 25.19071,-47.436902 5.427134,-5.568491 22.887769,-21.542941 47.604329,-25.073922 35.98193,-5.140346 81.37009,11.685423 69.50325,52.880494 21.40391,-17.159778 -0.14812,-64.770831 -59.36588,-65.068897 z m 30.06896,24.740092 c -0.13986,0.780925 15.7155,4.18369 18.12809,20.062341 1.84384,12.005594 -1.95562,24.498424 -4.14649,30.378504 -4.3814,11.75925 -12.17947,24.61767 -24.35033,36.75954 -12.17086,12.14187 -24.85679,20.30474 -37.63186,24.94269 -5.86887,2.13066 -18.24679,5.7681 -30.193502,3.83129 -15.558836,-2.49433 -18.996319,-17.81412 -20.177063,-17.60306 -1.194435,0.21437 1.39647,18.53479 18.936312,23.24974 13.319633,3.59786 27.519723,0.16754 33.996373,-1.85311 3.23912,-1.01058 6.47122,-2.23697 9.679,-3.67781 2.93812,3.21771 11.67161,9.65724 25.83356,3.22667 0.51974,2.27797 1.50261,5.26982 2.30529,8.72608 1.72873,10.67723 2.13014,19.22365 8.92193,28.33523 4.94229,5.39527 8.49946,11.66414 11.60748,18.21932 3.07739,6.49078 4.05348,16.71238 0.013,25.20955 -2.48575,5.22727 5.35512,8.95572 7.84087,3.72845 5.34005,-11.23027 4.62575,-23.9551 -0.44855,-33.54007 -2.8174,-7.44396 -7.35856,-11.57584 -11.88507,-20.45973 -5.93146,-7.95448 -4.20766,-14.06077 -4.92476,-23.05027 -0.40158,-5.97052 -1.96142,-10.8536 -3.63182,-13.19506 0.17381,-0.13365 0.34794,-0.26943 0.52297,-0.4067 1.73545,2.52942 4.90398,5.86046 8.0455,9.26094 6.76431,7.51395 13.01667,15.63107 16.51527,25.21034 1.35773,4.14855 2.10119,8.60352 3.45664,13.13305 0.98929,3.30466 3.27759,9.40579 7.58661,13.54595 6.38008,6.1429 15.91935,7.80933 24.11895,4.23385 4.93753,-2.20003 1.70548,-9.61259 -3.26647,-7.49154 -4.66716,2.03515 -10.78159,1.38248 -15.14998,-2.72076 -2.93588,-2.76759 -4.86938,-7.35322 -5.80326,-9.99526 -1.47415,-4.17243 -2.52565,-8.67391 -4.25814,-13.11651 -3.34012,-8.94625 -8.86563,-16.22478 -17.55707,-27.44225 -2.80001,-3.82946 -5.52491,-7.67078 -7.70237,-9.83351 1.2085,-1.15603 2.48234,-2.43766 3.67471,-3.70623 1.71163,0.90149 4.05496,1.86857 6.3562,3.58014 4.31134,3.41817 7.17269,8.23064 10.20455,12.73514 9.02396,13.81618 16.24631,18.39025 20.71863,20.64112 5.77715,2.91426 11.83293,4.03246 16.24242,7.167 3.06679,2.40147 5.623,6.10495 6.58771,9.92705 1.25189,5.5451 9.56816,3.67645 8.32766,-1.87121 -1.74384,-5.74755 -5.16756,-11.39162 -10.03815,-14.97118 -5.63746,-3.95554 -12.09561,-5.09221 -17.38189,-7.71529 -9.23039,-4.59405 -14.69079,-13.76571 -16.9478,-17.75964 -2.9899,-5.82031 -5.94378,-11.72918 -10.74043,-16.29564 -1.59447,-1.4853 -3.03675,-2.47899 -4.33307,-3.11144 3.47071,0.40841 8.54372,0.89003 14.17691,2.64893 6.75971,2.94516 9.44739,3.31851 25.0021,19.96467 2.64871,3.43112 7.37316,7.43824 11.24427,11.19622 5.86542,5.85693 13.04545,10.36975 21.14341,12.26178 6.27777,1.48346 8.51479,-7.92575 2.24121,-9.42681 -3.36191,-0.79944 -11.80251,-3.18999 -18.54409,-8.31784 -3.70865,-2.92513 -6.98198,-6.57663 -9.84901,-9.94668 -2.86708,-3.37004 -5.98505,-7.75417 -10.06502,-11.90625 -5.41677,-5.36572 -11.81147,-9.33587 -18.42368,-11.80083 -6.89679,-2.57107 -11.79147,-3.00767 -14.9009,-2.58124 2.50891,-5.48856 6.10219,-17.19419 -3.46387,-25.90178 1.43383,-3.25331 2.61886,-6.46821 3.57394,-9.61543 1.97457,-6.50664 5.23175,-20.59109 1.53686,-33.809822 C 187.55889,73.169869 170.9936,69.810673 169.39586,70.508875 Z m -37.95117,5.312902 C 119.8515,80.44692 108.52615,88.220935 98.601307,98.159622 88.676465,108.09831 80.763495,119.30523 76.343144,130.92022 c -7.230085,18.9979 -6.317388,68.18064 46.430236,44.70425 -34.346397,3.56965 -40.658237,-19.78677 -32.145837,-43.81283 3.109475,-8.77642 9.124568,-17.34164 16.745227,-24.9623 7.62068,-7.62068 16.2735,-13.399209 24.9623,-16.745748 31.64426,-11.637879 46.57574,-3.833923 43.81335,32.145848 C 201.58664,61.657824 144.7383,70.518235 131.44469,75.821777 Z m 16.0631,39.669363 c -7.36376,-0.22251 -16.21769,5.64079 -22.98826,13.28395 -9.02743,10.19087 -14.35077,23.54585 -7.49928,29.85709 6.85148,6.31124 20.13893,-0.69948 29.72273,-10.87376 9.5838,-10.17429 15.46351,-23.51218 7.49928,-29.85657 -1.99106,-1.5861 -4.27988,-2.33654 -6.73447,-2.41071 z"
|
||||
sodipodi:nodetypes="cssscsssccsssscccsssscsccsccccccccscscscccscsccccsscccccsccccccccscccsssccscscssss" /></svg>
|
||||
|
Before Width: | Height: | Size: 17 KiB |
@@ -93,8 +93,6 @@
|
||||
/* Begin PBXFileSystemSynchronizedRootGroup section */
|
||||
CFE47DDB2EA56B0200EB6067 /* icons */ = {
|
||||
isa = PBXFileSystemSynchronizedRootGroup;
|
||||
exceptions = (
|
||||
);
|
||||
path = icons;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
@@ -397,10 +395,14 @@
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Jellify/Pods-Jellify-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Jellify/Pods-Jellify-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Jellify/Pods-Jellify-frameworks.sh\"\n";
|
||||
@@ -414,10 +416,14 @@
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Jellify/Pods-Jellify-resources-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Jellify/Pods-Jellify-resources-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Jellify/Pods-Jellify-resources.sh\"\n";
|
||||
@@ -697,10 +703,7 @@
|
||||
"-DFOLLY_CFG_NO_COROUTINES=1",
|
||||
"-DFOLLY_HAVE_CLOCK_GETTIME=1",
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
" ",
|
||||
);
|
||||
OTHER_LDFLAGS = "$(inherited) ";
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
STRING_CATALOG_GENERATE_SYMBOLS = YES;
|
||||
@@ -787,10 +790,7 @@
|
||||
"-DFOLLY_CFG_NO_COROUTINES=1",
|
||||
"-DFOLLY_HAVE_CLOCK_GETTIME=1",
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
" ",
|
||||
);
|
||||
OTHER_LDFLAGS = "$(inherited) ";
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
STRING_CATALOG_GENERATE_SYMBOLS = YES;
|
||||
|
||||
@@ -1,20 +1,13 @@
|
||||
import { AxiosResponse } from 'axios'
|
||||
import { JellyfinCredentials } from '../../types/jellyfin-credentials'
|
||||
import { AuthenticationResult } from '@jellyfin/sdk/lib/generated-client'
|
||||
import { useMutation } from '@tanstack/react-query'
|
||||
import { useJellifyContext } from '../../../providers'
|
||||
import { JellifyUser } from '../../../types/JellifyUser'
|
||||
import { capitalize, isUndefined } from 'lodash'
|
||||
import { isUndefined } from 'lodash'
|
||||
import { getQuickConnectApi, getUserApi } from '@jellyfin/sdk/lib/utils/api'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
import LoginStackParamList from '@/src/screens/Login/types'
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack'
|
||||
import { getDeviceId, getDeviceNameSync, getUniqueIdSync } from 'react-native-device-info'
|
||||
import { name, version } from '../../../../package.json'
|
||||
|
||||
const QUICK_CONNECT_HEADER = encodeURIComponent(
|
||||
`MediaBrowser Device='${getDeviceNameSync()}' DeviceId='${getUniqueIdSync()}'`,
|
||||
)
|
||||
|
||||
export const useInitiateQuickConnect = () => {
|
||||
const { api } = useJellifyContext()
|
||||
@@ -23,12 +16,7 @@ export const useInitiateQuickConnect = () => {
|
||||
mutationFn: async () => {
|
||||
if (isUndefined(api)) return Promise.reject(new Error('API client is not initialized'))
|
||||
|
||||
console.debug('Initiating Quick Connect', QUICK_CONNECT_HEADER)
|
||||
return await getQuickConnectApi(api!).initiateQuickConnect({
|
||||
headers: {
|
||||
Authorization: QUICK_CONNECT_HEADER,
|
||||
},
|
||||
})
|
||||
return await getQuickConnectApi(api).initiateQuickConnect()
|
||||
},
|
||||
onError: async (error: Error) => {
|
||||
console.error('An error occurred initiating Quick Connect', error)
|
||||
@@ -95,4 +83,16 @@ const useAuthenticateWithQuickConnect = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const useQuickConnectStatus = () => {
|
||||
const { api } = useJellifyContext()
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async (secret: string) => {
|
||||
return await getQuickConnectApi(api!).getQuickConnectState({
|
||||
secret,
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export default useAuthenticateWithQuickConnect
|
||||
|
||||
@@ -10,6 +10,8 @@ const useGetQuickConnectState = (secret: string) => {
|
||||
queryFn: async () => {
|
||||
return await getQuickConnectApi(api!).getQuickConnectState({ secret })
|
||||
},
|
||||
gcTime: 0,
|
||||
staleTime: 0,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import React, { useCallback, useEffect, useLayoutEffect } from 'react'
|
||||
import useAuthenticateWithQuickConnect, {
|
||||
useInitiateQuickConnect,
|
||||
} from '../../../api/mutations/quickconnect'
|
||||
import useGetQuickConnectState from '../../../api/queries/quickconnect'
|
||||
import { View, Spinner, Button, YStack } from 'tamagui'
|
||||
import { Text } from '../../Global/helpers/text'
|
||||
import { View, Spinner, Button, YStack, H6, H5 } from 'tamagui'
|
||||
import { useFocusEffect, useNavigation } from '@react-navigation/native'
|
||||
import LoginStackParamList from '@/src/screens/Login/types'
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack'
|
||||
|
||||
// Handles polling, code display, error, and authentication
|
||||
function QuickConnectDisplay({
|
||||
@@ -16,36 +18,44 @@ function QuickConnectDisplay({
|
||||
code: string
|
||||
onExpired: () => void
|
||||
}) {
|
||||
const {
|
||||
data: stateData,
|
||||
error: stateError,
|
||||
isFetching: isStateFetching,
|
||||
} = useGetQuickConnectState(secret)
|
||||
const { mutate: authenticate, isPending: isAuthenticating } = useAuthenticateWithQuickConnect()
|
||||
|
||||
const {
|
||||
data: quickConnectData,
|
||||
error: quickConnectError,
|
||||
refetch: refetchQuickConnectData,
|
||||
} = useGetQuickConnectState(secret)
|
||||
|
||||
useEffect(() => {}, [secret, code])
|
||||
|
||||
// Authenticate when ready
|
||||
useEffect(() => {
|
||||
if (stateData?.data.Authenticated && secret) {
|
||||
if (quickConnectData?.data.Authenticated && secret) {
|
||||
authenticate(secret)
|
||||
}
|
||||
}, [stateData, secret, authenticate])
|
||||
}, [quickConnectData, secret, authenticate])
|
||||
|
||||
// Handle expired/errored code
|
||||
useEffect(() => {
|
||||
if (stateError) {
|
||||
if (quickConnectError) {
|
||||
onExpired()
|
||||
}
|
||||
}, [stateError, onExpired])
|
||||
}, [quickConnectError, onExpired])
|
||||
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
console.debug(`Checking Quick Connect State: ${JSON.stringify(quickConnectData)}`)
|
||||
|
||||
if (quickConnectData?.data.Authenticated) clearInterval(interval)
|
||||
refetchQuickConnectData()
|
||||
}, 5000)
|
||||
|
||||
return () => clearInterval(interval)
|
||||
}, [secret])
|
||||
|
||||
return (
|
||||
<View>
|
||||
<Text>{code}</Text>
|
||||
{isStateFetching && <Spinner />}
|
||||
{stateError && (
|
||||
<View>
|
||||
<Text color='red'>Code expired. Please try again.</Text>
|
||||
</View>
|
||||
)}
|
||||
<H6>{code}</H6>
|
||||
{isAuthenticating && <Spinner />}
|
||||
</View>
|
||||
)
|
||||
@@ -53,38 +63,36 @@ function QuickConnectDisplay({
|
||||
|
||||
// Initiates quick connect, manages secret/code state, and renders display
|
||||
export default function QuickConnectInitiator() {
|
||||
const navigation = useNavigation<NativeStackNavigationProp<LoginStackParamList>>()
|
||||
|
||||
const {
|
||||
mutate: initiateQuickConnect,
|
||||
reset: resetInitiateQuickConnect,
|
||||
data: quickConnectData,
|
||||
isPending: isInitiating,
|
||||
} = useInitiateQuickConnect()
|
||||
|
||||
// When QuickConnect is initiated, set secret and code
|
||||
useEffect(() => {
|
||||
initiateQuickConnect()
|
||||
}, [])
|
||||
|
||||
// Reset secret/code to retry
|
||||
const handleExpired = () => {
|
||||
const beginQuickConnect = useCallback(() => {
|
||||
resetInitiateQuickConnect()
|
||||
initiateQuickConnect()
|
||||
}
|
||||
}, [initiateQuickConnect, resetInitiateQuickConnect])
|
||||
|
||||
useEffect(() => {
|
||||
initiateQuickConnect()
|
||||
|
||||
return resetInitiateQuickConnect()
|
||||
})
|
||||
|
||||
return (
|
||||
<YStack>
|
||||
<Text bold>Quick Connect</Text>
|
||||
{isInitiating && <Spinner />}
|
||||
<YStack alignItems='center'>
|
||||
<H5>Quick Connect</H5>
|
||||
{quickConnectData?.data.Secret && quickConnectData?.data.Code ? (
|
||||
<QuickConnectDisplay
|
||||
secret={quickConnectData.data.Secret}
|
||||
code={quickConnectData.data.Code}
|
||||
onExpired={handleExpired}
|
||||
onExpired={beginQuickConnect}
|
||||
/>
|
||||
) : null}
|
||||
{!quickConnectData?.data.Secret && !isInitiating && (
|
||||
<Button onPress={() => initiateQuickConnect()}>Retry</Button>
|
||||
)}
|
||||
{!quickConnectData?.data.Secret && <Button onPress={beginQuickConnect}>Retry</Button>}
|
||||
</YStack>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { isEmpty, isUndefined } from 'lodash'
|
||||
import { Input, ListItem, Separator, Spinner, XStack, YGroup, YStack } from 'tamagui'
|
||||
import { H3, Image, Input, ListItem, Separator, Spinner, XStack, YGroup, YStack } from 'tamagui'
|
||||
import { SwitchWithLabel } from '../../components/Global/helpers/switch-with-label'
|
||||
import { H2, Text } from '../../components/Global/helpers/text'
|
||||
import Button from '../../components/Global/helpers/button'
|
||||
@@ -62,121 +62,130 @@ export default function ServerAddress({
|
||||
|
||||
return (
|
||||
<SafeAreaView style={{ flex: 1 }}>
|
||||
<YStack maxHeight={'$19'} flex={1} justifyContent='center'>
|
||||
<H2 marginHorizontal={'$10'} textAlign='center'>
|
||||
Connect to Jellyfin
|
||||
</H2>
|
||||
</YStack>
|
||||
<YStack flex={1} justifyContent='center' alignContent='center'>
|
||||
<YStack maxHeight={'$20'} flex={1} justifyContent='center'>
|
||||
<H3 marginHorizontal={'$10'} textAlign='center'>
|
||||
Connect to Jellyfin
|
||||
</H3>
|
||||
</YStack>
|
||||
|
||||
<YStack marginHorizontal={'$4'} gap={'$4'}>
|
||||
<XStack alignItems='center'>
|
||||
{!serverAddressContainsProtocol && (
|
||||
<Text
|
||||
borderColor={'$borderColor'}
|
||||
borderWidth={'$0.5'}
|
||||
borderRadius={'$4'}
|
||||
padding={'$2'}
|
||||
paddingTop={'$2.5'}
|
||||
width={'$6'}
|
||||
height={'$4'}
|
||||
marginRight={'$2'}
|
||||
color={useHttps ? '$success' : '$borderColor'}
|
||||
textAlign='center'
|
||||
verticalAlign={'center'}
|
||||
>
|
||||
{useHttps ? HTTPS : HTTP}
|
||||
</Text>
|
||||
)}
|
||||
<YStack marginHorizontal={'$4'} gap={'$4'} flex={1}>
|
||||
<XStack alignItems='center'>
|
||||
{!serverAddressContainsProtocol && (
|
||||
<Text
|
||||
borderColor={'$borderColor'}
|
||||
borderWidth={'$0.5'}
|
||||
borderRadius={'$4'}
|
||||
padding={'$2'}
|
||||
paddingTop={'$2.5'}
|
||||
width={'$6'}
|
||||
height={'$4'}
|
||||
marginRight={'$2'}
|
||||
color={useHttps ? '$success' : '$borderColor'}
|
||||
textAlign='center'
|
||||
verticalAlign={'center'}
|
||||
>
|
||||
{useHttps ? HTTPS : HTTP}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
<Input
|
||||
onChangeText={setServerAddress}
|
||||
autoCapitalize='none'
|
||||
autoCorrect={false}
|
||||
secureTextEntry={IS_MAESTRO_BUILD} // If Maestro build, don't show the server address as screen Records
|
||||
flex={1}
|
||||
placeholder='jellyfin.org'
|
||||
testID='server_address_input'
|
||||
/>
|
||||
</XStack>
|
||||
<Input
|
||||
onChangeText={setServerAddress}
|
||||
autoCapitalize='none'
|
||||
autoCorrect={false}
|
||||
secureTextEntry={IS_MAESTRO_BUILD} // If Maestro build, don't show the server address as screen Records
|
||||
flex={1}
|
||||
placeholder='jellyfin.org'
|
||||
testID='server_address_input'
|
||||
returnKeyType='send'
|
||||
onSubmitEditing={() => {
|
||||
if (!isUndefined(serverAddress))
|
||||
connectToServer({ serverAddress, useHttps })
|
||||
}}
|
||||
/>
|
||||
</XStack>
|
||||
|
||||
<YGroup
|
||||
gap={'$2'}
|
||||
borderColor={'$borderColor'}
|
||||
borderWidth={'$0.5'}
|
||||
borderRadius={'$4'}
|
||||
>
|
||||
<YGroup.Item>
|
||||
<ListItem
|
||||
icon={
|
||||
<Icon
|
||||
name={
|
||||
serverAddressContainsHttps || useHttps
|
||||
? 'lock-check'
|
||||
: 'lock-open'
|
||||
}
|
||||
color={
|
||||
serverAddressContainsHttps || useHttps
|
||||
? '$success'
|
||||
: '$borderColor'
|
||||
}
|
||||
/>
|
||||
}
|
||||
title='HTTPS'
|
||||
subTitle='Use HTTPS to connect to Jellyfin'
|
||||
disabled={serverAddressContainsProtocol}
|
||||
>
|
||||
<SwitchWithLabel
|
||||
checked={serverAddressContainsHttps || useHttps}
|
||||
onCheckedChange={(checked) => setUseHttps(checked)}
|
||||
label={
|
||||
serverAddressContainsHttps || useHttps
|
||||
? 'Use HTTPS'
|
||||
: 'Use HTTP'
|
||||
<YGroup gap={'$2'} flex={1}>
|
||||
<YGroup.Item>
|
||||
<ListItem
|
||||
icon={
|
||||
<Icon
|
||||
name={
|
||||
serverAddressContainsHttps || useHttps
|
||||
? 'lock-check'
|
||||
: 'lock-open'
|
||||
}
|
||||
color={
|
||||
serverAddressContainsHttps || useHttps
|
||||
? '$success'
|
||||
: '$borderColor'
|
||||
}
|
||||
/>
|
||||
}
|
||||
size='$2'
|
||||
width={100}
|
||||
/>
|
||||
</ListItem>
|
||||
</YGroup.Item>
|
||||
|
||||
<Separator />
|
||||
|
||||
<YGroup.Item>
|
||||
<ListItem
|
||||
icon={
|
||||
<Icon
|
||||
name={sendMetrics ? 'bug-check' : 'bug'}
|
||||
color={sendMetrics ? '$success' : '$borderColor'}
|
||||
title='HTTPS'
|
||||
subTitle='Use HTTPS to connect to Jellyfin'
|
||||
disabled={serverAddressContainsProtocol}
|
||||
>
|
||||
<SwitchWithLabel
|
||||
checked={serverAddressContainsHttps || useHttps}
|
||||
onCheckedChange={(checked) => setUseHttps(checked)}
|
||||
label={
|
||||
serverAddressContainsHttps || useHttps
|
||||
? 'Use HTTPS'
|
||||
: 'Use HTTP'
|
||||
}
|
||||
size='$2'
|
||||
width={100}
|
||||
/>
|
||||
}
|
||||
title='Submit Usage and Crash Data'
|
||||
subTitle='Send anonymized metrics and crash data'
|
||||
>
|
||||
<SwitchWithLabel
|
||||
checked={sendMetrics}
|
||||
onCheckedChange={(checked) => setSendMetrics(checked)}
|
||||
label='Send Metrics'
|
||||
size='$2'
|
||||
width={100}
|
||||
/>
|
||||
</ListItem>
|
||||
</YGroup.Item>
|
||||
</YGroup>
|
||||
</ListItem>
|
||||
</YGroup.Item>
|
||||
|
||||
{isPending ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
<Button
|
||||
disabled={isEmpty(serverAddress)}
|
||||
onPress={() => {
|
||||
if (!isUndefined(serverAddress))
|
||||
connectToServer({ serverAddress, useHttps })
|
||||
}}
|
||||
testID='connect_button'
|
||||
>
|
||||
Connect
|
||||
</Button>
|
||||
)}
|
||||
<Separator />
|
||||
|
||||
<YGroup.Item>
|
||||
<ListItem
|
||||
icon={
|
||||
<Icon
|
||||
name={sendMetrics ? 'bug-check' : 'bug'}
|
||||
color={sendMetrics ? '$success' : '$borderColor'}
|
||||
/>
|
||||
}
|
||||
title='Submit Usage and Crash Data'
|
||||
subTitle='Send anonymized metrics and crash data'
|
||||
>
|
||||
<SwitchWithLabel
|
||||
checked={sendMetrics}
|
||||
onCheckedChange={(checked) => setSendMetrics(checked)}
|
||||
label='Send Metrics'
|
||||
size='$2'
|
||||
width={100}
|
||||
/>
|
||||
</ListItem>
|
||||
</YGroup.Item>
|
||||
<Button
|
||||
borderWidth={'$1'}
|
||||
icon={() =>
|
||||
isPending ? (
|
||||
<Spinner color='$primary' />
|
||||
) : (
|
||||
<Icon name='connection' small color='$primary' />
|
||||
)
|
||||
}
|
||||
color={'$primary'}
|
||||
borderColor={'$primary'}
|
||||
disabled={isEmpty(serverAddress) || isPending}
|
||||
onPress={() => {
|
||||
if (!isUndefined(serverAddress))
|
||||
connectToServer({ serverAddress, useHttps })
|
||||
}}
|
||||
testID='connect_button'
|
||||
>
|
||||
<Text bold color={'$primary'}>
|
||||
Connect
|
||||
</Text>
|
||||
</Button>
|
||||
</YGroup>
|
||||
</YStack>
|
||||
</YStack>
|
||||
</SafeAreaView>
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import _ from 'lodash'
|
||||
import { H3, H6, Spacer, Spinner, XStack, YStack } from 'tamagui'
|
||||
import { H2 } from '../../components/Global/helpers/text'
|
||||
import { H2, Text } from '../../components/Global/helpers/text'
|
||||
import Button from '../../components/Global/helpers/button'
|
||||
import { SafeAreaView } from 'react-native-safe-area-context'
|
||||
import Input from '../../components/Global/helpers/input'
|
||||
@@ -38,90 +38,104 @@ export default function ServerAuthentication({
|
||||
|
||||
return (
|
||||
<SafeAreaView style={{ flex: 1 }}>
|
||||
<YStack maxHeight={'$19'} flex={1} justifyContent='center'>
|
||||
<H3 marginHorizontal={'$2'} textAlign='center'>
|
||||
{`Sign in to ${server?.name ?? 'Jellyfin'}`}
|
||||
</H3>
|
||||
<H6 marginHorizontal={'$2'} textAlign='center'>
|
||||
{server?.version ?? 'Unknown Jellyfin version'}
|
||||
</H6>
|
||||
</YStack>
|
||||
<YStack marginHorizontal={'$4'}>
|
||||
<Input
|
||||
prependElement={<Icon name='human-greeting-variant' color={'$primary'} />}
|
||||
placeholder='Username'
|
||||
value={username}
|
||||
style={
|
||||
IS_MAESTRO_BUILD ? { backgroundColor: '#000', color: '#000' } : undefined
|
||||
}
|
||||
testID='username_input'
|
||||
secureTextEntry={IS_MAESTRO_BUILD} // If Maestro build, don't show the username as screen Records
|
||||
onChangeText={(value: string | undefined) => setUsername(value)}
|
||||
autoCapitalize='none'
|
||||
autoCorrect={false}
|
||||
autoComplete='username'
|
||||
textContentType='username'
|
||||
importantForAutofill='yes'
|
||||
returnKeyType='next'
|
||||
autoFocus
|
||||
/>
|
||||
<YStack flex={1} justifyContent='center' alignContent='center'>
|
||||
<YStack flex={1} maxHeight={'$20'} justifyContent='center' alignContent='center'>
|
||||
<H3 textAlign='center'>{`Sign in to ${server?.name ?? 'Jellyfin'}`}</H3>
|
||||
<H6 textAlign='center'>{server?.version ?? 'Unknown Jellyfin version'}</H6>
|
||||
</YStack>
|
||||
<YStack marginHorizontal={'$4'} flex={1}>
|
||||
<Input
|
||||
prependElement={<Icon name='human-greeting-variant' color={'$primary'} />}
|
||||
placeholder='Username'
|
||||
value={username}
|
||||
style={
|
||||
IS_MAESTRO_BUILD
|
||||
? { backgroundColor: '#000', color: '#000' }
|
||||
: undefined
|
||||
}
|
||||
testID='username_input'
|
||||
secureTextEntry={IS_MAESTRO_BUILD} // If Maestro build, don't show the username as screen Records
|
||||
onChangeText={(value: string | undefined) => setUsername(value)}
|
||||
autoCapitalize='none'
|
||||
autoCorrect={false}
|
||||
autoComplete='username'
|
||||
textContentType='username'
|
||||
importantForAutofill='yes'
|
||||
returnKeyType='next'
|
||||
autoFocus
|
||||
/>
|
||||
|
||||
<Spacer />
|
||||
<Spacer />
|
||||
|
||||
<Input
|
||||
prependElement={<Icon name='lock-outline' color={'$primary'} />}
|
||||
placeholder='Password'
|
||||
value={password}
|
||||
testID='password_input'
|
||||
style={
|
||||
IS_MAESTRO_BUILD ? { backgroundColor: '#000', color: '#000' } : undefined
|
||||
}
|
||||
onChangeText={(value: string | undefined) => setPassword(value)}
|
||||
autoCapitalize='none'
|
||||
autoCorrect={false}
|
||||
secureTextEntry // Always secure text entry
|
||||
autoComplete='password'
|
||||
textContentType='password'
|
||||
importantForAutofill='yes'
|
||||
returnKeyType='go'
|
||||
/>
|
||||
<Input
|
||||
prependElement={<Icon name='lock-outline' color={'$primary'} />}
|
||||
placeholder='Password'
|
||||
value={password}
|
||||
testID='password_input'
|
||||
style={
|
||||
IS_MAESTRO_BUILD
|
||||
? { backgroundColor: '#000', color: '#000' }
|
||||
: undefined
|
||||
}
|
||||
onChangeText={(value: string | undefined) => setPassword(value)}
|
||||
autoCapitalize='none'
|
||||
autoCorrect={false}
|
||||
secureTextEntry // Always secure text entry
|
||||
autoComplete='password'
|
||||
textContentType='password'
|
||||
importantForAutofill='yes'
|
||||
returnKeyType='go'
|
||||
/>
|
||||
|
||||
<Spacer />
|
||||
<Spacer />
|
||||
|
||||
<QuickConnect />
|
||||
|
||||
<Spacer />
|
||||
|
||||
<XStack justifyContent='space-between'>
|
||||
<Button
|
||||
borderWidth={'$1'}
|
||||
borderColor={'$primary'}
|
||||
disabled={_.isEmpty(username) || isPending}
|
||||
icon={() =>
|
||||
isPending ? (
|
||||
<Spinner color='$primary' />
|
||||
) : (
|
||||
<Icon name='chevron-right' small color='$primary' />
|
||||
)
|
||||
}
|
||||
testID='sign_in_button'
|
||||
onPress={() => {
|
||||
if (!_.isUndefined(username)) {
|
||||
console.log(`Signing in...`)
|
||||
authenticateUserByName({ username, password })
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Text bold color={'$primary'}>
|
||||
Sign in
|
||||
</Text>
|
||||
</Button>
|
||||
|
||||
<Spacer />
|
||||
|
||||
<YStack flex={1} marginVertical={'$4'}>
|
||||
<QuickConnect />
|
||||
</YStack>
|
||||
|
||||
<Spacer />
|
||||
|
||||
<Button
|
||||
borderWidth={'$1'}
|
||||
borderColor={'$borderColor'}
|
||||
marginVertical={0}
|
||||
icon={() => <Icon name='chevron-left' small />}
|
||||
icon={() => <Icon name='chevron-left' small color='$borderColor' />}
|
||||
bordered={0}
|
||||
onPress={() => {
|
||||
navigation.popTo('ServerAddress', undefined)
|
||||
}}
|
||||
>
|
||||
Switch Server
|
||||
<Text bold color={'$borderColor'}>
|
||||
Switch Server
|
||||
</Text>
|
||||
</Button>
|
||||
{isPending ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
<Button
|
||||
marginVertical={0}
|
||||
disabled={_.isEmpty(username) || isPending}
|
||||
icon={() => <Icon name='chevron-right' small />}
|
||||
testID='sign_in_button'
|
||||
onPress={() => {
|
||||
if (!_.isUndefined(username)) {
|
||||
console.log(`Signing in...`)
|
||||
authenticateUserByName({ username, password })
|
||||
}
|
||||
}}
|
||||
>
|
||||
Sign in
|
||||
</Button>
|
||||
)}
|
||||
</XStack>
|
||||
</YStack>
|
||||
{/* <Toast /> */}
|
||||
</YStack>
|
||||
</SafeAreaView>
|
||||
|
||||
@@ -6,6 +6,7 @@ import { BaseItemDto } from '@jellyfin/sdk/lib/generated-client/models'
|
||||
import LibrarySelector from '../../components/Global/components/library-selector'
|
||||
import LoginStackParamList from './types'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
import { useInitiateQuickConnect } from '../../api/mutations/quickconnect'
|
||||
|
||||
export default function ServerLibrary({
|
||||
navigation,
|
||||
@@ -16,6 +17,8 @@ export default function ServerLibrary({
|
||||
|
||||
const rootNavigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>()
|
||||
|
||||
const initiateQuickConnect = useInitiateQuickConnect()
|
||||
|
||||
const handleLibrarySelected = (
|
||||
libraryId: string,
|
||||
selectedLibrary: BaseItemDto,
|
||||
@@ -32,9 +35,8 @@ export default function ServerLibrary({
|
||||
}
|
||||
|
||||
const handleCancel = () => {
|
||||
navigation.navigate('ServerAuthentication', undefined, {
|
||||
pop: true,
|
||||
})
|
||||
initiateQuickConnect.reset()
|
||||
navigation.popTo('ServerAuthentication', undefined)
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user