feat: clone repo onboarding step (#4542)

Co-authored-by: Pavel Laptev <pawellaptew@gmail.com>
This commit is contained in:
Nico Domino 2024-08-01 16:54:49 +02:00 committed by GitHub
parent 0cee9378cc
commit cda04e9b5b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
40 changed files with 761 additions and 419 deletions

View File

@ -1,35 +1,35 @@
<svg width="100%" height="100%" viewBox="0 0 400 400" fill="none" xmlns="http://www.w3.org/2000/svg">
<ellipse opacity="0.12" cx="199.59" cy="387.068" rx="132.59" ry="9.93566" fill="#475050"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M157.255 213.229C158.433 216.825 156.472 220.695 152.876 221.873C147.762 223.547 142.682 225.316 137.865 226.992C131.961 229.048 126.454 230.965 121.769 232.401C117.353 233.755 113.146 234.858 109.326 235.425C105.579 235.982 101.63 236.118 97.9947 235.048C94.0493 233.888 90.7797 231.387 88.7595 227.462C86.8963 223.843 86.3607 219.529 86.5045 214.98C86.7906 205.934 89.8998 193.153 95.6378 175.822L108.648 180.129C102.936 197.379 100.42 208.519 100.202 215.413C100.094 218.834 100.587 220.495 100.944 221.19C101.145 221.58 101.289 221.733 101.862 221.901C102.744 222.161 104.418 222.3 107.312 221.87C110.132 221.451 113.582 220.577 117.752 219.299C122.417 217.869 127.372 216.138 132.907 214.206C137.655 212.549 142.83 210.742 148.611 208.849C152.208 207.671 156.078 209.632 157.255 213.229Z" fill="#475050"/>
<path d="M204.217 386.723H203.306H102.579C106.89 364.234 143.047 339.243 171.913 339.243L195.426 226.039L206.732 227.752L219.066 230.15L235.856 339.514C257.069 339.514 295.729 354.565 303.348 386.723H204.217Z" fill="#FCFCF1"/>
<path d="M203.306 386.723H303.348C295.729 354.565 257.069 339.514 235.856 339.514L219.066 230.15L206.732 227.752M206.732 227.752L204.217 386.723H102.579C106.89 364.234 143.047 339.243 171.913 339.243L195.426 226.039L206.732 227.752Z" stroke="#475050" stroke-width="1.2"/>
<path d="M268.964 125.61C270.028 125.805 271.073 126.095 272.085 126.478L289 132.869C297.001 135.892 301.77 144.127 300.409 152.571L290.962 211.193C290.155 216.2 291.497 221.315 294.659 225.28L298.289 229.832C301.085 233.337 302.12 237.931 301.099 242.297C299.312 249.934 291.825 254.807 284.119 253.349L150.127 228.002C140.328 226.149 133.904 216.681 135.802 206.89L152.193 122.346C154.071 112.659 163.398 106.29 173.104 108.066L268.964 125.61Z" fill="#FCFCF1" stroke="#475050" stroke-width="1.2"/>
<path d="M236.809 244.2V244.2C244.784 245.703 252.441 240.375 253.805 232.375L268.918 143.733C270.543 134.203 264.35 125.092 254.891 123.096L254.012 122.91" stroke="#475050" stroke-width="1.2"/>
<rect opacity="0.13" x="162.368" y="115.594" width="100.912" height="100.863" rx="7.86364" transform="rotate(10.5121 162.368 115.594)" fill="#475050"/>
<rect opacity="0.2" width="9.9403" height="26.5802" transform="matrix(-0.985001 -0.172547 -0.172547 0.985001 200.751 186.181)" fill="#475050"/>
<rect opacity="0.7" width="9.9403" height="18.7625" transform="matrix(-0.985001 -0.172547 -0.172547 0.985001 189.611 192.167)" fill="#475050"/>
<rect opacity="0.2" width="9.9403" height="10.9448" transform="matrix(-0.985001 -0.172547 -0.172547 0.985001 178.471 198.152)" fill="#475050"/>
<rect opacity="0.4" width="9.9403" height="39.0886" transform="matrix(-0.985001 -0.172547 -0.172547 0.985001 173.536 168.715)" fill="#475050"/>
<path d="M175.298 226.469L172.46 240.879L186.539 237.685L198.092 245.876L201.192 231.779L187 233.994L175.298 226.469Z" fill="#475050"/>
<circle opacity="0.3" cx="228.968" cy="155.219" r="17.6051" fill="#475050"/>
<path d="M239.527 169.471C242.292 167.384 244.377 164.524 245.517 161.253C246.657 157.981 246.801 154.445 245.932 151.091C245.062 147.738 243.217 144.717 240.631 142.412C238.045 140.107 234.833 138.62 231.402 138.141L228.976 155.489L239.527 169.471Z" fill="#475050"/>
<path d="M213.034 183.488L233.388 186.996C235.359 187.335 236.683 189.209 236.343 191.181V191.181C236.003 193.153 234.129 194.476 232.157 194.136L215.698 191.3C213.547 190.93 211.503 192.373 211.132 194.524V194.524C210.762 196.675 212.205 198.72 214.356 199.09L230.815 201.927C232.787 202.266 234.11 204.14 233.77 206.112V206.112C233.43 208.084 231.556 209.407 229.584 209.067L212.801 206.175C210.829 205.836 208.955 207.159 208.615 209.131V209.131C208.275 211.103 209.599 212.977 211.57 213.316L231.924 216.824" stroke="#475050" stroke-width="2"/>
<rect x="211.416" y="179.957" width="7.47705" height="6.04684" transform="rotate(9.08743 211.416 179.957)" fill="#475050"/>
<rect x="226.179" y="213.342" width="7.9832" height="5.77427" transform="rotate(9.08743 226.179 213.342)" fill="#475050"/>
<rect x="216.259" y="196.758" width="5.77427" height="5.77427" transform="rotate(9.08743 216.259 196.758)" fill="#475050"/>
<path d="M170.332 131.047L203.915 137.287" stroke="#475050" stroke-width="3"/>
<path d="M169.113 137.604L188.003 141.114" stroke="#475050" stroke-width="3"/>
<path d="M166.677 150.717L176.122 152.472" stroke="#475050" stroke-width="3"/>
<path d="M167.895 144.16L196.231 149.425" stroke="#475050" stroke-width="3"/>
<path d="M89.7244 177.684C86.9436 175.28 88.8554 172.533 90.1589 171.246C88.8554 170.816 85.9587 169.529 84.9449 166.524C83.2069 161.373 85.8139 156.651 88.1898 153.217C77.7618 153.647 81.0343 135.189 86.6828 129.18C91.0171 124.569 95.8075 124.887 100.153 128.321C105.801 121.883 114.057 126.968 116.229 132.119C122.312 107.652 134.739 97.7593 139.258 100.85C143.777 103.94 132.306 129.895 126.657 141.628C131.437 142.916 134.478 146.35 134.478 151.071C134.478 162.232 124.485 172.104 116.229 173.821C117.533 175.538 117.369 177.846 115.795 179.401C111.45 183.694 93.2004 180.689 89.7244 177.684Z" fill="#FCFCF1"/>
<path d="M90.1589 171.246C88.8554 172.533 86.9436 175.28 89.7244 177.684C93.2004 180.689 111.45 183.694 115.795 179.401C117.369 177.846 117.533 175.538 116.229 173.821M90.1589 171.246C88.8554 170.816 85.9587 169.529 84.9449 166.524C83.2069 161.373 85.8139 156.651 88.1898 153.217M90.1589 171.246L96.242 172.533M116.229 173.821C124.485 172.104 134.478 162.232 134.478 151.071C134.478 146.35 131.437 142.916 126.657 141.628M116.229 173.821H110.309M126.657 141.628C132.306 129.895 143.777 103.94 139.258 100.85C134.739 97.7593 122.312 107.652 116.229 132.119C114.057 126.968 105.801 121.883 100.153 128.321M126.657 141.628C119.271 141.199 105.278 142.86 101.456 145.062C96.242 148.067 97.98 154.934 103.629 156.651C108.147 158.025 116.808 155.507 120.574 154.076C114.491 155.936 101.63 160.6 98.849 164.378M100.153 128.321C95.8075 124.887 91.0171 124.569 86.6828 129.18C81.0343 135.189 77.7618 153.647 88.1898 153.217M100.153 128.321C95.8075 131.755 89.6375 144.633 92.7659 149.784C94.0694 151.93 97.1147 151.93 98.4182 151.071M88.1898 153.217C89.2793 153.074 91.6736 152.101 92.5349 149.354M108.843 142.486L109.712 135.189" stroke="#475050" stroke-width="1.2"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M273.102 194.595C275.426 191.608 279.732 191.071 282.718 193.395C287.377 197.02 293.458 200.535 300.053 204.347C301.192 205.006 302.346 205.673 303.512 206.351C310.984 210.701 319.152 215.642 324.447 221.221C327.153 224.072 329.604 227.587 330.542 231.801C331.538 236.274 330.65 240.732 328.072 244.855C325.621 248.777 321.711 252.313 316.662 255.64C311.562 259.001 304.923 262.392 296.57 265.877L291.293 253.23C299.179 249.939 304.979 246.927 309.121 244.197C313.315 241.434 315.45 239.193 316.452 237.591C317.327 236.191 317.299 235.379 317.165 234.778C316.974 233.917 316.306 232.55 314.507 230.655C310.794 226.743 304.41 222.732 296.617 218.195C295.552 217.575 294.461 216.946 293.356 216.308C286.828 212.54 279.775 208.47 274.302 204.21C271.315 201.886 270.778 197.581 273.102 194.595Z" fill="#475050"/>
<path d="M292.025 248.847C289.573 246.861 285.821 246.975 284.081 248.72C279.473 242.595 263.873 247.357 254.55 256.987C246.012 265.807 248.378 276.019 253.676 277.265C252.918 282.631 256.2 287.573 261.429 289.307C262.622 294.949 266.53 298.985 273.36 299.95C281.41 301.087 292.508 291.21 295.218 286.12C297.386 282.047 292.63 279.783 289.565 280.345C290.748 279.019 291.092 276.58 291.44 274.122C292.831 274.836 295.564 275.64 297.148 272.46C300.621 265.486 296.49 252.463 292.025 248.847Z" fill="#FCFCF1"/>
<path d="M284.081 248.72C285.821 246.975 289.573 246.861 292.025 248.847C296.49 252.463 300.621 265.486 297.148 272.46C295.564 275.64 292.831 274.836 291.44 274.122M284.081 248.72C279.473 242.595 263.873 247.357 254.55 256.987C246.012 265.807 248.378 276.019 253.676 277.265M284.081 248.72L286.038 252.479M291.44 274.122C291.092 276.58 290.748 279.019 289.565 280.345M291.44 274.122C291.621 271.666 291.521 265.793 289.676 261.95M289.565 280.345C292.63 279.783 297.386 282.047 295.218 286.12C292.508 291.21 281.41 301.087 273.36 299.95C266.53 298.985 262.622 294.949 261.429 289.307M289.565 280.345C287.292 282.346 281.742 286.405 277.729 286.635M261.429 289.307C256.2 287.573 252.918 282.631 253.676 277.265M261.429 289.307C261.473 287.821 261.95 284.206 263.507 281.639M253.676 277.265C253.814 276.289 254.646 273.919 256.873 272.243M276.52 270.541L271.021 274.242M274.77 265.317L266.832 268.674M272.044 259.956L264.732 262.406" stroke="#475050" stroke-width="1.2"/>
<path d="M215.947 87.2089L212.533 104.121L239.547 109.564L243.003 92.4459C243.499 89.9896 245.892 88.4 248.348 88.895C261.851 91.6157 275.004 82.5928 277.547 69.0557C280.078 55.5772 271.341 42.3907 257.897 39.6818L221.388 32.3253C207.691 29.5654 194.382 38.5375 191.803 52.2695C189.271 65.7479 198.042 78.7584 211.486 81.4673L212.233 81.6178C214.803 82.1356 216.466 84.6392 215.947 87.2089Z" fill="#FCFCF1" stroke="#475050" stroke-width="1.2"/>
<path d="M216.381 84.2442L243.899 88.8051L214.785 91.2506L242.318 95.2351L213.674 97.6504L241.207 101.635L212.563 104.05L240.096 108.035" stroke="#475050" stroke-width="1.2"/>
<path d="M219.271 63.8942C219.218 63.9267 219.164 63.9587 219.109 63.9903C219.177 64.3337 219.271 64.6673 219.394 64.9878C220.121 66.8821 222.567 67.5627 224.391 67.6754C226.334 67.7953 228.099 67.1587 229.652 66.1243C229.244 65.428 228.994 64.6223 228.957 63.7369C228.798 59.9395 231.077 56.4694 233.774 53.9729C234.623 53.1874 236.468 51.5192 237.822 51.8857C238.756 52.1387 238.397 53.5438 238.239 54.1444C237.15 58.2851 234.298 62.139 231.139 64.9663C230.668 65.3879 230.172 65.7784 229.652 66.1243C230.645 67.816 232.578 68.8615 234.689 68.8334C237.06 68.8018 239.423 67.6747 241.466 66.1546C240.968 63.1564 241.84 59.8017 243.237 57.3038C243.75 56.3854 247.435 50.7065 249.07 52.4433C250.059 53.4948 248.761 56.4175 248.342 57.4325C247.57 59.3044 246.48 61.0656 245.181 62.6218C244.172 63.8314 242.898 65.0894 241.466 66.1546C239.423 67.6747 237.06 68.8018 234.689 68.8334C232.578 68.8615 230.645 67.816 229.652 66.1243C228.099 67.1587 226.334 67.7953 224.391 67.6754C222.567 67.5627 220.121 66.8821 219.394 64.9878C219.271 64.6673 219.177 64.3337 219.109 63.9903C218.608 61.465 219.495 58.4109 220.323 56.1602C220.841 54.7527 221.65 53.4425 222.642 52.3146C222.962 51.95 224.618 50.0197 225.277 50.8993C225.718 51.4883 225.428 52.8236 225.306 53.444C224.866 55.6758 223.888 57.8825 222.814 59.8771C221.948 61.4862 220.859 62.9298 219.271 63.8942Z" fill="#FCFCF1"/>
<path d="M208.412 61.3066C208.471 62.6425 209.348 63.6558 210.472 64.3373C213.041 65.8956 216.788 65.4023 219.271 63.8942C220.859 62.9298 221.948 61.4862 222.814 59.8771C223.888 57.8825 224.866 55.6758 225.306 53.444C225.428 52.8236 225.718 51.4883 225.277 50.8993C224.618 50.0197 222.962 51.95 222.642 52.3146C221.65 53.4425 220.841 54.7527 220.323 56.1602C219.382 58.717 218.366 62.3104 219.394 64.9878C220.121 66.8821 222.567 67.5627 224.391 67.6754C226.983 67.8354 229.259 66.6482 231.139 64.9663C234.298 62.139 237.15 58.2851 238.239 54.1444C238.397 53.5438 238.756 52.1387 237.822 51.8857C236.468 51.5192 234.623 53.1874 233.774 53.9729C231.077 56.4694 228.798 59.9395 228.957 63.7369C229.084 66.7734 231.709 68.8731 234.689 68.8334C238.722 68.7796 242.731 65.5576 245.181 62.6218C246.48 61.0656 247.57 59.3044 248.342 57.4325C248.761 56.4175 250.059 53.4948 249.07 52.4433C247.435 50.7065 243.751 56.3854 243.237 57.3038C241.243 60.8682 240.319 66.1771 242.92 69.7054C245.06 72.6092 249.329 70.7106 251.849 69.4409C256.115 67.2921 258.979 63.9381 261.686 60.1487" stroke="#475050" stroke-width="1.2"/>
<path d="M231.312 73.5742L228.976 86.1917" stroke="#475050" stroke-width="1.2"/>
<path d="M272.147 110.642L269.643 99.6692M304.702 82.9481L286.672 76.6776M304.702 32.262L278.658 36.9649M252.114 3L241.596 22.8564M193.015 5.61268L199.025 22.8564M181.495 55.7762H157.455M181.495 90.2636L193.015 82.9481" stroke="#FCFCF1" stroke-width="2"/>
<ellipse opacity="0.12" cx="199.59" cy="387.068" rx="132.59" ry="9.93566" fill="var(--clr-illustration-outline)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M157.255 213.229C158.433 216.825 156.472 220.695 152.876 221.873C147.762 223.547 142.682 225.316 137.865 226.992C131.961 229.048 126.454 230.965 121.769 232.401C117.353 233.755 113.146 234.858 109.326 235.425C105.579 235.982 101.63 236.118 97.9947 235.048C94.0493 233.888 90.7797 231.387 88.7595 227.462C86.8963 223.843 86.3607 219.529 86.5045 214.98C86.7906 205.934 89.8998 193.153 95.6378 175.822L108.648 180.129C102.936 197.379 100.42 208.519 100.202 215.413C100.094 218.834 100.587 220.495 100.944 221.19C101.145 221.58 101.289 221.733 101.862 221.901C102.744 222.161 104.418 222.3 107.312 221.87C110.132 221.451 113.582 220.577 117.752 219.299C122.417 217.869 127.372 216.138 132.907 214.206C137.655 212.549 142.83 210.742 148.611 208.849C152.208 207.671 156.078 209.632 157.255 213.229Z" fill="var(--clr-illustration-outline)"/>
<path d="M204.217 386.723H203.306H102.579C106.89 364.234 143.047 339.243 171.913 339.243L195.426 226.039L206.732 227.752L219.066 230.15L235.856 339.514C257.069 339.514 295.729 354.565 303.348 386.723H204.217Z" fill="var(--clr-illustration-fill)"/>
<path d="M203.306 386.723H303.348C295.729 354.565 257.069 339.514 235.856 339.514L219.066 230.15L206.732 227.752M206.732 227.752L204.217 386.723H102.579C106.89 364.234 143.047 339.243 171.913 339.243L195.426 226.039L206.732 227.752Z" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M268.964 125.61C270.028 125.805 271.073 126.095 272.085 126.478L289 132.869C297.001 135.892 301.77 144.127 300.409 152.571L290.962 211.193C290.155 216.2 291.497 221.315 294.659 225.28L298.289 229.832C301.085 233.337 302.12 237.931 301.099 242.297C299.312 249.934 291.825 254.807 284.119 253.349L150.127 228.002C140.328 226.149 133.904 216.681 135.802 206.89L152.193 122.346C154.071 112.659 163.398 106.29 173.104 108.066L268.964 125.61Z" fill="var(--clr-illustration-fill)" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M236.809 244.2V244.2C244.784 245.703 252.441 240.375 253.805 232.375L268.918 143.733C270.543 134.203 264.35 125.092 254.891 123.096L254.012 122.91" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<rect opacity="0.13" x="162.368" y="115.594" width="100.912" height="100.863" rx="7.86364" transform="rotate(10.5121 162.368 115.594)" fill="var(--clr-illustration-outline)"/>
<rect opacity="0.2" width="9.9403" height="26.5802" transform="matrix(-0.985001 -0.172547 -0.172547 0.985001 200.751 186.181)" fill="var(--clr-illustration-outline)"/>
<rect opacity="0.7" width="9.9403" height="18.7625" transform="matrix(-0.985001 -0.172547 -0.172547 0.985001 189.611 192.167)" fill="var(--clr-illustration-outline)"/>
<rect opacity="0.2" width="9.9403" height="10.9448" transform="matrix(-0.985001 -0.172547 -0.172547 0.985001 178.471 198.152)" fill="var(--clr-illustration-outline)"/>
<rect opacity="0.4" width="9.9403" height="39.0886" transform="matrix(-0.985001 -0.172547 -0.172547 0.985001 173.536 168.715)" fill="var(--clr-illustration-outline)"/>
<path d="M175.298 226.469L172.46 240.879L186.539 237.685L198.092 245.876L201.192 231.779L187 233.994L175.298 226.469Z" fill="var(--clr-illustration-outline)"/>
<circle opacity="0.3" cx="228.968" cy="155.219" r="17.6051" fill="var(--clr-illustration-outline)"/>
<path d="M239.527 169.471C242.292 167.384 244.377 164.524 245.517 161.253C246.657 157.981 246.801 154.445 245.932 151.091C245.062 147.738 243.217 144.717 240.631 142.412C238.045 140.107 234.833 138.62 231.402 138.141L228.976 155.489L239.527 169.471Z" fill="var(--clr-illustration-outline)"/>
<path d="M213.034 183.488L233.388 186.996C235.359 187.335 236.683 189.209 236.343 191.181V191.181C236.003 193.153 234.129 194.476 232.157 194.136L215.698 191.3C213.547 190.93 211.503 192.373 211.132 194.524V194.524C210.762 196.675 212.205 198.72 214.356 199.09L230.815 201.927C232.787 202.266 234.11 204.14 233.77 206.112V206.112C233.43 208.084 231.556 209.407 229.584 209.067L212.801 206.175C210.829 205.836 208.955 207.159 208.615 209.131V209.131C208.275 211.103 209.599 212.977 211.57 213.316L231.924 216.824" stroke="var(--clr-illustration-outline)" stroke-width="2"/>
<rect x="211.416" y="179.957" width="7.47705" height="6.04684" transform="rotate(9.08743 211.416 179.957)" fill="var(--clr-illustration-outline)"/>
<rect x="226.179" y="213.342" width="7.9832" height="5.77427" transform="rotate(9.08743 226.179 213.342)" fill="var(--clr-illustration-outline)"/>
<rect x="216.259" y="196.758" width="5.77427" height="5.77427" transform="rotate(9.08743 216.259 196.758)" fill="var(--clr-illustration-outline)"/>
<path d="M170.332 131.047L203.915 137.287" stroke="var(--clr-illustration-outline)" stroke-width="3"/>
<path d="M169.113 137.604L188.003 141.114" stroke="var(--clr-illustration-outline)" stroke-width="3"/>
<path d="M166.677 150.717L176.122 152.472" stroke="var(--clr-illustration-outline)" stroke-width="3"/>
<path d="M167.895 144.16L196.231 149.425" stroke="var(--clr-illustration-outline)" stroke-width="3"/>
<path d="M89.7244 177.684C86.9436 175.28 88.8554 172.533 90.1589 171.246C88.8554 170.816 85.9587 169.529 84.9449 166.524C83.2069 161.373 85.8139 156.651 88.1898 153.217C77.7618 153.647 81.0343 135.189 86.6828 129.18C91.0171 124.569 95.8075 124.887 100.153 128.321C105.801 121.883 114.057 126.968 116.229 132.119C122.312 107.652 134.739 97.7593 139.258 100.85C143.777 103.94 132.306 129.895 126.657 141.628C131.437 142.916 134.478 146.35 134.478 151.071C134.478 162.232 124.485 172.104 116.229 173.821C117.533 175.538 117.369 177.846 115.795 179.401C111.45 183.694 93.2004 180.689 89.7244 177.684Z" fill="var(--clr-illustration-fill)"/>
<path d="M90.1589 171.246C88.8554 172.533 86.9436 175.28 89.7244 177.684C93.2004 180.689 111.45 183.694 115.795 179.401C117.369 177.846 117.533 175.538 116.229 173.821M90.1589 171.246C88.8554 170.816 85.9587 169.529 84.9449 166.524C83.2069 161.373 85.8139 156.651 88.1898 153.217M90.1589 171.246L96.242 172.533M116.229 173.821C124.485 172.104 134.478 162.232 134.478 151.071C134.478 146.35 131.437 142.916 126.657 141.628M116.229 173.821H110.309M126.657 141.628C132.306 129.895 143.777 103.94 139.258 100.85C134.739 97.7593 122.312 107.652 116.229 132.119C114.057 126.968 105.801 121.883 100.153 128.321M126.657 141.628C119.271 141.199 105.278 142.86 101.456 145.062C96.242 148.067 97.98 154.934 103.629 156.651C108.147 158.025 116.808 155.507 120.574 154.076C114.491 155.936 101.63 160.6 98.849 164.378M100.153 128.321C95.8075 124.887 91.0171 124.569 86.6828 129.18C81.0343 135.189 77.7618 153.647 88.1898 153.217M100.153 128.321C95.8075 131.755 89.6375 144.633 92.7659 149.784C94.0694 151.93 97.1147 151.93 98.4182 151.071M88.1898 153.217C89.2793 153.074 91.6736 152.101 92.5349 149.354M108.843 142.486L109.712 135.189" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M273.102 194.595C275.426 191.608 279.732 191.071 282.718 193.395C287.377 197.02 293.458 200.535 300.053 204.347C301.192 205.006 302.346 205.673 303.512 206.351C310.984 210.701 319.152 215.642 324.447 221.221C327.153 224.072 329.604 227.587 330.542 231.801C331.538 236.274 330.65 240.732 328.072 244.855C325.621 248.777 321.711 252.313 316.662 255.64C311.562 259.001 304.923 262.392 296.57 265.877L291.293 253.23C299.179 249.939 304.979 246.927 309.121 244.197C313.315 241.434 315.45 239.193 316.452 237.591C317.327 236.191 317.299 235.379 317.165 234.778C316.974 233.917 316.306 232.55 314.507 230.655C310.794 226.743 304.41 222.732 296.617 218.195C295.552 217.575 294.461 216.946 293.356 216.308C286.828 212.54 279.775 208.47 274.302 204.21C271.315 201.886 270.778 197.581 273.102 194.595Z" fill="var(--clr-illustration-outline)"/>
<path d="M292.025 248.847C289.573 246.861 285.821 246.975 284.081 248.72C279.473 242.595 263.873 247.357 254.55 256.987C246.012 265.807 248.378 276.019 253.676 277.265C252.918 282.631 256.2 287.573 261.429 289.307C262.622 294.949 266.53 298.985 273.36 299.95C281.41 301.087 292.508 291.21 295.218 286.12C297.386 282.047 292.63 279.783 289.565 280.345C290.748 279.019 291.092 276.58 291.44 274.122C292.831 274.836 295.564 275.64 297.148 272.46C300.621 265.486 296.49 252.463 292.025 248.847Z" fill="var(--clr-illustration-fill)"/>
<path d="M284.081 248.72C285.821 246.975 289.573 246.861 292.025 248.847C296.49 252.463 300.621 265.486 297.148 272.46C295.564 275.64 292.831 274.836 291.44 274.122M284.081 248.72C279.473 242.595 263.873 247.357 254.55 256.987C246.012 265.807 248.378 276.019 253.676 277.265M284.081 248.72L286.038 252.479M291.44 274.122C291.092 276.58 290.748 279.019 289.565 280.345M291.44 274.122C291.621 271.666 291.521 265.793 289.676 261.95M289.565 280.345C292.63 279.783 297.386 282.047 295.218 286.12C292.508 291.21 281.41 301.087 273.36 299.95C266.53 298.985 262.622 294.949 261.429 289.307M289.565 280.345C287.292 282.346 281.742 286.405 277.729 286.635M261.429 289.307C256.2 287.573 252.918 282.631 253.676 277.265M261.429 289.307C261.473 287.821 261.95 284.206 263.507 281.639M253.676 277.265C253.814 276.289 254.646 273.919 256.873 272.243M276.52 270.541L271.021 274.242M274.77 265.317L266.832 268.674M272.044 259.956L264.732 262.406" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M215.947 87.2089L212.533 104.121L239.547 109.564L243.003 92.4459C243.499 89.9896 245.892 88.4 248.348 88.895C261.851 91.6157 275.004 82.5928 277.547 69.0557C280.078 55.5772 271.341 42.3907 257.897 39.6818L221.388 32.3253C207.691 29.5654 194.382 38.5375 191.803 52.2695C189.271 65.7479 198.042 78.7584 211.486 81.4673L212.233 81.6178C214.803 82.1356 216.466 84.6392 215.947 87.2089Z" fill="var(--clr-illustration-fill)" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M216.381 84.2442L243.899 88.8051L214.785 91.2506L242.318 95.2351L213.674 97.6504L241.207 101.635L212.563 104.05L240.096 108.035" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M219.271 63.8942C219.218 63.9267 219.164 63.9587 219.109 63.9903C219.177 64.3337 219.271 64.6673 219.394 64.9878C220.121 66.8821 222.567 67.5627 224.391 67.6754C226.334 67.7953 228.099 67.1587 229.652 66.1243C229.244 65.428 228.994 64.6223 228.957 63.7369C228.798 59.9395 231.077 56.4694 233.774 53.9729C234.623 53.1874 236.468 51.5192 237.822 51.8857C238.756 52.1387 238.397 53.5438 238.239 54.1444C237.15 58.2851 234.298 62.139 231.139 64.9663C230.668 65.3879 230.172 65.7784 229.652 66.1243C230.645 67.816 232.578 68.8615 234.689 68.8334C237.06 68.8018 239.423 67.6747 241.466 66.1546C240.968 63.1564 241.84 59.8017 243.237 57.3038C243.75 56.3854 247.435 50.7065 249.07 52.4433C250.059 53.4948 248.761 56.4175 248.342 57.4325C247.57 59.3044 246.48 61.0656 245.181 62.6218C244.172 63.8314 242.898 65.0894 241.466 66.1546C239.423 67.6747 237.06 68.8018 234.689 68.8334C232.578 68.8615 230.645 67.816 229.652 66.1243C228.099 67.1587 226.334 67.7953 224.391 67.6754C222.567 67.5627 220.121 66.8821 219.394 64.9878C219.271 64.6673 219.177 64.3337 219.109 63.9903C218.608 61.465 219.495 58.4109 220.323 56.1602C220.841 54.7527 221.65 53.4425 222.642 52.3146C222.962 51.95 224.618 50.0197 225.277 50.8993C225.718 51.4883 225.428 52.8236 225.306 53.444C224.866 55.6758 223.888 57.8825 222.814 59.8771C221.948 61.4862 220.859 62.9298 219.271 63.8942Z" fill="var(--clr-illustration-fill)"/>
<path d="M208.412 61.3066C208.471 62.6425 209.348 63.6558 210.472 64.3373C213.041 65.8956 216.788 65.4023 219.271 63.8942C220.859 62.9298 221.948 61.4862 222.814 59.8771C223.888 57.8825 224.866 55.6758 225.306 53.444C225.428 52.8236 225.718 51.4883 225.277 50.8993C224.618 50.0197 222.962 51.95 222.642 52.3146C221.65 53.4425 220.841 54.7527 220.323 56.1602C219.382 58.717 218.366 62.3104 219.394 64.9878C220.121 66.8821 222.567 67.5627 224.391 67.6754C226.983 67.8354 229.259 66.6482 231.139 64.9663C234.298 62.139 237.15 58.2851 238.239 54.1444C238.397 53.5438 238.756 52.1387 237.822 51.8857C236.468 51.5192 234.623 53.1874 233.774 53.9729C231.077 56.4694 228.798 59.9395 228.957 63.7369C229.084 66.7734 231.709 68.8731 234.689 68.8334C238.722 68.7796 242.731 65.5576 245.181 62.6218C246.48 61.0656 247.57 59.3044 248.342 57.4325C248.761 56.4175 250.059 53.4948 249.07 52.4433C247.435 50.7065 243.751 56.3854 243.237 57.3038C241.243 60.8682 240.319 66.1771 242.92 69.7054C245.06 72.6092 249.329 70.7106 251.849 69.4409C256.115 67.2921 258.979 63.9381 261.686 60.1487" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M231.312 73.5742L228.976 86.1917" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M272.147 110.642L269.643 99.6692M304.702 82.9481L286.672 76.6776M304.702 32.262L278.658 36.9649M252.114 3L241.596 22.8564M193.015 5.61268L199.025 22.8564M181.495 55.7762H157.455M181.495 90.2636L193.015 82.9481" stroke="var(--clr-illustration-fill)" stroke-width="2"/>
</svg>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1,49 @@
<svg width="400" height="400" viewBox="0 0 400 400" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_5582_984)">
<ellipse opacity="0.12" cx="197.1" cy="378.851" rx="161.9" ry="9.93566" fill="var(--clr-illustration-outline)"/>
<path d="M126.252 377.393C168.468 301.09 164.046 274.441 209.146 215.181L202.067 212.821L201.116 213.826C168.14 248.675 146.186 271.875 119.114 309.241C86.1007 298.996 64.7785 291.516 29.5318 311.413L126.252 377.393Z" fill="var(--clr-illustration-fill)" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M191.602 269.721L221.699 215.426L209.042 214.371C168.11 265.091 164.315 288.421 180.302 329.163C137.824 334.932 115.825 350.504 105.15 379.439H236.993C221.699 340.1 191.602 269.721 191.602 269.721Z" fill="var(--clr-illustration-fill)" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<ellipse cx="69.8588" cy="124.443" rx="60.1291" ry="38.3491" transform="rotate(-20.5917 69.8588 124.443)" fill="var(--clr-illustration-fill)" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<ellipse cx="69.8588" cy="124.442" rx="45.3603" ry="38.3491" transform="rotate(-20.5917 69.8588 124.442)" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<ellipse cx="69.8588" cy="124.443" rx="22.1998" ry="38.3491" transform="rotate(-20.5917 69.8588 124.443)" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M88.303 82.7295C85.7836 93.252 75.5921 103.768 61.2151 109.257C47.7691 114.391 34.1221 113.806 25.138 108.665" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M47.3058 165.728C49.5763 155.149 59.5171 144.396 73.7606 138.569C87.0819 133.12 100.739 133.383 109.842 138.311" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M55.2711 88.9062L84.3924 159.773" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M125.285 101.157L13.7115 145.646" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M114.261 146.292C115.292 153.173 112.466 161.545 105.47 171.281C110.896 174.143 108.565 182.363 97.9657 187.742C83.9984 194.83 75.9429 188.642 75.0257 181.256C64.9126 183.372 58.5535 171.664 58.5535 166.051C67.1935 165.194 75.0257 163.22 80.563 160.847C84.8345 153.095 90.6054 148.797 97.25 145C73.375 139.375 74.0765 126.042 83.2525 121.928C92.4284 117.815 112.485 134.44 114.261 146.292Z" fill="var(--clr-illustration-fill)"/>
<path d="M105.47 171.281C112.466 161.545 115.292 153.173 114.261 146.292C112.485 134.44 92.4284 117.815 83.2525 121.928C74.0765 126.042 73.375 139.375 97.25 145C90.6054 148.797 84.8345 153.095 80.563 160.847M105.47 171.281C110.896 174.143 108.565 182.363 97.9657 187.742C83.9984 194.83 75.9429 188.642 75.0257 181.256C64.9126 183.372 58.5535 171.664 58.5535 166.051C67.1935 165.194 75.0257 163.22 80.563 160.847M105.47 171.281C102.758 170.282 95.7508 169.264 89.4225 173.187M80.563 160.847L78.3481 165.668" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M111.657 231.045L113.605 225.37L111.657 231.045ZM98.1226 182.467C96.9595 179.364 93.5012 177.792 90.3983 178.955C87.2955 180.118 85.7229 183.576 86.886 186.679L98.1226 182.467ZM149.48 201.227C140.291 211.791 131.984 218.353 125.418 221.965C122.133 223.771 119.396 224.778 117.289 225.229C115.116 225.695 113.975 225.497 113.605 225.37L109.709 236.72C112.838 237.794 116.357 237.701 119.803 236.963C123.314 236.21 127.155 234.705 131.2 232.48C139.295 228.028 148.665 220.449 158.534 209.103L149.48 201.227ZM113.605 225.37C110.79 224.404 109.209 223.025 108.08 221.32C106.823 219.421 105.912 216.789 105.098 212.959C103.584 205.834 102.553 194.287 98.1226 182.467L86.886 186.679C90.9171 197.434 91.429 206.364 93.3598 215.453C94.2683 219.729 95.5548 224.138 98.0731 227.943C100.719 231.941 104.491 234.929 109.709 236.72L113.605 225.37Z" fill="var(--clr-illustration-outline)"/>
<path d="M266.377 104.143C276.133 105.725 282.789 114.877 281.287 124.646L275.722 160.853C274.815 166.752 276.891 172.716 281.263 176.777L288.563 183.557C292.906 187.591 294.984 193.503 294.121 199.367L290.908 221.192C289.447 231.12 280.149 237.936 270.241 236.342L141.292 215.597C131.326 213.994 124.627 204.512 126.445 194.583L143.388 102.068C145.153 92.4302 154.302 85.9745 163.974 87.5424L266.377 104.143Z" fill="var(--clr-illustration-fill)" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M267.269 208.177L280.952 205.113M266.673 214.804L280.357 211.739M266.078 221.427L279.762 218.363" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<rect opacity="0.13" x="153.994" y="94.7842" width="93.5302" height="104.822" rx="9.86" transform="rotate(9.40007 153.994 94.7842)" fill="var(--clr-illustration-outline)"/>
<path d="M156.065 142.667C152.928 158.601 150.616 176.15 163.697 180.111C176.778 184.071 180.546 163.628 184.133 147.743C187.721 131.857 190.131 113.81 176.322 111.296C162.513 108.783 159.203 126.733 156.065 142.667Z" fill="var(--clr-illustration-fill)" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M176.023 111.366C174.038 120.284 169.601 143.415 167.048 154.411L183.15 152.115C183.15 152.115 183.941 148.595 184.134 147.743C187.636 132.235 190.212 114.321 176.023 111.366Z" fill="var(--clr-illustration-outline)"/>
<path d="M201.522 148.932C198.384 164.867 196.073 182.416 209.154 186.376C222.235 190.337 226.003 169.894 229.59 154.008C233.177 138.123 235.588 120.076 221.779 117.562C207.969 115.048 204.66 132.998 201.522 148.932Z" fill="var(--clr-illustration-fill)" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M221.48 117.631C219.495 126.55 215.058 149.681 212.505 160.677L228.606 158.38C228.606 158.38 229.398 154.861 229.59 154.009C233.092 138.501 235.669 120.587 221.48 117.631Z" fill="var(--clr-illustration-outline)"/>
<path d="M192.08 185.38C191.42 187.25 189.653 188.5 187.67 188.5C183.112 188.5 181.259 181.135 184.979 178.5C188.701 175.863 193.598 181.079 192.08 185.38Z" fill="var(--clr-illustration-outline)"/>
<path d="M166.045 193.292L162.933 211.484L180.519 207.03L195.291 216.956L198.742 199.149L180.983 202.378L166.045 193.292Z" fill="var(--clr-illustration-outline)"/>
<path d="M214.08 227.293L218.876 228.083C228.678 229.696 237.935 223.063 239.558 213.262L254.903 120.578C256.548 110.643 249.724 101.292 239.761 99.8285L238.362 99.623" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M301.118 148.497L264.106 174.733L339.197 207.847L376.091 179.615L393.156 129.517L316.893 101.982L301.118 148.497Z" fill="var(--clr-illustration-fill)" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M301.089 147.997L368.308 175.067" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M259.083 262.524L260.824 256.782L259.083 262.524ZM263.514 196.1C263.977 192.819 261.692 189.783 258.411 189.32C255.13 188.857 252.094 191.142 251.631 194.423L263.514 196.1ZM290.815 213.814C286.397 220.395 282.619 226.804 279.29 232.571C275.917 238.417 273.099 243.432 270.437 247.569C267.73 251.775 265.577 254.426 263.76 255.847C262.215 257.055 261.489 256.984 260.824 256.782L257.341 268.266C262.669 269.882 267.378 268.252 271.153 265.3C274.654 262.561 277.705 258.448 280.528 254.063C283.395 249.607 286.433 244.202 289.683 238.57C292.979 232.86 296.593 226.736 300.778 220.502L290.815 213.814ZM260.824 256.782C258.818 256.174 257.678 255.042 256.914 252.668C256.017 249.879 255.811 245.698 256.35 239.86C256.879 234.126 258.049 227.473 259.426 219.988C260.786 212.592 262.335 204.455 263.514 196.1L251.631 194.423C250.496 202.47 249.004 210.312 247.624 217.817C246.259 225.233 244.987 232.403 244.401 238.756C243.824 245.005 243.828 251.175 245.491 256.344C247.287 261.928 251.058 266.36 257.341 268.266L260.824 256.782Z" fill="var(--clr-illustration-outline)"/>
<path d="M307.928 145.087L319.774 108.322L384.261 131.547L371.536 170.368L307.928 145.087Z" fill="var(--clr-illustration-outline)"/>
<path d="M277.405 184.917C276.373 191.799 277.405 198.806 284.401 208.542C278.975 211.404 281.588 220.734 287.798 224.778C300.922 233.327 308.66 228.113 309.577 220.727C319.69 222.843 328.786 212.398 330.755 203.929L301.482 190.866L292.996 186.187C314 174.25 311.169 160.99 301.482 160.25C291.795 159.509 279.181 173.065 277.405 184.917Z" fill="var(--clr-illustration-fill)"/>
<path d="M284.401 208.542C277.405 198.806 276.373 191.799 277.405 184.917C279.181 173.065 291.795 159.509 301.482 160.25C311.169 160.99 314 174.25 292.996 186.187L301.482 190.866M284.401 208.542C278.975 211.404 281.588 220.734 287.798 224.778C300.922 233.327 308.66 228.113 309.577 220.727C319.69 222.843 328.786 212.398 330.755 203.929L301.482 190.866M284.401 208.542C287.638 213.047 292.375 216.75 297.625 218.875M301.482 190.866C304.117 193.245 308.848 201.532 306.294 208.931" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M78.5 70.4996C134 17.4995 249 1.49957 343 91.1975M343 91.1975C333.549 68.6647 331.982 55.7508 340 33.4996M343 91.1975C319.28 83.5874 305.227 85.7495 284.718 91.1975" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M124.635 27.2601C125.415 22.9112 129.573 20.0181 133.922 20.7981L140.934 22.0557C143.038 22.433 144.903 23.6367 146.114 25.3983L154.014 36.8905C155.207 38.6259 155.667 40.7618 155.295 42.8346L153.293 53.9996C152.513 58.3485 148.355 61.2416 144.006 60.4616L127.344 57.4731C122.995 56.6931 120.102 52.5353 120.882 48.1864L124.635 27.2601Z" fill="var(--clr-illustration-fill)" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M127.72 42.3486L147.924 45.9723M127.053 46.0651L147.257 49.6888M126.387 49.7815L136.747 51.6398" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M141.367 34.3252L143.42 22.8828L146.041 25.7531L153.979 37.0806L155.089 40.8502L144.598 38.9686C142.424 38.5786 140.977 36.4997 141.367 34.3252Z" fill="var(--clr-illustration-outline)"/>
<path d="M189.868 16.8367C188.817 12.5453 191.443 8.2142 195.735 7.16295L211.218 3.37007C213.294 2.86148 215.488 3.20491 217.309 4.32377L237.563 16.7658C239.357 17.8681 240.645 19.6335 241.146 21.6789L246.416 43.193C247.467 47.4844 244.84 51.8154 240.549 52.8667L208.834 60.6358C204.543 61.6871 200.211 59.0604 199.16 54.769L189.868 16.8367Z" fill="var(--clr-illustration-fill)" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M203.987 39.0762L233.444 31.8602M205.314 44.4948L234.772 37.2788M206.642 49.9135L221.748 46.213" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M218.063 21.9146L213.522 3.37598L218.782 5.68137L236.292 16.2212L240.051 20.6464L222.9 24.848C220.754 25.3736 218.589 24.0603 218.063 21.9146Z" fill="var(--clr-illustration-outline)"/>
<path d="M271.632 34.9625C271.292 30.5574 274.587 26.7103 278.992 26.3699L287.598 25.7047C289.729 25.54 291.837 26.2351 293.453 27.6348L305.262 37.8672C306.854 39.2462 307.837 41.1972 308 43.2968L309.016 56.449C309.357 60.8541 306.062 64.7012 301.656 65.0416L282.098 66.5533C277.692 66.8938 273.845 63.5987 273.505 59.1935L271.632 34.9625Z" fill="var(--clr-illustration-fill)" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M279.022 50.5684L301.158 48.8575M279.337 54.6403L301.473 52.9295M279.652 58.7123L291.003 57.8349" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M291.147 38.7768L290.153 25.9141L293.679 28.2047L305.074 37.8996L307.264 41.5431L295.444 42.4567C293.241 42.6269 291.318 40.9794 291.147 38.7768Z" fill="var(--clr-illustration-outline)"/>
<path d="M323.163 135.409C324.597 135.929 325.382 135.143 326.173 132.962L327.577 133.471C326.504 136.43 324.93 137.344 322.748 136.553C320.475 135.729 319.689 133.804 321.155 129.761C322.62 125.719 324.458 124.745 326.731 125.569C328.912 126.36 329.504 128.059 328.664 130.378L327.26 129.869C327.819 128.328 327.777 127.157 326.343 126.637C324.818 126.084 323.747 126.99 322.558 130.27C321.369 133.55 321.638 134.856 323.163 135.409ZM328.137 138.334L332.008 127.656L333.381 128.153L330.505 136.086L329.833 137.654L333.616 139.026L333.835 138.328L334.056 137.718L335.429 138.216L334.544 140.657L328.137 138.334ZM344.162 138.103C345.351 134.823 345.095 133.436 343.569 132.883C342.044 132.33 340.958 133.23 339.769 136.51C338.635 139.637 338.864 141.101 340.389 141.654C341.915 142.207 343.028 141.23 344.162 138.103ZM338.381 136.007C339.846 131.964 341.684 130.991 343.957 131.815C346.229 132.639 347.016 134.564 345.55 138.606C344.085 142.649 342.247 143.622 339.974 142.798C337.701 141.974 336.915 140.049 338.381 136.007ZM345.439 144.607L349.311 133.929L351.675 134.786L350.921 145.386L351.379 145.552L353.015 139.897L354.497 135.809L355.87 136.307L351.999 146.985L349.634 146.128L350.388 135.527L349.93 135.362L348.294 141.016L346.812 145.105L345.439 144.607ZM354.205 147.785L358.076 137.107L364.56 139.457L364.172 140.525L358.97 138.639L358.537 140.122L358.288 140.808L357.671 142.224L361.805 143.723L361.418 144.791L357.284 143.292L356.85 144.774L356.49 145.766L355.901 147.106L361.103 148.992L360.688 150.136L354.205 147.785ZM365.136 151.748L365.828 149.842L367.735 150.533L367.043 152.44L365.136 151.748ZM362.055 150.631L362.746 148.724L364.653 149.416L363.962 151.323L362.055 150.631ZM368.233 152.871L368.924 150.964L370.831 151.656L370.14 153.563L368.233 152.871Z" fill="var(--clr-illustration-fill)"/>
</g>
<defs>
<clipPath id="clip0_5582_984">
<rect width="400" height="400" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1,9 +0,0 @@
<svg width="54" height="61" viewBox="0 0 54 61" fill="none" xmlns="http://www.w3.org/2000/svg">
<g opacity="0.8">
<path d="M1 44.5C1 40.9101 3.91015 38 7.5 38H53V51H7.5C3.91015 51 1 48.0899 1 44.5Z" fill="var(--clr-scale-pop-30)" stroke="var(--clr-scale-pop-30)" stroke-width="1.2"/>
<path d="M53 38.1458V1H9.66667C4.8802 1 1 4.51776 1 8.85714V45" stroke="var(--clr-scale-pop-30)" stroke-width="1.2"/>
<path d="M10 44H24V61L17 55.0665L10 61V44Z" fill="var(--clr-scale-pop-30)"/>
<path d="M10 44C10 42.8954 10.8954 42 12 42H22C23.1046 42 24 42.8954 24 44V51H10V44Z" fill="var(--clr-illustration-bg)"/>
<path d="M27 8V31M38 19.5L16 19.5" stroke="var(--clr-scale-pop-30)" stroke-width="1.2"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 702 B

View File

@ -1,6 +0,0 @@
<svg width="56" height="54" viewBox="0 0 56 54" fill="none" xmlns="http://www.w3.org/2000/svg">
<g opacity="0.8">
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.086 52.0879V39.1311H18.5052V50.7376H26.6367V48.0103H21.2325V39.1311H26.6367V36.4038H21.2325V28.4292H26.6367V25.7019H18.5052V36.4038H14.086V16.3206H17.091C21.3587 16.3206 24.8184 12.8609 24.8184 8.59321C24.8184 4.32549 21.3587 0.865822 17.091 0.865822H7.99997C3.73225 0.865822 0.272583 4.32549 0.272583 8.59321C0.272583 12.8609 3.73225 16.3206 7.99997 16.3206H11.3587V52.0879H14.086ZM12.5455 10.0264L17.1725 12.1085C17.7741 12.3792 18.4547 11.9392 18.4547 11.2795V5.90955C18.4547 5.24985 17.7741 4.8098 17.1725 5.08052L12.5455 7.16267L7.91848 5.08052C7.31689 4.8098 6.63631 5.24985 6.63631 5.90955V11.2795C6.63631 11.9392 7.31689 12.3792 7.91848 12.1085L12.5455 10.0264Z" fill="var(--clr-scale-pop-30)"/>
<path d="M38.9099 0.863281C34.6422 0.863281 31.1825 4.32295 31.1825 8.59067C31.1825 12.8584 34.6422 16.3181 38.9099 16.3181H39.3231L32.0916 53.1367H54.8192L47.5877 16.3181H48.0009C52.2687 16.3181 55.7283 12.8584 55.7283 8.59067C55.7283 4.32295 52.2687 0.863281 48.0009 0.863281H38.9099Z" fill="var(--clr-scale-pop-30)"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,6 @@
<svg width="100" height="66" viewBox="0 0 100 66" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 12C0 5.37258 5.37258 0 12 0H88C94.6274 0 100 5.37258 100 12V54C100 60.6274 94.6274 66 88 66H12C5.37258 66 0 60.6274 0 54V12Z" fill="var(--clr-illustration-bg)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M68.7826 14.5215C63.3798 14.5215 59 18.9013 59 24.3041C59 28.7844 62.0118 32.5612 66.1212 33.7203L62.2609 51.478H80.7391L76.8788 33.7203C80.9882 32.5612 84 28.7844 84 24.3041C84 18.9013 79.6202 14.5215 74.2174 14.5215H68.7826Z" fill="var(--clr-illustration-outline)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M28 25.5V40.5C28 42.433 26.433 44 24.5 44C22.567 44 21 42.433 21 40.5V25.5C21 23.567 22.567 22 24.5 22C26.433 22 28 23.567 28 25.5ZM15 25.5C15 20.2533 19.2533 16 24.5 16C29.7467 16 34 20.2533 34 25.5V29.5H41.5H50.5H53.5V32.5V44H47.5V35.5H44.5V44H38.5V35.5H34V40.5C34 45.7467 29.7467 50 24.5 50C19.2533 50 15 45.7467 15 40.5V25.5Z" fill="var(--clr-illustration-fill)"/>
<path d="M34 29.5H33.4V30.1H34V29.5ZM53.5 29.5H54.1V28.9H53.5V29.5ZM53.5 44V44.6H54.1V44H53.5ZM47.5 44H46.9V44.6H47.5V44ZM47.5 35.5H48.1V34.9H47.5V35.5ZM44.5 35.5V34.9H43.9V35.5H44.5ZM44.5 44V44.6H45.1V44H44.5ZM38.5 44H37.9V44.6H38.5V44ZM38.5 35.5H39.1V34.9H38.5V35.5ZM34 35.5V34.9H33.4V35.5H34ZM28.6 40.5V25.5H27.4V40.5H28.6ZM24.5 44.6C26.7644 44.6 28.6 42.7644 28.6 40.5H27.4C27.4 42.1016 26.1016 43.4 24.5 43.4V44.6ZM20.4 40.5C20.4 42.7644 22.2356 44.6 24.5 44.6V43.4C22.8984 43.4 21.6 42.1016 21.6 40.5H20.4ZM20.4 25.5V40.5H21.6V25.5H20.4ZM24.5 21.4C22.2356 21.4 20.4 23.2356 20.4 25.5H21.6C21.6 23.8984 22.8984 22.6 24.5 22.6V21.4ZM28.6 25.5C28.6 23.2356 26.7644 21.4 24.5 21.4V22.6C26.1016 22.6 27.4 23.8984 27.4 25.5H28.6ZM24.5 15.4C18.9219 15.4 14.4 19.9219 14.4 25.5H15.6C15.6 20.5847 19.5847 16.6 24.5 16.6V15.4ZM34.6 25.5C34.6 19.9219 30.0781 15.4 24.5 15.4V16.6C29.4153 16.6 33.4 20.5847 33.4 25.5H34.6ZM34.6 29.5V25.5H33.4V29.5H34.6ZM34 30.1H41.5V28.9H34V30.1ZM41.5 30.1H50.5V28.9H41.5V30.1ZM50.5 30.1H53.5V28.9H50.5V30.1ZM52.9 29.5V32.5H54.1V29.5H52.9ZM52.9 32.5V44H54.1V32.5H52.9ZM53.5 43.4H47.5V44.6H53.5V43.4ZM48.1 44V35.5H46.9V44H48.1ZM47.5 34.9H44.5V36.1H47.5V34.9ZM43.9 35.5V44H45.1V35.5H43.9ZM44.5 43.4H38.5V44.6H44.5V43.4ZM39.1 44V35.5H37.9V44H39.1ZM38.5 34.9H34V36.1H38.5V34.9ZM34.6 40.5V35.5H33.4V40.5H34.6ZM24.5 50.6C30.0781 50.6 34.6 46.0781 34.6 40.5H33.4C33.4 45.4153 29.4153 49.4 24.5 49.4V50.6ZM14.4 40.5C14.4 46.0781 18.9219 50.6 24.5 50.6V49.4C19.5847 49.4 15.6 45.4153 15.6 40.5H14.4ZM14.4 25.5V40.5H15.6V25.5H14.4Z" fill="var(--clr-illustration-outline)"/>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,7 @@
<svg width="100" height="90" viewBox="0 0 100 90" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 12C0 5.37258 5.37258 0 12 0H88C94.6274 0 100 5.37258 100 12V78C100 84.6274 94.6274 90 88 90H12C5.37258 90 0 84.6274 0 78V12Z" fill="var(--clr-illustration-bg)"/>
<path d="M42 39C42 35.6863 44.6863 33 48 33H82V75H48C44.6863 75 42 72.3137 42 69V39Z" fill="var(--clr-illustration-fill)" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M18 21C18 17.6863 20.6863 15 24 15H58V57H24C20.6863 57 18 54.3137 18 51V21Z" fill="var(--clr-illustration-fill)" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M18 49C18 45.6863 20.6863 43 24 43H58V57H24C20.6863 57 18 54.3137 18 51V49Z" fill="var(--clr-illustration-fill)" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M23 49C23 48.4477 23.4477 48 24 48H37C37.5523 48 38 48.4477 38 49V60.8675C38 62.5395 36.0703 63.4734 34.7591 62.436L30.5 59.0665L26.2409 62.436C24.9297 63.4734 23 62.5395 23 60.8675V49Z" fill="var(--clr-illustration-outline)"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,7 @@
<svg width="100" height="90" viewBox="0 0 100 90" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 12C0 5.37258 5.37258 0 12 0H88C94.6274 0 100 5.37258 100 12V78C100 84.6274 94.6274 90 88 90H12C5.37258 90 0 84.6274 0 78V12Z" fill="var(--clr-illustration-bg)"/>
<path d="M76 20H32C27.5817 20 24 23.5817 24 28V63C24 67.4183 27.5817 71 32 71H76V20Z" fill="var(--clr-illustration-fill)" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M51 28V51M62 39.5L40 39.5" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M76 57H31C27.134 57 24 60.134 24 64C24 67.866 27.134 71 31 71H76V57Z" fill="var(--clr-illustration-fill)" stroke="var(--clr-illustration-outline)" stroke-width="1.2"/>
<path d="M32 64C32 63.4477 32.4477 63 33 63H47C47.5523 63 48 63.4477 48 64V77.7443C48 79.4375 46.0272 80.3647 44.7236 79.2841L40 75.3684L35.2764 79.2841C33.9728 80.3647 32 79.4375 32 77.7443V64Z" fill="var(--clr-illustration-outline)"/>
</svg>

After

Width:  |  Height:  |  Size: 975 B

View File

@ -106,9 +106,11 @@ export class ProjectService {
await invoke('open_project_in_window', { id: projectId });
}
async addProject() {
const path = await this.promptForDirectory();
if (!path) return;
async addProject(path?: string) {
if (!path) {
path = await this.promptForDirectory();
if (!path) return;
}
if (!this.validateProjectPath(path)) return;

View File

@ -0,0 +1,39 @@
<script lang="ts">
import { listen } from '$lib/backend/ipc';
import { ProjectService } from '$lib/backend/projects';
import { getContext } from '$lib/utils/context';
import { createKeybind } from '$lib/utils/hotkeys';
import { onMount } from 'svelte';
import { goto } from '$app/navigation';
const projectService = getContext(ProjectService);
onMount(() => {
const unsubscribeAddLocalRepo = listen<string>(
'menu://file/add-local-repo/clicked',
async () => {
await projectService.addProject();
}
);
const unsubscribeCloneRepo = listen<string>('menu://file/clone-repo/clicked', async () => {
goto('/onboarding/clone');
});
return async () => {
unsubscribeAddLocalRepo();
unsubscribeCloneRepo();
};
});
const handleKeyDown = createKeybind({
'$mod+O': async () => {
await projectService.addProject();
},
'$mod+Shift+O': async () => {
goto('/onboarding/clone');
}
});
</script>
<svelte:window on:keydown={handleKeyDown} />

View File

@ -0,0 +1,69 @@
<script lang="ts">
import { listen } from '$lib/backend/ipc';
import { Project } from '$lib/backend/projects';
import { editor } from '$lib/editorLink/editorLink';
import { getContext } from '$lib/utils/context';
import * as events from '$lib/utils/events';
import { createKeybind } from '$lib/utils/hotkeys';
import { unsubscribe } from '$lib/utils/unsubscribe';
import { open } from '@tauri-apps/api/shell';
import { onMount } from 'svelte';
import { goto } from '$app/navigation';
const project = getContext(Project);
interface Props {
showHistory: boolean;
onHistoryShow: (show: boolean) => void;
}
const { showHistory, onHistoryShow }: Props = $props();
let showHistoryState = $state(showHistory);
onMount(() => {
const unsubscribeSettings = listen<string>('menu://project/settings/clicked', () => {
goto(`/${project.id}/settings/`);
});
const unsubscribeOpenInVSCode = listen<string>(
'menu://project/open-in-vscode/clicked',
async () => {
const path = `${$editor}://file${project.vscodePath}?windowId=_blank`;
open(path);
}
);
const unsubscribeHistory = listen<string>('menu://project/history/clicked', () => {
showHistoryState = true;
});
const unsubscribeHistoryButton = unsubscribe(
events.on('openHistory', () => {
showHistoryState = true;
})
);
return () => {
unsubscribeSettings();
unsubscribeOpenInVSCode();
unsubscribeHistory();
unsubscribeHistoryButton();
};
});
const handleKeyDown = createKeybind({
'$mod+Shift+H': () => {
showHistoryState = !showHistoryState;
}
});
$effect(() => {
onHistoryShow(showHistoryState);
});
$effect(() => {
showHistoryState = showHistory;
});
</script>
<svelte:window on:keydown={handleKeyDown} />

View File

@ -1,30 +0,0 @@
<script lang="ts">
import { listen } from '$lib/backend/ipc';
import { Project } from '$lib/backend/projects';
import { editor } from '$lib/editorLink/editorLink';
import { getContext } from '$lib/utils/context';
import { open } from '@tauri-apps/api/shell';
import { onMount } from 'svelte';
import { goto } from '$app/navigation';
const project = getContext(Project);
onMount(() => {
const unsubscribeSettings = listen<string>('menu://project/settings/clicked', () => {
goto(`/${project.id}/settings/`);
});
const unsubscribeOpenInVSCode = listen<string>(
'menu://project/open-in-vscode/clicked',
async () => {
const path = `${$editor}://file${project.vscodePath}?windowId=_blank`;
open(path);
}
);
return () => {
unsubscribeSettings();
unsubscribeOpenInVSCode();
};
});
</script>

View File

@ -247,8 +247,8 @@
</svelte:fragment>
</SetupFeature>
</div>
<div class="floating-buttons">
<BackButton>Back</BackButton>
<div class="action-buttons">
<BackButton>Cancel</BackButton>
<Button
style="pop"
kind="solid"
@ -300,7 +300,7 @@
gap: 12px;
}
.floating-buttons {
.action-buttons {
display: flex;
justify-content: flex-end;
width: 100%;

View File

@ -19,8 +19,10 @@
}))
);
let loading = $state(false);
let selectedProjectId: string | undefined = $state(project ? project.id : undefined);
let newProjectLoading = $state(false);
let cloneProjectLoading = $state(false);
</script>
<div class="project-switcher">
@ -43,17 +45,31 @@
<OptionsGroup>
<SelectItem
icon="plus"
{loading}
loading={newProjectLoading}
on:click={async () => {
loading = true;
newProjectLoading = true;
try {
await projectService.addProject();
} finally {
loading = false;
newProjectLoading = false;
}
}}
>
Add new project
Add local repository
</SelectItem>
<SelectItem
icon="clone"
loading={cloneProjectLoading}
on:click={async () => {
cloneProjectLoading = true;
try {
goto('/onboarding/clone');
} finally {
cloneProjectLoading = false;
}
}}
>
Clone repository
</SelectItem>
</OptionsGroup>
</Select>

View File

@ -1,138 +0,0 @@
<script lang="ts">
import Icon from '$lib/shared/Icon.svelte';
import { createEventDispatcher, getContext, onMount } from 'svelte';
import type iconsJson from '$lib/icons/icons.json';
import type { SegmentContext } from './segment';
export let id: string;
export let disabled = false;
export let icon: keyof typeof iconsJson | undefined = undefined;
export let label: string | undefined = undefined;
export let size: 'small' | 'medium' = 'medium';
let ref: HTMLButtonElement | undefined;
const dispatcher = createEventDispatcher<{ select: string }>();
const context = getContext<SegmentContext>('SegmentedControl');
const index = context.setIndex();
const focusedSegmentIndex = context.focusedSegmentIndex;
const selectedSegmentIndex = context.selectedSegmentIndex;
const length = context.length;
$: isFocused = $focusedSegmentIndex === index;
$: if (isFocused) {
ref?.focus();
}
$: isSelected = $selectedSegmentIndex === index;
onMount(() => {
context.addSegment({ id, index, disabled });
});
</script>
<button
bind:this={ref}
class="segment-btn segment-{size}"
class:left={index === 0}
class:right={index === $length - 1}
role="tab"
tabindex={isSelected ? -1 : 0}
aria-selected={isSelected}
aria-disabled={disabled}
{...$$restProps}
on:mousedown|preventDefault={() => {
if (index !== $selectedSegmentIndex && !disabled) {
context.setSelected(index);
dispatcher('select', id);
}
}}
on:keydown={({ key }) => {
if (key === 'Enter' || key === ' ') {
if (index !== $selectedSegmentIndex && !disabled) {
context.setSelected(index);
dispatcher('select', id);
}
}
}}
>
{#if label}
<span class="label text-base-12">
{label}
</span>
{/if}
{#if icon}
<div class="icon">
<Icon name={icon} />
</div>
{/if}
</button>
<style lang="postcss">
.segment-btn {
cursor: pointer;
display: inline-flex;
flex-grow: 1;
flex-basis: 0;
align-items: center;
justify-content: center;
gap: 4px;
height: var(--size-button);
border-top-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
border-color: var(--clr-border-2);
transition: background var(--transition-fast);
&[aria-selected='true'] {
background-color: var(--clr-bg-2);
cursor: default;
& > .label,
& > .icon {
color: var(--clr-scale-ntrl-50);
cursor: default;
}
&:focus {
outline: none;
}
}
&.left {
border-left-width: 1px;
border-top-left-radius: var(--radius-m);
border-bottom-left-radius: var(--radius-m);
}
&.right {
border-right-width: 1px;
border-top-right-radius: var(--radius-m);
border-bottom-right-radius: var(--radius-m);
}
}
.icon {
display: flex;
justify-content: center;
align-items: center;
color: var(--clr-scale-ntrl-30);
}
.label {
color: var(--clr-scale-ntrl-30);
}
/* MODIFIERS */
.segment-small {
height: var(--size-tag);
padding: 2px 4px;
}
.segment-medium {
height: var(--size-button);
padding: 4px 8px;
}
</style>

View File

@ -1,58 +0,0 @@
<script lang="ts">
import { createEventDispatcher, setContext } from 'svelte';
import { writable } from 'svelte/store';
import type { SegmentContext, SegmentItem } from './segment';
export let wide = false;
export let selectedIndex = 0;
export let selected: string | undefined = undefined;
let dispatch = createEventDispatcher<{ select: string }>();
let indexesIterator = -1;
let segments: SegmentItem[] = [];
let focusedSegmentIndex = writable(-1);
let selectedSegmentIndex = writable(selectedIndex);
let length = writable(0);
const context: SegmentContext = {
focusedSegmentIndex,
selectedSegmentIndex,
length,
setIndex: () => {
indexesIterator += 1;
return indexesIterator;
},
addSegment: ({ id, index, disabled }) => {
segments = [...segments, { id, index, disabled }];
length.set(segments.length);
if (index === selectedIndex) selected = id;
},
setSelected: (segmentIndex) => {
if (segmentIndex >= 0 && segmentIndex < segments.length) {
$focusedSegmentIndex = segmentIndex;
if (!segments[segmentIndex].disabled) {
$selectedSegmentIndex = $focusedSegmentIndex;
selected = segments[segmentIndex].id;
dispatch('select', selected);
}
}
}
};
setContext<SegmentContext>('SegmentedControl', context);
</script>
<div class="wrapper" class:wide>
<slot />
</div>
<style lang="postcss">
.wrapper {
display: inline-flex;
&.wide {
display: flex;
}
}
</style>

View File

@ -1,15 +0,0 @@
import type { Writable } from 'svelte/store';
export interface SegmentItem {
id: string;
index: number;
disabled: boolean;
}
export interface SegmentContext {
focusedSegmentIndex: Writable<number>;
selectedSegmentIndex: Writable<number>;
length: Writable<number>;
setIndex(): number;
addSegment(segment: SegmentItem): void;
setSelected(index: number): void;
}

View File

@ -1,14 +1,17 @@
<script lang="ts">
import WelcomeAction from './WelcomeAction.svelte';
import WelcomeSigninAction from './WelcomeSigninAction.svelte';
import newProjectSvg from '$lib/assets/no-projects/new-project.svg?raw';
import cloneRepoSvg from '$lib/assets/welcome/clone-repo.svg?raw';
import newProjectSvg from '$lib/assets/welcome/new-local-project.svg?raw';
import { ProjectService } from '$lib/backend/projects';
import IconLink from '$lib/shared/IconLink.svelte';
import { getContext } from '$lib/utils/context';
import { goto } from '$app/navigation';
const projectService = getContext(ProjectService);
let newProjectLoading = false;
let cloneProjectLoading = false;
async function onNewProject() {
newProjectLoading = true;
@ -18,19 +21,43 @@
newProjectLoading = false;
}
}
async function onCloneProject() {
goto('/onboarding/clone');
}
</script>
<div class="welcome">
<h1 class="welcome-title text-serif-40">Welcome to GitButler</h1>
<div class="welcome__actions">
<WelcomeAction title="Add new project" loading={newProjectLoading} on:mousedown={onNewProject}>
<svelte:fragment slot="icon">
{@html newProjectSvg}
</svelte:fragment>
<svelte:fragment slot="message">
Verify valid Git repository in selected folder before importing.
</svelte:fragment>
</WelcomeAction>
<div class="welcome__actions--repo">
<WelcomeAction
title="Add local project"
loading={newProjectLoading}
onclick={onNewProject}
dimMessage
>
{#snippet icon()}
{@html newProjectSvg}
{/snippet}
{#snippet message()}
Should be a valid git repository
{/snippet}
</WelcomeAction>
<WelcomeAction
title="Clone repository"
loading={cloneProjectLoading}
onclick={onCloneProject}
dimMessage
>
{#snippet icon()}
{@html cloneRepoSvg}
{/snippet}
{#snippet message()}
Clone a repo using a URL
{/snippet}
</WelcomeAction>
</div>
<!-- Using instance of user here to not hide after login -->
<WelcomeSigninAction />
</div>
@ -56,6 +83,7 @@
<IconLink icon="discord" href="https://discord.gg/MmFkmaJ42D">Discord</IconLink>
<IconLink icon="x" href="https://twitter.com/gitbutler">X</IconLink>
<IconLink icon="instagram" href="https://www.instagram.com/gitbutler/">Instagram</IconLink>
<IconLink icon="youtube" href="https://www.youtube.com/@gitbutlerapp">YouTube</IconLink>
</div>
</div>
</div>
@ -78,11 +106,16 @@
margin-top: 32px;
}
.welcome__actions--repo {
display: flex;
gap: 8px;
}
.links {
display: flex;
gap: 56px;
padding: 28px;
background: var(--clr-bg-2);
background: var(--clr-bg-1-muted);
border-radius: var(--radius-m);
margin-top: 20px;
}
@ -102,11 +135,13 @@
}
.community-links {
display: flex;
flex-wrap: wrap;
display: grid;
grid-template-columns: repeat(2, 1fr);
column-gap: 12px;
row-gap: 4px;
max-width: 192px;
margin-left: -6px;
}
/* SMALL ILLUSTRATIONS */
</style>

View File

@ -1,18 +1,46 @@
<script lang="ts">
import Icon from '$lib/shared/Icon.svelte';
import type { Snippet } from 'svelte';
export let title: string;
export let loading = false;
const {
title,
loading = false,
onmousedown,
onclick,
icon,
message,
dimMessage,
row,
rowReverse
}: {
title: string;
loading: boolean;
onmousedown?: (e: MouseEvent) => void;
onclick?: (e: MouseEvent) => void;
icon: Snippet;
message: Snippet;
dimMessage?: boolean;
row?: boolean;
rowReverse?: boolean;
} = $props();
</script>
<button class="action" class:loading on:click on:mousedown disabled={loading}>
<button
class="action__wrapper"
class:loading
class:row
class:row-reverse={rowReverse}
{onclick}
{onmousedown}
disabled={loading}
>
<div class="icon">
<slot name="icon" />
{@render icon()}
</div>
<div class="action__content">
<div class="action__title text-base-18 text-bold">{title}</div>
<div class="action__message text-base-body-12">
<slot name="message" />
<div class="action__message text-base-body-12" class:dim-message={dimMessage}>
{@render message()}
</div>
</div>
{#if loading}
@ -23,17 +51,19 @@
</button>
<style lang="postcss">
.action {
.action__wrapper {
width: 100%;
height: auto;
position: relative;
display: flex;
flex-direction: column;
gap: 20px;
overflow: hidden;
border-radius: var(--radius-m);
border: 1px solid var(--clr-border-2);
display: flex;
position: relative;
padding: 16px;
flex-direction: row;
gap: 20px;
align-items: center;
text-align: left;
transition:
background-color var(--transition-fast),
@ -47,6 +77,14 @@
}
}
.action__wrapper.row {
flex-direction: row;
}
.action__wrapper.row-reverse {
flex-direction: row-reverse;
}
.loading {
pointer-events: none;
background-color: var(--clr-bg-2);
@ -55,12 +93,10 @@
}
.action__content {
flex: 1;
position: relative;
z-index: 0;
width: 100%;
display: flex;
flex-direction: column;
gap: 10px;
gap: 8px;
transition: opacity var(--transition-slow);
}
@ -76,19 +112,17 @@
}
.action__message {
color: var(--clr-scale-ntrl-30);
max-width: 80%;
color: var(--clr-text-2);
max-width: 90%;
}
.dim-message {
color: var(--clr-text-3);
}
.icon {
opacity: 0.8;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
width: 80px;
height: 80px;
border-radius: var(--radius-m);
background-color: var(--clr-illustration-bg);
}
</style>

View File

@ -1,11 +1,16 @@
<script lang="ts">
import WelcomeAction from './WelcomeAction.svelte';
import signinSvg from '$lib/assets/no-projects/signin.svg?raw';
import signinSvg from '$lib/assets/signin.svg?raw';
import { UserService } from '$lib/stores/user';
import { getContext } from '$lib/utils/context';
export let prompt: string =
'Enable GitButler features like automatic branch and commit message generation.';
const {
dimMessage,
prompt = 'Enable GitButler features like automatic branch and commit message generation.'
}: {
dimMessage?: boolean;
prompt?: string;
} = $props();
const userService = getContext(UserService);
const loading = userService.loading;
@ -16,13 +21,17 @@
<WelcomeAction
title="Log in or Sign up"
loading={$loading}
on:mousedown={async () => {
onclick={async () => {
await userService.login();
}}
rowReverse
{dimMessage}
>
<svelte:fragment slot="icon">
{#snippet icon()}
{@html signinSvg}
</svelte:fragment>
<svelte:fragment slot="message">{prompt}</svelte:fragment>
{/snippet}
{#snippet message()}
{prompt}
{/snippet}
</WelcomeAction>
{/if}

View File

@ -130,5 +130,7 @@
"robot": "M12.3829 3.33776C11.9899 3.1336 11.5223 3.05284 10.8366 3.0209C10.4307 1.8448 9.31402 1 8 1C6.68598 1 5.56928 1.8448 5.1634 3.0209C4.47768 3.05284 4.01011 3.1336 3.61708 3.33776C3.06915 3.62239 2.62239 4.06915 2.33776 4.61708C2.1456 4.987 2.06277 5.42295 2.02706 6.04467C0.872483 6.26574 0 7.28098 0 8.5C0 9.71002 0.859646 10.7193 2.00153 10.9503C2.00923 12.1554 2.05584 12.8402 2.33776 13.3829C2.62239 13.9309 3.06915 14.3776 3.61708 14.6622C4.26729 15 5.12153 15 6.83 15H9.17C10.8785 15 11.7327 15 12.3829 14.6622C12.9309 14.3776 13.3776 13.9309 13.6622 13.3829C13.9442 12.8402 13.9908 12.1554 13.9985 10.9503C15.1404 10.7193 16 9.71002 16 8.5C16 7.28098 15.1275 6.26574 13.9729 6.04467C13.9372 5.42295 13.8544 4.987 13.6622 4.61708C13.3776 4.06915 12.9309 3.62239 12.3829 3.33776ZM6.83 4.5C5.95059 4.5 5.38275 4.50121 4.95083 4.53707C4.53687 4.57145 4.38385 4.62976 4.30854 4.66888C4.03457 4.81119 3.81119 5.03457 3.66888 5.30854C3.62976 5.38385 3.57145 5.53687 3.53707 5.95083C3.50121 6.38275 3.5 6.95059 3.5 7.83V10.17C3.5 11.0494 3.50121 11.6173 3.53707 12.0492C3.57145 12.4631 3.62976 12.6161 3.66888 12.6915C3.81119 12.9654 4.03457 13.1888 4.30854 13.3311C4.38385 13.3702 4.53687 13.4285 4.95083 13.4629C5.38275 13.4988 5.95059 13.5 6.83 13.5H9.17C10.0494 13.5 10.6173 13.4988 11.0492 13.4629C11.4631 13.4285 11.6161 13.3702 11.6915 13.3311C11.9654 13.1888 12.1888 12.9654 12.3311 12.6915C12.3702 12.6161 12.4285 12.4631 12.4629 12.0492C12.4988 11.6173 12.5 11.0494 12.5 10.17V7.83C12.5 6.95059 12.4988 6.38275 12.4629 5.95083C12.4285 5.53687 12.3702 5.38385 12.3311 5.30854C12.1888 5.03457 11.9654 4.81119 11.6915 4.66888C11.6161 4.62976 11.4631 4.57145 11.0492 4.53707C10.6173 4.50121 10.0494 4.5 9.17 4.5H6.83ZM5.75 10C5.33579 10 5 10.3358 5 10.75C5 11.1642 5.33579 11.5 5.75 11.5H10.25C10.6642 11.5 11 11.1642 11 10.75C11 10.3358 10.6642 10 10.25 10H5.75ZM6 9C6.55228 9 7 8.55228 7 8C7 7.44772 6.55228 7 6 7C5.44772 7 5 7.44772 5 8C5 8.55228 5.44772 9 6 9ZM11 8C11 8.55228 10.5523 9 10 9C9.44771 9 9 8.55228 9 8C9 7.44772 9.44771 7 10 7C10.5523 7 11 7.44772 11 8Z",
"doc": "M12 6.75H4V5.25H12V6.75Z M4 9.75H8V8.25H4V9.75Z M4 1C2.34315 1 1 2.34315 1 4V12C1 13.6569 2.34315 15 4 15H12C13.6569 15 15 13.6569 15 12V4C15 2.34315 13.6569 1 12 1H4ZM2.5 12C2.5 12.8284 3.17157 13.5 4 13.5H12C12.8284 13.5 13.5 12.8284 13.5 12V4C13.5 3.17157 12.8284 2.5 12 2.5H4C3.17157 2.5 2.5 3.17157 2.5 4V12Z",
"clear-input": "M1 8C1 4.13401 4.13401 1 8 1C11.866 1 15 4.13401 15 8C15 11.866 11.866 15 8 15C4.13401 15 1 11.866 1 8ZM8 6.93934L10.4697 4.46967L11.5303 5.53033L9.06066 8L11.5303 10.4697L10.4697 11.5303L8 9.06066L5.53033 11.5303L4.46967 10.4697L6.93934 8L4.46967 5.53033L5.53033 4.46967L8 6.93934Z",
"new-branch": "M4 14.5H9C10.3807 14.5 11.5 13.3807 11.5 12V4C11.5 2.61929 10.3807 1.5 9 1.5H8.99999H4C2.61929 1.5 1.5 2.61929 1.5 4V12C1.5 13.3807 2.61929 14.5 4 14.5ZM8.99999 0H9H12C14.2091 0 16 1.79086 16 4V12C16 14.2091 14.2091 16 12 16H9H4C1.79086 16 0 14.2091 0 12V4C0 1.79086 1.79086 0 4 0H8.99999ZM12.1252 14.4969C13.4477 14.4317 14.5 13.3387 14.5 12V4C14.5 2.66126 13.4477 1.56829 12.1252 1.50308C12.6726 2.18741 13 3.05547 13 4V12C13 12.9445 12.6726 13.8126 12.1252 14.4969ZM5.75 6.75V4H7.25V6.75H10V8.25H7.25V11H5.75V8.25H3V6.75L5.75 6.75Z"
"new-branch": "M4 14.5H9C10.3807 14.5 11.5 13.3807 11.5 12V4C11.5 2.61929 10.3807 1.5 9 1.5H8.99999H4C2.61929 1.5 1.5 2.61929 1.5 4V12C1.5 13.3807 2.61929 14.5 4 14.5ZM8.99999 0H9H12C14.2091 0 16 1.79086 16 4V12C16 14.2091 14.2091 16 12 16H9H4C1.79086 16 0 14.2091 0 12V4C0 1.79086 1.79086 0 4 0H8.99999ZM12.1252 14.4969C13.4477 14.4317 14.5 13.3387 14.5 12V4C14.5 2.66126 13.4477 1.56829 12.1252 1.50308C12.6726 2.18741 13 3.05547 13 4V12C13 12.9445 12.6726 13.8126 12.1252 14.4969ZM5.75 6.75V4H7.25V6.75H10V8.25H7.25V11H5.75V8.25H3V6.75L5.75 6.75Z",
"youtube": "M14.2509 2.35842C14.9397 2.55597 15.4811 3.13594 15.6654 3.87394C15.9987 5.21025 16 8 16 8C16 8 16 10.7898 15.6654 12.1261C15.4811 12.8641 14.9397 13.444 14.2509 13.6416C13.0036 14 7.99997 14 7.99997 14C7.99997 14 2.99637 14 1.74909 13.6416C1.06026 13.444 0.518933 12.8641 0.33454 12.1261C0 10.7898 0 8 0 8C0 8 0 5.21025 0.33454 3.87394C0.518933 3.13594 1.06026 2.55597 1.74909 2.35842C2.99637 2 7.99997 2 7.99997 2C7.99997 2 13.0036 2 14.2509 2.35842ZM10.5552 8.00024L6.39847 10.5712V5.4292L10.5552 8.00024Z",
"clone": "M5.25 8.75V7H6.75V8.75H8.5V10.25H6.75V12H5.25V10.25H3.5V8.75H5.25Z M7 0.25C5.48122 0.25 4.25 1.48122 4.25 3V3.25H3C1.48122 3.25 0.25 4.48122 0.25 6V13C0.25 14.5188 1.48122 15.75 3 15.75H9C10.5188 15.75 11.75 14.5188 11.75 13V12.75H13C14.5188 12.75 15.75 11.5188 15.75 10V3C15.75 1.48122 14.5188 0.25 13 0.25H7ZM11.75 11.25H13C13.6904 11.25 14.25 10.6904 14.25 10V3C14.25 2.30964 13.6904 1.75 13 1.75H7C6.30964 1.75 5.75 2.30964 5.75 3V3.25H9C10.5188 3.25 11.75 4.48122 11.75 6V11.25ZM1.75 6C1.75 5.30964 2.30964 4.75 3 4.75H9C9.69036 4.75 10.25 5.30964 10.25 6V13C10.25 13.6904 9.69036 14.25 9 14.25H3C2.30964 14.25 1.75 13.6904 1.75 13V6Z"
}

View File

@ -13,6 +13,7 @@
label: string;
selected?: boolean;
icon?: string;
loading?: boolean;
onclick: (event?: any) => void;
}
@ -29,7 +30,9 @@
let inputBoundingRect: DOMRect | undefined = $state();
let optionsEl: HTMLDivElement | undefined = $state();
let hidden = $state(true);
let loading = $state(false);
let newProjectLoading = $state(false);
let cloneProjectLoading = $state(false);
function getInputBoundingRect() {
if (target) {
@ -72,7 +75,7 @@
{#if props.icon || props.selected}
<div class="icon">
{#if props.icon}
<Icon name={loading ? 'spinner' : props.icon as keyof typeof iconsJson} />
<Icon name={props.loading ? 'spinner' : props.icon as keyof typeof iconsJson} />
{:else}
<Icon name="tick" />
{/if}
@ -127,14 +130,29 @@
{/if}
<div class="popup__actions">
{@render itemSnippet({
label: 'Add new project',
label: 'Add local repository',
icon: 'plus',
loading: newProjectLoading,
onclick: async () => {
loading = true;
newProjectLoading = true;
try {
await projectService.addProject();
} finally {
loading = false;
newProjectLoading = false;
hide();
}
}
})}
{@render itemSnippet({
label: 'Clone repository',
icon: 'clone',
loading: cloneProjectLoading,
onclick: async () => {
cloneProjectLoading = true;
try {
goto('/onboarding/clone');
} finally {
cloneProjectLoading = false;
hide();
}
}

View File

@ -0,0 +1,223 @@
<script lang="ts">
import { invoke } from '$lib/backend/ipc';
import { ProjectService } from '$lib/backend/projects';
import { persisted } from '$lib/persisted/persisted';
import Section from '$lib/settings/Section.svelte';
import Button from '$lib/shared/Button.svelte';
import InfoMessage, { type MessageStyle } from '$lib/shared/InfoMessage.svelte';
import Spacer from '$lib/shared/Spacer.svelte';
import TextBox from '$lib/shared/TextBox.svelte';
import { parseRemoteUrl } from '$lib/url/gitUrl';
import { getContext } from '$lib/utils/context';
import Segment from '@gitbutler/ui/SegmentControl/Segment.svelte';
import SegmentControl from '@gitbutler/ui/SegmentControl/SegmentControl.svelte';
import { open } from '@tauri-apps/api/dialog';
import { documentDir } from '@tauri-apps/api/path';
import { join } from '@tauri-apps/api/path';
import { posthog } from 'posthog-js';
import { onMount } from 'svelte';
import { goto } from '$app/navigation';
const projectService = getContext(ProjectService);
/* eslint-disable-next-line */
enum RemoteType {
http = 'http',
ssh = 'ssh'
}
let loading = $state(false);
let errors = $state<{ label: string }[]>([]);
let completed = $state(false);
let repositoryUrl = $state('');
let targetDirPath = $state('');
let selectedRemoteType = $state<keyof typeof RemoteType>(RemoteType.http);
let savedTargetDirPath = persisted('', 'clone_targetDirPath');
onMount(async () => {
if ($savedTargetDirPath) {
targetDirPath = $savedTargetDirPath;
} else {
targetDirPath = await documentDir();
}
});
async function handleCloneTargetSelect() {
const selectedPath = await open({
directory: true,
recursive: true,
title: 'Target Clone Directory'
});
if (!selectedPath) return;
targetDirPath = Array.isArray(selectedPath) ? selectedPath[0] : selectedPath;
}
async function cloneRepository() {
loading = true;
savedTargetDirPath.set(targetDirPath);
if (errors.length) {
errors = [];
}
if (!repositoryUrl || !targetDirPath) {
errors.push({
label: 'You must add both a repository URL and target directory.'
});
loading = false;
return;
}
try {
const { name, protocol } = parseRemoteUrl(repositoryUrl);
const targetDir = await join(targetDirPath, name);
// TODO: Remove once 'ssh' clone support is implemented
if (protocol !== 'https') {
errors.push({
label: 'Only HTTP Remote URLs allowed'
});
return;
}
await invoke('git_clone_repository', {
repositoryUrl,
targetDir
});
posthog.capture('Repository Cloned', { protocol });
await projectService.addProject(targetDir);
} catch (e) {
errors.push({
label: String(e)
});
} finally {
loading = false;
}
}
function handleCancel() {
if (history.length > 0) {
history.back();
} else {
goto('/');
}
}
</script>
<h1 class="clone-title text-serif-40">Clone a repository</h1>
<Section>
<div class="clone__remoteType">
<fieldset name="remoteType" class="remoteType-group">
<SegmentControl
fullWidth
defaultIndex={0}
onselect={(id) => {
selectedRemoteType = id as keyof typeof RemoteType;
}}
>
<Segment id="http">HTTP</Segment>
<Segment disabled tooltipText="Coming Soon" id="ssh">SSH</Segment>
</SegmentControl>
</fieldset>
</div>
<div class="clone__field repositoryUrl">
<TextBox
bind:value={repositoryUrl}
placeholder={selectedRemoteType === RemoteType.http ? 'https://' : 'ssh://'}
helperText={selectedRemoteType === RemoteType.http
? 'Clone using the web URL'
: 'Clone using the SSH URL'}
/>
</div>
<div class="clone__field repositoryTargetPath">
<div class="text-base-13 text-semibold clone__field--label">Where to clone</div>
<TextBox bind:value={targetDirPath} placeholder={'/Users/tipsy/Documents'} />
<Button
style="ghost"
outline
kind="solid"
disabled={loading}
on:click={handleCloneTargetSelect}
>
Choose..
</Button>
</div>
</Section>
<Spacer dotted margin={24} />
{#if completed}
{@render Notification({ title: 'Success', style: 'success' })}
{/if}
{#if errors.length}
{@render Notification({ title: 'Error', items: errors, style: 'error' })}
{/if}
<div class="clone__actions">
<Button style="ghost" outline kind="solid" disabled={loading} on:click={handleCancel}>
Cancel
</Button>
<Button
style="pop"
kind="solid"
icon={errors.length > 0 ? 'update-small' : 'chevron-right-small'}
disabled={loading}
{loading}
on:click={cloneRepository}
>
{#if loading}
Cloning..
{:else if errors.length > 0}
Retry clone
{:else}
Clone
{/if}
</Button>
</div>
{#snippet Notification({ title, items, style }: { title: string, items?: any[], style: MessageStyle})}
<div class="clone__info-message">
<InfoMessage {style} filled outlined={false}>
<svelte:fragment slot="title">
{title}
</svelte:fragment>
<svelte:fragment slot="content">
{#if items && items.length > 0}
{#each items as item}
{@html item.label}
{/each}
{/if}
</svelte:fragment>
</InfoMessage>
</div>
{/snippet}
<style>
.clone-title {
color: var(--clr-scale-ntrl-0);
line-height: 1;
margin-bottom: 20px;
}
.clone__field {
display: flex;
flex-direction: column;
gap: 8px;
}
.clone__field--label {
color: var(--clr-scale-ntrl-50);
}
.clone__actions {
display: flex;
gap: 8px;
justify-content: end;
}
.clone__info-message {
margin-bottom: 20px;
}
</style>

View File

@ -3,12 +3,11 @@
import Icon from '$lib/shared/Icon.svelte';
import type iconsJson from '$lib/icons/icons.json';
export let iconOpacity: number = 0.7;
export let icon: keyof typeof iconsJson;
</script>
<a class="link" target="_blank" {href}>
<Icon name={icon} opacity={iconOpacity} />
<Icon name={icon} />
<span class="text-base-12"><slot /></span>
</a>
@ -16,12 +15,18 @@
.link {
display: flex;
align-items: center;
width: fit-content;
gap: 10px;
padding: 4px 6px;
border-radius: var(--radius-m);
color: var(--clr-scale-ntrl-40);
text-decoration: none;
transition: background-color var(--transition-fast);
&:hover {
color: var(--clr-text-1);
background-color: oklch(from var(--clr-scale-ntrl-0) l c h / 0.05);
}
}

View File

@ -1,7 +1,13 @@
<script lang="ts">
import { pxToRem } from '@gitbutler/ui/utils/pxToRem';
export let margin: number | undefined = 16;
export let noLine = false;
interface SpacerProps {
margin?: number;
noLine?: boolean;
dotted?: boolean;
}
const { margin = 16, noLine = false, dotted = false }: SpacerProps = $props();
function getMargins() {
if (margin === undefined) {
@ -12,7 +18,12 @@
}
</script>
<div class="divider" style={getMargins()} class:line={!noLine}></div>
<div
class="divider"
style={getMargins()}
class:line={!noLine && !dotted}
class:dotted={!noLine && dotted}
></div>
<style lang="postcss">
.divider {
@ -22,6 +33,16 @@
}
.divider.line {
border-bottom: 1px solid var(--clr-scale-ntrl-0);
background-color: var(--clr-scale-ntrl-0);
}
.divider.dotted {
background: repeating-linear-gradient(
90deg,
transparent,
transparent 2px,
var(--clr-scale-ntrl-0) 2px,
var(--clr-scale-ntrl-0) 4px
);
}
</style>

View File

@ -11,6 +11,7 @@
export let width: number | undefined = undefined;
export let textAlign: 'left' | 'center' | 'right' = 'left';
export let placeholder: string | undefined = undefined;
export let helperText: string | undefined = undefined;
export let label: string | undefined = undefined;
export let reversedDirection: boolean = false;
export let wide: boolean = false;
@ -139,6 +140,10 @@
<Icon name={showPassword ? 'eye-shown' : 'eye-hidden'} />
</button>
{/if}
{#if helperText}
<p class="text-base-body-11 textbox__helper-text">{helperText}</p>
{/if}
</div>
</div>
@ -178,6 +183,11 @@
color: var(--clr-scale-ntrl-50);
}
.textbox__helper-text {
color: var(--clr-scale-ntrl-50);
margin-top: 6px;
}
.textbox__icon {
z-index: var(--z-ground);
pointer-events: none;

View File

@ -5,11 +5,13 @@ export type RepoInfo = {
name: string;
owner: string;
organization?: string;
protocol?: string;
};
export function parseRemoteUrl(url: string): RepoInfo {
const { source, name, owner, organization } = gitUrlParse(url);
const { protocol, source, name, owner, organization } = gitUrlParse(url);
return {
protocol,
source,
name,
owner,

View File

@ -2,7 +2,7 @@ import toast, { type ToastOptions, type ToastPosition } from 'svelte-french-toas
const defaultOptions = {
position: 'bottom-center' as ToastPosition,
style: 'border-radius: 8px; background: black; color: #fff;'
style: 'border-radius: 8px; background: black; color: #fff; font-size: 0.813em;'
};
export function error(msg: string, options: ToastOptions = {}) {

View File

@ -1,12 +1,6 @@
<script lang="ts">
import analyticsSvg from '$lib/assets/illustrations/analytics.svg?raw';
import newProjectSvg from '$lib/assets/illustrations/new-project.svg?raw';
import { ProjectService } from '$lib/backend/projects';
import DecorativeSplitView from '$lib/components/DecorativeSplitView.svelte';
import FullviewLoading from '$lib/components/FullviewLoading.svelte';
import Welcome from '$lib/components/Welcome.svelte';
import { appAnalyticsConfirmed } from '$lib/config/appSettings';
import AnalyticsConfirmation from '$lib/settings/AnalyticsConfirmation.svelte';
import { getContext } from '$lib/utils/context';
import { derived } from 'svelte/store';
import { goto } from '$app/navigation';
@ -18,7 +12,6 @@
$: debug = $page.url.searchParams.get('debug');
const analyticsConfirmed = appAnalyticsConfirmed();
const persistedId = projectService.getLastOpenedProject();
const redirect = derived(projects, (projects) => {
if (debug || !projects) return null;
@ -28,17 +21,15 @@
return null;
});
$: if ($redirect) goto(`/${$redirect}/`);
$: {
if ($redirect) {
goto(`/${$redirect}/`);
} else if ($redirect === null) {
goto('/onboarding');
}
}
</script>
{#if $redirect === undefined}
<FullviewLoading />
{:else if !$analyticsConfirmed}
<DecorativeSplitView img={analyticsSvg}>
<AnalyticsConfirmation {analyticsConfirmed} />
</DecorativeSplitView>
{:else if $redirect === null}
<DecorativeSplitView img={newProjectSvg} showLinks={false}>
<Welcome />
</DecorativeSplitView>
{/if}

View File

@ -1,6 +1,7 @@
<script lang="ts">
import { listen } from '$lib/backend/ipc';
import { Project } from '$lib/backend/projects';
import FileMenuAction from '$lib/barmenuActions/FileMenuAction.svelte';
import ProjectSettingsMenuAction from '$lib/barmenuActions/ProjectSettingsMenuAction.svelte';
import { BaseBranch, NoDefaultTarget } from '$lib/baseBranch/baseBranch';
import { BaseBranchService } from '$lib/baseBranch/baseBranchService';
import { BranchDragActionsFactory } from '$lib/branches/dragActions';
@ -10,7 +11,6 @@
import NoBaseBranch from '$lib/components/NoBaseBranch.svelte';
import NotOnGitButlerBranch from '$lib/components/NotOnGitButlerBranch.svelte';
import ProblemLoadingRepo from '$lib/components/ProblemLoadingRepo.svelte';
import ProjectSettingsMenuAction from '$lib/components/ProjectSettingsMenuAction.svelte';
import { ReorderDropzoneManagerFactory } from '$lib/dragging/reorderDropzoneManager';
import { DefaultGitHostFactory } from '$lib/gitHost/gitHostFactory';
import { octokitFromAccessToken } from '$lib/gitHost/github/octokit';
@ -24,13 +24,11 @@
import { RemoteBranchService } from '$lib/stores/remoteBranches';
import { parseRemoteUrl } from '$lib/url/gitUrl';
import { debounce } from '$lib/utils/debounce';
import * as events from '$lib/utils/events';
import { createKeybind } from '$lib/utils/hotkeys';
import { unsubscribe } from '$lib/utils/unsubscribe';
import { BranchController } from '$lib/vbranches/branchController';
import { VirtualBranchService } from '$lib/vbranches/virtualBranch';
import { onDestroy, onMount, setContext, type Snippet } from 'svelte';
import { onDestroy, setContext, type Snippet } from 'svelte';
import type { LayoutData } from './$types';
import { goto } from '$app/navigation';
const { data, children }: { data: LayoutData; children: Snippet } = $props();
@ -125,7 +123,11 @@
// Once on load and every time the project id changes
$effect(() => {
if (projectId) setupFetchInterval();
if (projectId) {
setupFetchInterval();
} else {
goto('/onboarding');
}
});
function setupFetchInterval() {
@ -141,43 +143,20 @@
if (intervalId) clearInterval(intervalId);
}
onMount(() => {
const unsubscribe = listen<string>('menu://project/history/clicked', () => {
$showHistoryView = !$showHistoryView;
});
return async () => {
unsubscribe();
};
});
const handleKeyDown = createKeybind({
'$mod+Shift+H': () => {
$showHistoryView = !$showHistoryView;
}
});
onMount(() => {
return unsubscribe(
events.on('openHistory', () => {
$showHistoryView = true;
})
);
});
onDestroy(() => clearFetchInterval());
</script>
<svelte:window on:keydown={handleKeyDown} />
<!-- forces components to be recreated when projectId changes -->
{#key projectId}
<ProjectSettingsMenuAction />
<ProjectSettingsMenuAction
showHistory={$showHistoryView}
onHistoryShow={(show) => ($showHistoryView = show)}
/>
<FileMenuAction />
{#if !project}
<p>Project not found!</p>
{:else if $baseError instanceof NoDefaultTarget}
<!-- Note that this requires the redirect above to work -->
<NoBaseBranch />
{:else if $baseError}
<ProblemLoadingRepo error={$baseError} />

View File

@ -0,0 +1,18 @@
<script lang="ts">
import analyticsSvg from '$lib/assets/illustrations/analytics.svg?raw';
import newProjectSvg from '$lib/assets/illustrations/new-project.svg?raw';
import DecorativeSplitView from '$lib/components/DecorativeSplitView.svelte';
import Welcome from '$lib/components/Welcome.svelte';
import { appAnalyticsConfirmed } from '$lib/config/appSettings';
import AnalyticsConfirmation from '$lib/settings/AnalyticsConfirmation.svelte';
const analyticsConfirmed = appAnalyticsConfirmed();
</script>
<DecorativeSplitView img={$analyticsConfirmed ? newProjectSvg : analyticsSvg}>
{#if $analyticsConfirmed}
<Welcome />
{:else}
<AnalyticsConfirmation {analyticsConfirmed} />
{/if}
</DecorativeSplitView>

View File

@ -0,0 +1,9 @@
<script lang="ts">
import cloningRepoSvg from '$lib/assets/illustrations/cloning-repo.svg?raw';
import DecorativeSplitView from '$lib/components/DecorativeSplitView.svelte';
import CloneForm from '$lib/onboarding/CloneForm.svelte';
</script>
<DecorativeSplitView img={cloningRepoSvg}>
<CloneForm />
</DecorativeSplitView>

View File

@ -146,6 +146,7 @@ fn main() {
repo::commands::git_get_local_config,
repo::commands::git_set_local_config,
repo::commands::check_signing_settings,
repo::commands::git_clone_repository,
virtual_branches::commands::list_virtual_branches,
virtual_branches::commands::create_virtual_branch,
virtual_branches::commands::commit_virtual_branch,

View File

@ -83,14 +83,27 @@ pub fn build(_package_info: &PackageInfo) -> Menu {
}
let mut file_menu = Menu::new();
file_menu = file_menu.add_item(
CustomMenuItem::new("file/add-local-repo", "Add Local Repository…")
.accelerator("CmdOrCtrl+O"),
);
file_menu = file_menu.add_item(
CustomMenuItem::new("file/clone-repo", "Clone Repository…")
.accelerator("CmdOrCtrl+Shift+O"),
);
#[cfg(target_os = "macos")]
{
// NB: macOS has the concept of having an app running but its
// window closed, but other platforms do not
file_menu = file_menu.add_native_item(MenuItem::Separator);
file_menu = file_menu.add_native_item(MenuItem::CloseWindow);
}
#[cfg(not(target_os = "macos"))]
{
file_menu = file_menu.add_native_item(MenuItem::Separator);
file_menu = file_menu.add_native_item(MenuItem::Quit);
}
@ -199,6 +212,16 @@ fn disabled_menu_item(id: &str, title: &str) -> CustomMenuItem {
}
pub fn handle_event<R: Runtime>(event: &WindowMenuEvent<R>) {
if event.menu_item_id() == "file/add-local-repo" {
emit(event.window(), "menu://file/add-local-repo/clicked");
return;
}
if event.menu_item_id() == "file/clone-repo" {
emit(event.window(), "menu://file/clone-repo/clicked");
return;
}
#[cfg(any(debug_assertions, feature = "devtools"))]
{
if event.menu_item_id() == "view/devtools" {

View File

@ -1,7 +1,10 @@
pub mod commands {
use anyhow::{Context, Result};
use git2::{self};
use gitbutler_project as projects;
use gitbutler_project::ProjectId;
use gitbutler_repo::RepoCommands;
use std::path::Path;
use tauri::State;
use tracing::instrument;
@ -39,4 +42,10 @@ pub mod commands {
let project = projects.get(id)?;
project.check_signing_settings().map_err(Into::into)
}
#[tauri::command(async)]
pub fn git_clone_repository(repository_url: &str, target_dir: &Path) -> Result<(), Error> {
git2::Repository::clone(repository_url, target_dir).context("Cloning failed")?;
Ok(())
}
}

View File

@ -1,4 +1,5 @@
<script lang="ts">
import { tooltip } from '@gitbutler/ui/utils/tooltip';
import { getContext, onMount } from 'svelte';
import type { SegmentContext } from './segmentTypes';
import type { Snippet } from 'svelte';
@ -6,10 +7,12 @@
interface SegmentProps {
id: string;
onselect?: (id: string) => void;
disabled?: boolean;
tooltipText?: string;
children: Snippet;
}
const { id, onselect, children }: SegmentProps = $props();
const { id, onselect, children, tooltipText, disabled = false }: SegmentProps = $props();
const context = getContext<SegmentContext>('SegmentControl');
const index = context.setIndex();
@ -37,6 +40,7 @@
{id}
class="segment"
role="tab"
{disabled}
tabindex={isSelected ? -1 : 0}
aria-selected={isSelected}
onmousedown={() => {
@ -59,10 +63,15 @@
}
}
}}
><span class="text-base-12 label">
{@render children()}
</span></button
use:tooltip={{
text: tooltipText ? tooltipText : '',
delay: 1000
}}
>
<span class="text-base-12 label">
{@render children()}
</span>
</button>
<style lang="postcss">
.segment {
@ -106,5 +115,10 @@
background-color: var(--clr-bg-2);
color: var(--clr-text-2);
}
&:disabled {
cursor: default;
opacity: 0.5;
}
}
</style>

View File

@ -5,18 +5,18 @@
import type { Snippet } from 'svelte';
interface SegmentProps {
selectedIndex: number;
defaultIndex: number;
fullWidth?: boolean;
onselect?: (id: string) => void;
children: Snippet;
}
const { selectedIndex, fullWidth, onselect, children }: SegmentProps = $props();
const { defaultIndex, fullWidth, onselect, children }: SegmentProps = $props();
let indexesIterator = -1;
let segments: SegmentItem[] = [];
let selectedSegmentIndex = writable(selectedIndex);
let selectedSegmentIndex = writable(defaultIndex);
const context: SegmentContext = {
selectedSegmentIndex,

View File

@ -10,7 +10,7 @@ type Story = StoryObj<typeof meta>;
export const SegmentControlStory: Story = {
args: {
selectedIndex: 1,
defaultIndex: 1,
fullWidth: false
}
};

View File

@ -3,15 +3,15 @@
import SegmentControl from '$lib/SegmentControl/SegmentControl.svelte';
interface Props {
selectedIndex: number;
defaultIndex: number;
fullWidth?: boolean;
}
const { selectedIndex, fullWidth }: Props = $props();
const { defaultIndex, fullWidth }: Props = $props();
</script>
<SegmentControl
{selectedIndex}
{defaultIndex}
{fullWidth}
onselect={(id) => {
console.log('Selected index:', id);

View File

@ -5,7 +5,6 @@
--border-color: var(--clr-commit-shadow);
--border-style: solid;
--border-dashed: dashed;
&.none {
--border-color: transparent;

View File

@ -164,6 +164,7 @@
font-family: var(--serif-font-family);
font-size: 2.5rem;
line-height: var(--text-body-line-height);
font-weight: 400;
}
/* modifiers */