Improve dashboard
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"info": {
|
||||
"author": "xcode",
|
||||
"version": 1
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"symbol-rendering-intent" : "template"
|
||||
},
|
||||
"symbols" : [
|
||||
{
|
||||
"filename" : "singbox-menubar.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 25.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 3300 2200" style="enable-background:new 0 0 3300 2200;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;}
|
||||
.st1{fill:none;stroke:#000000;stroke-width:0.5;}
|
||||
.st2{font-family:'Helvetica-Bold';}
|
||||
.st3{font-size:13px;}
|
||||
.st4{font-family:'Helvetica';}
|
||||
.st5{fill:none;stroke:#00AEEF;stroke-width:0.5;}
|
||||
.st6{fill:#27AAE1;}
|
||||
.st7{fill:none;stroke:#27AAE1;stroke-width:0.5;}
|
||||
</style>
|
||||
<g id="Notes">
|
||||
<rect id="artboard" class="st0" width="3300" height="2200"/>
|
||||
<line class="st1" x1="263" y1="292" x2="3036" y2="292"/>
|
||||
<text transform="matrix(1 0 0 1 263 322)" class="st2 st3">Weight/Scale Variations</text>
|
||||
<text transform="matrix(1 0 0 1 534.0632935 322)" class="st4 st3">Ultralight</text>
|
||||
<text transform="matrix(1 0 0 1 843.7774658 322)" class="st4 st3">Thin</text>
|
||||
<text transform="matrix(1 0 0 1 1139.0350342 322)" class="st4 st3">Light</text>
|
||||
<text transform="matrix(1 0 0 1 1427.0772705 322)" class="st4 st3">Regular</text>
|
||||
<text transform="matrix(1 0 0 1 1723.4418945 322)" class="st4 st3">Medium</text>
|
||||
<text transform="matrix(1 0 0 1 2016.171875 322)" class="st4 st3">Semibold</text>
|
||||
<text transform="matrix(1 0 0 1 2326.970459 322)" class="st4 st3">Bold</text>
|
||||
<text transform="matrix(1 0 0 1 2618.2658691 322)" class="st4 st3">Heavy</text>
|
||||
<text transform="matrix(1 0 0 1 2917.5053711 322)" class="st4 st3">Black</text>
|
||||
<line class="st1" x1="263" y1="1903" x2="3036" y2="1903"/>
|
||||
<g transform="matrix(1 0 0 1 263 1933)">
|
||||
<path d="M9.2480497,0.830078c4.3066502,0,7.8906507-3.5742178,7.8906507-7.8808579
|
||||
c0-4.3066201-3.5938005-7.8808198-7.9004202-7.8808198c-4.2968702,0-7.8710904,3.5741997-7.8710904,7.8808198
|
||||
C1.36719-2.7441399,4.95117,0.830078,9.2480497,0.830078z M9.2480497-0.654297
|
||||
c-3.5449295,0-6.3769598-2.8417931-6.3769598-6.3964829c0-3.5547204,2.8222699-6.3965201,6.3671904-6.3965201
|
||||
c3.5547199,0,6.4062195,2.8417997,6.4062195,6.3965201C15.6444998-3.4960899,12.8027-0.654297,9.2480497-0.654297z
|
||||
M5.6543002-7.0507798c0,0.4296899,0.3027296,0.7226596,0.7519498,0.7226596h2.0996103v2.1191401
|
||||
c0,0.43945,0.2929697,0.7421801,0.7226601,0.7421801c0.4492092,0,0.7421799-0.3027301,0.7421799-0.7421801v-2.1191401h2.1190996
|
||||
c0.4394999,0,0.7421999-0.2929697,0.7421999-0.7226596c0-0.4394503-0.3027-0.7421904-0.7421999-0.7421904H9.9707003v-2.1093698
|
||||
c0-0.4492598-0.2929707-0.7519598-0.7421799-0.7519598c-0.4296904,0-0.7226601,0.3027-0.7226601,0.7519598v2.1093698H6.40625
|
||||
C5.9570298-7.7929702,5.6543002-7.4902301,5.6543002-7.0507798z"/>
|
||||
</g>
|
||||
<g transform="matrix(1 0 0 1 281.867 1933)">
|
||||
<path d="M11.7089996,2.9101601c5.4491997,0,9.9609013-4.5214901,9.9609013-9.9609394
|
||||
c0-5.4492207-4.5215015-9.9609203-9.9707012-9.9609203c-5.4394288,0-9.951149,4.5116997-9.951149,9.9609203
|
||||
C1.7480507-1.61133,6.2695308,2.9101601,11.7089996,2.9101601z M11.7089996,1.25
|
||||
c-4.6093888,0-8.291029-3.6914101-8.291029-8.3007793c0-4.6094208,3.6718702-8.3008194,8.281229-8.3008194
|
||||
c4.6093998,0,8.3106003,3.6913996,8.3106003,8.3008194C20.0098-2.4414101,16.3183994,1.25,11.7089996,1.25z M7.177731-7.0507798
|
||||
C7.177731-6.5722699,7.5097709-6.25,8.0078096-6.25h2.8710899v2.8808601c0,0.4882798,0.3320007,0.8300798,0.8106003,0.8300798
|
||||
c0.4882002,0,0.8299999-0.3320298,0.8299999-0.8300798V-6.25h2.8809004c0.4882994,0,0.8300991-0.3222699,0.8300991-0.8007798
|
||||
c0-0.4882803-0.3417997-0.83008-0.8300991-0.83008h-2.8809004v-2.87114c0-0.4980001-0.3417997-0.8397999-0.8299999-0.8397999
|
||||
c-0.4785995,0-0.8106003,0.3417997-0.8106003,0.8397999v2.87114H8.0078096
|
||||
C7.5097709-7.8808599,7.177731-7.5390601,7.177731-7.0507798z"/>
|
||||
</g>
|
||||
<g transform="matrix(1 0 0 1 305.646 1933)">
|
||||
<path d="M14.9707003,5.6640601c6.9628992,0,12.7245989-5.7617164,12.7245989-12.7148399
|
||||
c0-6.9629197-5.7714996-12.7246208-12.7343988-12.7246208c-6.9530907,0-12.70504,5.7617006-12.70504,12.7246208
|
||||
C2.2558601-0.0976562,8.01758,5.6640601,14.9707003,5.6640601z M14.9707003,3.8476601
|
||||
c-6.0351505,0-10.88867-4.8632803-10.88867-10.8984394c0-6.04492,4.843751-10.8984203,10.87887-10.8984203
|
||||
c6.0449991,0,10.9082003,4.8534994,10.9082003,10.8984203C25.8691006-1.01562,21.0156002,3.8476601,14.9707003,3.8476601z
|
||||
M9.1992197-7.0507798c0,0.51758,0.3710899,0.8789001,0.9179802,0.8789001H14.0625V-2.2168
|
||||
c0,0.53711,0.3711004,0.9179699,0.8886995,0.9179699c0.5371008,0,0.9082003-0.3710899,0.9082003-0.9179699v-3.9550798h3.955101
|
||||
c0.5370998,0,0.9179001-0.36132,0.9179001-0.8789001c0-0.5468802-0.3711014-0.9179702-0.9179001-0.9179702h-3.955101v-3.9453497
|
||||
c0-0.5468006-0.3710995-0.9277-0.9082003-0.9277c-0.5175991,0-0.8886995,0.3808994-0.8886995,0.9277V-7.96875h-3.9453001
|
||||
C9.5703096-7.96875,9.1992197-7.5976601,9.1992197-7.0507798z"/>
|
||||
</g>
|
||||
<text transform="matrix(1 0 0 1 263 1953)" class="st2 st3">Design Variations</text>
|
||||
<text transform="matrix(1 0 0 1 263 1971)" class="st4 st3">Symbols are supported in up to nine weights and three scales.</text>
|
||||
<text transform="matrix(1 0 0 1 263 1989)" class="st4 st3">For optimal layout with text and other symbols, vertically align</text>
|
||||
<text transform="matrix(1 0 0 1 263 2007)" class="st4 st3">symbols with the adjacent text.</text>
|
||||
<line class="st5" x1="776" y1="1919" x2="776" y2="1933"/>
|
||||
<g transform="matrix(1 0 0 1 776 1933)">
|
||||
<path d="M3.31055,0.15625c0.51757,0,0.7714798-0.1953125,0.9570301-0.742188l1.2597599-3.4472618h5.7617598l1.2597008,3.4472618
|
||||
c0.1855993,0.5468755,0.4394999,0.742188,0.9473,0.742188c0.5175991,0,0.8495998-0.3125,0.8495998-0.800781
|
||||
c0-0.166016-0.0293007-0.322266-0.1073999-0.527349L9.6582003-13.3690996c-0.2246103-0.5957003-0.625-0.8985004-1.25-0.8985004
|
||||
c-0.6054702,0-1.0156202,0.2930002-1.2304702,0.8887005L2.5976601-1.16211c-0.07813,0.205079-0.10743,0.361329-0.10743,0.527344
|
||||
C2.4902301-0.146484,2.8027301,0.15625,3.31055,0.15625z M6.0058599-5.51758l2.3730502-6.5722198h0.0488195L10.8008003-5.51758
|
||||
H6.0058599z"/>
|
||||
</g>
|
||||
<line class="st5" x1="793.1970215" y1="1919" x2="793.1970215" y2="1933"/>
|
||||
<text transform="matrix(1 0 0 1 776 1953)" class="st2 st3">Margins</text>
|
||||
<text transform="matrix(1 0 0 1 776 1971)" class="st4 st3">Leading and trailing margins on the left and right side of each symbol</text>
|
||||
<text transform="matrix(1 0 0 1 776 1989)" class="st4 st3">can be adjusted by modifying the x-location of the margin guidelines.</text>
|
||||
<text transform="matrix(1 0 0 1 776 2007)" class="st4 st3">Modifications are automatically applied proportionally to all</text>
|
||||
<text transform="matrix(1 0 0 1 776 2025)" class="st4 st3">scales and weights.</text>
|
||||
<g transform="matrix(1 0 0 1 1289 1933)">
|
||||
<path d="M2.8418,1.86523l1.6992199,1.70899c0.8593702,0.8691399,1.8457003,0.81055,2.7734299-0.2148399L18.0077991-8.4277296
|
||||
l-0.9667988-0.9765701L6.4257798,2.2753899c-0.3515596,0.4003901-0.6835899,0.49805-1.1523399,0.0293L4.1015601,1.14258
|
||||
c-0.46875-0.458986-0.36133-0.800783,0.0390601-1.1621113L15.6152-10.8203001l-0.9765005-0.9667997L3.04688-0.898438
|
||||
C2.06055,0.0195312,1.98242,0.996094,2.8418,1.86523z M9.2578096-16.3281002
|
||||
c-0.41992,0.4101-0.4492197,0.9863005-0.2148399,1.3769007c0.2343702,0.3613997,0.6933603,0.5956993,1.3379307,0.4296999
|
||||
c1.4647999-0.3418007,2.9881992-0.4004002,4.4139996,0.5370998l-0.5859003,1.4551001
|
||||
c-0.3417997,0.8301001-0.1659994,1.4159994,0.3711004,1.9629002L16.875-8.2519503
|
||||
c0.4883003,0.4882803,0.8983994,0.5078101,1.4647999,0.4101501l1.0645008-0.1953101l0.6640987,0.6738305l-0.0390987,0.5566397
|
||||
c-0.0391006,0.4980502,0.0879002,0.8789101,0.5761986,1.35742l0.7617016,0.7421904
|
||||
c0.4784985,0.4785099,1.0936985,0.5078096,1.5625,0.0390596l2.910099-2.91992
|
||||
c0.4687996-0.4687495,0.4493008-1.0644498-0.0293007-1.5429702L25.0391006-9.89258
|
||||
c-0.4786015-0.4785204-0.8495998-0.6347198-1.3282013-0.5957203L23.1348-10.4394999L22.4902-11.0741997L22.7343998-12.1973
|
||||
c0.1268997-0.5663996-0.0293007-1.0058002-0.6152992-1.5917997l-2.1972008-2.1875
|
||||
C16.5820007-19.2968998,12.1484003-19.2187996,9.2578096-16.3281002z M10.7519999-15.9569998
|
||||
c2.4316006-1.7774,5.7226-1.4746008,7.9492006,0.7518997l2.4315987,2.4120998
|
||||
c0.2344017,0.2343998,0.2734013,0.4200001,0.205101,0.7617998l-0.3223,1.4843006L22.5195007-9.0625l0.9863987-0.0585899
|
||||
C23.7598-9.1308603,23.8379002-9.11133,24.0331993-8.9160204l0.5762005,0.5761805l-2.4414005,2.4414001l-0.5761986-0.57617
|
||||
c-0.1953011-0.1953101-0.2245998-0.2734404-0.2147999-0.5371103l0.0682983-0.9765596l-1.4940987-1.4843802L18.4277-9.21875
|
||||
c-0.3222008,0.0683603-0.4687004,0.0390596-0.7129002-0.1953096l-2.0018997-2.0019407
|
||||
c-0.2539005-0.2343998-0.2832003-0.4003992-0.1269999-0.7714996l0.8788996-2.0897999
|
||||
c-1.5625-1.4551001-3.5936995-2.080101-5.625-1.4843998C10.6836004-15.7227001,10.625-15.8495998,10.7519999-15.9569998z"/>
|
||||
</g>
|
||||
<text transform="matrix(1 0 0 1 1289 1953)" class="st2 st3">Exporting</text>
|
||||
<text transform="matrix(1 0 0 1 1289 1971)" class="st4 st3">Symbols should be outlined when exporting to ensure the</text>
|
||||
<text transform="matrix(1 0 0 1 1289 1989)" class="st4 st3">design is preserved when submitting to Xcode.</text>
|
||||
<text id="template-version" transform="matrix(1 0 0 1 2952.4140625 1933)" class="st4 st3">Template v.4.0</text>
|
||||
<text transform="matrix(1 0 0 1 2865.4575195 1951)" class="st4 st3">Requires Xcode 14 or greater</text>
|
||||
<text id="descriptive-name" transform="matrix(1 0 0 1 2826.4448242 1969)" class="st4 st3">Generated from custom.shippingbox</text>
|
||||
<text transform="matrix(1 0 0 1 2912.4111328 1987)" class="st4 st3">Typeset at 100 points</text>
|
||||
<text transform="matrix(1 0 0 1 263 726)" class="st4 st3">Small</text>
|
||||
<text transform="matrix(1 0 0 1 263 1156)" class="st4 st3">Medium</text>
|
||||
<text transform="matrix(1 0 0 1 263 1586)" class="st4 st3">Large</text>
|
||||
</g>
|
||||
<g id="Guides">
|
||||
<g id="H-reference" transform="matrix(1 0 0 1 339 696)">
|
||||
<path class="st6" d="M0.993654,0h2.6440959l25.6903496-67.1323013h0.7021999v-3.3266983h-1.9076996L0.993654,0z
|
||||
M11.6885004-24.4799004h35.2929993l-0.75-2.2486H12.4385004L11.6885004-24.4799004z M55.1195984,0h2.6441002
|
||||
L30.6382008-70.4589996H29.4326v3.3266983L55.1195984,0z"/>
|
||||
</g>
|
||||
<line id="Baseline-S" class="st7" x1="263" y1="696" x2="3036" y2="696"/>
|
||||
<line id="Capline-S" class="st7" x1="263" y1="625.5410156" x2="3036" y2="625.5410156"/>
|
||||
<g id="H-reference_1_" transform="matrix(1 0 0 1 339 1126)">
|
||||
<path class="st6" d="M0.993654,0h2.6440959l25.6903496-67.1323013h0.7021999v-3.3266983h-1.9076996L0.993654,0z
|
||||
M11.6885004-24.4799004h35.2929993l-0.75-2.2486H12.4385004L11.6885004-24.4799004z M55.1195984,0h2.6441002
|
||||
L30.6382008-70.4589996H29.4326v3.3266983L55.1195984,0z"/>
|
||||
</g>
|
||||
<line id="Baseline-M" class="st7" x1="263" y1="1126" x2="3036" y2="1126"/>
|
||||
<line id="Capline-M" class="st7" x1="263" y1="1055.5400391" x2="3036" y2="1055.5400391"/>
|
||||
<g id="H-reference_2_" transform="matrix(1 0 0 1 339 1556)">
|
||||
<path class="st6" d="M0.993654,0h2.6440959l25.6903496-67.1323013h0.7021999v-3.3266983h-1.9076996L0.993654,0z
|
||||
M11.6885004-24.4799004h35.2929993l-0.75-2.2486H12.4385004L11.6885004-24.4799004z M55.1195984,0h2.6441002
|
||||
L30.6382008-70.4589996H29.4326v3.3266983L55.1195984,0z"/>
|
||||
</g>
|
||||
<line id="Baseline-L" class="st7" x1="263" y1="1556" x2="3036" y2="1556"/>
|
||||
<line id="Capline-L" class="st7" x1="263" y1="1485.5400391" x2="3036" y2="1485.5400391"/>
|
||||
<line id="left-margin-Ultralight-S" class="st5" x1="512.4619751" y1="600.7849731" x2="512.4619751" y2="720.1209717"/>
|
||||
<line id="right-margin-Ultralight-S" class="st5" x1="606.9609985" y1="600.7849731" x2="606.9609985" y2="720.1209717"/>
|
||||
<line id="left-margin-Regular-S" class="st5" x1="1401.1899414" y1="600.7849731" x2="1401.1899414" y2="720.1209717"/>
|
||||
<line id="right-margin-Regular-S" class="st5" x1="1498.5" y1="600.7849731" x2="1498.5" y2="720.1209717"/>
|
||||
<line id="left-margin-Black-S" class="st5" x1="2883.0100098" y1="600.7849731" x2="2883.0100098" y2="720.1209717"/>
|
||||
<line id="right-margin-Black-S" class="st5" x1="2983.7900391" y1="600.7849731" x2="2983.7900391" y2="720.1209717"/>
|
||||
</g>
|
||||
<g id="Symbols">
|
||||
<g id="Black-S">
|
||||
<path d="M2898.9768066,686.625l31.2011719,16.1621094c1.8554688,0.9765625,4.5898438,0.9765625,6.4453125,0L2967.8244629,686.625
|
||||
c4.4921875-2.343811,6.2011719-5.1757812,6.2011719-10.156189v-34.1309204c0-4.5410156-1.7578125-7.6171875-6.1035156-9.8632812
|
||||
l-26.0742188-13.6229858c-5.1757812-2.734436-11.71875-2.734436-16.8945312,0l-26.0742188,13.6229858
|
||||
c-4.3457031,2.2460938-6.1035156,5.3222656-6.1035156,9.8632812v34.1309204
|
||||
C2892.7756348,681.4492188,2894.4846191,684.281189,2898.9768066,686.625z M2906.5939941,676.6641235
|
||||
c-1.5136719-0.8301392-2.0996094-1.7579346-2.0996094-3.2715454v-22.9980469l22.7539062,11.8163452v25.4883423
|
||||
L2906.5939941,676.6641235z M2962.3068848,650.3945312v22.9980469c0,1.5136108-0.5859375,2.4414062-2.0996094,3.2715454
|
||||
l-20.6542969,11.0350952v-25.4883423l4.2817383-2.2281494v1.9515991c0,3.9360962,3.1765137,7.1125488,7.1125488,7.1125488
|
||||
c3.9016113-0.0345459,7.0778809-3.1419067,7.0778809-7.0779419v-9.3511353L2962.3068848,650.3945312z M2933.4006348,651.5175781
|
||||
l-22.1679688-11.5722656l5.0292969-2.5878906l22.3144531,11.4746094L2933.4006348,651.5175781z M2951.1252441,642.2401733
|
||||
l-22.0703125-11.5722046l1.3671875-0.6835938c1.9042969-0.9765625,4.0039062-0.9765625,5.9570312,0l19.1894531,9.9609375
|
||||
L2951.1252441,642.2401733z"/>
|
||||
</g>
|
||||
<g id="Regular-S">
|
||||
<path d="M1406.8195801,684.4480591l29.7851562,17.0410767c2.2949219,1.3183594,4.3945312,1.3183594,6.640625,0
|
||||
l29.7851562-17.0410767c3.7109375-2.1483765,5.8105469-4.1991577,5.8105469-10.3026733v-29.4921875
|
||||
c0-4.4434204-1.6113281-7.1777344-5.2246094-9.3262329l-26.1230469-14.9901733
|
||||
c-5.1269531-2.8809204-9.9609375-2.8809204-15.0878906,0l-26.1230469,14.9901733
|
||||
c-3.6621094,2.1484985-5.2246094,4.8828125-5.2246094,9.3262329v29.4921875
|
||||
C1401.0578613,680.2489014,1403.1574707,682.2996826,1406.8195801,684.4480591z M1410.5793457,678.6375732
|
||||
c-2.0996094-1.2695923-2.9296875-2.5390625-2.9296875-4.6875v-27.9296875l28.8574219,16.6992188v30.859375
|
||||
L1410.5793457,678.6375732z M1472.2492676,646.0203857v27.9296875c0,2.1484375-0.8789062,3.4179077-2.9296875,4.6875
|
||||
l-25.9277344,14.9414062v-30.859375l10.9072266-6.3255615v9.8839111c0,1.9334717,1.5882568,3.5217285,3.5217285,3.5217285
|
||||
s3.5217285-1.5882568,3.5217285-3.5217285l-0.0345459-13.9328613L1472.2492676,646.0203857z M1439.9250488,656.6160889
|
||||
l-28.4179688-16.2598267l10.8398438-6.2987671l28.3691406,16.3573608L1439.9250488,656.6160889z M1457.7473145,646.4110107
|
||||
l-28.5644531-16.2598267l5.9571533-3.4179077c3.3201904-1.9042969,6.2987061-1.953064,9.5701904,0l23.6816406,13.6229858
|
||||
L1457.7473145,646.4110107z"/>
|
||||
</g>
|
||||
<g id="Ultralight-S">
|
||||
<path d="M525.7642822,682.3652954l31.465271,17.1317749c1.6592407,0.8643188,3.2139282,0.909729,4.9604492,0
|
||||
l31.4653931-17.1317749c2.6210938-1.4672852,3.539978-3.0640259,3.539978-5.9434204v-33.8515625
|
||||
c0-1.6733398-0.9755859-2.8184204-2.4091797-3.6499023l-31.2089233-17.2607422
|
||||
c-2.4478149-1.3823853-5.2838135-1.3823853-7.7315063,0l-31.2089844,17.2607422
|
||||
c-1.4370117,0.8314819-2.4091797,1.9765625-2.4091797,3.6499023v33.8515625
|
||||
C522.2276001,679.3012695,523.1011963,680.8980103,525.7642822,682.3652954z M527.6621704,680.9141235
|
||||
c-2.6898804-1.4512329-3.065918-2.4937134-3.065918-4.6875v-33.015625l33.9432983,18.4248047v35.8998413L527.6621704,680.9141235z
|
||||
M578.9451904,651.8189087l15.8814697-8.6079102v33.015625c0,2.1937866-0.3793945,3.2362671-3.065918,4.6875
|
||||
l-30.9227905,16.621521v-35.8998413l15.8883667-8.6142578l-0.0074463,15.2365112
|
||||
c0.0320435,0.6169434,0.5285645,1.0493164,1.0813599,1.0812988c0.6491089,0,1.1455688-0.4963379,1.1455688-1.1455078
|
||||
L578.9451904,651.8189087z M559.6870728,659.7098999l-34.4575195-18.6663818l16.3799438-9.0234985l34.6356812,18.71875
|
||||
L559.6870728,659.7098999z M578.553772,649.5048828l-34.6494141-18.7572632l13.5405273-7.4595337
|
||||
c1.4584961-0.8598633,3.074707-0.8632812,4.5297852,0l32.1732788,17.7554321L578.553772,649.5048828z"/>
|
||||
</g>
|
||||
</g>
|
||||
<path d="M2282.9038086,649.5722046"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 16 KiB |
@@ -1,6 +1,6 @@
|
||||
import SwiftUI
|
||||
|
||||
public func NavigationStackCompat<T>(@ViewBuilder content: () -> T) -> some View where T: View{
|
||||
public func NavigationStackCompat(@ViewBuilder content: () -> some View) -> some View {
|
||||
viewBuilder {
|
||||
if #available(iOS 17.0, *) {
|
||||
// view not updating in iOS 16, but why?
|
||||
|
||||
@@ -4,82 +4,53 @@ import Library
|
||||
import SwiftUI
|
||||
|
||||
public struct ActiveDashboardView: View {
|
||||
public static let NotificationUpdateSelectedProfile = Notification.Name("update-selected-profile")
|
||||
|
||||
@Environment(\.scenePhase) var scenePhase
|
||||
@Environment(\.selection) private var selection
|
||||
|
||||
@Environment(\.selection) private var parentSelection
|
||||
@EnvironmentObject private var profile: ExtensionProfile
|
||||
|
||||
@State private var isLoading = true
|
||||
@State private var profileList: [Profile] = []
|
||||
@State private var selectedProfileID: Int64!
|
||||
@State private var reasserting = false
|
||||
@State private var observer: Any?
|
||||
@State private var alert: Alert?
|
||||
@State private var selection = DashboardPage.overview
|
||||
|
||||
public init() {}
|
||||
|
||||
public var body: some View {
|
||||
viewBuilder {
|
||||
if isLoading {
|
||||
ProgressView().onAppear {
|
||||
Task.detached {
|
||||
await doReload()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if profileList.isEmpty {
|
||||
Text("Empty profiles")
|
||||
} else {
|
||||
VStack {
|
||||
#if os(iOS) || os(tvOS)
|
||||
if ApplicationLibrary.inPreview || profile.status.isConnected {
|
||||
ExtensionStatusView()
|
||||
.listStyle(.automatic)
|
||||
#if os(iOS)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
#endif
|
||||
}
|
||||
FormView {
|
||||
StartStopButton()
|
||||
Section("Profile") {
|
||||
Picker(selection: $selectedProfileID) {
|
||||
ForEach(profileList, id: \.id) { profile in
|
||||
Text(profile.name).tag(profile.id)
|
||||
}
|
||||
} label: {}
|
||||
.pickerStyle(.inline)
|
||||
}
|
||||
}
|
||||
#elseif os(macOS)
|
||||
if ApplicationLibrary.inPreview || profile.status.isConnected {
|
||||
ExtensionStatusView()
|
||||
}
|
||||
FormView {
|
||||
Section("Profile") {
|
||||
ForEach(profileList, id: \.id) { profile in
|
||||
Picker(profile.name, selection: $selectedProfileID) {
|
||||
Text("").tag(profile.id)
|
||||
}
|
||||
}
|
||||
.pickerStyle(.radioGroup)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
.onChangeCompat(of: selectedProfileID) {
|
||||
reasserting = true
|
||||
Task.detached {
|
||||
await switchProfile(selectedProfileID!)
|
||||
}
|
||||
}
|
||||
.disabled(!ApplicationLibrary.inPreview && (!profile.status.isSwitchable || reasserting))
|
||||
if isLoading {
|
||||
ProgressView().onAppear {
|
||||
Task.detached {
|
||||
await doReload()
|
||||
}
|
||||
}
|
||||
}
|
||||
.alertBinding($alert)
|
||||
#if os(iOS) || os(tvOS)
|
||||
} else {
|
||||
viewBuilder {
|
||||
#if os(iOS) || os(tvOS)
|
||||
if ApplicationLibrary.inPreview || profile.status.isConnectedStrict {
|
||||
Picker("Page", selection: $selection) {
|
||||
ForEach(DashboardPage.allCases) { page in
|
||||
page.label
|
||||
}
|
||||
}
|
||||
.pickerStyle(.segmented)
|
||||
#if os(iOS)
|
||||
|
||||
.padding([.leading, .trailing])
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
#endif
|
||||
TabView(selection: $selection) {
|
||||
ForEach(DashboardPage.allCases) { page in
|
||||
page.contentView($profileList, $selectedProfileID)
|
||||
.tag(page)
|
||||
}
|
||||
}
|
||||
.tabViewStyle(.page(indexDisplayMode: .always))
|
||||
} else {
|
||||
OverviewView($profileList, $selectedProfileID)
|
||||
}
|
||||
#elseif os(macOS)
|
||||
OverviewView($profileList, $selectedProfileID)
|
||||
#endif
|
||||
}
|
||||
#if os(iOS) || os(tvOS)
|
||||
.onChangeCompat(of: scenePhase) { newValue in
|
||||
if newValue == .active {
|
||||
Task.detached {
|
||||
@@ -87,29 +58,16 @@ public struct ActiveDashboardView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChangeCompat(of: selection.wrappedValue) { newValue in
|
||||
.onChangeCompat(of: parentSelection.wrappedValue) { newValue in
|
||||
if newValue == .dashboard {
|
||||
Task.detached {
|
||||
await doReload()
|
||||
}
|
||||
}
|
||||
}
|
||||
#elseif os(macOS)
|
||||
.onAppear {
|
||||
if observer == nil {
|
||||
observer = NotificationCenter.default.addObserver(forName: ActiveDashboardView.NotificationUpdateSelectedProfile, object: nil, queue: nil, using: { _ in
|
||||
Task.detached {
|
||||
await doReload()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
.onDisappear {
|
||||
if let observer {
|
||||
NotificationCenter.default.removeObserver(observer)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
.alertBinding($alert)
|
||||
}
|
||||
}
|
||||
|
||||
private func doReload() {
|
||||
@@ -143,28 +101,4 @@ public struct ActiveDashboardView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func switchProfile(_ newProfileID: Int64) {
|
||||
SharedPreferences.selectedProfileID = newProfileID
|
||||
NotificationCenter.default.post(name: ActiveDashboardView.NotificationUpdateSelectedProfile, object: nil)
|
||||
if profile.status.isConnected {
|
||||
do {
|
||||
try LibboxNewStandaloneCommandClient()!.serviceReload()
|
||||
} catch {
|
||||
alert = Alert(error)
|
||||
}
|
||||
}
|
||||
reasserting = false
|
||||
}
|
||||
|
||||
private struct ServiceErrorReporter: View {
|
||||
private let parent: ActiveDashboardView
|
||||
init(_ parent: ActiveDashboardView) {
|
||||
self.parent = parent
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
EmptyView()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import Foundation
|
||||
import Library
|
||||
import SwiftUI
|
||||
|
||||
public enum DashboardPage: Int, CaseIterable, Identifiable {
|
||||
public var id: Self {
|
||||
self
|
||||
}
|
||||
|
||||
case overview
|
||||
case groups
|
||||
}
|
||||
|
||||
public extension DashboardPage {
|
||||
var title: String {
|
||||
switch self {
|
||||
case .overview:
|
||||
return NSLocalizedString("Overview", comment: "")
|
||||
case .groups:
|
||||
return NSLocalizedString("Groups", comment: "")
|
||||
}
|
||||
}
|
||||
|
||||
var label: some View {
|
||||
switch self {
|
||||
case .overview:
|
||||
return Label("Overview", systemImage: "text.and.command.macwindow")
|
||||
case .groups:
|
||||
return Label("Groups", systemImage: "rectangle.3.group.fill")
|
||||
}
|
||||
}
|
||||
|
||||
func contentView(_ profileList: Binding<[Profile]>, _ selectedProfileID: Binding<Int64?>) -> some View {
|
||||
viewBuilder {
|
||||
switch self {
|
||||
case .overview:
|
||||
OverviewView(profileList, selectedProfileID)
|
||||
case .groups:
|
||||
GroupListView()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,6 @@ public struct DashboardView: View {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
.navigationTitle("Dashboard")
|
||||
}
|
||||
|
||||
#if os(macOS)
|
||||
|
||||
@@ -18,28 +18,50 @@ public struct ExtensionStatusView: View {
|
||||
VStack {
|
||||
LazyVGrid(columns: Array(repeating: GridItem(.flexible()), count: columnCount), alignment: .leading) {
|
||||
if ApplicationLibrary.inPreview {
|
||||
StatusItem("Memory", "6.4 MiB")
|
||||
StatusItem("Goroutines", "89")
|
||||
StatusItem("Inbound Connections", "34")
|
||||
StatusItem("Outbound Connections", "28")
|
||||
StatusItem("Uplink", "38 B/s")
|
||||
StatusItem("Downlink", "249 MiB/s")
|
||||
StatusItem("Uplink Total", "52 MiB")
|
||||
StatusItem("Downlink Total", "5.6 GiB")
|
||||
StatusItem("Status") {
|
||||
StatusLine("Memory", "6.4 MiB")
|
||||
StatusLine("Goroutines", "89")
|
||||
}
|
||||
StatusItem("Connections") {
|
||||
StatusLine("Inbound", "34")
|
||||
StatusLine("Outbound", "28")
|
||||
}
|
||||
StatusItem("Traffic") {
|
||||
StatusLine("Uplink", "38 B/s")
|
||||
StatusLine("Downlink", "249 MiB/s")
|
||||
}
|
||||
StatusItem("TrafficTotal") {
|
||||
StatusLine("Uplink", "52 MiB")
|
||||
StatusLine("Downlink", "5.6 GiB")
|
||||
}
|
||||
} else if let message {
|
||||
StatusItem("Memory", LibboxFormatBytes(message.memory))
|
||||
StatusItem("Goroutines", "\(message.goroutines)")
|
||||
StatusItem("Status") {
|
||||
StatusLine("Memory", LibboxFormatBytes(message.memory))
|
||||
StatusLine("Goroutines", "\(message.goroutines)")
|
||||
}
|
||||
StatusItem("Connections") {
|
||||
StatusLine("Inbound", "\(message.connectionsIn)")
|
||||
StatusLine("Outbound", "\(message.connectionsOut)")
|
||||
}
|
||||
if message.trafficAvailable {
|
||||
StatusItem("Inbound Connections", "\(message.connectionsIn)")
|
||||
StatusItem("Outbound Connections", "\(message.connectionsOut)")
|
||||
StatusItem("Uplink", LibboxFormatBytes(message.uplink) + "/s")
|
||||
StatusItem("Downlink", LibboxFormatBytes(message.downlink) + "/s")
|
||||
StatusItem("Uplink Total", LibboxFormatBytes(message.uplinkTotal))
|
||||
StatusItem("Downlink Total", LibboxFormatBytes(message.downlinkTotal))
|
||||
StatusItem("Traffic") {
|
||||
StatusLine("Uplink", "\(LibboxFormatBytes(message.uplink))/s")
|
||||
StatusLine("Downlink", "\(LibboxFormatBytes(message.downlink))/s")
|
||||
}
|
||||
StatusItem("TrafficTotal") {
|
||||
StatusLine("Uplink", LibboxFormatBytes(message.uplinkTotal))
|
||||
StatusLine("Downlink", LibboxFormatBytes(message.downlinkTotal))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
StatusItem("Memory", "Loading...")
|
||||
StatusItem("Goroutines", "Loading...")
|
||||
StatusItem("Status") {
|
||||
StatusLine("Memory", "...")
|
||||
StatusLine("Goroutines", "...")
|
||||
}
|
||||
StatusItem("Connections") {
|
||||
StatusLine("Inbound", "...")
|
||||
StatusLine("Outbound", "...")
|
||||
}
|
||||
}
|
||||
}.background {
|
||||
GeometryReader { geometry in
|
||||
@@ -142,26 +164,25 @@ public struct ExtensionStatusView: View {
|
||||
func writeGroups(_: LibboxOutboundGroupIteratorProtocol?) {}
|
||||
}
|
||||
|
||||
private struct StatusItem: View {
|
||||
private let name: String
|
||||
private let value: String
|
||||
init(_ name: String, _ value: String) {
|
||||
self.name = name
|
||||
self.value = value
|
||||
private struct StatusItem<T>: View where T: View {
|
||||
private let title: String
|
||||
@ViewBuilder private let content: () -> T
|
||||
|
||||
init(_ title: String, @ViewBuilder content: @escaping () -> T) {
|
||||
self.title = title
|
||||
self.content = content
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
VStack(alignment: .leading) {
|
||||
HStack {
|
||||
Text(name)
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.secondary)
|
||||
Text(title)
|
||||
.font(.headline)
|
||||
Spacer()
|
||||
}
|
||||
Text(value)
|
||||
.font(.system(size: 16))
|
||||
}.padding(.bottom, 8)
|
||||
content()
|
||||
}
|
||||
.frame(minWidth: 125)
|
||||
.frame(minWidth: 125, alignment: .topLeading)
|
||||
#if os(tvOS)
|
||||
.padding(EdgeInsets(top: 20, leading: 26, bottom: 20, trailing: 26))
|
||||
#else
|
||||
@@ -181,4 +202,25 @@ public struct ExtensionStatusView: View {
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
private struct StatusLine: View {
|
||||
private let name: String
|
||||
private let value: String
|
||||
|
||||
init(_ name: String, _ value: String) {
|
||||
self.name = name
|
||||
self.value = value
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
HStack {
|
||||
Text(name)
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.secondary)
|
||||
Spacer()
|
||||
Text(value)
|
||||
.font(.subheadline)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
import Foundation
|
||||
import Libbox
|
||||
import Library
|
||||
import SwiftUI
|
||||
|
||||
public struct OverviewView: View {
|
||||
public static let NotificationUpdateSelectedProfile = Notification.Name("update-selected-profile")
|
||||
|
||||
@Environment(\.scenePhase) var scenePhase
|
||||
@Environment(\.selection) private var selection
|
||||
@EnvironmentObject private var profile: ExtensionProfile
|
||||
@Binding private var profileList: [Profile]
|
||||
@Binding private var selectedProfileID: Int64!
|
||||
@State private var alert: Alert?
|
||||
@State private var reasserting = false
|
||||
@State private var observer: Any?
|
||||
|
||||
public init(_ profileList: Binding<[Profile]>, _ selectedProfileID: Binding<Int64?>) {
|
||||
_profileList = profileList
|
||||
_selectedProfileID = selectedProfileID
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
VStack {
|
||||
if ApplicationLibrary.inPreview || profile.status.isConnected {
|
||||
ExtensionStatusView()
|
||||
}
|
||||
FormView {
|
||||
#if os(iOS) || os(tvOS)
|
||||
StartStopButton()
|
||||
Section("Profile") {
|
||||
Picker(selection: $selectedProfileID) {
|
||||
ForEach(profileList, id: \.id) { profile in
|
||||
Text(profile.name).tag(profile.id)
|
||||
}
|
||||
} label: {}
|
||||
.pickerStyle(.inline)
|
||||
}
|
||||
#elseif os(macOS)
|
||||
Section("Profile") {
|
||||
ForEach(profileList, id: \.id) { profile in
|
||||
Picker(profile.name, selection: $selectedProfileID) {
|
||||
Text("").tag(profile.id)
|
||||
}
|
||||
}
|
||||
.pickerStyle(.radioGroup)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
.alertBinding($alert)
|
||||
.onChangeCompat(of: selectedProfileID) {
|
||||
reasserting = true
|
||||
Task.detached {
|
||||
await switchProfile(selectedProfileID!)
|
||||
}
|
||||
}
|
||||
.disabled(!ApplicationLibrary.inPreview && (!profile.status.isSwitchable || reasserting))
|
||||
#if os(macOS)
|
||||
.onAppear {
|
||||
if observer == nil {
|
||||
observer = NotificationCenter.default.addObserver(forName: OverviewView.NotificationUpdateSelectedProfile, object: nil, queue: nil, using: { newProfileID in
|
||||
selectedProfileID = newProfileID.object as! Int64
|
||||
})
|
||||
}
|
||||
}
|
||||
.onDisappear {
|
||||
if let observer {
|
||||
NotificationCenter.default.removeObserver(observer)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private func switchProfile(_ newProfileID: Int64) {
|
||||
SharedPreferences.selectedProfileID = newProfileID
|
||||
NotificationCenter.default.post(name: OverviewView.NotificationUpdateSelectedProfile, object: newProfileID)
|
||||
if profile.status.isConnected {
|
||||
do {
|
||||
try LibboxNewStandaloneCommandClient()!.serviceReload()
|
||||
} catch {
|
||||
alert = Alert(error)
|
||||
}
|
||||
}
|
||||
reasserting = false
|
||||
}
|
||||
}
|
||||
@@ -17,48 +17,54 @@ public struct GroupItemView: View {
|
||||
@State private var alert: Alert?
|
||||
|
||||
public var body: some View {
|
||||
HStack {
|
||||
if group.selected == item.tag {
|
||||
Rectangle()
|
||||
.fill(Color.accentColor)
|
||||
.frame(width: 6)
|
||||
} else {
|
||||
Rectangle()
|
||||
.fill(.clear)
|
||||
.frame(width: 6)
|
||||
}
|
||||
VStack {
|
||||
HStack {
|
||||
Text(item.tag)
|
||||
.truncationMode(.tail)
|
||||
.lineLimit(1)
|
||||
.font(.system(size: 14))
|
||||
Spacer(minLength: 6)
|
||||
}
|
||||
Spacer(minLength: 6)
|
||||
HStack(alignment: .center) {
|
||||
Text(item.type)
|
||||
.foregroundColor(.secondary)
|
||||
.font(.system(size: 12))
|
||||
Spacer(minLength: 6)
|
||||
if item.urlTestDelay > 0 {
|
||||
Text(item.delayString)
|
||||
.foregroundColor(item.delayColor)
|
||||
.font(.system(size: 11))
|
||||
}
|
||||
}
|
||||
}
|
||||
.frame(height: 36)
|
||||
.padding([.top, .bottom, .trailing], 12)
|
||||
}
|
||||
.background(backgroundColor)
|
||||
.onTapGesture {
|
||||
Button(action: {
|
||||
if group.selectable, group.selected != item.tag {
|
||||
Task.detached {
|
||||
selectOutbound()
|
||||
}
|
||||
}
|
||||
}
|
||||
}, label: {
|
||||
HStack {
|
||||
VStack {
|
||||
HStack {
|
||||
Text(item.tag)
|
||||
.font(.caption)
|
||||
.foregroundStyle(.foreground)
|
||||
.lineLimit(1)
|
||||
.truncationMode(.tail)
|
||||
Spacer(minLength: 0)
|
||||
|
||||
}
|
||||
Spacer(minLength: 8)
|
||||
HStack {
|
||||
Text(item.type)
|
||||
.font(.caption)
|
||||
.foregroundColor(.secondary)
|
||||
Spacer(minLength: 0)
|
||||
|
||||
}
|
||||
}
|
||||
Spacer(minLength: 0)
|
||||
VStack {
|
||||
if group.selected == item.tag {
|
||||
Image(systemName: "checkmark.circle.fill")
|
||||
.foregroundStyle(Color.accentColor)
|
||||
}
|
||||
Spacer(minLength: 0)
|
||||
if item.urlTestDelay > 0 {
|
||||
Text(item.delayString)
|
||||
.font(.caption)
|
||||
.foregroundColor(item.delayColor)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
#if !os(tvOS)
|
||||
.buttonStyle(.borderless)
|
||||
.padding(EdgeInsets(top: 10, leading: 13, bottom: 10, trailing: 13))
|
||||
.background(backgroundColor)
|
||||
.cornerRadius(10)
|
||||
#endif
|
||||
.alertBinding($alert)
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ public struct GroupListView: View {
|
||||
}, set: { newValue in
|
||||
groupExpand[it.tag] = newValue
|
||||
}))
|
||||
Spacer()
|
||||
}
|
||||
}.padding()
|
||||
}
|
||||
@@ -40,7 +39,6 @@ public struct GroupListView: View {
|
||||
}
|
||||
commandClient = nil
|
||||
}
|
||||
.navigationTitle("Groups")
|
||||
}
|
||||
|
||||
private func doReload() {
|
||||
@@ -51,7 +49,7 @@ public struct GroupListView: View {
|
||||
OutboundGroupItem(tag: "server2", type: "WireGuard", urlTestTime: .now, urlTestDelay: 34),
|
||||
OutboundGroupItem(tag: "auto", type: "URLTest", urlTestTime: .now, urlTestDelay: 100),
|
||||
]),
|
||||
OutboundGroup(tag: "group2", type: "urltest", selected: "client", selectable: false, items:
|
||||
OutboundGroup(tag: "group2", type: "urltest", selected: "client", selectable: true, items:
|
||||
(0 ..< 234).map { index in
|
||||
OutboundGroupItem(tag: "client\(index)", type: "Shadowsocks", urlTestTime: .now, urlTestDelay: UInt16(100 + index * 10))
|
||||
}),
|
||||
|
||||
@@ -15,12 +15,12 @@ public struct GroupView: View {
|
||||
private var title: some View {
|
||||
HStack {
|
||||
Text(group.tag)
|
||||
.font(.system(size: 17))
|
||||
.font(.headline)
|
||||
Text(group.displayType)
|
||||
.font(.system(size: 13))
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.secondary)
|
||||
Text("\(group.items.count)")
|
||||
.font(.system(size: 11))
|
||||
.font(.subheadline)
|
||||
.padding(EdgeInsets(top: 2, leading: 4, bottom: 2, trailing: 4))
|
||||
.background(Color.gray.opacity(0.5))
|
||||
.cornerRadius(4)
|
||||
@@ -33,7 +33,7 @@ public struct GroupView: View {
|
||||
Image(systemName: "arrow.up.to.line")
|
||||
}
|
||||
}
|
||||
#if os(macOS)
|
||||
#if os(macOS) || os(tvOS)
|
||||
.buttonStyle(.plain)
|
||||
#endif
|
||||
Button {
|
||||
@@ -43,11 +43,10 @@ public struct GroupView: View {
|
||||
} label: {
|
||||
Image(systemName: "bolt.fill")
|
||||
}
|
||||
#if os(macOS)
|
||||
#if os(macOS) || os(tvOS)
|
||||
.buttonStyle(.plain)
|
||||
#endif
|
||||
Spacer(minLength: 6)
|
||||
}
|
||||
}.padding([.top, .bottom], 8)
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
@@ -61,13 +60,17 @@ public struct GroupView: View {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
VStack {
|
||||
VStack(spacing: 5) {
|
||||
ForEach(Array(itemGroups.enumerated()), id: \.offset) { items in
|
||||
HStack {
|
||||
HStack(spacing: 5) {
|
||||
ForEach(items.element, id: \.tag) { it in
|
||||
Rectangle()
|
||||
.fill(it.delayColor)
|
||||
#if !os(tvOS)
|
||||
.frame(width: 10, height: 10)
|
||||
#else
|
||||
.frame(width: 30, height: 30)
|
||||
#endif
|
||||
}
|
||||
}.frame(maxWidth: .infinity, alignment: .topLeading)
|
||||
}
|
||||
@@ -93,7 +96,12 @@ public struct GroupView: View {
|
||||
}
|
||||
|
||||
private var itemGroups: [[OutboundGroupItem]] {
|
||||
let count = Int(Int(geometryWidth) / 20)
|
||||
let count: Int
|
||||
#if os(tvOS)
|
||||
count = Int(Int(geometryWidth) / 40)
|
||||
#else
|
||||
count = Int(Int(geometryWidth) / 20)
|
||||
#endif
|
||||
if count == 0 {
|
||||
return [group.items]
|
||||
} else {
|
||||
@@ -104,11 +112,13 @@ public struct GroupView: View {
|
||||
}
|
||||
|
||||
private func explandColumnCount() -> Int {
|
||||
let count = Int(Int(geometryWidth) / 180)
|
||||
let standardCount = Int(Int(geometryWidth) / 180)
|
||||
#if os(iOS)
|
||||
return count < 2 ? 2 : count
|
||||
return standardCount < 2 ? 2 : standardCount
|
||||
#elseif os(tvOS)
|
||||
return Int(Int(geometryWidth) / 400)
|
||||
#else
|
||||
return count < 1 ? 1 : count
|
||||
return standardCount < 1 ? 1 : standardCount
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ public struct LogView: View {
|
||||
Text("Service not started")
|
||||
}
|
||||
}
|
||||
.navigationTitle("Logs")
|
||||
}
|
||||
|
||||
private struct LogView0: View {
|
||||
@@ -43,7 +42,7 @@ public struct LogView: View {
|
||||
#if os(tvOS)
|
||||
.focusable()
|
||||
#endif
|
||||
Spacer(minLength: 5)
|
||||
Spacer(minLength: 8)
|
||||
}
|
||||
|
||||
.onChangeCompat(of: logClient.logList.count) { newCount in
|
||||
|
||||
@@ -8,13 +8,19 @@ public enum NavigationPage: Int, CaseIterable, Identifiable {
|
||||
}
|
||||
|
||||
case dashboard
|
||||
case groups
|
||||
#if os(macOS)
|
||||
case groups
|
||||
#endif
|
||||
case logs
|
||||
case profiles
|
||||
case settings
|
||||
}
|
||||
|
||||
public extension NavigationPage {
|
||||
static var macosDefaultPages: [NavigationPage] {
|
||||
[.logs, .profiles, .settings]
|
||||
}
|
||||
|
||||
var label: some View {
|
||||
Label(title, systemImage: iconImage)
|
||||
}
|
||||
@@ -23,8 +29,10 @@ public extension NavigationPage {
|
||||
switch self {
|
||||
case .dashboard:
|
||||
return NSLocalizedString("Dashboard", comment: "")
|
||||
case .groups:
|
||||
return NSLocalizedString("Groups", comment: "")
|
||||
#if os(macOS)
|
||||
case .groups:
|
||||
return NSLocalizedString("Groups", comment: "")
|
||||
#endif
|
||||
case .logs:
|
||||
return NSLocalizedString("Logs", comment: "")
|
||||
case .profiles:
|
||||
@@ -38,8 +46,10 @@ public extension NavigationPage {
|
||||
switch self {
|
||||
case .dashboard:
|
||||
return "text.and.command.macwindow"
|
||||
case .groups:
|
||||
return "rectangle.3.group.fill"
|
||||
#if os(macOS)
|
||||
case .groups:
|
||||
return "rectangle.3.group.fill"
|
||||
#endif
|
||||
case .logs:
|
||||
return "doc.text.fill"
|
||||
case .profiles:
|
||||
@@ -54,9 +64,10 @@ public extension NavigationPage {
|
||||
switch self {
|
||||
case .dashboard:
|
||||
DashboardView()
|
||||
|
||||
case .groups:
|
||||
GroupListView()
|
||||
#if os(macOS)
|
||||
case .groups:
|
||||
GroupListView()
|
||||
#endif
|
||||
case .logs:
|
||||
LogView()
|
||||
case .profiles:
|
||||
@@ -70,20 +81,14 @@ public extension NavigationPage {
|
||||
#endif
|
||||
}
|
||||
|
||||
func visible(_ profile: ExtensionProfile?) -> Bool {
|
||||
switch self {
|
||||
case .groups:
|
||||
#if os(tvOS)
|
||||
// TODO: fix groups ui
|
||||
return false
|
||||
#else
|
||||
if ApplicationLibrary.inPreview {
|
||||
return true
|
||||
}
|
||||
#if os(macOS)
|
||||
func visible(_ profile: ExtensionProfile?) -> Bool {
|
||||
switch self {
|
||||
case .groups:
|
||||
return profile?.status.isConnectedStrict == true
|
||||
#endif
|
||||
default:
|
||||
return true
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -115,7 +115,6 @@ public struct ProfileView: View {
|
||||
}
|
||||
}
|
||||
.disabled(isUpdating)
|
||||
.navigationTitle("Profiles")
|
||||
.alertBinding($alert, $isLoading)
|
||||
.onAppear {
|
||||
if let profile = importProfile.wrappedValue {
|
||||
|
||||
@@ -129,7 +129,6 @@ public struct SettingView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationTitle("Settings")
|
||||
.alertBinding($alert)
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ public struct MacApplication: Scene {
|
||||
MenuBarExtra(isInserted: $showMenuBarExtra) {
|
||||
MenuView(isMenuPresented: $isMenuPresented)
|
||||
} label: {
|
||||
Image(systemName: "network.badge.shield.half.filled")
|
||||
Image("MenuIcon")
|
||||
}
|
||||
.menuBarExtraStyle(.window)
|
||||
.menuBarExtraAccess(isPresented: $isMenuPresented)
|
||||
|
||||
@@ -17,11 +17,7 @@ public struct MainView: View {
|
||||
public init() {}
|
||||
public var body: some View {
|
||||
NavigationSplitView {
|
||||
VStack {
|
||||
SidebarView()
|
||||
}
|
||||
|
||||
.frame(minWidth: 150)
|
||||
SidebarView()
|
||||
} detail: {
|
||||
if profileLoading {
|
||||
ProgressView().onAppear {
|
||||
@@ -32,6 +28,7 @@ public struct MainView: View {
|
||||
}
|
||||
} else {
|
||||
selection.contentView
|
||||
.navigationTitle(selection.title)
|
||||
}
|
||||
}
|
||||
#if !DEBUG
|
||||
|
||||
@@ -149,8 +149,8 @@ public struct MenuView: View {
|
||||
}
|
||||
.onAppear {
|
||||
if observer == nil {
|
||||
observer = NotificationCenter.default.addObserver(forName: ActiveDashboardView.NotificationUpdateSelectedProfile, object: nil, queue: nil, using: { _ in
|
||||
doReload()
|
||||
observer = NotificationCenter.default.addObserver(forName: OverviewView.NotificationUpdateSelectedProfile, object: nil, queue: nil, using: { notification in
|
||||
selectedProfileID = notification.object as! Int64
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -188,7 +188,7 @@ public struct MenuView: View {
|
||||
|
||||
private func switchProfile(_ newProfileID: Int64) {
|
||||
SharedPreferences.selectedProfileID = newProfileID
|
||||
NotificationCenter.default.post(name: ActiveDashboardView.NotificationUpdateSelectedProfile, object: nil)
|
||||
NotificationCenter.default.post(name: OverviewView.NotificationUpdateSelectedProfile, object: newProfileID)
|
||||
if profile.status.isConnected {
|
||||
do {
|
||||
try LibboxNewStandaloneCommandClient()?.serviceReload()
|
||||
|
||||
@@ -8,13 +8,13 @@ public struct SidebarView: View {
|
||||
|
||||
public init() {}
|
||||
public var body: some View {
|
||||
viewBuilder {
|
||||
VStack {
|
||||
if let profile = extensionProfile.wrappedValue {
|
||||
SidebarView0().environmentObject(profile)
|
||||
} else {
|
||||
SidebarView1()
|
||||
}
|
||||
}
|
||||
}.frame(minWidth: 150)
|
||||
}
|
||||
|
||||
struct SidebarView0: View {
|
||||
@@ -22,11 +22,27 @@ public struct SidebarView: View {
|
||||
@EnvironmentObject private var extensionProfile: ExtensionProfile
|
||||
|
||||
var body: some View {
|
||||
List(NavigationPage.allCases.filter { it in
|
||||
it.visible(extensionProfile)
|
||||
}, selection: selection) { it in
|
||||
it.label
|
||||
}.onChangeCompat(of: extensionProfile.status) {
|
||||
VStack {
|
||||
if extensionProfile.status.isConnectedStrict {
|
||||
List(selection: selection) {
|
||||
Section(NavigationPage.dashboard.title) {
|
||||
Label("Overview", systemImage: "text.and.command.macwindow").tag(NavigationPage.dashboard)
|
||||
NavigationPage.groups.label.tag(NavigationPage.groups)
|
||||
}
|
||||
Divider()
|
||||
ForEach(NavigationPage.macosDefaultPages, id: \.self) { it in
|
||||
it.label
|
||||
}
|
||||
}
|
||||
} else {
|
||||
List(NavigationPage.allCases.filter { it in
|
||||
it.visible(extensionProfile)
|
||||
}, selection: selection) { it in
|
||||
it.label
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChangeCompat(of: extensionProfile.status) {
|
||||
if !selection.wrappedValue.visible(extensionProfile) {
|
||||
selection.wrappedValue = NavigationPage.dashboard
|
||||
}
|
||||
|
||||
+10
-1
@@ -24,7 +24,16 @@ struct MainView: View {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ContentView()
|
||||
TabView(selection: $selection) {
|
||||
ForEach(NavigationPage.allCases, id: \.self) { page in
|
||||
NavigationStackCompat {
|
||||
page.contentView
|
||||
.navigationTitle(page.title)
|
||||
}
|
||||
.tag(page)
|
||||
.tabItem { page.label }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.alertBinding($alert)
|
||||
|
||||
+11
-1
@@ -22,7 +22,17 @@ struct MainView: View {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ContentView()
|
||||
TabView(selection: $selection) {
|
||||
ForEach(NavigationPage.allCases, id: \.self) { page in
|
||||
NavigationStackCompat {
|
||||
page.contentView
|
||||
.navigationTitle(page.title)
|
||||
.focusSection()
|
||||
}
|
||||
.tag(page)
|
||||
.tabItem { page.label }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChangeCompat(of: scenePhase) { newValue in
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
/* Begin PBXBuildFile section */
|
||||
3A017F922A4AB2E4009149FA /* GRDB in Frameworks */ = {isa = PBXBuildFile; productRef = 3A017F912A4AB2E4009149FA /* GRDB */; };
|
||||
3A096F8F2A4ED3DE00D4A2ED /* Extension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 3A096F862A4ED3DE00D4A2ED /* Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
3A0C6D3C2A79D46500A4DF2B /* OverviewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A0C6D3B2A79D46500A4DF2B /* OverviewView.swift */; };
|
||||
3A0C6D3E2A79D6A600A4DF2B /* DashboardPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A0C6D3D2A79D6A600A4DF2B /* DashboardPage.swift */; };
|
||||
3A1CF2F02A50E5EE000A8289 /* GroupListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A1CF2EF2A50E5EE000A8289 /* GroupListView.swift */; };
|
||||
3A1CF2F22A50E613000A8289 /* OutboundGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A1CF2F12A50E613000A8289 /* OutboundGroup.swift */; };
|
||||
3A1CF2F62A50EE9C000A8289 /* GroupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A1CF2F52A50EE9C000A8289 /* GroupView.swift */; };
|
||||
@@ -72,7 +74,6 @@
|
||||
3A7E90352A46756300D53052 /* SharedPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A7E90342A46756300D53052 /* SharedPreferences.swift */; };
|
||||
3A7E90382A46778E00D53052 /* BinaryCodable in Frameworks */ = {isa = PBXBuildFile; productRef = 3A7E90372A46778E00D53052 /* BinaryCodable */; };
|
||||
3A8655142A4FA26600B7181F /* IntentsExtension.appex in Embed ExtensionKit Extensions */ = {isa = PBXBuildFile; fileRef = 3A77016D2A4E6B34008F031F /* IntentsExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
3A9108E42A511AE70088B196 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A9108E32A511AE70088B196 /* ContentView.swift */; };
|
||||
3A9144D92A46AE370036E9AD /* ShadredPreferences+Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A9144D82A46AE370036E9AD /* ShadredPreferences+Database.swift */; };
|
||||
3A9759202A4EB69C00E4404B /* Library.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AEC211D2A459B4700A63465 /* Library.framework */; };
|
||||
3A9759212A4EB69C00E4404B /* Library.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3AEC211D2A459B4700A63465 /* Library.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
@@ -81,7 +82,6 @@
|
||||
3A99B42E2A752ABB0010D4B0 /* NavigationDestinationCompat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A99B42D2A752ABB0010D4B0 /* NavigationDestinationCompat.swift */; };
|
||||
3AB1220B2A70FD500087CD55 /* Alert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AB1220A2A70FD500087CD55 /* Alert.swift */; };
|
||||
3AC03B992A72BF3300B7946F /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AC03B982A72BF3300B7946F /* Application.swift */; };
|
||||
3AC03B9B2A72BF3300B7946F /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AC03B9A2A72BF3300B7946F /* ContentView.swift */; };
|
||||
3AC03B9D2A72BF3500B7946F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3AC03B9C2A72BF3500B7946F /* Assets.xcassets */; };
|
||||
3AC194492A50013F00BD8CB9 /* IntentsExtension.appex in Embed ExtensionKit Extensions */ = {isa = PBXBuildFile; fileRef = 3A77016D2A4E6B34008F031F /* IntentsExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
3AC1944F2A50247300BD8CB9 /* ApplicationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AC1944E2A50247300BD8CB9 /* ApplicationDelegate.swift */; };
|
||||
@@ -413,6 +413,8 @@
|
||||
3A096F892A4ED3DE00D4A2ED /* ExtensionProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionProvider.swift; sourceTree = "<group>"; };
|
||||
3A096F8B2A4ED3DE00D4A2ED /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
3A096F8C2A4ED3DE00D4A2ED /* Extension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Extension.entitlements; sourceTree = "<group>"; };
|
||||
3A0C6D3B2A79D46500A4DF2B /* OverviewView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverviewView.swift; sourceTree = "<group>"; };
|
||||
3A0C6D3D2A79D6A600A4DF2B /* DashboardPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardPage.swift; sourceTree = "<group>"; };
|
||||
3A1CF2EF2A50E5EE000A8289 /* GroupListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupListView.swift; sourceTree = "<group>"; };
|
||||
3A1CF2F12A50E613000A8289 /* OutboundGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OutboundGroup.swift; sourceTree = "<group>"; };
|
||||
3A1CF2F32A50E937000A8289 /* SidebarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarView.swift; sourceTree = "<group>"; };
|
||||
@@ -450,7 +452,6 @@
|
||||
3A7701802A4E71F5008F031F /* IntentsExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = IntentsExtension.entitlements; sourceTree = "<group>"; };
|
||||
3A7E90302A46745A00D53052 /* ViewBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewBuilder.swift; sourceTree = "<group>"; };
|
||||
3A7E90342A46756300D53052 /* SharedPreferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharedPreferences.swift; sourceTree = "<group>"; };
|
||||
3A9108E32A511AE70088B196 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
||||
3A9144D82A46AE370036E9AD /* ShadredPreferences+Database.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ShadredPreferences+Database.swift"; sourceTree = "<group>"; };
|
||||
3A99B4292A7526990010D4B0 /* NavigationStackCompat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationStackCompat.swift; sourceTree = "<group>"; };
|
||||
3A99B42B2A75288C0010D4B0 /* ViewCompat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewCompat.swift; sourceTree = "<group>"; };
|
||||
@@ -465,7 +466,6 @@
|
||||
3ABA46D22A6A32A100D8366B /* Messages.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Messages.framework; path = Library/Frameworks/Messages.framework; sourceTree = DEVELOPER_DIR; };
|
||||
3AC03B962A72BF3300B7946F /* sing-box.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "sing-box.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
3AC03B982A72BF3300B7946F /* Application.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = "<group>"; };
|
||||
3AC03B9A2A72BF3300B7946F /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
||||
3AC03B9C2A72BF3500B7946F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
3AC1944E2A50247300BD8CB9 /* ApplicationDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationDelegate.swift; sourceTree = "<group>"; };
|
||||
3AC194512A50303300BD8CB9 /* ApplicationDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationDelegate.swift; sourceTree = "<group>"; };
|
||||
@@ -707,7 +707,6 @@
|
||||
children = (
|
||||
3A4FB1642A73568E007012B9 /* SFT.entitlements */,
|
||||
3AC03B982A72BF3300B7946F /* Application.swift */,
|
||||
3AC03B9A2A72BF3300B7946F /* ContentView.swift */,
|
||||
3AC03B9C2A72BF3500B7946F /* Assets.xcassets */,
|
||||
3A4FB1652A73574B007012B9 /* Info.plist */,
|
||||
3A4FB1672A7358C9007012B9 /* ApplicationDelegate.swift */,
|
||||
@@ -783,7 +782,6 @@
|
||||
3AEC20F92A459AB500A63465 /* Assets.xcassets */,
|
||||
3A44BB812A4DC28700E4C9F8 /* MainView.swift */,
|
||||
3AC1944E2A50247300BD8CB9 /* ApplicationDelegate.swift */,
|
||||
3A9108E32A511AE70088B196 /* ContentView.swift */,
|
||||
);
|
||||
path = SFI;
|
||||
sourceTree = "<group>";
|
||||
@@ -925,6 +923,8 @@
|
||||
3AF342CC2A4AA88C002B34AC /* StartStopButton.swift */,
|
||||
3ADF8DF32A4AF9B500900CC8 /* DashboardView.swift */,
|
||||
3AE4D0C02A6E4852009FEA9E /* InstallSystemExtensionButton.swift */,
|
||||
3A0C6D3B2A79D46500A4DF2B /* OverviewView.swift */,
|
||||
3A0C6D3D2A79D6A600A4DF2B /* DashboardPage.swift */,
|
||||
);
|
||||
path = Dashboard;
|
||||
sourceTree = "<group>";
|
||||
@@ -1384,10 +1384,12 @@
|
||||
3A99B42E2A752ABB0010D4B0 /* NavigationDestinationCompat.swift in Sources */,
|
||||
3A4EAD332A4FEB7F005435B3 /* LogClient.swift in Sources */,
|
||||
3AC729F22A76088E00FE8EC1 /* ShareButton.swift in Sources */,
|
||||
3A0C6D3C2A79D46500A4DF2B /* OverviewView.swift in Sources */,
|
||||
3A4EAD262A4FEB65005435B3 /* ExtensionStatusView.swift in Sources */,
|
||||
3A4EAD252A4FEB65005435B3 /* StartStopButton.swift in Sources */,
|
||||
3A4EAD2B2A4FEB6D005435B3 /* ViewBuilder.swift in Sources */,
|
||||
3AC5EC082A6417470077AF34 /* DeviceCensorship.swift in Sources */,
|
||||
3A0C6D3E2A79D6A600A4DF2B /* DashboardPage.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -1406,7 +1408,6 @@
|
||||
files = (
|
||||
3A4FB1682A7358C9007012B9 /* ApplicationDelegate.swift in Sources */,
|
||||
3A4FB16A2A735AC9007012B9 /* MainView.swift in Sources */,
|
||||
3AC03B9B2A72BF3300B7946F /* ContentView.swift in Sources */,
|
||||
3AC03B992A72BF3300B7946F /* Application.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -1417,7 +1418,6 @@
|
||||
files = (
|
||||
3AC1944F2A50247300BD8CB9 /* ApplicationDelegate.swift in Sources */,
|
||||
3AEC20F62A459AB400A63465 /* Application.swift in Sources */,
|
||||
3A9108E42A511AE70088B196 /* ContentView.swift in Sources */,
|
||||
3A44BB822A4DC28700E4C9F8 /* MainView.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -2074,7 +2074,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.3.5;
|
||||
MARKETING_VERSION = 1.3.6;
|
||||
OTHER_CODE_SIGN_FLAGS = "--deep";
|
||||
OTHER_LDFLAGS = "-ld_classic";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa;
|
||||
@@ -2115,7 +2115,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.3.5;
|
||||
MARKETING_VERSION = 1.3.6;
|
||||
OTHER_CODE_SIGN_FLAGS = "--deep";
|
||||
OTHER_LDFLAGS = "-ld_classic";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa;
|
||||
@@ -2139,7 +2139,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 14;
|
||||
CURRENT_PROJECT_VERSION = 21;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = Z56Z6NYZN2;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
@@ -2155,7 +2155,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||
MARKETING_VERSION = 1.3.5;
|
||||
MARKETING_VERSION = 1.3.6;
|
||||
OTHER_CODE_SIGN_FLAGS = "";
|
||||
OTHER_LDFLAGS = "-ld_classic";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa;
|
||||
@@ -2178,7 +2178,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 14;
|
||||
CURRENT_PROJECT_VERSION = 21;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = Z56Z6NYZN2;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
@@ -2194,7 +2194,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||
MARKETING_VERSION = 1.3.5;
|
||||
MARKETING_VERSION = 1.3.6;
|
||||
OTHER_CODE_SIGN_FLAGS = "";
|
||||
OTHER_LDFLAGS = "-ld_classic";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<key>ApplicationLibrary.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>8</integer>
|
||||
<integer>2</integer>
|
||||
</dict>
|
||||
<key>Associations (Playground) 1.xcscheme</key>
|
||||
<dict>
|
||||
@@ -141,7 +141,7 @@
|
||||
<key>SFT.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>7</integer>
|
||||
<integer>5</integer>
|
||||
</dict>
|
||||
<key>ShareExtension.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
@@ -151,7 +151,7 @@
|
||||
<key>SystemExtension.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>5</integer>
|
||||
<integer>4</integer>
|
||||
</dict>
|
||||
<key>Test.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
|
||||
Reference in New Issue
Block a user