Updated file & folder icons

This commit is contained in:
Prozilla 2023-12-12 22:53:17 +01:00
parent cc796ea8bb
commit 75666e7135
No known key found for this signature in database
GPG key ID: 5858DFE71CAF31EE
34 changed files with 492 additions and 154 deletions

1
.gitignore vendored
View file

@ -21,3 +21,4 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*
*.ini

View file

@ -0,0 +1,29 @@
<svg width="150" height="200" viewBox="0 0 150 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="mask0_152_55" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="150" height="200">
<path d="M25 0C11.1929 0 0 11.1929 0 25V175C0 188.807 11.1929 200 25 200H125C138.807 200 150 188.807 150 175V62.5L87.5 0H25Z" fill="#C8D6E5"/>
</mask>
<g mask="url(#mask0_152_55)">
<path d="M25 0C11.1929 0 0 11.1929 0 25V175C0 188.807 11.1929 200 25 200H125C138.807 200 150 188.807 150 175V62.5L87.5 0H25Z" fill="#C8D6E5"/>
<g filter="url(#filter0_d_152_55)">
<g clip-path="url(#clip0_152_55)">
<path d="M87.5 62.5L150 62.5L87.5 1.78815e-07V62.5Z" fill="#C8D6E5"/>
</g>
</g>
<path d="M47.6562 125L59.7656 112.891H59.7266C63.3984 109.258 63.3594 103.32 59.7266 99.6484C56.0937 95.9766 50.1562 95.9766 46.4844 99.6484L27.7344 118.398C24.0625 122.031 24.0625 127.969 27.7344 131.641L46.5234 150.352C50.1562 154.023 56.0938 153.984 59.7656 150.352C63.4375 146.719 63.4375 140.781 59.7656 137.109L47.6562 125Z" fill="#222F3E"/>
<path d="M122.266 118.359L103.516 99.6094V99.6484C99.8828 95.9766 93.9453 96.0156 90.2734 99.6484C86.6016 103.281 86.6016 109.219 90.2734 112.891L102.383 125L90.2734 137.109C86.6016 140.742 86.6406 146.68 90.2734 150.352C93.9062 154.023 99.8438 154.023 103.516 150.352L122.266 131.602C125.938 127.969 125.938 122.031 122.266 118.359Z" fill="#222F3E"/>
</g>
<defs>
<filter id="filter0_d_152_55" x="65.0281" y="-139.972" width="224.944" height="224.944" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset/>
<feGaussianBlur stdDeviation="11.236"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_152_55"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_152_55" result="shape"/>
</filter>
<clipPath id="clip0_152_55">
<rect x="87.5" y="-117.5" width="180" height="180" rx="25" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

@ -0,0 +1,28 @@
<svg width="150" height="200" viewBox="0 0 150 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="mask0_150_59" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="150" height="200">
<path d="M25 0C11.1929 0 0 11.1929 0 25V175C0 188.807 11.1929 200 25 200H125C138.807 200 150 188.807 150 175V62.5L87.5 0H25Z" fill="#C8D6E5"/>
</mask>
<g mask="url(#mask0_150_59)">
<path d="M25 0C11.1929 0 0 11.1929 0 25V175C0 188.807 11.1929 200 25 200H125C138.807 200 150 188.807 150 175V62.5L87.5 0H25Z" fill="#C8D6E5"/>
<g filter="url(#filter0_d_150_59)">
<g clip-path="url(#clip0_150_59)">
<path d="M87.5 62.5L150 62.5L87.5 1.78815e-07V62.5Z" fill="#C8D6E5"/>
</g>
</g>
<path d="M75.5 174C86.7717 174 97.5817 169.522 105.552 161.552C113.522 153.582 118 142.772 118 131.5C118 120.228 113.522 109.418 105.552 101.448C97.5817 93.4777 86.7717 89 75.5 89C64.2283 89 53.4183 93.4777 45.448 101.448C37.4777 109.418 33 120.228 33 131.5C33 142.772 37.4777 153.582 45.448 161.552C53.4183 169.522 64.2283 174 75.5 174ZM68.8594 144.781H72.8438V134.156H68.8594C66.6514 134.156 64.875 132.38 64.875 130.172C64.875 127.964 66.6514 126.188 68.8594 126.188H76.8281C79.0361 126.188 80.8125 127.964 80.8125 130.172V144.781H82.1406C84.3486 144.781 86.125 146.558 86.125 148.766C86.125 150.974 84.3486 152.75 82.1406 152.75H68.8594C66.6514 152.75 64.875 150.974 64.875 148.766C64.875 146.558 66.6514 144.781 68.8594 144.781ZM75.5 110.25C76.909 110.25 78.2602 110.81 79.2565 111.806C80.2528 112.802 80.8125 114.154 80.8125 115.562C80.8125 116.971 80.2528 118.323 79.2565 119.319C78.2602 120.315 76.909 120.875 75.5 120.875C74.091 120.875 72.7398 120.315 71.7435 119.319C70.7472 118.323 70.1875 116.971 70.1875 115.562C70.1875 114.154 70.7472 112.802 71.7435 111.806C72.7398 110.81 74.091 110.25 75.5 110.25Z" fill="#222F3E"/>
</g>
<defs>
<filter id="filter0_d_150_59" x="65.0281" y="-139.972" width="224.944" height="224.944" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset/>
<feGaussianBlur stdDeviation="11.236"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_150_59"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_150_59" result="shape"/>
</filter>
<clipPath id="clip0_150_59">
<rect x="87.5" y="-117.5" width="180" height="180" rx="25" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View file

@ -0,0 +1,30 @@
<svg width="150" height="200" viewBox="0 0 150 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="mask0_150_72" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="150" height="200">
<path d="M25 0C11.1929 0 0 11.1929 0 25V175C0 188.807 11.1929 200 25 200H125C138.807 200 150 188.807 150 175V62.5L87.5 0H25Z" fill="#C8D6E5"/>
</mask>
<g mask="url(#mask0_150_72)">
<path d="M25 0C11.1929 0 0 11.1929 0 25V175C0 188.807 11.1929 200 25 200H125C138.807 200 150 188.807 150 175V62.5L87.5 0H25Z" fill="#C8D6E5"/>
<g filter="url(#filter0_d_150_72)">
<g clip-path="url(#clip0_150_72)">
<path d="M87.5 62.5L150 62.5L87.5 1.78815e-07V62.5Z" fill="#C8D6E5"/>
</g>
</g>
<rect x="37.5" y="100" width="75" height="12.5" rx="6.25" fill="#222F3E"/>
<rect x="37.5" y="125" width="75" height="12.5" rx="6.25" fill="#222F3E"/>
<rect x="37.5" y="150" width="75" height="12.5" rx="6.25" fill="#222F3E"/>
</g>
<defs>
<filter id="filter0_d_150_72" x="65.0281" y="-139.972" width="224.944" height="224.944" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset/>
<feGaussianBlur stdDeviation="11.236"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_150_72"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_150_72" result="shape"/>
</filter>
<clipPath id="clip0_150_72">
<rect x="87.5" y="-117.5" width="180" height="180" rx="25" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -0,0 +1,27 @@
<svg width="150" height="200" viewBox="0 0 150 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="mask0_146_65" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="150" height="200">
<path d="M25 0C11.1929 0 0 11.1929 0 25V175C0 188.807 11.1929 200 25 200H125C138.807 200 150 188.807 150 175V62.5L87.5 0H25Z" fill="#C8D6E5"/>
</mask>
<g mask="url(#mask0_146_65)">
<path d="M25 0C11.1929 0 0 11.1929 0 25V175C0 188.807 11.1929 200 25 200H125C138.807 200 150 188.807 150 175V62.5L87.5 0H25Z" fill="#C8D6E5"/>
<g filter="url(#filter0_d_146_65)">
<g clip-path="url(#clip0_146_65)">
<path d="M87.5 62.5L150 62.5L87.5 1.78815e-07V62.5Z" fill="#C8D6E5"/>
</g>
</g>
</g>
<defs>
<filter id="filter0_d_146_65" x="65.0281" y="-139.972" width="224.944" height="224.944" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset/>
<feGaussianBlur stdDeviation="11.236"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_146_65"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_146_65" result="shape"/>
</filter>
<clipPath id="clip0_146_65">
<rect x="87.5" y="-117.5" width="180" height="180" rx="25" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -0,0 +1,24 @@
<svg width="200" height="176" viewBox="0 0 200 176" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="mask0_146_93" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="200" height="176">
<path d="M25 175.5H175C188.789 175.5 200 164.289 200 150.5V50.5C200 36.7109 188.789 25.5 175 25.5H112.5C108.555 25.5 104.844 23.6641 102.5 20.5L95 10.5C90.2734 4.21094 82.8516 0.5 75 0.5H25C11.2109 0.5 0 11.7109 0 25.5V150.5C0 164.289 11.2109 175.5 25 175.5Z" fill="#FF9F43"/>
</mask>
<g mask="url(#mask0_146_93)">
<path d="M25 175.5H175C188.789 175.5 200 164.289 200 150.5V50.5C200 36.7109 188.789 25.5 175 25.5H112.5C108.555 25.5 104.844 23.6641 102.5 20.5L95 10.5C90.2734 4.21094 82.8516 0.5 75 0.5H25C11.2109 0.5 0 11.7109 0 25.5V150.5C0 164.289 11.2109 175.5 25 175.5Z" fill="#FF9F43"/>
<g filter="url(#filter0_d_146_93)">
<rect y="37" width="200" height="139" rx="25" fill="#FECA57"/>
</g>
<path d="M52 76.1429C52 69.4453 57.4373 64 64.125 64H136.875C143.563 64 149 69.4453 149 76.1429V136.857C149 143.555 143.563 149 136.875 149H64.125C57.4373 149 52 143.555 52 136.857V76.1429Z" fill="#FECA57"/>
<path d="M52 76.1429C52 69.4453 57.4373 64 64.125 64H136.875C143.563 64 149 69.4453 149 76.1429V136.857C149 143.555 143.563 149 136.875 149H64.125C57.4373 149 52 143.555 52 136.857V76.1429ZM113.345 96.3493C112.492 95.0971 111.09 94.3571 109.594 94.3571C108.097 94.3571 106.676 95.0971 105.843 96.3493L89.3602 120.559L84.3396 114.279C83.4682 113.198 82.1609 112.571 80.7969 112.571C79.4328 112.571 78.1066 113.198 77.2541 114.279L65.1291 129.458C64.0303 130.824 63.8219 132.702 64.5797 134.277C65.3375 135.852 66.9289 136.857 68.6719 136.857H86.8594H92.9219H132.328C134.014 136.857 135.568 135.927 136.345 134.429C137.121 132.93 137.027 131.127 136.079 129.742L113.345 96.3493ZM73.2188 94.3571C75.6306 94.3571 77.9436 93.3976 79.649 91.6897C81.3544 89.9818 82.3125 87.6654 82.3125 85.25C82.3125 82.8346 81.3544 80.5182 79.649 78.8103C77.9436 77.1024 75.6306 76.1429 73.2188 76.1429C70.8069 76.1429 68.4939 77.1024 66.7885 78.8103C65.0831 80.5182 64.125 82.8346 64.125 85.25C64.125 87.6654 65.0831 89.9818 66.7885 91.6897C68.4939 93.3976 70.8069 94.3571 73.2188 94.3571Z" fill="#222F3E"/>
</g>
<defs>
<filter id="filter0_d_146_93" x="-20" y="17" width="240" height="179" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset/>
<feGaussianBlur stdDeviation="10"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_146_93"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_146_93" result="shape"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View file

@ -0,0 +1,24 @@
<svg width="200" height="176" viewBox="0 0 200 176" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="mask0_146_57" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="200" height="176">
<path d="M25 175.5H175C188.789 175.5 200 164.289 200 150.5V50.5C200 36.7109 188.789 25.5 175 25.5H112.5C108.555 25.5 104.844 23.6641 102.5 20.5L95 10.5C90.2734 4.21094 82.8516 0.5 75 0.5H25C11.2109 0.5 0 11.7109 0 25.5V150.5C0 164.289 11.2109 175.5 25 175.5Z" fill="#FF9F43"/>
</mask>
<g mask="url(#mask0_146_57)">
<path d="M25 175.5H175C188.789 175.5 200 164.289 200 150.5V50.5C200 36.7109 188.789 25.5 175 25.5H112.5C108.555 25.5 104.844 23.6641 102.5 20.5L95 10.5C90.2734 4.21094 82.8516 0.5 75 0.5H25C11.2109 0.5 0 11.7109 0 25.5V150.5C0 164.289 11.2109 175.5 25 175.5Z" fill="#FF9F43"/>
<g filter="url(#filter0_d_146_57)">
<rect y="37" width="200" height="139" rx="25" fill="#FECA57"/>
</g>
<path d="M58 106.5C58 117.772 62.4777 128.582 70.448 136.552C78.4183 144.522 89.2283 149 100.5 149C111.772 149 122.582 144.522 130.552 136.552C138.522 128.582 143 117.772 143 106.5C143 95.2283 138.522 84.4183 130.552 76.448C122.582 68.4777 111.772 64 100.5 64C89.2283 64 78.4183 68.4777 70.448 76.448C62.4777 84.4183 58 95.2283 58 106.5Z" fill="#FECA57"/>
<path d="M58 106.5C58 117.772 62.4777 128.582 70.448 136.552C78.4183 144.522 89.2283 149 100.5 149C111.772 149 122.582 144.522 130.552 136.552C138.522 128.582 143 117.772 143 106.5C143 95.2283 138.522 84.4183 130.552 76.448C122.582 68.4777 111.772 64 100.5 64C89.2283 64 78.4183 68.4777 70.448 76.448C62.4777 84.4183 58 95.2283 58 106.5ZM104.65 127.916C103.09 129.477 100.566 129.477 99.0225 127.916C97.4785 126.355 97.4619 123.832 99.0225 122.288L110.81 110.501L80.5781 110.484C78.3701 110.484 76.5938 108.708 76.5938 106.5C76.5938 104.292 78.3701 102.516 80.5781 102.516H110.81L99.0225 90.7285C97.4619 89.168 97.4619 86.6445 99.0225 85.1006C100.583 83.5566 103.106 83.54 104.65 85.1006L123.244 103.678C124.805 105.238 124.805 107.762 123.244 109.306L104.65 127.916Z" fill="#222F3E"/>
</g>
<defs>
<filter id="filter0_d_146_57" x="-20" y="17" width="240" height="179" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset/>
<feGaussianBlur stdDeviation="10"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_146_57"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_146_57" result="shape"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View file

@ -0,0 +1,23 @@
<svg width="200" height="176" viewBox="0 0 200 176" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="mask0_146_102" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="200" height="176">
<path d="M25 175.5H175C188.789 175.5 200 164.289 200 150.5V50.5C200 36.7109 188.789 25.5 175 25.5H112.5C108.555 25.5 104.844 23.6641 102.5 20.5L95 10.5C90.2734 4.21094 82.8516 0.5 75 0.5H25C11.2109 0.5 0 11.7109 0 25.5V150.5C0 164.289 11.2109 175.5 25 175.5Z" fill="#FF9F43"/>
</mask>
<g mask="url(#mask0_146_102)">
<path d="M25 175.5H175C188.789 175.5 200 164.289 200 150.5V50.5C200 36.7109 188.789 25.5 175 25.5H112.5C108.555 25.5 104.844 23.6641 102.5 20.5L95 10.5C90.2734 4.21094 82.8516 0.5 75 0.5H25C11.2109 0.5 0 11.7109 0 25.5V150.5C0 164.289 11.2109 175.5 25 175.5Z" fill="#FF9F43"/>
<g filter="url(#filter0_d_146_102)">
<rect y="37" width="200" height="139" rx="25" fill="#FECA57"/>
</g>
<path d="M116.272 133.996H84.5701L79.4881 149H57.8291L88.5631 64.058H112.521L143.255 149H121.354L116.272 133.996ZM110.948 118.024L100.421 86.927L90.0151 118.024H110.948Z" fill="#222F3E"/>
</g>
<defs>
<filter id="filter0_d_146_102" x="-20" y="17" width="240" height="179" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset/>
<feGaussianBlur stdDeviation="10"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_146_102"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_146_102" result="shape"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -0,0 +1,27 @@
<svg width="200" height="176" viewBox="0 0 200 176" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_146_55)">
<mask id="mask0_146_55" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="200" height="176">
<path d="M25 175.5H175C188.789 175.5 200 164.289 200 150.5V50.5C200 36.7109 188.789 25.5 175 25.5H112.5C108.555 25.5 104.844 23.6641 102.5 20.5L95 10.5C90.2734 4.21094 82.8516 0.5 75 0.5H25C11.2109 0.5 0 11.7109 0 25.5V150.5C0 164.289 11.2109 175.5 25 175.5Z" fill="#FF9F43"/>
</mask>
<g mask="url(#mask0_146_55)">
<path d="M25 175.5H175C188.789 175.5 200 164.289 200 150.5V50.5C200 36.7109 188.789 25.5 175 25.5H112.5C108.555 25.5 104.844 23.6641 102.5 20.5L95 10.5C90.2734 4.21094 82.8516 0.5 75 0.5H25C11.2109 0.5 0 11.7109 0 25.5V150.5C0 164.289 11.2109 175.5 25 175.5Z" fill="#FF9F43"/>
<g filter="url(#filter0_d_146_55)">
<rect y="37" width="200" height="139" rx="25" fill="#FECA57"/>
</g>
</g>
</g>
<defs>
<filter id="filter0_d_146_55" x="-20" y="17" width="240" height="179" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset/>
<feGaussianBlur stdDeviation="10"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_146_55"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_146_55" result="shape"/>
</filter>
<clipPath id="clip0_146_55">
<rect width="200" height="175" fill="white" transform="translate(0 0.5)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -11,7 +11,7 @@ import { QuickAccessButton } from "./QuickAccessButton.jsx";
import { useDialogBox } from "../../../hooks/modals/dialogBox.js";
import Vector2 from "../../../features/math/vector2.js";
import { DIALOG_CONTENT_TYPES } from "../../../constants/modals.js";
import { DirectoryList } from "./DirectoryList.jsx";
import { DirectoryList } from "./directory-list/DirectoryList.jsx";
export function FileExplorer({ startPath, app }) {
const virtualRoot = useVirtualRoot();
@ -130,8 +130,8 @@ export function FileExplorer({ startPath, app }) {
<div className={styles.Sidebar}>
<QuickAccessButton name={"Home"} onClick={() => { changeDirectory("~"); }} icon={faHouse}/>
<QuickAccessButton name={"Desktop"} onClick={() => { changeDirectory("~/Desktop"); }} icon={faDesktop}/>
<QuickAccessButton name={"Documents"} onClick={() => { changeDirectory("~/Documents"); }} icon={faFileLines}/>
<QuickAccessButton name={"Images"} onClick={() => { changeDirectory("~/Images"); }} icon={faImage}/>
<QuickAccessButton name={"Documents"} onClick={() => { changeDirectory("~/Documents"); }} icon={faFileLines}/>
</div>
<div id="main" className={styles.Main}>
<DirectoryList

View file

@ -1,31 +0,0 @@
import { faFile, faFileInvoice, faFileLines } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import styles from "./FilePreview.module.css";
import { VirtualFile } from "../../../features/virtual-drive/virtualFile.js";
/**
* @param {object} props
* @param {VirtualFile} props.file
*/
export function FilePreview({ file }) {
let preview = null;
switch (file.extension) {
case "png":
preview = (<div className={styles["File-button-preview"]}>
<img src={file.source} alt={file.id} draggable="false"/>
</div>);
break;
case "txt":
preview = <FontAwesomeIcon icon={faFileLines}/>;
break;
case "md":
preview = <FontAwesomeIcon icon={faFileInvoice}/>;
break;
default:
preview = <FontAwesomeIcon icon={faFile}/>;
break;
}
return preview;
}

View file

@ -1,18 +0,0 @@
import { faFolder, faLink } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import styles from "./FolderPreview.module.css";
import { VirtualFolder } from "../../../features/virtual-drive/virtualFolder.js";
/**
* @param {object} props
* @param {VirtualFolder} props.folder
*/
export function FolderPreview({ folder }) {
return (<div>
<FontAwesomeIcon icon={faFolder}/>
{folder.linkedPath
? <div className={styles["Folder-link-icon"]}><FontAwesomeIcon icon={faLink}/></div>
: null
}
</div>);
}

View file

@ -1,20 +0,0 @@
.Folder-link-icon {
position: absolute;
display: flex;
justify-content: flex-end;
align-items: flex-end;
top: 0;
left: 0;
width: 92.5%;
height: 87.5%;
}
.Folder-link-icon svg {
width: 55%;
height: auto;
aspect-ratio: 1;
}
.Folder-link-icon svg * {
fill: var(--background-color-b);
}

View file

@ -1,7 +1,7 @@
import { VirtualFile } from "../../../features/virtual-drive/virtualFile.js";
import { VirtualFolder } from "../../../features/virtual-drive/virtualFolder.js";
import { FilePreview } from "./FilePreview.jsx";
import { FolderPreview } from "./FolderPreview.jsx";
import { VirtualFile } from "../../../../features/virtual-drive/virtualFile.js";
import { VirtualFolder } from "../../../../features/virtual-drive/virtualFolder.js";
import { FileIcon } from "./FileIcon.jsx";
import { FolderIcon } from "./FolderIcon.jsx";
import styles from "./DirectoryList.module.css";
/**
@ -32,23 +32,28 @@ export function DirectoryList({ directory, showHidden = false, folderClassname,
if (!directory)
return null;
// const folders = directory.getSubFolders(showHidden);
// const files = directory.getFiles(showHidden);
const folderClassNames = [styles["Folder-button"]];
const fileClassNames = [styles["File-button"]];
if (folderClassname)
folderClassNames.push(folderClassname);
if (fileClassname)
fileClassNames.push(fileClassname);
return <>
{directory?.getSubFolders(showHidden)?.map((folder) =>
<button
key={folder.id}
tabIndex={0}
className={`${styles["Folder-button"]} ${folderClassname}`}
className={folderClassNames.join(" ")}
onContextMenu={(event) => {
onContextMenuFolder(event, folder);
onContextMenuFolder?.(event, folder);
}}
onClick={(event) => {
onClickFolder(event, folder);
onClickFolder?.(event, folder);
}}
>
<FolderPreview folder={folder}/>
<FolderIcon folder={folder} iconUrl={folder.getIconUrl()}/>
<p>{folder.name}</p>
</button>
)}
@ -56,15 +61,15 @@ export function DirectoryList({ directory, showHidden = false, folderClassname,
<button
key={file.id}
tabIndex={0}
className={`${styles["File-button"]} ${fileClassname}`}
className={fileClassNames.join(" ")}
onContextMenu={(event) => {
onContextMenuFile(event, file);
onContextMenuFile?.(event, file);
}}
onClick={(event) => {
onClickFile(event, file);
onClickFile?.(event, file);
}}
>
<FilePreview file={file}/>
<FileIcon file={file} iconUrl={file.getIconUrl()}/>
<p>{file.id}</p>
</button>
)}

View file

@ -1,6 +1,6 @@
.File-button, .Folder-button {
display: flex;
gap: 0.5rem;
gap: 0.25rem;
flex-direction: column;
align-items: center;
justify-content: center;
@ -15,29 +15,26 @@
transition: background-color 100ms ease-in-out;
}
.File-button:hover, .Folder-button:hover,
.File-button:focus-visible, .Folder-button:focus-visible {
.File-button:hover,
.Folder-button:hover,
.File-button:focus-visible,
.Folder-button:focus-visible {
background-color: hsla(var(--background-color-a-hsl), 35%);
}
.File-button svg, .Folder-button > div {
width: 50%;
height: auto;
aspect-ratio: 1;
}
.Folder-button > div > svg {
width: 100%;
height: 100%;
aspect-ratio: 1;
}
.File-button p, .Folder-button p {
max-width: 100%;
margin: 0;
word-wrap: break-word;
}
.Folder-button > div {
position: relative;
.File-icon div, .Folder-icon div {
width: 100%;
height: 100%;
}
.File-icon svg, .Folder-icon svg {
width: 50%;
height: auto;
aspect-ratio: 1;
}

View file

@ -0,0 +1,38 @@
import styles from "./DirectoryList.module.css";
import { VirtualFile } from "../../../../features/virtual-drive/virtualFile.js";
import { ImagePreview } from "./ImagePreview.jsx";
import AppsManager from "../../../../features/applications/applications.js";
import { APPS } from "../../../../constants/applications.js";
/**
* @param {object} props
* @param {VirtualFile} props.file
* @param {string} props.iconUrl
*/
export function FileIcon({ file, iconUrl }) {
let preview = null;
if (iconUrl && file.extension !== "png") {
preview = <ImagePreview source={iconUrl}/>;
} else {
switch (file.extension) {
case "png":
preview = <ImagePreview source={file.source}/>;
break;
case "txt":
case "md":
preview = <ImagePreview source={AppsManager.getAppIconUrl(APPS.FILE_EXPLORER, "file-text")}/>;
break;
case "xml":
preview = <ImagePreview source={AppsManager.getAppIconUrl(APPS.FILE_EXPLORER, "file-code")}/>;
break;
default:
preview = <ImagePreview source={AppsManager.getAppIconUrl(APPS.FILE_EXPLORER, "file")}/>;
break;
}
}
return (<div className={styles["File-icon"]}>
{preview}
</div>);
}

View file

@ -0,0 +1,26 @@
import styles from "./DirectoryList.module.css";
import { VirtualFolder } from "../../../../features/virtual-drive/virtualFolder.js";
import { ImagePreview } from "./ImagePreview.jsx";
import AppsManager from "../../../../features/applications/applications.js";
import { APPS } from "../../../../constants/applications.js";
/**
* @param {object} props
* @param {VirtualFolder} props.folder
* @param {string} props.iconUrl
*/
export function FolderIcon({ folder, iconUrl }) {
let preview = null;
if (iconUrl) {
preview = <ImagePreview source={iconUrl}/>;
} else if (folder.linkedPath) {
preview = <ImagePreview source={AppsManager.getAppIconUrl(APPS.FILE_EXPLORER, "folder-link")}/>;
} else {
preview = <ImagePreview source={AppsManager.getAppIconUrl(APPS.FILE_EXPLORER, "folder")}/>;
}
return (<div className={styles["Folder-icon"]}>
{preview}
</div>);
}

View file

@ -0,0 +1,19 @@
import { useState } from "react";
import styles from "./ImagePreview.module.css";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faFile } from "@fortawesome/free-solid-svg-icons";
import { ReactSVG } from "react-svg";
export function ImagePreview({ source }) {
const [loadingFailed, setLoadingFailed] = useState(false);
if (loadingFailed)
return <FontAwesomeIcon icon={faFile}/>;
return (<div className={styles["Image-preview"]}>
{source.endsWith(".svg")
? <ReactSVG src={source}/>
: <img src={source} onError={() => { setLoadingFailed(true); }} alt="Preview" draggable="false"/>
}
</div>);
}

View file

@ -1,4 +1,4 @@
.File-button-preview {
.Image-preview {
display: flex;
justify-content: center;
align-items: center;
@ -6,13 +6,13 @@
overflow: hidden;
}
.File-button-preview > * {
.Image-preview > * {
width: 100%;
height: 100%;
object-fit: contain;
}
.File-button-preview > img {
.Image-preview > img {
height: auto;
max-height: 100%;
border-radius: 0.5rem;

View file

@ -3,6 +3,7 @@ import { useEffect } from "react";
import { VirtualFile } from "../../../features/virtual-drive/virtualFile.js";
import { useWindowsManager } from "../../../hooks/windows/windowsManagerContext.js";
import styles from "./MediaViewer.module.css";
import { APPS } from "../../../constants/applications.js";
/**
* @param {object} props
@ -20,7 +21,7 @@ export function MediaViewer({ file, close, setTitle }) {
if (file == null) {
setTimeout(() => {
windowsManager.open("file-explorer", { startPath: "~/Images" });
windowsManager.open(APPS.FILE_EXPLORER, { startPath: "~/Images" });
close();
}, 10);
return;

View file

@ -5,6 +5,7 @@ import { HeaderMenu } from "../.common/HeaderMenu.jsx";
import Markdown from "markdown-to-jsx";
import Application from "../../../features/applications/application.js";
import { DEFAULT_ZOOM, ZOOM_FACTOR } from "../../../constants/applications/textEditor.js";
import AppsManager from "../../../features/applications/applications.js";
/**
* @param {object} props
@ -13,8 +14,9 @@ import { DEFAULT_ZOOM, ZOOM_FACTOR } from "../../../constants/applications/textE
* @param {Function} props.close
* @param {string} props.mode
* @param {Application} props.app
* @param {Function} props.setIconUrl
*/
export function TextEditor({ file, setTitle, close, mode, app }) {
export function TextEditor({ file, setTitle, setIconUrl, close, mode, app }) {
const [currentFile, setCurrentFile] = useState(file);
const [currentMode, setCurrentMode] = useState(mode);
const [content, setContent] = useState(file?.content ?? "");
@ -25,6 +27,7 @@ export function TextEditor({ file, setTitle, close, mode, app }) {
(async () => {
let newContent = "";
// Load file
if (currentFile) {
if (currentFile.content) {
newContent = currentFile.content;
@ -35,13 +38,21 @@ export function TextEditor({ file, setTitle, close, mode, app }) {
newContent = response;
});
}
const iconUrl = currentFile.getIconUrl();
console.log(iconUrl);
if (iconUrl)
setIconUrl(iconUrl);
} else {
setIconUrl(AppsManager.getAppIconUrl(app.id));
}
setContent(newContent);
})();
}, [currentFile]);
}, [app.id, currentFile, setIconUrl]);
useEffect(() => {
// Update title
let label = currentFile?.id ?? "Untitled";
if (unsavedChanges)

View file

@ -10,7 +10,9 @@ import { useContextMenu } from "../../hooks/modals/contextMenu.js";
import { FALLBACK_WALLPAPER } from "../../constants/desktop.js";
import { reloadViewport } from "../../features/utils/browser.js";
import { useVirtualRoot } from "../../hooks/virtual-drive/virtualRootContext.js";
import { DirectoryList } from "../applications/file-explorer/DirectoryList.jsx";
import { DirectoryList } from "../applications/file-explorer/directory-list/DirectoryList.jsx";
import { APPS } from "../../constants/applications.js";
import Vector2 from "../../features/math/vector2.js";
export const Desktop = memo(() => {
const settingsManager = useSettingsManager();
@ -23,7 +25,7 @@ export const Desktop = memo(() => {
options: {
"Refresh": () => { reloadViewport(); },
"Change appearance": () => { windowsManager.open("settings", { initialTabIndex: 0 }); },
"Open in Files": () => { windowsManager.open("file-explorer", { startPath: "~/Desktop" }); },
"Open in Files": () => { windowsManager.open(APPS.FILE_EXPLORER, { startPath: "~/Desktop" }); },
}
});
@ -54,10 +56,17 @@ export const Desktop = memo(() => {
folderClassname={styles["Item"]}
onClickFile={(event, file) => {
event.preventDefault();
windowsManager.openFile(file);
const options = {};
if (file.name === "info.md") {
options.mode = "view";
options.size = new Vector2(575, 675);
}
windowsManager.openFile(file, options);
}}
onClickFolder={(event, { linkedPath, path }) => {
windowsManager.open("file-explorer", { startPath: linkedPath ?? path });
windowsManager.open(APPS.FILE_EXPLORER, { startPath: linkedPath ?? path });
}}
/>
</div>

View file

@ -36,9 +36,9 @@
.Item {
padding: 0.25rem;
text-shadow: 0.1rem 0.1rem 0.2rem hsla(var(--background-color-a-hsl), 50%);
text-shadow: 0.1rem 0.1rem 0.2rem hsla(var(--background-color-a-hsl), 75%);
}
.Item > svg, .Item > div > svg {
.Item svg {
filter: drop-shadow(0.1rem 0.1rem 0.2rem hsla(var(--background-color-a-hsl), 50%));
}

View file

@ -2,7 +2,7 @@ import { memo, useRef, useState } from "react";
import styles from "./TaskBar.module.css";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faSearch } from "@fortawesome/free-solid-svg-icons";
import ApplicationsManager from "../../features/applications/applications.js";
import AppsManager from "../../features/applications/applications.js";
import { ReactSVG } from "react-svg";
import { HomeMenu } from "./menus/HomeMenu.jsx";
import OutsideClickListener from "../../hooks/utils/outsideClick.js";
@ -105,7 +105,7 @@ export const Taskbar = memo(() => {
</div>
<div className={styles["App-icons"]} style={{ boxShadow }}>
<div className={styles["App-icons-inner"]} onScroll={onUpdate} onResize={onUpdate} ref={ref}>
{ApplicationsManager.APPLICATIONS.map((app) =>
{AppsManager.APPLICATIONS.map((app) =>
<AppButton app={app} key={app.id}/>
)}
</div>

View file

@ -3,7 +3,7 @@ import styles from "./HomeMenu.module.css";
import appStyles from "./AppList.module.css";
import { faCircleInfo, faFileLines, faGear, faImage, faPowerOff } from "@fortawesome/free-solid-svg-icons";
import { useWindowsManager } from "../../../hooks/windows/windowsManagerContext.js";
import ApplicationsManager from "../../../features/applications/applications.js";
import AppsManager from "../../../features/applications/applications.js";
import { ReactSVG } from "react-svg";
import { closeViewport } from "../../../features/utils/browser.js";
import { useKeyboardListener } from "../../../hooks/utils/keyboard.js";
@ -11,6 +11,7 @@ import { useVirtualRoot } from "../../../hooks/virtual-drive/virtualRootContext.
import { useEffect, useState } from "react";
import Vector2 from "../../../features/math/vector2.js";
import utilStyles from "../../../styles/utils.module.css";
import { APPS } from "../../../constants/applications.js";
/**
* @param {object} props
@ -82,13 +83,13 @@ export function HomeMenu({ active, setActive, search }) {
</button>
<button title="Images" tabIndex={tabIndex} onClick={() => {
setActive(false);
windowsManager.open("file-explorer", { startPath: "~/Images" });
windowsManager.open(APPS.FILE_EXPLORER, { startPath: "~/Images" });
}}>
<FontAwesomeIcon icon={faImage}/>
</button>
<button title="Documents" tabIndex={tabIndex} onClick={() => {
setActive(false);
windowsManager.open("file-explorer", { startPath: "~/Documents" }); }
windowsManager.open(APPS.FILE_EXPLORER, { startPath: "~/Documents" }); }
}>
<FontAwesomeIcon icon={faFileLines}/>
</button>
@ -96,7 +97,7 @@ export function HomeMenu({ active, setActive, search }) {
<div className={styles.Apps}>
<h1 className={utilStyles["Text-bold"]}>ProzillaOS</h1>
<div className={appStyles["App-list"]}>
{ApplicationsManager.APPLICATIONS.map(({ name, id }) =>
{AppsManager.APPLICATIONS.map(({ name, id }) =>
<button
key={id}
className={appStyles["App-button"]}
@ -107,7 +108,7 @@ export function HomeMenu({ active, setActive, search }) {
}}
title={name}
>
<ReactSVG src={`${process.env.PUBLIC_URL}/media/applications/icons/${id}.svg`}/>
<ReactSVG src={AppsManager.getAppIconUrl(id)}/>
<h2 className={utilStyles["Text-regular"]}>{name}</h2>
</button>
)}

View file

@ -1,6 +1,6 @@
import styles from "./SearchMenu.module.css";
import appStyles from "./AppList.module.css";
import ApplicationsManager from "../../../features/applications/applications.js";
import AppsManager from "../../../features/applications/applications.js";
import { useWindowsManager } from "../../../hooks/windows/windowsManagerContext.js";
import { ReactSVG } from "react-svg";
import { useEffect } from "react";
@ -32,7 +32,7 @@ export function SearchMenu({ active, setActive, searchQuery, setSearchQuery, inp
}, [inputRef]);
useEffect(() => {
setApps(ApplicationsManager.APPLICATIONS.filter(({ name }) =>
setApps(AppsManager.APPLICATIONS.filter(({ name }) =>
name.toLowerCase().includes(searchQuery.toLowerCase().trim())
));
}, [searchQuery]);
@ -78,7 +78,7 @@ export function SearchMenu({ active, setActive, searchQuery, setSearchQuery, inp
windowsManager.open(id);
}}
>
<ReactSVG src={`${process.env.PUBLIC_URL}/media/applications/icons/${id}.svg`}/>
<ReactSVG src={AppsManager.getAppIconUrl(id)}/>
<p>{name}</p>
</button>
)}

View file

@ -12,6 +12,7 @@ import utilStyles from "../../styles/utils.module.css";
import { useModals } from "../../hooks/modals/modals.js";
import { ModalsView } from "../modals/ModalsView.jsx";
import { useContextMenu } from "../../hooks/modals/contextMenu.js";
import AppsManager from "../../features/applications/applications.js";
/**
* @param {object} props
@ -40,6 +41,7 @@ export const WindowView = memo(({ id, app, size, position, onInteract, options,
const [screenHeight, setScreenHeight] = useState(100);
const [title, setTitle] = useState(app.name);
const [iconUrl, setIconUrl] = useState(AppsManager.getAppIconUrl(app.id));
const { onContextMenu } = useContextMenu({
modalsManager,
@ -137,7 +139,7 @@ export const WindowView = memo(({ id, app, size, position, onInteract, options,
<div className={`${styles.Header} Window-handle`} onContextMenu={onContextMenu}>
<ReactSVG
className={styles["Window-icon"]}
src={process.env.PUBLIC_URL + `/media/applications/icons/${app.id}.svg`}
src={iconUrl}
/>
<p className={utilStyles["Text-semibold"]}>{title}</p>
<button aria-label="Minimize" className={styles["Header-button"]} tabIndex={0} id="minimize-window"
@ -162,7 +164,15 @@ export const WindowView = memo(({ id, app, size, position, onInteract, options,
</button>
</div>
<div className={styles["Window-content"]}>
<app.WindowContent {...options} app={app} setTitle={setTitle} close={close} focus={focus} active={active}/>
<app.WindowContent
{...options}
app={app}
setTitle={setTitle}
setIconUrl={setIconUrl}
close={close}
focus={focus}
active={active}
/>
</div>
</div>
</Draggable>

View file

@ -0,0 +1,7 @@
export const APPS = {
TERMINAL: "terminal",
SETTINGS: "settings",
MEDIA_VIEWER: "media-viewer",
TEXT_EDITOR: "text-editor",
FILE_EXPLORER: "file-explorer"
};

View file

@ -7,17 +7,18 @@ import { TextEditor } from "../../components/applications/text-editor/TextEditor
import { Settings } from "../../components/applications/settings/Settings.jsx";
// import { Calculator } from "../../components/applications/calculator/Calculator.jsx";
import Vector2 from "../math/vector2.js";
import { APPS } from "../../constants/applications.js";
export default class ApplicationsManager {
export default class AppsManager {
static APPLICATIONS = [
new Application("Commands", "terminal", Terminal),
new Application("Settings", "settings", Settings),
new Application("Photos", "media-viewer", MediaViewer),
new Application("Commands", APPS.TERMINAL, Terminal),
new Application("Settings", APPS.SETTINGS, Settings),
new Application("Photos", APPS.MEDIA_VIEWER, MediaViewer),
// new Application("Browser", "browser"),
// new Application("Calculator", "calculator", Calculator, { size: new Vector2(400, 600) }),
new Application("Notes", "text-editor", TextEditor),
new Application("Notes", APPS.TEXT_EDITOR, TextEditor),
// new Application("Code Editor", "code-editor"),
new Application("Files", "file-explorer", FileExplorer),
new Application("Files", APPS.FILE_EXPLORER, FileExplorer),
new Application("Wordle", "wordle", WebView, {
source: "https://prozilla.dev/wordle",
size: new Vector2(400, 650)
@ -36,7 +37,7 @@ export default class ApplicationsManager {
* @param {string} id
* @returns {Application | null}
*/
static getApplication(id) {
static getApp(id) {
let application = null;
this.APPLICATIONS.forEach((app) => {
@ -54,21 +55,35 @@ export default class ApplicationsManager {
* @param {string} fileExtension
* @returns {Application}
*/
static getFileApplication(fileExtension) {
static getFileApp(fileExtension) {
let app = null;
// eslint-disable-next-line default-case
switch (fileExtension) {
case "png":
app = this.getApplication("media-viewer");
app = this.getApp(APPS.MEDIA_VIEWER);
break;
case "txt":
case "md":
case "xml":
app = this.getApplication("text-editor");
app = this.getApp(APPS.TEXT_EDITOR);
break;
}
return app;
}
/**
* Returns the url of an icon inside the icons folder or the default icon of an app
* @param {string} appId
* @param {string | null} iconName
* @returns {string}
*/
static getAppIconUrl(appId, iconName) {
if (iconName == null) {
return `${process.env.PUBLIC_URL}/media/applications/icons/${appId}.svg`;
} else {
return `${process.env.PUBLIC_URL}/media/applications/${appId}/icons/${iconName}.svg`;
}
}
}

View file

@ -1,7 +1,8 @@
import { APPS } from "../../../../constants/applications.js";
import { ASCII_LOGO, NAME } from "../../../../constants/branding.js";
import { START_DATE } from "../../../../index.js";
import { formatRelativeTime } from "../../../utils/date.js";
import ApplicationsManager from "../../applications.js";
import AppsManager from "../../applications.js";
import Command from "../command.js";
export const neofetch = new Command("neofetch", (args, { username, hostname }) => {
@ -32,7 +33,7 @@ export const neofetch = new Command("neofetch", (args, { username, hostname }) =
`RESOLUTION: ${window.innerWidth}x${window.innerHeight}`,
"THEME: default",
"ICONS: Font Awesome",
`TERMINAL: ${ApplicationsManager.getApplication("terminal")?.name ?? "Unknown"}`,
`TERMINAL: ${AppsManager.getApp(APPS.TERMINAL)?.name ?? "Unknown"}`,
`BROWSER: ${browserName}`,
`PLATFORM: ${navigator.platform}`,
`LANGUAGE: ${navigator.language}`,

View file

@ -69,6 +69,27 @@ export class VirtualBase extends EventEmitter {
return this;
}
/**
* @param {string} iconUrl
* @returns {VirtualBase}
*/
setIconUrl(iconUrl) {
if (this.iconUrl === iconUrl || !this.canBeEdited)
return;
this.iconUrl = iconUrl;
this.confirmChanges();
return this;
}
/**
* @returns {string}
*/
getIconUrl = () => {
return this.iconUrl ?? this.linkedFile?.iconUrl ?? this.linkedFolder?.iconUrl;
};
delete() {
if (!this.canBeEdited)
return;
@ -168,7 +189,8 @@ export class VirtualBase extends EventEmitter {
*/
toJSON() {
const object = {
nam: this.name
nam: this.name,
ico: this.iconUrl,
};
return object;

View file

@ -26,7 +26,7 @@ export class VirtualFolder extends VirtualBase {
/**
* @param {string} alias
* @returns {VirtualFolder}
* @returns {ThisType}
*/
setAlias(alias) {
return super.setAlias(alias);
@ -36,7 +36,7 @@ export class VirtualFolder extends VirtualBase {
* Returns true if this folder contains a file matching a name and extension
* @param {string} name
* @param {string} extension
* @returns {VirtualFile}
* @returns {ThisType}
*/
hasFile(name, extension) {
return this.findFile(name, extension) !== null;
@ -61,7 +61,9 @@ export class VirtualFolder extends VirtualBase {
let resultFile = null;
this.files.forEach((file) => {
if ((file.name === name || (file.alias && file.alias === name)) && file.extension === extension) {
const matchingName = (file.name === name || (file.alias && file.alias === name));
const matchingExtension = (extension == null || file.extension === extension);
if (matchingName && matchingExtension) {
return resultFile = file;
}
});

View file

@ -1,4 +1,6 @@
import { APPS } from "../../constants/applications.js";
import { WALLPAPERS } from "../../constants/desktop.js";
import AppsManager from "../applications/applications.js";
import { StorageManager } from "../storage/storageManager.js";
import { VirtualFolderLink } from "./VirtualFolderLink.js";
import { VirtualFile } from "./virtualFile.js";
@ -56,7 +58,7 @@ export class VirtualRoot extends VirtualFolder {
});
})
.createFolder("Images", (folder) => {
linkedPaths.images = folder.path;
folder.setIconUrl(AppsManager.getAppIconUrl(APPS.FILE_EXPLORER, "folder-images"));
folder.createFolder("Wallpapers", (folder) => {
folder.setProtected(true);
for (let i = 0; i < WALLPAPERS.length; i++) {
@ -68,15 +70,19 @@ export class VirtualRoot extends VirtualFolder {
}).createFile("ProzillaOS", "png", (file) => {
file.setSource("/media/banner-logo-title.png");
});
linkedPaths.images = folder.path;
})
.createFolder("Documents", (folder) => {
linkedPaths.documents = folder.path;
folder.setIconUrl(AppsManager.getAppIconUrl(APPS.FILE_EXPLORER, "folder-text"));
folder.createFile("text", "txt", (file) => {
file.setContent("Hello world!");
}).createFile("info", "md", (file) => {
file.setProtected(true)
.setSource("/documents/info.md")
.setIconUrl(AppsManager.getAppIconUrl(APPS.FILE_EXPLORER, "file-info"));
linkedPaths.info = file.path;
file.setProtected(true).setSource("/documents/info.md");
});
linkedPaths.documents = folder.path;
})
.createFolder("Desktop", (folder) => {
folder.createFileLink("info.md", (fileLink) => {
@ -126,10 +132,20 @@ export class VirtualRoot extends VirtualFolder {
const shortcuts = {...object.scs};
const addFile = ({ nam: name, ext: extension, src: source, cnt: content, lnk: link }, parent = this) => {
const addFile = ({
nam: name,
ext: extension,
src: source,
cnt: content,
lnk: link,
ico: iconUrl,
}, parent = this) => {
if (link) {
parent.createFileLink(name, (fileLink) => {
fileLink.setLinkedPath(link);
if (iconUrl != null) {
fileLink.setIconUrl(iconUrl);
}
});
return;
}
@ -140,13 +156,25 @@ export class VirtualRoot extends VirtualFolder {
} else if (content != null) {
file.setContent(content);
}
if (iconUrl != null) {
file.setIconUrl(iconUrl);
}
});
};
const addFolder = ({ nam: name, fds: folders, fls: files, lnk: link }, parent = this) => {
const addFolder = ({
nam: name,
fds: folders,
fls: files,
lnk: link,
ico: iconUrl,
}, parent = this) => {
if (link) {
parent.createFolderLink(name, (folderLink) => {
folderLink.setLinkedPath(link);
if (iconUrl != null) {
folderLink.setIconUrl(iconUrl);
}
});
return;
}
@ -170,6 +198,9 @@ export class VirtualRoot extends VirtualFolder {
addFile(file, folder);
});
}
if (iconUrl != null) {
folder.setIconUrl(iconUrl);
}
});
};

View file

@ -1,5 +1,5 @@
import { SCREEN_MARGIN, TASKBAR_HEIGHT } from "../../constants/windows.js";
import ApplicationsManager from "../applications/applications.js";
import AppsManager from "../applications/applications.js";
import { randomRange } from "../math/random.js";
import Vector2 from "../math/vector2.js";
import { VirtualFile } from "../virtual-drive/virtualFile.js";
@ -16,7 +16,7 @@ export default class WindowsManager {
* @returns {object | null}
*/
open(appId, options) {
const app = ApplicationsManager.getApplication(appId);
const app = AppsManager.getApp(appId);
if (app == null) {
console.warn(`Failed to open app ${appId}: app not found`);
@ -52,14 +52,13 @@ export default class WindowsManager {
/**
* @param {VirtualFile} file
* @param {object} options
* @returns {object}
*/
openFile(file) {
console.log(file);
const app = ApplicationsManager.getFileApplication(file.extension);
console.log(app);
openFile(file, options = {}) {
const app = AppsManager.getFileApp(file.extension);
if (app != null)
return this.open(app.id, { file });
return this.open(app.id, { file, ...options });
}
/**