From a5d45b8a174fe7371b30e264b0f07d5313273297 Mon Sep 17 00:00:00 2001 From: Mujinniao <78023097+Mujinniao@users.noreply.github.com> Date: Mon, 21 Nov 2022 17:34:52 +0800 Subject: [PATCH] Delete picx directory --- picx/LICENSE | 674 ------------------ picx/README.md | 75 -- picx/commitlint.config.js | 1 - picx/index.html | 18 - picx/package.json | 63 -- picx/public/CNAME | 1 - picx/public/logo.png | Bin 34955 -> 0 bytes picx/public/logo@192x192.png | Bin 36532 -> 0 bytes picx/src/App.vue | 74 -- picx/src/assets/logo.png | Bin 34955 -> 0 bytes picx/src/common/api/index.ts | 82 --- picx/src/common/model/delete.model.ts | 6 - picx/src/common/model/dir.model.ts | 11 - picx/src/common/model/external-link.model.ts | 8 - picx/src/common/model/storage.model.ts | 6 - picx/src/common/model/upload.model.ts | 68 -- .../common/model/user-config-info.model.ts | 35 - picx/src/common/model/user-settings.model.ts | 15 - picx/src/common/model/vite-config.model.ts | 11 - .../copy-external-link.styl | 62 -- .../copy-external-link/copy-external-link.vue | 104 --- .../components/folder-card/folder-card.styl | 47 -- .../components/folder-card/folder-card.vue | 116 --- .../header-content/header-content.styl | 92 --- .../header-content/header-content.vue | 122 ---- .../src/components/image-card/image-card.styl | 142 ---- picx/src/components/image-card/image-card.vue | 287 -------- .../image-selector/image-selector.styl | 52 -- .../image-selector/image-selector.vue | 103 --- .../components/image-viewer/image-viewer.styl | 75 -- .../components/image-viewer/image-viewer.vue | 44 -- .../main-container/main-container.styl | 73 -- .../main-container/main-container.vue | 64 -- .../components/nav-content/nav-content.styl | 40 -- .../components/nav-content/nav-content.vue | 152 ---- .../selected-info-bar/selected-info-bar.styl | 16 - .../selected-info-bar/selected-info-bar.vue | 35 - picx/src/components/site-count/site-count.vue | 58 -- .../to-upload-image-card.styl | 211 ------ .../to-upload-image-card.vue | 300 -------- picx/src/components/tutorials-step/step1.vue | 40 -- picx/src/components/tutorials-step/step2.vue | 54 -- picx/src/components/tutorials-step/step3.vue | 62 -- .../components/upload-area/upload-area.styl | 57 -- .../components/upload-area/upload-area.vue | 148 ---- picx/src/main.ts | 21 - picx/src/plugins/index.ts | 32 - picx/src/plugins/pwa.ts | 24 - picx/src/router/index.ts | 82 --- picx/src/shims-vue.d.ts | 6 - picx/src/store/index.ts | 57 -- .../src/store/modules/dir-image-list/index.ts | 260 ------- .../src/store/modules/dir-image-list/types.ts | 14 - .../src/store/modules/dir-image-list/utils.ts | 73 -- picx/src/store/modules/image-card/index.ts | 41 -- picx/src/store/modules/image-card/types.ts | 5 - picx/src/store/modules/image-viewer/index.ts | 29 - picx/src/store/modules/image-viewer/types.ts | 12 - .../store/modules/to-upload-image/index.ts | 92 --- .../store/modules/to-upload-image/types.ts | 6 - .../store/modules/upload-area-active/index.ts | 25 - .../store/modules/upload-area-active/types.ts | 3 - .../store/modules/upload-settings/index.ts | 24 - .../store/modules/upload-settings/types.ts | 6 - .../modules/uploaded-image-list/index.ts | 53 -- .../modules/uploaded-image-list/types.ts | 5 - .../store/modules/user-config-info/index.ts | 155 ---- .../store/modules/user-config-info/types.ts | 5 - picx/src/store/modules/user-settings/index.ts | 67 -- picx/src/store/modules/user-settings/types.ts | 5 - picx/src/store/types.ts | 21 - picx/src/style/base.styl | 98 --- picx/src/style/theme.styl | 25 - picx/src/style/variables.styl | 110 --- picx/src/utils/axios.ts | 51 -- picx/src/utils/common-utils.ts | 27 - picx/src/utils/compress.ts | 26 - picx/src/utils/create-to-upload-image.ts | 42 -- picx/src/utils/delete-image-card.ts | 64 -- picx/src/utils/env.ts | 23 - picx/src/utils/external-link-handler.ts | 178 ----- picx/src/utils/file-handle-helper.ts | 50 -- picx/src/utils/image-helper.ts | 42 -- picx/src/utils/object-helper.ts | 59 -- picx/src/utils/paste.ts | 28 - picx/src/utils/register-sw.ts | 3 - picx/src/utils/rename-image.ts | 56 -- picx/src/utils/selected-file-handle.ts | 67 -- picx/src/utils/set-theme-mode.ts | 51 -- picx/src/utils/time-helper.ts | 26 - picx/src/utils/upload-helper.ts | 134 ---- picx/src/views/about/about.styl | 25 - picx/src/views/about/about.vue | 77 -- picx/src/views/config/config.styl | 13 - picx/src/views/config/config.vue | 498 ------------- picx/src/views/management/management.styl | 70 -- picx/src/views/management/management.util.ts | 57 -- picx/src/views/management/management.vue | 201 ------ picx/src/views/settings/settings.styl | 44 -- picx/src/views/settings/settings.vue | 149 ---- picx/src/views/tutorials/tutorials.styl | 15 - picx/src/views/tutorials/tutorials.vue | 64 -- picx/src/views/upload/upload.styl | 135 ---- picx/src/views/upload/upload.vue | 151 ---- picx/tsconfig.json | 35 - picx/vite.config.ts | 53 -- 106 files changed, 7574 deletions(-) delete mode 100644 picx/LICENSE delete mode 100644 picx/README.md delete mode 100644 picx/commitlint.config.js delete mode 100644 picx/index.html delete mode 100644 picx/package.json delete mode 100644 picx/public/CNAME delete mode 100644 picx/public/logo.png delete mode 100644 picx/public/logo@192x192.png delete mode 100644 picx/src/App.vue delete mode 100644 picx/src/assets/logo.png delete mode 100644 picx/src/common/api/index.ts delete mode 100644 picx/src/common/model/delete.model.ts delete mode 100644 picx/src/common/model/dir.model.ts delete mode 100644 picx/src/common/model/external-link.model.ts delete mode 100644 picx/src/common/model/storage.model.ts delete mode 100644 picx/src/common/model/upload.model.ts delete mode 100644 picx/src/common/model/user-config-info.model.ts delete mode 100644 picx/src/common/model/user-settings.model.ts delete mode 100644 picx/src/common/model/vite-config.model.ts delete mode 100644 picx/src/components/copy-external-link/copy-external-link.styl delete mode 100644 picx/src/components/copy-external-link/copy-external-link.vue delete mode 100644 picx/src/components/folder-card/folder-card.styl delete mode 100644 picx/src/components/folder-card/folder-card.vue delete mode 100644 picx/src/components/header-content/header-content.styl delete mode 100644 picx/src/components/header-content/header-content.vue delete mode 100644 picx/src/components/image-card/image-card.styl delete mode 100644 picx/src/components/image-card/image-card.vue delete mode 100644 picx/src/components/image-selector/image-selector.styl delete mode 100644 picx/src/components/image-selector/image-selector.vue delete mode 100644 picx/src/components/image-viewer/image-viewer.styl delete mode 100644 picx/src/components/image-viewer/image-viewer.vue delete mode 100644 picx/src/components/main-container/main-container.styl delete mode 100644 picx/src/components/main-container/main-container.vue delete mode 100644 picx/src/components/nav-content/nav-content.styl delete mode 100644 picx/src/components/nav-content/nav-content.vue delete mode 100644 picx/src/components/selected-info-bar/selected-info-bar.styl delete mode 100644 picx/src/components/selected-info-bar/selected-info-bar.vue delete mode 100644 picx/src/components/site-count/site-count.vue delete mode 100644 picx/src/components/to-upload-image-card/to-upload-image-card.styl delete mode 100644 picx/src/components/to-upload-image-card/to-upload-image-card.vue delete mode 100644 picx/src/components/tutorials-step/step1.vue delete mode 100644 picx/src/components/tutorials-step/step2.vue delete mode 100644 picx/src/components/tutorials-step/step3.vue delete mode 100644 picx/src/components/upload-area/upload-area.styl delete mode 100644 picx/src/components/upload-area/upload-area.vue delete mode 100644 picx/src/main.ts delete mode 100644 picx/src/plugins/index.ts delete mode 100644 picx/src/plugins/pwa.ts delete mode 100644 picx/src/router/index.ts delete mode 100644 picx/src/shims-vue.d.ts delete mode 100644 picx/src/store/index.ts delete mode 100644 picx/src/store/modules/dir-image-list/index.ts delete mode 100644 picx/src/store/modules/dir-image-list/types.ts delete mode 100644 picx/src/store/modules/dir-image-list/utils.ts delete mode 100644 picx/src/store/modules/image-card/index.ts delete mode 100644 picx/src/store/modules/image-card/types.ts delete mode 100644 picx/src/store/modules/image-viewer/index.ts delete mode 100644 picx/src/store/modules/image-viewer/types.ts delete mode 100644 picx/src/store/modules/to-upload-image/index.ts delete mode 100644 picx/src/store/modules/to-upload-image/types.ts delete mode 100644 picx/src/store/modules/upload-area-active/index.ts delete mode 100644 picx/src/store/modules/upload-area-active/types.ts delete mode 100644 picx/src/store/modules/upload-settings/index.ts delete mode 100644 picx/src/store/modules/upload-settings/types.ts delete mode 100644 picx/src/store/modules/uploaded-image-list/index.ts delete mode 100644 picx/src/store/modules/uploaded-image-list/types.ts delete mode 100644 picx/src/store/modules/user-config-info/index.ts delete mode 100644 picx/src/store/modules/user-config-info/types.ts delete mode 100644 picx/src/store/modules/user-settings/index.ts delete mode 100644 picx/src/store/modules/user-settings/types.ts delete mode 100644 picx/src/store/types.ts delete mode 100644 picx/src/style/base.styl delete mode 100644 picx/src/style/theme.styl delete mode 100644 picx/src/style/variables.styl delete mode 100644 picx/src/utils/axios.ts delete mode 100644 picx/src/utils/common-utils.ts delete mode 100644 picx/src/utils/compress.ts delete mode 100644 picx/src/utils/create-to-upload-image.ts delete mode 100644 picx/src/utils/delete-image-card.ts delete mode 100644 picx/src/utils/env.ts delete mode 100644 picx/src/utils/external-link-handler.ts delete mode 100644 picx/src/utils/file-handle-helper.ts delete mode 100644 picx/src/utils/image-helper.ts delete mode 100644 picx/src/utils/object-helper.ts delete mode 100644 picx/src/utils/paste.ts delete mode 100644 picx/src/utils/register-sw.ts delete mode 100644 picx/src/utils/rename-image.ts delete mode 100644 picx/src/utils/selected-file-handle.ts delete mode 100644 picx/src/utils/set-theme-mode.ts delete mode 100644 picx/src/utils/time-helper.ts delete mode 100644 picx/src/utils/upload-helper.ts delete mode 100644 picx/src/views/about/about.styl delete mode 100644 picx/src/views/about/about.vue delete mode 100644 picx/src/views/config/config.styl delete mode 100644 picx/src/views/config/config.vue delete mode 100644 picx/src/views/management/management.styl delete mode 100644 picx/src/views/management/management.util.ts delete mode 100644 picx/src/views/management/management.vue delete mode 100644 picx/src/views/settings/settings.styl delete mode 100644 picx/src/views/settings/settings.vue delete mode 100644 picx/src/views/tutorials/tutorials.styl delete mode 100644 picx/src/views/tutorials/tutorials.vue delete mode 100644 picx/src/views/upload/upload.styl delete mode 100644 picx/src/views/upload/upload.vue delete mode 100644 picx/tsconfig.json delete mode 100644 picx/vite.config.ts diff --git a/picx/LICENSE b/picx/LICENSE deleted file mode 100644 index f288702..0000000 --- a/picx/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/picx/README.md b/picx/README.md deleted file mode 100644 index d81cb04..0000000 --- a/picx/README.md +++ /dev/null @@ -1,75 +0,0 @@ - -PicX - - -# PicX 图床 - -[![Author](https://img.shields.io/badge/author-XPoet-violet.svg)](https://github.com/XPoet) -[![Release](https://img.shields.io/github/release/XPoet/picx.svg)](https://github.com/XPoet/picx/releases) -[![License](https://img.shields.io/github/license/XPoet/picx.svg)](https://github.com/XPoet/picx/blob/master/LICENSE) -[![Stars](https://img.shields.io/github/stars/XPoet/picx)](https://github.com/XPoet/picx) -[![Issues](https://img.shields.io/github/issues/XPoet/picx)](https://github.com/XPoet/picx/issues) -[![Deploy](https://github.com/XPoet/picx/workflows/deploy/badge.svg)](https://github.com/XPoet/picx/actions/workflows/deploy.yml) -[![JavaScript Style Guide](https://img.shields.io/badge/code_style-Airbnb-hotpink.svg)](https://github.com/lin-123/javascript) - -**[PicX](https://picx.xpoet.cn)** 是一款基于 GitHub API 开发的具有 CDN 加速功能的图床管理工具 - - - -> 在线使用入口 **https://picx.xpoet.cn** - -**灵魂拷问,你为图床问题烦恼过吗?** - -- 用 Hexo、VuePress、Hugo 等静态博客写文章,不知图片保存到哪里去... -- 特意花钱租云服务器托管图片,太贵划不来,而且上传配置好繁琐... -- 网上复制的心仪图片的链接,用着用着某一天就失效了... -- 使用其他的付费图床,速度慢,容量小,还限时、限流量... -- 想找一款真正免费、稳定、不限容量、访问速度还很快的图床... -- ...... - -那么,快来试试 **[PicX 图床](https://picx.xpoet.cn)** 吧,专为技术博主打造,谁用谁知道~ - -只需选择一个 GitHub 仓库作为图床,然后在 **[PicX 官网](https://picx.xpoet.cn/)** 完成 Token 绑定和相应配置就能使用了。 - -**[PicX 图床](https://picx.xpoet.cn)** 浏览器在线使用,免下载&安装,如此简单。 - -🆓 免费 🆓 🏆 稳定 🏆 🚀 极速 🚀 🔒 安全 🔒 - -## 功能特性 | Features - -- [x] 支持 **拖拽**、**复制粘贴**、**选择文件** 等方式进行选择图片 -- [x] 支持图片 **重命名**、**哈希化**(确保图片名唯一)和 **设置命名前缀** -- [x] 支持 **批量上传图片**、**批量删除图片** 和 **批量复制图片外链** -- [x] 支持 **多级目录** 管理 (创建多级目录 / 查看多级目录图片) -- [x] 支持 **一键复制** 图片外链和 **一键转换 Markdown 格式** -- [x] 支持 **图床管理**(对仓库图片的 **增删改查**) -- [x] 支持 **图片压缩** (内置三款压缩算法,可在上传前自动压缩,效果极佳) -- [x] 支持 **暗夜模式** (自由切换 / 自动切换) -- [x] 支持 **PWA** -- [ ] i18n -- [ ] 设置图片水印 -- [ ] 支持其他 Git 厂商 (例如:Gitee / Coding) - -## 使用教程 | Using the tutorial - -官方文档 >> https://picx-docs.xpoet.cn - -## 快速开始 | Get start - -通过阅读官方文档的快速开始教程,可帮助你迅速上手 PicX 图床 - -https://picx-docs.xpoet.cn/tutorial/get-start.html - -## 贡献 | Contribution - -欢迎各种形式的贡献,包括但不限于:美化界面、增加功能、改进代码、 修复 Bug 等 - -## 反馈 | Feedback - -在使用过程中,如遇问题,请仔细阅读 **[官方文档](https://picx-docs.xpoet.cn)** ,或给作者提 **[Issue](https://github.com/XPoet/picx/issues)** - -## 许可 | License - -**[GPL-3.0](https://github.com/XPoet/picx/blob/master/LICENSE)** - -Copyright © 2020-Present PicX Dev Team diff --git a/picx/commitlint.config.js b/picx/commitlint.config.js deleted file mode 100644 index 4fedde6..0000000 --- a/picx/commitlint.config.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { extends: ['@commitlint/config-conventional'] } diff --git a/picx/index.html b/picx/index.html deleted file mode 100644 index d80f0d6..0000000 --- a/picx/index.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - PicX 图床神器 - - - -
- - - - diff --git a/picx/package.json b/picx/package.json deleted file mode 100644 index 54dafbd..0000000 --- a/picx/package.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "name": "picx", - "version": "2.1.0", - "private": false, - "author": "XPoet", - "license": "GPL-3.0", - "bugs": { - "url": "https://github.com/XPoet/picx/issues" - }, - "homepage": "https://github.com/XPoet/picx#readme", - "scripts": { - "dev": "vite", - "build": "vite build", - "serve": "vite preview", - "release": "git push --tag && git push -u", - "format": "prettier --write", - "prepare": "husky install" - }, - "lint-staged": { - "*.{vue,js,ts}": "eslint --fix" - }, - "dependencies": { - "@element-plus/icons-vue": "^2.0.4", - "@yireen/squoosh-browser": "^1.0.7", - "axios": "^0.21.4", - "element-plus": "^2.2.5", - "vue": "^3.2.18", - "vue-router": "^4.0.11", - "vuex": "^4.0.2" - }, - "devDependencies": { - "@commitlint/cli": "^12.1.1", - "@commitlint/config-conventional": "^12.1.1", - "@types/node": "^15.0.1", - "@typescript-eslint/eslint-plugin": "^4.22.0", - "@typescript-eslint/parser": "^4.22.0", - "@vitejs/plugin-vue": "^1.1.5", - "@vue/compiler-sfc": "^3.2.18", - "commitizen": "^4.2.3", - "cz-conventional-changelog": "^3.3.0", - "cz-customizable": "^6.3.0", - "eslint": "^7.32.0", - "eslint-config-airbnb-base": "^14.2.1", - "eslint-config-prettier": "^8.3.0", - "eslint-plugin-import": "^2.22.1", - "eslint-plugin-prettier": "^3.4.0", - "eslint-plugin-vue": "^9.1.1", - "husky": "^6.0.0", - "lint-staged": "^10.5.4", - "prettier": "^2.2.1", - "stylus": "^0.54.8", - "typescript": "^4.1.5", - "unplugin-auto-import": "^0.8.7", - "unplugin-vue-components": "^0.19.6", - "vite": "~2.7.13", - "vite-plugin-pwa": "^0.11.2" - }, - "config": { - "commitizen": { - "path": "./node_modules/cz-conventional-changelog" - } - } -} diff --git a/picx/public/CNAME b/picx/public/CNAME deleted file mode 100644 index b8268a5..0000000 --- a/picx/public/CNAME +++ /dev/null @@ -1 +0,0 @@ -picx.xpoet.cn diff --git a/picx/public/logo.png b/picx/public/logo.png deleted file mode 100644 index a33970843f08ce369553bc7c592b0c759add947a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34955 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 D_u|G9zP>Je=cB$K%p{;sGL@?? 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

M;`C{18+Hamx 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�dx!+475npA6`ao1X&I0MZ$F(r@9n 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 diff --git a/picx/public/logo@192x192.png b/picx/public/logo@192x192.png deleted file mode 100644 index 14ab5fe9a2523d8b6712dc618002da5532b7ad51..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36532 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 qyw5&Trm;E7 diff --git a/picx/src/App.vue b/picx/src/App.vue deleted file mode 100644 index d239c0c..0000000 --- a/picx/src/App.vue +++ /dev/null @@ -1,74 +0,0 @@ - - - - - diff --git a/picx/src/assets/logo.png b/picx/src/assets/logo.png deleted file mode 100644 index a33970843f08ce369553bc7c592b0c759add947a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34955 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 D_u|G9zP>Je=cB$K%p{;sGL@?? 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

M;`C{18+Hamx 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�dx!+475npA6`ao1X&I0MZ$F(r@9n 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 diff --git a/picx/src/common/api/index.ts b/picx/src/common/api/index.ts deleted file mode 100644 index 50005a2..0000000 --- a/picx/src/common/api/index.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { computed } from 'vue' -import axios from '@/utils/axios' -import { store } from '@/store' -import { getFileSuffix, isImage } from '@/utils/file-handle-helper' -import structureImageObject from '@/utils/image-helper' - -const userConfigInfo = computed(() => store.getters.getUserConfigInfo).value - -/** - * 获取指定路径(path)下的目录列表 - * @param path 路径 - */ -export const getDirListByPath = (path: string = '') => { - return new Promise((resolve) => { - axios - .get( - `/repos/${userConfigInfo.owner}/${userConfigInfo.selectedRepos}/contents/${path}`, - { - params: { - ref: userConfigInfo.selectedBranch - } - } - ) - .then((res: any) => { - if (res && res.status === 200 && res.data.length > 0) { - resolve( - res.data - .filter((v: any) => v.type === 'dir') - .map((x: any) => ({ - value: x.name, - label: x.name - })) - ) - } else { - resolve(null) - } - }) - .catch(() => { - resolve(null) - }) - }) -} - -/** - * 获取指定路径(path)下的目录和图片 - * @param path - */ -export const getContentByReposPath = (path: string = '') => { - return new Promise((resolve) => { - axios - .get( - `/repos/${userConfigInfo.owner}/${userConfigInfo.selectedRepos}/contents/${path}`, - { - params: { - ref: userConfigInfo.selectedBranch - } - } - ) - .then((res: any) => { - if (res && res.status === 200 && res.data.length > 0) { - res.data - .filter((v: any) => v.type === 'dir') - .forEach((x: any) => store.dispatch('DIR_IMAGE_LIST_ADD_DIR', x.path)) - - setTimeout(() => { - res.data - .filter((v: any) => v.type === 'file' && isImage(getFileSuffix(v.name))) - .forEach((x: any) => - store.dispatch('DIR_IMAGE_LIST_ADD_IMAGE', structureImageObject(x, path)) - ) - }, 100) - - resolve(true) - } else { - resolve(null) - } - }) - .catch(() => { - resolve(null) - }) - }) -} diff --git a/picx/src/common/model/delete.model.ts b/picx/src/common/model/delete.model.ts deleted file mode 100644 index 2a79dd6..0000000 --- a/picx/src/common/model/delete.model.ts +++ /dev/null @@ -1,6 +0,0 @@ -/* eslint-disable import/prefer-default-export */ -export enum deleteStatusEnum { - deleted = 'deleted', - allDeleted = 'allDeleted', - deleteFail = 'deleteFail' -} diff --git a/picx/src/common/model/dir.model.ts b/picx/src/common/model/dir.model.ts deleted file mode 100644 index 40fac92..0000000 --- a/picx/src/common/model/dir.model.ts +++ /dev/null @@ -1,11 +0,0 @@ -export interface DirModel { - value: string - label: string -} - -export enum DirModeEnum { - autoDir = 'autoDir', - newDir = 'newDir', - rootDir = 'rootDir', - reposDir = 'reposDir' -} diff --git a/picx/src/common/model/external-link.model.ts b/picx/src/common/model/external-link.model.ts deleted file mode 100644 index 82e6c4c..0000000 --- a/picx/src/common/model/external-link.model.ts +++ /dev/null @@ -1,8 +0,0 @@ -enum ExternalLinkType { - staticaly = 'staticaly', - jsdelivr = 'jsdelivr', - github = 'github', - cloudflare = 'cloudflare' -} - -export default ExternalLinkType diff --git a/picx/src/common/model/storage.model.ts b/picx/src/common/model/storage.model.ts deleted file mode 100644 index 7f7a94b..0000000 --- a/picx/src/common/model/storage.model.ts +++ /dev/null @@ -1,6 +0,0 @@ -const PICX_PREFIX = 'PICX_' - -export const PICX_CONFIG = `${PICX_PREFIX}CONFIG` -export const PICX_UPLOADED = `${PICX_PREFIX}UPLOADED` -export const PICX_MANAGEMENT = `${PICX_PREFIX}MANAGEMENT_MULTI` -export const PICX_SETTINGS = `${PICX_PREFIX}SETTINGS` diff --git a/picx/src/common/model/upload.model.ts b/picx/src/common/model/upload.model.ts deleted file mode 100644 index 2b91a39..0000000 --- a/picx/src/common/model/upload.model.ts +++ /dev/null @@ -1,68 +0,0 @@ -export enum UploadStatusEnum { - // eslint-disable-next-line no-unused-vars - uploaded = 'uploaded', - // eslint-disable-next-line no-unused-vars - allUploaded = 'allUploaded', - // eslint-disable-next-line no-unused-vars - uploadFail = 'uploadFail' -} - -export interface UploadedImageModel { - type: string - uuid: string - sha: string - dir: string - path: string - name: string - size: any - deleting: boolean - is_transform_md: boolean - checked: boolean - github_url: string - jsdelivr_cdn_url: string - staticaly_cdn_url: string - cloudflare_cdn_url: string -} - -export interface ToUploadImageModel { - uuid: string - - uploadStatus: { - progress: number - uploading: boolean - } - - imgData: { - base64Content: string - base64Url: string - } - - fileInfo: { - compressedSize?: number | undefined - originSize?: number | undefined - size: number | undefined - lastModified: number | undefined - } - - filename: { - name: string - hash: string - suffix: string - prefixName: string - now: string - initName: string - newName: string - isHashRename: boolean - isRename: boolean - isPrefix: boolean - } - - externalLink: { - github: string - jsdelivr: string - staticaly: string - cloudflare: string - } - - uploadedImg?: UploadedImageModel -} diff --git a/picx/src/common/model/user-config-info.model.ts b/picx/src/common/model/user-config-info.model.ts deleted file mode 100644 index f11ed55..0000000 --- a/picx/src/common/model/user-config-info.model.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { DirModeEnum, DirModel } from './dir.model' - -export interface ReposModel { - value: string - label: string - desc?: string -} - -export interface BranchModel { - value: string - label: string -} - -export enum BranchModeEnum { - newBranch = 'newBranch', - reposBranch = 'reposBranch' -} - -export interface UserConfigInfoModel { - token: string - owner: string - email: string - name: string - avatarUrl: string - selectedRepos: string - reposList: ReposModel[] - selectedBranch: string - branchMode: BranchModeEnum - branchList: BranchModel[] - dirMode: DirModeEnum - selectedDir: string - selectedDirList: string[] - dirList: DirModel[] - loggingStatus: boolean -} diff --git a/picx/src/common/model/user-settings.model.ts b/picx/src/common/model/user-settings.model.ts deleted file mode 100644 index 5d44ef4..0000000 --- a/picx/src/common/model/user-settings.model.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { CompressEncoderMap } from '../../utils/compress' -import ExternalLinkType from '@/common/model/external-link.model' - -export interface UserSettingsModel { - defaultHash: boolean - defaultMarkdown: boolean - defaultPrefix: boolean - prefixName: string - themeMode: 'auto' | 'light' | 'dark' - autoLightThemeTime: string[] - isCompress: boolean - compressEncoder: CompressEncoderMap - elementPlusSize: 'large' | 'default' | 'small' - externalLinkType: ExternalLinkType -} diff --git a/picx/src/common/model/vite-config.model.ts b/picx/src/common/model/vite-config.model.ts deleted file mode 100644 index 19121e8..0000000 --- a/picx/src/common/model/vite-config.model.ts +++ /dev/null @@ -1,11 +0,0 @@ -export declare type Recordable = Record - -export declare interface ViteEnv { - VITE_PORT?: number - VITE_USE_PWA?: boolean - VITE_PUBLIC_PATH?: string - VITE_GLOB_APP_TITLE?: string - VITE_GLOB_APP_SHORT_NAME?: string - VITE_OPEN_BROWSER?: boolean - VITE_CORS?: boolean -} diff --git a/picx/src/components/copy-external-link/copy-external-link.styl b/picx/src/components/copy-external-link/copy-external-link.styl deleted file mode 100644 index f51c446..0000000 --- a/picx/src/components/copy-external-link/copy-external-link.styl +++ /dev/null @@ -1,62 +0,0 @@ -@import "../../style/base.styl" - -.copy-external-link-box { - position relative - width 100% - height 100% - box-sizing border-box - display flex - justify-content space-between - align-items flex-end - padding 2rem - - .markdown-icon-box { - width 26rem - height 20rem - position relative - cursor pointer - - .markdown-icon { - path { - fill var(--markdown-icon-color) - } - - &.active { - path { - fill var(--markdown-icon-active-color) - } - } - } - } - - - .btn-box { - position relative - box-sizing border-box - height 100% - display flex - justify-content space-between - - .btn-item { - height 20rem - box-sizing border-box - border-radius 5rem - font-size 12rem - cursor pointer - transition all 0.3s ease - } - - .copy-url { - box-sizing border-box - border 1rem solid var(--default-text-color) - color var(--default-text-color) - padding 1rem 2rem - margin-right 4rem - - &:hover { - background var(--default-text-color) - color var(--background-color) - } - } - } -} diff --git a/picx/src/components/copy-external-link/copy-external-link.vue b/picx/src/components/copy-external-link/copy-external-link.vue deleted file mode 100644 index edb4cfa..0000000 --- a/picx/src/components/copy-external-link/copy-external-link.vue +++ /dev/null @@ -1,104 +0,0 @@ - - - - - diff --git a/picx/src/components/folder-card/folder-card.styl b/picx/src/components/folder-card/folder-card.styl deleted file mode 100644 index b61ac4b..0000000 --- a/picx/src/components/folder-card/folder-card.styl +++ /dev/null @@ -1,47 +0,0 @@ -@import '../../style/base.styl' - -.folder-card { - position relative - width 110rem - height 106rem - display flex - align-items center - flex-direction column - justify-content flex-start - cursor pointer - box-sizing border-box - padding 3rem - user-select none - - &:hover { - background var(--second-background-color) - } - - .icon { - display flex - align-items center - justify-content center - width 50rem - height 50rem - - svg { - width 100% - height 100% - } - } - - - .text { - width 90% - font-size 14rem - margin-top 5rem - text-align center - overflow hidden - text-overflow ellipsis - display -webkit-box - -webkit-box-orient vertical - -webkit-line-clamp 2 - word-wrap break-word - word-break break-all - } -} diff --git a/picx/src/components/folder-card/folder-card.vue b/picx/src/components/folder-card/folder-card.vue deleted file mode 100644 index f332c32..0000000 --- a/picx/src/components/folder-card/folder-card.vue +++ /dev/null @@ -1,116 +0,0 @@ - - - - - diff --git a/picx/src/components/header-content/header-content.styl b/picx/src/components/header-content/header-content.styl deleted file mode 100644 index 825efab..0000000 --- a/picx/src/components/header-content/header-content.styl +++ /dev/null @@ -1,92 +0,0 @@ -@import "../../style/base.styl" - -.header { - width 100% - height 100% - background var(--background-color) - padding 0 20rem - box-sizing border-box - display flex - justify-content space-between - align-items center - - .header-left { - height 100% - display flex - justify-content flex-start - - .brand { - height 100% - display flex - justify-content flex-start - align-items center - cursor pointer - - .logo { - width 46rem - height 46rem - margin-right 10rem - - img { - width 100% - } - - } - - - .title { - font-size 36rem - font-weight bold - } - } - - - .website-count { - box-sizing border-box - display flex - align-items flex-end - font-size 14rem - margin-left 10rem - padding-bottom 12rem - cursor pointer - - +picx-mobile() { - display none - } - } - } - - - .header-right { - .user-info { - display: flex; - align-items: center; - cursor: pointer; - - .username { - font-size: 16rem; - } - - .avatar { - display: flex; - justify-content: center; - align-items: center; - width: 38rem; - height: 38rem; - color: var(--default-text-color); - border-radius: 50%; - border: 1rem solid var(--default-text-color); - margin-left: 10rem; - padding: 1rem; - box-sizing: border-box; - - img { - width: 100%; - height: 100%; - border-radius: 50%; - } - } - - } - } -} diff --git a/picx/src/components/header-content/header-content.vue b/picx/src/components/header-content/header-content.vue deleted file mode 100644 index 79dcd9c..0000000 --- a/picx/src/components/header-content/header-content.vue +++ /dev/null @@ -1,122 +0,0 @@ - - - - - diff --git a/picx/src/components/image-card/image-card.styl b/picx/src/components/image-card/image-card.styl deleted file mode 100644 index 1db2ce8..0000000 --- a/picx/src/components/image-card/image-card.styl +++ /dev/null @@ -1,142 +0,0 @@ -@import "../../style/base.styl" - -$infoBoxHeight = 56rem - -.image-card { - position relative - width 100% - height 100% - box-shadow 1rem 2rem 3rem var(--shadow-color) - box-sizing border-box - padding-bottom $infoBoxHeight - user-select none - - &.checked, &:hover { - box-shadow 0 0 10rem #666 - } - - &.listing { - display flex - justify-content flex-start - align-items center - padding 5rem - border-radius $box-border-radius - - .image-box { - height 45rem - width 45rem - } - - .info-box { - position relative - width 80% - } - - :deep(.el-loading-mask) { - .el-loading-spinner { - margin-top -25rem - - .circular { - height 24rem - width 24rem - } - - .el-loading-text { - margin 0 - } - } - - } - } - - - .image-box { - position relative - width 100% - height 100% - - img { - width 100% - height 100% - object-fit cover - cursor pointer - } - } - - - .info-box { - width 100% - height $infoBoxHeight - position absolute - bottom 0 - left 0 - - .image-info { - width 100% - height 100% - padding 5rem - color var(--default-text-color) - box-sizing border-box - display flex - flex-direction column - justify-content space-between - - .rename-input { - height 20rem - display flex - margin-bottom 4rem - } - - .filename { - height 16rem - overflow hidden - text-overflow ellipsis - white-space nowrap - font-size 14rem - margin-bottom 6rem - } - } - } - - - .operation-box { - position absolute - top 10rem - right 8rem - width calc(100% - 16rem) - display flex - justify-content space-between - - .operation-left { - .picked-btn { - i { - font-weight bold - } - } - } - - .operation-right { - display flex - } - - .operation-btn { - width 32rem - height 32rem - border-radius 50% - box-shadow 0 0 6rem #555 - cursor pointer - background var(--background-color) - display flex - justify-content center - align-items center - margin-right 8rem - font-size 18rem - - &:last-child { - margin-right 0 - } - } - } - - -} diff --git a/picx/src/components/image-card/image-card.vue b/picx/src/components/image-card/image-card.vue deleted file mode 100644 index 4df449a..0000000 --- a/picx/src/components/image-card/image-card.vue +++ /dev/null @@ -1,287 +0,0 @@ - - - - - diff --git a/picx/src/components/image-selector/image-selector.styl b/picx/src/components/image-selector/image-selector.styl deleted file mode 100644 index 2a3a18c..0000000 --- a/picx/src/components/image-selector/image-selector.styl +++ /dev/null @@ -1,52 +0,0 @@ -@import "../../style/base.styl" - -.selector-wrapper { - padding 4rem 12rem - width 100% - box-sizing border-box - display flex - justify-content space-between - align-items center - border-bottom 1rem solid var(--third-background-color) - - - .selector-left-box { - display flex - align-items center - - :deep(.el-checkbox) { - font-weight unset - } - - :deep(.el-checkbox__label ) { - line-height unset - } - - .cancel-select-btn { - color #576b95 - cursor pointer - } - - div.item { - margin-left 8rem - } - } - - .selector-right-box { - .btn-icon { - cursor: pointer; - font-size: 22rem; - margin-left: 10rem; - } - - } -} - -.temp-batch-externalink { - opacity 0 - position absolute - left -9999rem - top -9999rem - width 0 - height 0 -} diff --git a/picx/src/components/image-selector/image-selector.vue b/picx/src/components/image-selector/image-selector.vue deleted file mode 100644 index 45162f3..0000000 --- a/picx/src/components/image-selector/image-selector.vue +++ /dev/null @@ -1,103 +0,0 @@ - - - - diff --git a/picx/src/components/image-viewer/image-viewer.styl b/picx/src/components/image-viewer/image-viewer.styl deleted file mode 100644 index 7f88182..0000000 --- a/picx/src/components/image-viewer/image-viewer.styl +++ /dev/null @@ -1,75 +0,0 @@ -$transition-duration = 0.3s -$transition-delay = 0s - -.image-viewer { - position fixed - left 0 - top 0 - width 100% - height 100% - display flex - align-items center - justify-content center - background rgba(0, 0, 0, 0) - visibility hidden - z-index 1000 - padding 6% - box-sizing border-box - transition-property visibility, background - transition-delay $transition-delay, $transition-delay - transition-duration $transition-duration, $transition-duration - transition-timing-function ease, ease - - &.active { - background rgba(0, 0, 0, 0.6) - visibility visible - - .image-box { - transform scale(1) - padding 2rem - - .image-info { - display block - } - } - - - } - - - .image-box { - position relative; - width 60% - height 100% - display flex - flex-direction column - justify-content center - align-items center - transform scale(0) - transition-property transform - transition-delay $transition-delay - transition-duration $transition-duration - transition-timing-function ease - - - @media (max-width: 1200px) { - width 80% - } - - .img { - cursor zoom-out - max-width 100% - max-height 100% - } - - .image-info { - display none - padding 10rem - - .item { - margin 0 6rem - } - } - - } -} diff --git a/picx/src/components/image-viewer/image-viewer.vue b/picx/src/components/image-viewer/image-viewer.vue deleted file mode 100644 index a2512ca..0000000 --- a/picx/src/components/image-viewer/image-viewer.vue +++ /dev/null @@ -1,44 +0,0 @@ - - - - - diff --git a/picx/src/components/main-container/main-container.styl b/picx/src/components/main-container/main-container.styl deleted file mode 100644 index 523c84e..0000000 --- a/picx/src/components/main-container/main-container.styl +++ /dev/null @@ -1,73 +0,0 @@ -@import "../../style/base.styl" - -$top-height = 60rem -$left-side-width = 80rem - -.main-container { - position absolute - box-sizing border-box - width 100% - height 100% - background var(--second-background-color) - padding-top $top-height - font-size 15rem - - - - .top { - position absolute - top 0 - left 0 - box-sizing border-box - width 100% - height $top-height - } - - - .bottom { - position relative - box-sizing border-box - width 100% - height 100% - padding-top $component-interval - - - .container { - position relative - box-sizing border-box - width 100% - height 100% - padding-left $left-side-width - - - .left { - position absolute - box-sizing border-box - width $left-side-width - height 100% - top 0 - left 0 - } - - - .right { - position relative - width 100% - height 100% - box-sizing border-box - padding 0 $component-interval 0 $component-interval - - - .content { - position relative - box-sizing border-box - width 100% - height 100% - } - } - - } - - - } -} diff --git a/picx/src/components/main-container/main-container.vue b/picx/src/components/main-container/main-container.vue deleted file mode 100644 index 088f3f4..0000000 --- a/picx/src/components/main-container/main-container.vue +++ /dev/null @@ -1,64 +0,0 @@ - - - - - diff --git a/picx/src/components/nav-content/nav-content.styl b/picx/src/components/nav-content/nav-content.styl deleted file mode 100644 index 6cbcac4..0000000 --- a/picx/src/components/nav-content/nav-content.styl +++ /dev/null @@ -1,40 +0,0 @@ -@import "../../style/base.styl" - -.nav { - position relative - width 100% - height 100% - box-sizing border-box - background var(--background-color) - - ul.nav-list { - padding 0 - margin 0 - - li.nav-item { - box-sizing border-box - width 100% - height 76rem - cursor pointer - - &.active { - font-weight bold - background var(--second-background-color) - } - - .nav-content { - display flex - flex-direction column - justify-content center - align-items center - - .nav-name { - margin-top 5rem - font-size 12rem - } - } - } - - } - -} diff --git a/picx/src/components/nav-content/nav-content.vue b/picx/src/components/nav-content/nav-content.vue deleted file mode 100644 index 10dc70e..0000000 --- a/picx/src/components/nav-content/nav-content.vue +++ /dev/null @@ -1,152 +0,0 @@ - - - - - diff --git a/picx/src/components/selected-info-bar/selected-info-bar.styl b/picx/src/components/selected-info-bar/selected-info-bar.styl deleted file mode 100644 index eb3f16e..0000000 --- a/picx/src/components/selected-info-bar/selected-info-bar.styl +++ /dev/null @@ -1,16 +0,0 @@ -.selected-info-bar-box { - height 100% - display flex - align-items center - justify-content flex-start - font-size 12rem - box-sizing border-box - - .info-item { - margin-right 8rem - - &:last-child { - margin-right 0 - } - } -} diff --git a/picx/src/components/selected-info-bar/selected-info-bar.vue b/picx/src/components/selected-info-bar/selected-info-bar.vue deleted file mode 100644 index 0fbaabb..0000000 --- a/picx/src/components/selected-info-bar/selected-info-bar.vue +++ /dev/null @@ -1,35 +0,0 @@ - - - - - diff --git a/picx/src/components/site-count/site-count.vue b/picx/src/components/site-count/site-count.vue deleted file mode 100644 index 685b6ac..0000000 --- a/picx/src/components/site-count/site-count.vue +++ /dev/null @@ -1,58 +0,0 @@ - - - - diff --git a/picx/src/components/to-upload-image-card/to-upload-image-card.styl b/picx/src/components/to-upload-image-card/to-upload-image-card.styl deleted file mode 100644 index 10c8d52..0000000 --- a/picx/src/components/to-upload-image-card/to-upload-image-card.styl +++ /dev/null @@ -1,211 +0,0 @@ -@import "../../style/base.styl" - -$info-item-height = 68rem -$info-item-border = 1rem -$info-item-padding = 5rem -$compressed-file-background-color = #228eff -$image-width = $info-item-height - ($info-item-border * 2) - -.to-upload-image-list-card { - position relative - width 100% - box-sizing border-box - margin-top 6rem - - .header { - width 100% - height 30rem - box-sizing border-box - font-size 12rem - display flex - align-items center - justify-content space-between - padding-bottom 6rem - } - - .body { - width 100% - height 100% - max-height 170rem - overflow-y auto - box-sizing border-box - padding 10rem - border 1rem solid var(--border-color) - margin-top 10rem - - &::-webkit-scrollbar { - width 5rem - } - - &::-webkit-scrollbar-thumb { - border-radius 2rem - } - - .image-uploading-info-box { - position relative - width 100% - box-sizing border-box - padding 0 - margin 0 - - .image-uploading-info-item { - position relative - box-sizing border-box - width 100% - height $info-item-height - border $info-item-border solid var(--border-color) - border-radius 5rem - margin-bottom 10rem - overflow hidden - font-size 15rem - padding-left $image-width - transition all 0.3s ease - - &.disable { - pointer-events none - cursor not-allowed - } - - &:last-child { - margin-bottom 0 - } - - &:hover { - box-shadow 0 0 5rem var(--shadow-hover-color) - } - - .left-image-box { - position absolute - top 0 - left 0 - width $image-width - height 100% - box-sizing border-box - margin-right 5rem - - img { - object-fit cover - width 100% - height 100% - overflow hidden - cursor pointer - border-top-left-radius 5rem - border-bottom-left-radius 5rem - } - } - - - .right-operation-box { - position relative - width 100% - height 100% - box-sizing border-box - padding $info-item-padding 20rem $info-item-padding $info-item-padding - - .top, .bottom { - width 100% - height 50% - box-sizing border-box - padding 0 5rem - } - - .top { - display flex - justify-content space-between - - .image-name, - .image-info { - display flex - align-items center - box-sizing border-box - height 100% - } - - .image-name { - font-size 13rem - overflow hidden - text-overflow ellipsis - white-space nowrap - } - - .image-info { - font-size 12rem - - .item { - padding 1rem 4rem - background var(--third-background-color) - border-radius 2rem - margin-left 10rem - - &.compressed { - color $compressed-file-background-color - } - } - } - } - - - .bottom { - display flex - align-items center - - &.rename-operation { - - .el-checkbox { - margin-right 20rem - } - - .rename-input { - input { - height 23rem - line-height 23rem - } - } - } - } - } - - - .upload-status-box { - box-sizing border-box - color #fff - position absolute - right -17rem - top -7rem - width 46rem - height 26rem - text-align center - transform rotate(45deg) - box-shadow 0 1rem 1rem var(--border-color) - - &.wait-upload { - background var(--await-upload-color) - } - - &.uploading { - background var(--uploading-color) - } - - &.uploaded { - background var(--uploaded-color) - } - - i { - font-size 12rem - margin-top 12rem - transform rotate(-45deg) - } - } - - .remove-to-upload-image { - position absolute - bottom 5rem - right 5rem - cursor pointer - } - - } - } - - } -} diff --git a/picx/src/components/to-upload-image-card/to-upload-image-card.vue b/picx/src/components/to-upload-image-card/to-upload-image-card.vue deleted file mode 100644 index 99d6614..0000000 --- a/picx/src/components/to-upload-image-card/to-upload-image-card.vue +++ /dev/null @@ -1,300 +0,0 @@ - - - - - diff --git a/picx/src/components/tutorials-step/step1.vue b/picx/src/components/tutorials-step/step1.vue deleted file mode 100644 index af8e1ac..0000000 --- a/picx/src/components/tutorials-step/step1.vue +++ /dev/null @@ -1,40 +0,0 @@ - - - - - diff --git a/picx/src/components/tutorials-step/step2.vue b/picx/src/components/tutorials-step/step2.vue deleted file mode 100644 index 924264b..0000000 --- a/picx/src/components/tutorials-step/step2.vue +++ /dev/null @@ -1,54 +0,0 @@ - - - - - diff --git a/picx/src/components/tutorials-step/step3.vue b/picx/src/components/tutorials-step/step3.vue deleted file mode 100644 index ff9acd5..0000000 --- a/picx/src/components/tutorials-step/step3.vue +++ /dev/null @@ -1,62 +0,0 @@ - - - diff --git a/picx/src/components/upload-area/upload-area.styl b/picx/src/components/upload-area/upload-area.styl deleted file mode 100644 index 54c2900..0000000 --- a/picx/src/components/upload-area/upload-area.styl +++ /dev/null @@ -1,57 +0,0 @@ -@import "../../style/base.styl" - -.upload-area { - position: relative; - width: 100%; - height: 300rem; - border: 4rem dashed var(--third-text-color) - box-sizing border-box - display: flex; - align-items: center; - justify-content: center; - z-index: 999; - - &.focus { - border-color: var(--upload-area-focus-color); - } - - &:hover { - border-color: var(--upload-area-focus-color); - } - - label { - display: block; - position: absolute; - width: 100%; - height: 100%; - z-index: 1000; - cursor: pointer; - } - - input[type="file"] { - position: absolute; - left: -9999rem; - top: -9999rem; - } - - .tips { - text-align: center; - color: #aaa; - - .icon { - font-size: 100rem; - } - - .text { - cursor: default; - font-size: 20rem; - } - } - - img { - object-fit: cover; - width: 100%; - height: 100%; - } - -} diff --git a/picx/src/components/upload-area/upload-area.vue b/picx/src/components/upload-area/upload-area.vue deleted file mode 100644 index 2169abf..0000000 --- a/picx/src/components/upload-area/upload-area.vue +++ /dev/null @@ -1,148 +0,0 @@ - - - - - diff --git a/picx/src/main.ts b/picx/src/main.ts deleted file mode 100644 index aac61c5..0000000 --- a/picx/src/main.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { createApp } from 'vue' -import * as ElementPlusIconsVue from '@element-plus/icons-vue' -import router from '@/router/index' -import { key, store } from '@/store' -import App from './App.vue' -import 'element-plus/theme-chalk/dark/css-vars.css' - -if (import.meta.env.MODE === 'production') { - // @ts-ignore - import('@/utils/register-sw.ts') -} - -const app = createApp(App) - -// import element-plus icons -// eslint-disable-next-line no-restricted-syntax -for (const [key, component] of Object.entries(ElementPlusIconsVue)) { - app.component(key, component) -} -// @ts-ignore -app.use(router).use(store, key).mount('#app') diff --git a/picx/src/plugins/index.ts b/picx/src/plugins/index.ts deleted file mode 100644 index b9848df..0000000 --- a/picx/src/plugins/index.ts +++ /dev/null @@ -1,32 +0,0 @@ -import type { Plugin } from 'vite' -import vue from '@vitejs/plugin-vue' -import AutoImport from 'unplugin-auto-import/vite' -import Components from 'unplugin-vue-components/vite' -import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' -import { ViteEnv } from '@/common/model/vite-config.model' - -import configPWAPlugin from './pwa' - -export default function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) { - const vitePlugins: (Plugin | Plugin[])[] = [vue()] - - // On-demand import style for Element Plus - vitePlugins.push( - AutoImport({ - resolvers: [ElementPlusResolver()] - }), - Components({ - resolvers: [ElementPlusResolver()] - }) - ) - - // production env - if (isBuild) { - // add plugin vite-plugin-pwa - if (viteEnv.VITE_USE_PWA) { - vitePlugins.push(configPWAPlugin(viteEnv)) - } - } - - return vitePlugins -} diff --git a/picx/src/plugins/pwa.ts b/picx/src/plugins/pwa.ts deleted file mode 100644 index 9d89758..0000000 --- a/picx/src/plugins/pwa.ts +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Zero config PWA for Vite - * Plugin: vite-plugin-pwa - * https://github.com/antfu/vite-plugin-pwa - */ -import { VitePWA } from 'vite-plugin-pwa' -import { ViteEnv } from '@/common/model/vite-config.model' - -export default function configPWAPlugin(env: ViteEnv) { - return VitePWA({ - registerType: 'autoUpdate', - manifest: { - name: env.VITE_GLOB_APP_TITLE, - short_name: env.VITE_GLOB_APP_SHORT_NAME, - icons: [ - { - src: './logo@192x192.png', - sizes: '192x192', - type: 'image/png' - } - ] - } - }) -} diff --git a/picx/src/router/index.ts b/picx/src/router/index.ts deleted file mode 100644 index ef83833..0000000 --- a/picx/src/router/index.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router' -import config from '@/views/config/config.vue' -import upload from '@/views/upload/upload.vue' -import management from '@/views/management/management.vue' -import tutorials from '@/views/tutorials/tutorials.vue' -import settings from '@/views/settings/settings.vue' -import { store } from '@/store' - -const titleSuffix = ` | PicX 图床神器` - -const routes: Array = [ - { - path: '/', - name: 'index', - redirect: { - name: 'upload' - } - }, - { - path: '/config', - name: 'config', - component: config, - meta: { - title: `图床配置${titleSuffix}` - } - }, - { - path: '/upload', - name: 'upload', - component: upload, - meta: { - title: `图片上传${titleSuffix}` - } - }, - { - path: '/management', - name: 'Management', - component: management, - meta: { - title: `图床管理${titleSuffix}` - } - }, - { - path: '/tutorials', - name: 'tutorials', - component: tutorials, - meta: { - title: `使用教程${titleSuffix}` - } - }, - { - path: '/about', - name: 'about', - component: () => import('@/views/about/about.vue'), - meta: { - title: `帮助反馈${titleSuffix}` - } - }, - { - path: '/settings', - name: 'settings', - component: settings, - meta: { - title: `我的设置${titleSuffix}` - } - } -] - -const router = createRouter({ - history: createWebHashHistory(), - routes -}) - -router.beforeEach((to, from, next) => { - if (to.meta.title) (window).document.title = to.meta.title - if (from.path === '/management') { - store.dispatch('USER_CONFIG_INFO_RESET') - } - next() -}) - -export default router diff --git a/picx/src/shims-vue.d.ts b/picx/src/shims-vue.d.ts deleted file mode 100644 index d53ab3d..0000000 --- a/picx/src/shims-vue.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare module '*.vue' { - import { DefineComponent } from 'vue' - - const component: DefineComponent<{}, {}, any> - export default component -} diff --git a/picx/src/store/index.ts b/picx/src/store/index.ts deleted file mode 100644 index 5209066..0000000 --- a/picx/src/store/index.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { InjectionKey } from 'vue' -import { createStore, Store, useStore as baseUseStore } from 'vuex' -import RootStateTypes, { AllStateTypes } from './types' -import dirImageListModule from './modules/dir-image-list' -import toUploadImageModule from './modules/to-upload-image' -import uploadedImageListModule from './modules/uploaded-image-list' -import userConfigInfoModule from './modules/user-config-info' -import imageViewerModule from './modules/image-viewer' -import imageCardModule from './modules/image-card' -import uploadAreaActiveModule from './modules/upload-area-active' -import uploadSettingsModule from './modules/upload-settings' -import userSettingsModule from './modules/user-settings' - -// Create a new store instance. -export const store = createStore({ - modules: { - dirImageListModule, - toUploadImageModule, - uploadedImageListModule, - userConfigInfoModule, - imageViewerModule, - imageCardModule, - uploadAreaActiveModule, - uploadSettingsModule, - userSettingsModule - }, - - state: { - rootName: 'root' - }, - - mutations: {}, - - actions: { - // 退出登录(删除 localStorage 和 sessionStorage 数据,清空 state 的值) - LOGOUT({ dispatch, commit }) { - dispatch('DIR_IMAGE_LOGOUT') - dispatch('TO_UPLOAD_IMAGE_LOGOUT') - dispatch('UPLOADED_LIST_LOGOUT') - dispatch('USER_CONFIG_INFO_LOGOUT') - commit('IMAGE_VIEWER_LOGOUT') - commit('UPLOAD_AREA_ACTIVE_LOGOUT') - commit('UPLOAD_SETTINGS_LOGOUT') - dispatch('USER_SETTINGS_LOGOUT') - localStorage.clear() - sessionStorage.clear() - } - }, - - getters: {} -}) - -export const key: InjectionKey> = Symbol('vuex-store') - -export function useStore() { - return baseUseStore(key) -} diff --git a/picx/src/store/modules/dir-image-list/index.ts b/picx/src/store/modules/dir-image-list/index.ts deleted file mode 100644 index d482d6c..0000000 --- a/picx/src/store/modules/dir-image-list/index.ts +++ /dev/null @@ -1,260 +0,0 @@ -import { Module } from 'vuex' -import { PICX_MANAGEMENT } from '@/common/model/storage.model' -import DirImageListStateTypes, { DirObject } from './types' -import RootStateTypes from '../../types' -import { - createDirObject, - getUpLevelDirList, - getUpOneLevelDir -} from '@/store/modules/dir-image-list/utils' -import { UploadedImageModel } from '@/common/model/upload.model' -import { getDirContent } from '@/views/management/management.util' - -const initDirObject = () => { - const dirObj = localStorage.getItem(PICX_MANAGEMENT) - return dirObj ? JSON.parse(dirObj) : createDirObject('/', '/') -} - -const dirImageListModule: Module = { - state: { - name: 'dirImageListModule', - dirObject: initDirObject() - }, - - mutations: {}, - - actions: { - // 图床管理 - 增加目录 - DIR_IMAGE_LIST_ADD_DIR({ state, dispatch }, dirPath: string) { - if (dirPath === '/') { - return - } - - const findAssign = (dirObj: DirObject, dir: string, dirPath: string) => { - if (dirObj) { - if (!dirObj.childrenDirs.some((v: DirObject) => v.dir === dir)) { - dirObj.childrenDirs.push(createDirObject(dir, dirPath)) - } - const temp = dirObj.childrenDirs.find((x: DirObject) => x.dir === dir) - return temp || createDirObject(dir, dirPath) - } - return createDirObject(dir, dirPath) - } - - const dirList: string[] = dirPath.split('/') - let dirPathC = '' - let tempDirObj: DirObject = state.dirObject - - // eslint-disable-next-line no-plusplus - for (let i = 0, len = dirList.length; i < len; i++) { - const dirName = dirList[i] - dirPathC += `${i > 0 ? '/' : ''}${dirName}` - tempDirObj = findAssign(tempDirObj, dirName, dirPathC) - - if (i === 0) { - dispatch('USER_CONFIG_INFO_ADD_DIR', dirName) - } - } - - dispatch('DIR_IMAGE_LIST_PERSIST') - }, - - // 图床管理 - 删除目录 - DIR_IMAGE_LIST_REMOVE_DIR({ state, dispatch }, dirPath: string) { - if (dirPath === '/') { - return - } - - const rmDir = (dirObj: DirObject, dir: string, isRm: boolean) => { - if (dir === '/') { - return state.dirObject - } - - const temp = dirObj.childrenDirs.find((v) => v.dir === dir) - if (!temp) { - return dirObj - } - - if (isRm) { - const rmIndex = dirObj.childrenDirs.findIndex((v: any) => v.dir === dir) - if (rmIndex !== -1) { - dirObj.childrenDirs.splice(rmIndex, 1) - } - } - - return temp - } - - const dirList = dirPath.split('/') - - let tempDirObj = state.dirObject - dirList.forEach((d, i) => { - tempDirObj = rmDir(tempDirObj, d, i === dirList.length - 1) - - // 删除在用户配置信息模块里的目录项 - if (i === 0) { - dispatch('USER_CONFIG_INFO_REMOVE_DIR', d) - } - }) - - dispatch('DIR_IMAGE_LIST_PERSIST') - }, - - // 图床管理 - 增加图片 - DIR_IMAGE_LIST_ADD_IMAGE({ state, dispatch }, item: UploadedImageModel) { - const addImg = ( - dirObj: DirObject, - dir: string, - Img: UploadedImageModel, - isAdd: boolean = false - ) => { - if (!dirObj) { - return state.dirObject - } - - const temp = dirObj.childrenDirs?.find((x: DirObject) => x.dir === dir) - if (!temp) { - return state.dirObject - } - - if (isAdd && !temp.imageList.some((v) => v.name === Img.name)) { - temp.imageList.push(Img) - } - - return temp - } - - let tempDirObj: DirObject = state.dirObject - - if (item.dir === '/') { - if (!tempDirObj.imageList.some((v) => v.name === item.name)) { - tempDirObj.imageList.push(item) - } - } else { - const dirList: string[] = item.dir.split('/') - dirList.forEach((dir, i) => { - tempDirObj = addImg(tempDirObj, dir, item, i === dirList.length - 1) - }) - } - dispatch('DIR_IMAGE_LIST_PERSIST') - }, - - // 图床管理 - 删除图片(即删除指定目录里的指定图片) - DIR_IMAGE_LIST_REMOVE({ state, dispatch }, item: any) { - // 删除 - const rm = (list: UploadedImageModel[], uuid: string) => { - if (list.length) { - const rmIndex = list.findIndex((v: any) => v.uuid === uuid) - if (rmIndex !== -1) { - list.splice(rmIndex, 1) - } - } - } - - // 删除图片 - const rmImg = ( - dirObj: DirObject, - dir: string, - img: UploadedImageModel, - isRm: boolean - ) => { - if (!dirObj) { - return state.dirObject - } - - const temp = dirObj.childrenDirs.find((x: DirObject) => x.dir === dir) - if (!temp) { - return state.dirObject - } - - if (temp.dir === dir && isRm) { - rm(temp.imageList, img.uuid) - } - - return temp - } - - const { dir, uuid } = item - - if (dir === '/') { - rm(state.dirObject.imageList, uuid) - dispatch('DIR_IMAGE_LIST_PERSIST') - return - } - - const dirList: string[] = dir.split('/') - let tempDirObj: DirObject = state.dirObject - - dirList.forEach((d, i) => { - tempDirObj = rmImg(tempDirObj, d, item, i === dirList.length - 1) - if (!tempDirObj.imageList.length && !tempDirObj.childrenDirs.length) { - const dirPathList = getUpLevelDirList(tempDirObj.dirPath) - - // 循环遍历判断上一级目录的内容是否为空,为空则删除,依次往上查找,直到根目录 - dirPathList.forEach((dp) => { - const dpc = getDirContent(dp, state.dirObject) - if (dpc && !dpc.imageList.length && !dpc.childrenDirs.length) { - const { dirPath } = getUpOneLevelDir(dp) - dispatch('SET_USER_CONFIG_INFO', { selectedDir: dirPath }) - dispatch('DIR_IMAGE_LIST_REMOVE_DIR', dp) - } - }) - } - }) - }, - - // 图床管理 - 初始化指定目录(即删除指定目录的子目录列表和图片列表) -- OK - DIR_IMAGE_LIST_INIT_DIR({ state, dispatch }, dirPath: string) { - let tempDirObj = state.dirObject - - if (dirPath === '/') { - tempDirObj.imageList = [] - tempDirObj.childrenDirs = [] - dispatch('DIR_IMAGE_LIST_PERSIST') - return - } - - const initDirObject = (dirObj: DirObject, dir: string, isInit: boolean) => { - if (!dirObj) { - return state.dirObject - } - - const temp = dirObj.childrenDirs?.find((x: DirObject) => x.dir === dir) - if (!temp) { - return state.dirObject - } - - if (isInit) { - temp.imageList = [] - temp.childrenDirs = [] - } - - return temp - } - - const dirList = dirPath.split('/') - - dirList.forEach((d, i) => { - tempDirObj = initDirObject(tempDirObj, d, i === dirList.length - 1) - }) - - dispatch('DIR_IMAGE_LIST_PERSIST') - }, - - // 图床管理 - 持久化存储 -- OK - DIR_IMAGE_LIST_PERSIST({ state }) { - localStorage.setItem(PICX_MANAGEMENT, JSON.stringify(state.dirObject)) - }, - - // 图床管理 - 退出登录 - DIR_IMAGE_LOGOUT({ state }) { - state.dirObject = createDirObject('/', '/') - } - }, - - getters: { - getDirObject: (state: any) => state.dirObject - } -} - -export default dirImageListModule diff --git a/picx/src/store/modules/dir-image-list/types.ts b/picx/src/store/modules/dir-image-list/types.ts deleted file mode 100644 index fdda470..0000000 --- a/picx/src/store/modules/dir-image-list/types.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { UploadedImageModel } from '@/common/model/upload.model' - -export interface DirObject { - type: 'dir' - dir: string - dirPath: string - childrenDirs: DirObject[] - imageList: UploadedImageModel[] -} - -export default interface DirImageListStateTypes { - name: string - dirObject: DirObject -} diff --git a/picx/src/store/modules/dir-image-list/utils.ts b/picx/src/store/modules/dir-image-list/utils.ts deleted file mode 100644 index 3d4694d..0000000 --- a/picx/src/store/modules/dir-image-list/utils.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { DirObject } from '@/store/modules/dir-image-list/types' - -/** - * 构造一个新的目录对象 - * @param dir - * @param dirPath - */ -export const createDirObject = (dir: string, dirPath: string): DirObject => { - return { - type: 'dir', - dir, - dirPath, - childrenDirs: [], - imageList: [] - } -} - -/** - * 获取上一级目录 - * @param dirPath - */ -export const getUpOneLevelDir = (dirPath: string) => { - if (dirPath === '/') { - return { - currentDir: '/', - dirPath: '/' - } - } - - const dirList = dirPath.split('/') - - if (dirList.length === 1) { - return { - currentDir: '/', - dirPath: '/' - } - } - - if (dirList.length > 1) { - dirList.length -= 1 - return { - currentDir: dirList[dirList.length - 1], - dirPath: dirList.join('/') - } - } - - return { - currentDir: '/', - dirPath: '/' - } -} - -/** - * 获取上级目录列表 - * @param dirPath - */ -export const getUpLevelDirList = (dirPath: string) => { - if (dirPath === '/') { - return [] - } - - const dirList = dirPath.split('/') - - const tempL: string[] = [] - let tempP = '' - - dirList.forEach((d, i) => { - tempP += `${i > 0 ? '/' : ''}${d}` - tempL.unshift(tempP) - }) - - return tempL -} diff --git a/picx/src/store/modules/image-card/index.ts b/picx/src/store/modules/image-card/index.ts deleted file mode 100644 index 32c4e42..0000000 --- a/picx/src/store/modules/image-card/index.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Module } from 'vuex' -import { ImageCardStateTypes } from './types' -import RootStateTypes from '../../types' -import { UploadedImageModel } from '@/common/model/upload.model' - -const imageCardModule: Module = { - state: { - imgCardArr: [] - }, - mutations: { - IMAGE_CARD(state: ImageCardStateTypes, { imageObj }) { - const { uuid, checked } = imageObj - if (checked) { - state.imgCardArr.forEach((item) => { - if (item.uuid === uuid) { - // eslint-disable-next-line no-param-reassign - item.checked = true - } - }) - } - }, - REPLACE_IMAGE_CARD(state: ImageCardStateTypes, { checkedImgArr }) { - if (checkedImgArr.length > 0) { - state.imgCardArr = checkedImgArr - } else { - state.imgCardArr = [] - } - } - }, - actions: {}, - getters: { - getImageCardArr: (state: ImageCardStateTypes) => state.imgCardArr, - getImageCardCheckedArr: (state: ImageCardStateTypes) => { - return state.imgCardArr.filter((item: UploadedImageModel) => { - return item.checked - }) - } - } -} - -export default imageCardModule diff --git a/picx/src/store/modules/image-card/types.ts b/picx/src/store/modules/image-card/types.ts deleted file mode 100644 index b750664..0000000 --- a/picx/src/store/modules/image-card/types.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { UploadedImageModel } from '@/common/model/upload.model' - -export interface ImageCardStateTypes { - imgCardArr: UploadedImageModel[] -} diff --git a/picx/src/store/modules/image-viewer/index.ts b/picx/src/store/modules/image-viewer/index.ts deleted file mode 100644 index 07a2bf3..0000000 --- a/picx/src/store/modules/image-viewer/index.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Module } from 'vuex' -import ImageViewerStateTypes from './types' -import RootStateTypes from '../../types' - -const imageViewerModule: Module = { - state: { - imageViewer: { - imgInfo: null, - isShow: false - } - }, - mutations: { - IMAGE_VIEWER(state: ImageViewerStateTypes, { imgInfo, isShow }) { - state.imageViewer.imgInfo = imgInfo - state.imageViewer.isShow = isShow - }, - - IMAGE_VIEWER_LOGOUT(state: ImageViewerStateTypes) { - state.imageViewer.isShow = false - state.imageViewer.imgInfo = null - } - }, - actions: {}, - getters: { - getImageViewer: (state: ImageViewerStateTypes) => state.imageViewer - } -} - -export default imageViewerModule diff --git a/picx/src/store/modules/image-viewer/types.ts b/picx/src/store/modules/image-viewer/types.ts deleted file mode 100644 index fbbcf07..0000000 --- a/picx/src/store/modules/image-viewer/types.ts +++ /dev/null @@ -1,12 +0,0 @@ -export interface ImgInfo { - name: string - size: number - lastModified: number - url: string -} -export default interface ImageViewerStateTypes { - imageViewer: { - imgInfo: ImgInfo | null - isShow: boolean - } -} diff --git a/picx/src/store/modules/to-upload-image/index.ts b/picx/src/store/modules/to-upload-image/index.ts deleted file mode 100644 index e7f6c1c..0000000 --- a/picx/src/store/modules/to-upload-image/index.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { ToUploadImageModel } from '@/common/model/upload.model' -import { Module } from 'vuex' -import ToUploadImageStateTypes from '@/store/modules/to-upload-image/types' -import RootStateTypes from '@/store/types' - -const toUploadImageModule: Module = { - state: { - curImgBase64Url: '', - curImgUuid: '', - list: [], - uploadedNumber: 0 - }, - - actions: { - // 要上传的图片列表 - 增加图片项 - TO_UPLOAD_IMAGE_LIST_ADD({ state }, item: ToUploadImageModel) { - state.list.unshift(item) - }, - - // 要上传的图片列表 - 设置当前图片的 Base64Url - TO_UPLOAD_IMAGE_SET_CURRENT({ state }, { uuid, base64Url }) { - state.curImgUuid = uuid - state.curImgBase64Url = base64Url - }, - - // 要上传的图片列表 - 上传完成的图片数量 +1 - TO_UPLOAD_IMAGE_UPLOADED({ state }) { - state.uploadedNumber += 1 - }, - - // 要上传的图片列表 - 删除图片项 - TO_UPLOAD_IMAGE_LIST_REMOVE({ state }, uuid: string) { - if (state.list.length > 0) { - const rmIndex = state.list.findIndex((v: ToUploadImageModel) => v.uuid === uuid) - if (rmIndex !== -1) { - state.list.splice(rmIndex, 1) - } - if (state.list.length === 0) { - state.curImgBase64Url = '' - state.uploadedNumber = 0 - } else if (state.curImgUuid === uuid) { - const cur = state.list[0] - state.curImgBase64Url = cur.imgData.base64Url - state.curImgUuid = cur.uuid - } - } - }, - - // 要上传的图片列表 - 上传失败时,在列表中移除已上传的图片 - TO_UPLOAD_IMAGE_LIST_FAIL({ state }) { - if (state.list.length > 0) { - const temp: ToUploadImageModel[] = state.list.filter( - (v: ToUploadImageModel) => v.uploadStatus.progress !== 100 - ) - if (temp.length > 0) { - state.list = temp - state.uploadedNumber = 0 - state.curImgBase64Url = temp[0].imgData.base64Url - } - } - }, - - // 要上传的图片列表 - 清空 Url - TO_UPLOAD_IMAGE_CLEAN_URL({ state }) { - state.curImgBase64Url = '' - }, - - // 要上传的图片列表 - 清空 List - TO_UPLOAD_IMAGE_CLEAN_LIST({ state }) { - state.list = [] - }, - - // 要上传的图片列表 - 清空上传完成数量 - TO_UPLOAD_IMAGE_CLEAN_UPLOADED_NUMBER({ state }) { - state.uploadedNumber = 0 - }, - - // 要上传的图片列表 - 退出登录 - TO_UPLOAD_IMAGE_LOGOUT({ state }) { - state.curImgBase64Url = '' - state.list = [] - state.uploadedNumber = 0 - } - }, - - getters: { - getToUploadImageList: (state: ToUploadImageStateTypes) => state.list, - getToUploadImage: (state: ToUploadImageStateTypes) => state - } -} - -export default toUploadImageModule diff --git a/picx/src/store/modules/to-upload-image/types.ts b/picx/src/store/modules/to-upload-image/types.ts deleted file mode 100644 index 0e7cf40..0000000 --- a/picx/src/store/modules/to-upload-image/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -export default interface ToUploadImageStateTypes { - curImgBase64Url: string - curImgUuid: string - list: any[] - uploadedNumber: number -} diff --git a/picx/src/store/modules/upload-area-active/index.ts b/picx/src/store/modules/upload-area-active/index.ts deleted file mode 100644 index 0e22bbf..0000000 --- a/picx/src/store/modules/upload-area-active/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Module } from 'vuex' -import UploadAreaActiveStateTypes from './types' -import RootStateTypes from '../../types' - -const uploadAreaActiveModule: Module = { - state: { - uploadAreaActive: false - }, - mutations: { - // 修改上传区域激活状态 - CHANGE_UPLOAD_AREA_ACTIVE(state: UploadAreaActiveStateTypes, isActive: boolean) { - state.uploadAreaActive = isActive - }, - - UPLOAD_AREA_ACTIVE_LOGOUT(state: UploadAreaActiveStateTypes) { - state.uploadAreaActive = false - } - }, - actions: {}, - getters: { - getUploadAreaActive: (state: UploadAreaActiveStateTypes) => state.uploadAreaActive - } -} - -export default uploadAreaActiveModule diff --git a/picx/src/store/modules/upload-area-active/types.ts b/picx/src/store/modules/upload-area-active/types.ts deleted file mode 100644 index 4e8f4f3..0000000 --- a/picx/src/store/modules/upload-area-active/types.ts +++ /dev/null @@ -1,3 +0,0 @@ -export default interface UploadAreaActiveStateTypes { - uploadAreaActive: boolean -} diff --git a/picx/src/store/modules/upload-settings/index.ts b/picx/src/store/modules/upload-settings/index.ts deleted file mode 100644 index 3455fad..0000000 --- a/picx/src/store/modules/upload-settings/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Module } from 'vuex' -import UploadAreaActiveStateTypes from './types' -import RootStateTypes from '../../types' - -const uploadSettingsModule: Module = { - state: { - uploadSettings: { - isSetMaxSize: true, - imageMaxSize: 30 * 1024 - } - }, - mutations: { - UPLOAD_SETTINGS_LOGOUT(state: UploadAreaActiveStateTypes) { - state.uploadSettings.isSetMaxSize = true - state.uploadSettings.imageMaxSize = 50 * 1024 - } - }, - actions: {}, - getters: { - getUploadSettings: (state) => state.uploadSettings - } -} - -export default uploadSettingsModule diff --git a/picx/src/store/modules/upload-settings/types.ts b/picx/src/store/modules/upload-settings/types.ts deleted file mode 100644 index 5e1ff9d..0000000 --- a/picx/src/store/modules/upload-settings/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -export default interface UploadSettingsStateTypes { - uploadSettings: { - isSetMaxSize: boolean - imageMaxSize: number - } -} diff --git a/picx/src/store/modules/uploaded-image-list/index.ts b/picx/src/store/modules/uploaded-image-list/index.ts deleted file mode 100644 index ea96a74..0000000 --- a/picx/src/store/modules/uploaded-image-list/index.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Module } from 'vuex' -import UploadedImageListStateTypes from '@/store/modules/uploaded-image-list/types' -import RootStateTypes from '@/store/types' -import { PICX_UPLOADED } from '@/common/model/storage.model' -import { UploadedImageModel } from '@/common/model/upload.model' - -const initUploadedImageList = (): UploadedImageModel[] => { - const imageList: string | null = sessionStorage.getItem(PICX_UPLOADED) - return imageList ? JSON.parse(imageList) : [] -} - -const uploadedImageListModule: Module = { - state: { - uploadedImageList: initUploadedImageList() - }, - - mutations: {}, - - actions: { - // 上传完成的图片列表 - 增加 - UPLOADED_LIST_ADD({ state, dispatch }, item: UploadedImageModel) { - state.uploadedImageList.unshift(item) - dispatch('UPLOADED_LIST_PERSIST') - }, - - // 上传完成的图片列表 - 删除 - UPLOADED_LIST_REMOVE({ state, dispatch }, uuid: string) { - if (state.uploadedImageList.length > 0) { - const rmIndex = state.uploadedImageList.findIndex((v) => v.uuid === uuid) - if (rmIndex !== -1) { - state.uploadedImageList.splice(rmIndex, 1) - dispatch('UPLOADED_LIST_PERSIST') - } - } - }, - - // 上传完成的图片列表 - 持久化 - UPLOADED_LIST_PERSIST({ state }) { - sessionStorage.setItem(PICX_UPLOADED, JSON.stringify(state.uploadedImageList)) - }, - - // 上传完成的图片列表 - 退出登录 - UPLOADED_LIST_LOGOUT({ state }) { - state.uploadedImageList = [] - } - }, - - getters: { - getUploadedImageList: (state: any) => state.uploadedImageList - } -} - -export default uploadedImageListModule diff --git a/picx/src/store/modules/uploaded-image-list/types.ts b/picx/src/store/modules/uploaded-image-list/types.ts deleted file mode 100644 index 6048dd1..0000000 --- a/picx/src/store/modules/uploaded-image-list/types.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { UploadedImageModel } from '@/common/model/upload.model' - -export default interface UploadedImageListStateTypes { - uploadedImageList: UploadedImageModel[] -} diff --git a/picx/src/store/modules/user-config-info/index.ts b/picx/src/store/modules/user-config-info/index.ts deleted file mode 100644 index 6f73e99..0000000 --- a/picx/src/store/modules/user-config-info/index.ts +++ /dev/null @@ -1,155 +0,0 @@ -import { Module } from 'vuex' -import { - BranchModeEnum, - UserConfigInfoModel -} from '@/common/model/user-config-info.model' -import { PICX_CONFIG } from '@/common/model/storage.model' -import { deepAssignObject, cleanObject } from '@/utils/object-helper' -import UserConfigInfoStateTypes from '@/store/modules/user-config-info/types' -import RootStateTypes from '@/store/types' -import { DirModeEnum } from '@/common/model/dir.model' -import TimeHelper from '@/utils/time-helper' - -const initUserConfigInfo = (): UserConfigInfoModel => { - const initConfig: UserConfigInfoModel = { - token: '', - owner: '', - email: '', - name: '', - avatarUrl: '', - selectedRepos: '', - reposList: [], - branchMode: BranchModeEnum.reposBranch, - branchList: [], - selectedBranch: '', - selectedDir: '', - dirMode: DirModeEnum.reposDir, - dirList: [], - loggingStatus: false, - selectedDirList: [] - } - - const LSConfig: string | null = localStorage.getItem(PICX_CONFIG) - - if (LSConfig) { - // Assign: oldConfig -> initConfig - deepAssignObject(initConfig, JSON.parse(LSConfig)) - - if (initConfig.selectedBranch && !initConfig.branchList.length) { - initConfig.branchList = [ - { - value: initConfig.selectedBranch, - label: initConfig.selectedBranch - } - ] - } - - if (initConfig.dirMode === DirModeEnum.autoDir) { - initConfig.selectedDir = TimeHelper.getYyyyMmDd() - } - - return initConfig - } - - return initConfig -} - -const userConfigInfoUpdate = (state: UserConfigInfoStateTypes): void => { - const { selectedDir, selectedBranch, dirMode } = state.userConfigInfo - if (dirMode === 'newDir') { - const strList = selectedDir.split('') - let count = 0 - let newStr = '' - // eslint-disable-next-line no-plusplus - for (let i = 0; i < strList.length; i++) { - if (strList[i] === ' ' || strList[i] === '.' || strList[i] === '、') { - strList[i] = '-' - } - if (strList[i] === '/') { - count += 1 - } - if (count >= 3) { - break - } - newStr += strList[i] - } - state.userConfigInfo.selectedDir = newStr - } - state.userConfigInfo.selectedBranch = selectedBranch.replace(/\s+/g, '-') -} - -const userConfigInfoModule: Module = { - state: { - userConfigInfo: initUserConfigInfo() - }, - - actions: { - // 持久化状态获取 - USER_CONFIG_INFO_RESET({ state }) { - state.userConfigInfo = initUserConfigInfo() - }, - // 设置用户配置信息 - SET_USER_CONFIG_INFO( - { state, dispatch }, - configInfo: UserConfigInfoStateTypes, - needPersist: boolean = true - ) { - // eslint-disable-next-line no-restricted-syntax - for (const key in configInfo) { - // eslint-disable-next-line no-prototype-builtins - if (state.userConfigInfo.hasOwnProperty(key)) { - // @ts-ignore - state.userConfigInfo[key] = configInfo[key] - } else if (key === 'needPersist') { - // eslint-disable-next-line - needPersist = false - } - } - if (!needPersist) return - dispatch('USER_CONFIG_INFO_PERSIST') - }, - - // 用户配置信息 - 增加目录 - USER_CONFIG_INFO_ADD_DIR({ state, dispatch }, dir: string) { - if (!state.userConfigInfo.dirList.some((v: any) => v.value === dir)) { - state.userConfigInfo.dirList.push({ label: dir, value: dir }) - dispatch('USER_CONFIG_INFO_PERSIST') - } - }, - - // 用户配置信息 - 删除目录列表的某个目录 - USER_CONFIG_INFO_REMOVE_DIR({ state, dispatch }, dir: string) { - const { dirList } = state.userConfigInfo - if (dirList.some((v: any) => v.value === dir)) { - const rmIndex = dirList.findIndex((v: any) => v.value === dir) - dirList.splice(rmIndex, 1) - dispatch('USER_CONFIG_INFO_PERSIST') - } - }, - - // 持久化用户配置信息 - USER_CONFIG_INFO_PERSIST({ state }) { - userConfigInfoUpdate(state) - localStorage.setItem(PICX_CONFIG, JSON.stringify(state.userConfigInfo)) - }, - - // 修改 userConfigInfo 但无需持久化 (目前提供图床管理页面使用) - USER_CONFIG_INFO_NOT_PERSIST({ state }) { - userConfigInfoUpdate(state) - }, - - // 退出登录 - USER_CONFIG_INFO_LOGOUT({ state }) { - cleanObject(state.userConfigInfo) - } - }, - - getters: { - getUserLoggingStatus: (state: UserConfigInfoStateTypes): boolean => - state.userConfigInfo.loggingStatus, - getUserConfigInfo: (state: UserConfigInfoStateTypes): UserConfigInfoModel => - state.userConfigInfo - } -} - -export default userConfigInfoModule diff --git a/picx/src/store/modules/user-config-info/types.ts b/picx/src/store/modules/user-config-info/types.ts deleted file mode 100644 index e54818e..0000000 --- a/picx/src/store/modules/user-config-info/types.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { UserConfigInfoModel } from '@/common/model/user-config-info.model' - -export default interface UserConfigInfoStateTypes { - userConfigInfo: UserConfigInfoModel -} diff --git a/picx/src/store/modules/user-settings/index.ts b/picx/src/store/modules/user-settings/index.ts deleted file mode 100644 index 6607590..0000000 --- a/picx/src/store/modules/user-settings/index.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Module } from 'vuex' -import { PICX_SETTINGS } from '@/common/model/storage.model' -import { deepAssignObject } from '@/utils/object-helper' -import UserConfigInfoStateTypes from '@/store/modules/user-config-info/types' -import RootStateTypes from '@/store/types' -import { CompressEncoderMap } from '@/utils/compress' -import { UserSettingsModel } from '@/common/model/user-settings.model' -import UserSettingsStateTypes from '@/store/modules/user-settings/types' -import { getLocalItem } from '@/utils/common-utils' -import ExternalLinkType from '@/common/model/external-link.model' - -const initSettings: UserSettingsModel = { - defaultHash: true, - defaultMarkdown: false, - defaultPrefix: false, - prefixName: '', - isCompress: true, - compressEncoder: CompressEncoderMap.webP, - themeMode: 'light', - autoLightThemeTime: ['08:00', '19:00'], - elementPlusSize: 'default', - externalLinkType: ExternalLinkType.staticaly -} - -const initUserSettings = (): UserSettingsModel => { - const LSSettings = getLocalItem(PICX_SETTINGS) - if (LSSettings) { - deepAssignObject(initSettings, LSSettings) - } - return initSettings -} - -const userSettingsModule: Module = { - state: { - userSettings: initUserSettings() - }, - - actions: { - // 设置 - SET_USER_SETTINGS({ state }, configInfo: UserConfigInfoStateTypes) { - // eslint-disable-next-line no-restricted-syntax - for (const key in configInfo) { - // eslint-disable-next-line no-prototype-builtins - if (state.userSettings.hasOwnProperty(key)) { - // @ts-ignore - state.userSettings[key] = configInfo[key] - } - } - }, - - // 持久化 - USER_SETTINGS_PERSIST({ state }) { - localStorage.setItem(PICX_SETTINGS, JSON.stringify(state.userSettings)) - }, - - // 退出登录 - USER_SETTINGS_LOGOUT({ state }) { - state.userSettings = initSettings - } - }, - - getters: { - getUserSettings: (state): UserSettingsModel => state.userSettings - } -} - -export default userSettingsModule diff --git a/picx/src/store/modules/user-settings/types.ts b/picx/src/store/modules/user-settings/types.ts deleted file mode 100644 index 596b418..0000000 --- a/picx/src/store/modules/user-settings/types.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { UserSettingsModel } from '@/common/model/user-settings.model' - -export default interface UserSettingsStateTypes { - userSettings: UserSettingsModel -} diff --git a/picx/src/store/types.ts b/picx/src/store/types.ts deleted file mode 100644 index dca2872..0000000 --- a/picx/src/store/types.ts +++ /dev/null @@ -1,21 +0,0 @@ -import DirImageListStateTypes from './modules/dir-image-list/types' -import ToUploadImageStateTypes from './modules/to-upload-image/types' -import UploadedImageListStateTypes from './modules/uploaded-image-list/types' -import UserConfigInfoStateTypes from './modules/user-config-info/types' -import ImageViewerStateTypes from './modules/image-viewer/types' -import UploadAreaActiveStateTypes from './modules/upload-area-active/types' -import UploadSettingsStateTypes from './modules/upload-settings/types' - -export default interface RootStateTypes { - rootName: string -} - -export interface AllStateTypes extends RootStateTypes { - dirImageListModule: DirImageListStateTypes - toUploadImageModule: ToUploadImageStateTypes - uploadedImageListModule: UploadedImageListStateTypes - userConfigInfoModule: UserConfigInfoStateTypes - imageViewerModule: ImageViewerStateTypes - uploadAreaActiveModule: UploadAreaActiveStateTypes - uploadSettingsModule: UploadSettingsStateTypes -} diff --git a/picx/src/style/base.styl b/picx/src/style/base.styl deleted file mode 100644 index acce335..0000000 --- a/picx/src/style/base.styl +++ /dev/null @@ -1,98 +0,0 @@ -@import './theme.styl' -@import './variables.styl' - -$component-interval = 16rem -$box-border-radius = 6rem -$content-max-width = 888rem -$scrollbar-size = 8rem - -:root { - font-size 1px - - +picx-tablet() { - font-size 0.9px - } - - +picx-mobile() { - font-size 0.8px - } -} - -html, body { - position relative - padding 0 - margin 0 - width 100% - height 100% - color var(--default-text-color) -} - -a { - text-decoration none - font-size 1.5rem - color var(--default-text-color) -} - -a:link { - color var(--default-text-color) - text-decoration none -} - -ul, ol, li { - list-style none -} - -* { - &::-webkit-scrollbar { - height $scrollbar-size - width $scrollbar-size - } - - &::-webkit-scrollbar-thumb { - background var(--scrollbar-color) - border-radius $box-border-radius - } - - &::-webkit-scrollbar-track { - background transparent - } -} - - -.flex-center { - display flex - justify-content center - align-items center -} - - -.flex-start { - display flex - justify-content flex-start - align-items center -} - - -.page-container { - width 100% - height 100% - box-sizing border-box - padding 30rem - background var(--background-color) - border-top-left-radius $box-border-radius - border-top-right-radius $box-border-radius - overflow-y auto -} - -.clear { - &::after { - content '' - display block - clear both - visibility hidden - overflow hidden - height 0 - } -} - - diff --git a/picx/src/style/theme.styl b/picx/src/style/theme.styl deleted file mode 100644 index 5f3e64c..0000000 --- a/picx/src/style/theme.styl +++ /dev/null @@ -1,25 +0,0 @@ -@import './variables.styl' - -:root { - root-color('light') -} - -@media (prefers-color-scheme light) { - :root { - root-color('light') - } -} - -@media (prefers-color-scheme dark) { - :root { - root-color('dark') - } -} - -.light { - root-color('light') -} - -.dark { - root-color('dark') -} diff --git a/picx/src/style/variables.styl b/picx/src/style/variables.styl deleted file mode 100644 index f43d8b4..0000000 --- a/picx/src/style/variables.styl +++ /dev/null @@ -1,110 +0,0 @@ -// ======================================================================================== -// media query -// ======================================================================================== -$media-max-width-tablet = 800px; // media query max width (tablet) -$media-max-width-mobile = 500px; // media query max width (mobile) - -picx-tablet() - @media (max-width: $media-max-width-tablet) - { block } - -picx-mobile() - @media (max-width: $media-max-width-mobile) - { block } - - -// ======================================================================================== -// z-index -// ======================================================================================== -$z-index-1 = 1001; -$z-index-2 = 1002; -$z-index-3 = 1003; -$z-index-4 = 1004; -$z-index-5 = 1005; -$z-index-6 = 1006; -$z-index-7 = 1007; -$z-index-8 = 1008; -$z-index-9 = 1009; - - -// ======================================================================================== -// light mode color -// ======================================================================================== -$primary-color = #0066CC; -$background-color = #fff; -$second-background-color = darken($background-color, 5%); -$third-background-color = darken($background-color, 10%); -$default-text-color = #50505c; -$first-text-color = darken($default-text-color, 10%); -$second-text-color = darken($default-text-color, 5%); -$third-text-color = lighten($default-text-color, 30%); -$fourth-text-color = lighten($default-text-color, 90%); -$border-color = darken($background-color, 30%); -$selection-color = lighten($primary-color, 10%); -$shadow-color = rgba(0, 0, 0, 0.2); -$shadow-hover-color = rgba(0, 0, 0, 0.28); -$scrollbar-color = darken($background-color, 20%); -$scroll-bar-bg-color = darken($background-color, 30%); -$upload-area-focus-color = #0066CC; -$await-upload-color = #E6A23C; -$uploading-color = #409EFF; -$uploaded-color = #67C23A; -$markdown-icon-color = #808080; -$markdown-icon-active-color = darken($markdown-icon-color, 30%); - - - -// ======================================================================================== -// dark mode color -// ======================================================================================== -$dark-primary-color = #0066CC; -$dark-background-color = #2a2a2f; -$dark-second-background-color = darken($dark-background-color, 10%); -$dark-third-background-color = darken($dark-background-color, 15%); -$dark-default-text-color = #bebec6; -$dark-first-text-color = lighten($dark-default-text-color, 30%); -$dark-second-text-color = lighten($dark-default-text-color, 20%); -$dark-third-text-color = darken($dark-default-text-color, 20%); -$dark-fourth-text-color = darken($dark-default-text-color, 80%); -$dark-border-color = lighten($dark-background-color, 20%); -$dark-selection-color = $selection-color; -$dark-shadow-color = rgba(128, 128, 128, 0.2); -$dark-shadow-hover-color = rgba(128, 128, 128, 0.28); -$dark-scrollbar-color = darken($dark-background-color, 20%); -$dark-scroll-bar-bg-color = lighten($dark-background-color, 30%); -$dark-upload-area-focus-color = #1070d0; -$dark-await-upload-color = #c08327; -$dark-uploading-color = #287dd5; -$dark-uploaded-color = #55b626; -$dark-markdown-icon-color = #aaa; -$dark-markdown-icon-active-color = lighten($dark-markdown-icon-color, 30%); - - - -// ======================================================================== -// light/dark mode color -// ======================================================================== -root-color(mode) { - --background-color: mode == 'light' ? $background-color : $dark-background-color; - --second-background-color: mode == 'light' ? $second-background-color : $dark-second-background-color; - --third-background-color: mode == 'light' ? $third-background-color : $dark-third-background-color; - --primary-color: mode == 'light' ? $primary-color : $dark-primary-color; - --first-text-color: mode == 'light' ? $first-text-color : $dark-first-text-color; - --second-text-color: mode == 'light' ? $second-text-color : $dark-second-text-color; - --third-text-color: mode == 'light' ? $third-text-color : $dark-third-text-color; - --fourth-text-color: mode == 'light' ? $fourth-text-color : $dark-fourth-text-color; - --default-text-color: mode == 'light' ? $default-text-color : $dark-default-text-color; - --border-color: mode == 'light' ? $border-color : $dark-border-color; - --selection-color: mode == 'light' ? $selection-color : $dark-selection-color; - --shadow-color: mode == 'light' ? $shadow-color : $dark-shadow-color; - --shadow-hover-color: mode == 'light' ? $shadow-hover-color : $dark-shadow-hover-color; - --scrollbar-color: mode == 'light' ? $scrollbar-color : $dark-scrollbar-color; - --scroll-bar-bg-color: mode == 'light' ? $scroll-bar-bg-color : $dark-scroll-bar-bg-color; - --upload-area-focus-color : mode == 'light' ? $upload-area-focus-color : $dark-upload-area-focus-color; - --await-upload-color : mode == 'light' ? $await-upload-color : $dark-await-upload-color; - --uploading-color : mode == 'light' ? $uploading-color : $dark-uploading-color; - --uploaded-color : mode == 'light' ? $uploaded-color : $dark-uploaded-color; - --markdown-icon-color : mode == 'light' ? $markdown-icon-color : $dark-markdown-icon-color; - --markdown-icon-active-color : mode == 'light' ? $markdown-icon-active-color : $dark-markdown-icon-active-color; -} - diff --git a/picx/src/utils/axios.ts b/picx/src/utils/axios.ts deleted file mode 100644 index 37c0b38..0000000 --- a/picx/src/utils/axios.ts +++ /dev/null @@ -1,51 +0,0 @@ -import Axios from 'axios' -import { PICX_CONFIG } from '@/common/model/storage.model' - -const baseURL = 'https://api.github.com' - -const axios = Axios.create({ - baseURL, - timeout: 300000 // request timeout 请求超时 5m -}) - -axios.defaults.headers['Content-Type'] = 'application/json' - -// 发起请求之前的拦截器(前置拦截) -axios.interceptors.request.use( - (config) => { - const userConfig = localStorage.getItem(PICX_CONFIG) - - if (userConfig) { - const { token } = JSON.parse(userConfig) - if (token) { - config.headers.Authorization = `token ${token}` - } - } - - return config - }, - (error) => { - return Promise.reject(error) - } -) - -// 响应拦截器 -axios.interceptors.response.use( - (response) => { - return response - }, - (error) => { - if (error.response && error.response.data) { - const code = error.response.status - const msg = error.response.data.message - ElMessage.error(`Code: ${code}, Message: ${msg}`) - console.error(`[PicX Error]`, error.response) - } else { - ElMessage.error(`${error}`) - } - - return error.response - } -) - -export default axios diff --git a/picx/src/utils/common-utils.ts b/picx/src/utils/common-utils.ts deleted file mode 100644 index d22db32..0000000 --- a/picx/src/utils/common-utils.ts +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Get JavaScript basic data types - * @param data - * @returns {string} array | string | number ... - */ -export const getType = (data: string) => { - const type = Object.prototype.toString.call(data).split(' ')[1] - return type.substring(0, type.length - 1).toLowerCase() -} - -/** - * Gets a string(uuid) that is not repeated - * @returns uuid {string} - */ -export const getUuid = () => { - return Number(Math.random().toString().substr(2, 5) + Date.now()).toString(36) -} - -/** - * get localStorage value - * @param key - * @returns {*} - */ -export const getLocalItem = (key: string) => { - const temp = window.localStorage.getItem(key) - return temp ? JSON.parse(temp) : null -} diff --git a/picx/src/utils/compress.ts b/picx/src/utils/compress.ts deleted file mode 100644 index e058abb..0000000 --- a/picx/src/utils/compress.ts +++ /dev/null @@ -1,26 +0,0 @@ -import Compress from '@yireen/squoosh-browser' -import { - defaultPreprocessorState, - defaultProcessorState, - encoderMap, - EncoderState -} from '@yireen/squoosh-browser/dist/client/lazy-app/feature-meta' - -export enum CompressEncoderMap { - mozJPEG = 'mozJPEG', - avif = 'avif', - webP = 'webP' -} - -export const compress = async (file: File, encoder: CompressEncoderMap) => { - const compress = new Compress(file, { - encoderState: { - type: encoder, - options: encoderMap[encoder].meta.defaultOptions - } as EncoderState, - processorState: defaultProcessorState, - preprocessorState: defaultPreprocessorState - }) - - return compress.process() -} diff --git a/picx/src/utils/create-to-upload-image.ts b/picx/src/utils/create-to-upload-image.ts deleted file mode 100644 index 547c489..0000000 --- a/picx/src/utils/create-to-upload-image.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { ToUploadImageModel } from '../common/model/upload.model' - -export default (): ToUploadImageModel => { - return { - uuid: '', - - uploadStatus: { - progress: 0, - uploading: false - }, - - imgData: { - base64Content: '', - base64Url: '' - }, - - fileInfo: { - size: 0, - lastModified: 0 - }, - - filename: { - name: '', - hash: '', - suffix: '', - prefixName: '', - now: '', - initName: '', - newName: 'xxx', - isHashRename: true, - isRename: false, - isPrefix: false - }, - - externalLink: { - github: '', - jsdelivr: '', - staticaly: '', - cloudflare: '' - } - } -} diff --git a/picx/src/utils/delete-image-card.ts b/picx/src/utils/delete-image-card.ts deleted file mode 100644 index a90852a..0000000 --- a/picx/src/utils/delete-image-card.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { UploadedImageModel } from '../common/model/upload.model' -import { UserConfigInfoModel } from '../common/model/user-config-info.model' -import axios from '@/utils/axios' -import { deleteStatusEnum } from '../common/model/delete.model' -import { store } from '@/store' - -let deleteIndex = 0 - -export async function deleteSingleImage( - imageObj: UploadedImageModel, - userConfigInfo: UserConfigInfoModel -): Promise { - // eslint-disable-next-line no-param-reassign - imageObj.deleting = true - const { owner, selectedRepos } = userConfigInfo - return new Promise((resolve, reject) => { - axios - .delete(`/repos/${owner}/${selectedRepos}/contents/${imageObj.path}`, { - data: { - owner, - repo: selectedRepos, - path: imageObj.path, - message: 'delete picture via PicX(https://github.com/XPoet/picx)', - sha: imageObj.sha - } - }) - .then((res) => { - if (res && res.status === 200) { - // eslint-disable-next-line no-param-reassign - imageObj.deleting = false - store.dispatch('UPLOADED_LIST_REMOVE', imageObj.uuid) - store.dispatch('DIR_IMAGE_LIST_REMOVE', imageObj) - resolve(true) - } else { - // eslint-disable-next-line no-param-reassign - imageObj.deleting = false - resolve(false) - } - }) - .catch((err) => { - reject(err) - }) - }) -} - -export async function delelteBatchImage( - imgCardArr: Array, - userConfigInfo: UserConfigInfoModel -) { - if (deleteIndex >= imgCardArr.length) { - return deleteStatusEnum.deleted - } - if (await deleteSingleImage(imgCardArr[deleteIndex], userConfigInfo)) { - if (deleteIndex < imgCardArr.length) { - deleteIndex += 1 - if (await delelteBatchImage(imgCardArr, userConfigInfo)) { - deleteIndex = 0 - return deleteStatusEnum.allDeleted - } - } - return deleteStatusEnum.deleted - } - return deleteStatusEnum.deleteFail -} diff --git a/picx/src/utils/env.ts b/picx/src/utils/env.ts deleted file mode 100644 index 99919a5..0000000 --- a/picx/src/utils/env.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable no-restricted-syntax */ -import { Recordable, ViteEnv } from '@/common/model/vite-config.model' - -// Read all environment variable configuration files to process.env -export default function wrapperEnv(envConf: Recordable): ViteEnv { - const ret: any = {} - - for (const envName of Object.keys(envConf)) { - let realName = envConf[envName].replace(/\\n/g, '\n') - if (realName === 'true') { - realName = true - } else if (realName === 'false') { - realName = false - } - - if (envName === 'VITE_PORT') { - realName = Number(realName) - } - ret[envName] = realName - process.env[envName] = realName - } - return ret -} diff --git a/picx/src/utils/external-link-handler.ts b/picx/src/utils/external-link-handler.ts deleted file mode 100644 index e8f4a3e..0000000 --- a/picx/src/utils/external-link-handler.ts +++ /dev/null @@ -1,178 +0,0 @@ -import ExternalLinkType from '@/common/model/external-link.model' -import { UserConfigInfoModel } from '@/common/model/user-config-info.model' -import { getFilename } from '@/utils/file-handle-helper' -import { UploadedImageModel } from '@/common/model/upload.model' - -/** - * 创建承载图片外链文本的 DOM 元素 - */ -export const createExternalLinkDom = () => { - let externalLinkDom: any = document.querySelector('.temp-external-link-txt') - if (!externalLinkDom) { - externalLinkDom = document.createElement('textarea') - externalLinkDom.setAttribute('class', 'temp-external-link-txt') - externalLinkDom.style.position = 'absolute' - externalLinkDom.style.top = '-99999rem' - externalLinkDom.style.left = '-99999rem' - document.body.appendChild(externalLinkDom) - } - return externalLinkDom -} - -/** - * 生成图片外链 - * @param type - * @param content - * @param config - */ -export const generateExternalLink = ( - type: ExternalLinkType, - content: any, - config: UserConfigInfoModel -): string => { - const staticalyLink: string = `https://cdn.staticaly.com/gh/${config.owner}/${config.selectedRepos}@${config.selectedBranch}/${content.path}` - const cloudflareLink: string = `https://git.poker/${config.owner}/${config.selectedRepos}/blob/${config.selectedBranch}/${content.path}?raw=true` - const jsdelivrLink: string = `https://cdn.jsdelivr.net/gh/${config.owner}/${config.selectedRepos}@${config.selectedBranch}/${content.path}` - const githubLink: string = decodeURI(content.download_url) - - // eslint-disable-next-line default-case - switch (type) { - case ExternalLinkType.staticaly: - return staticalyLink - - case ExternalLinkType.cloudflare: - return cloudflareLink - - case ExternalLinkType.jsdelivr: - return jsdelivrLink - - case ExternalLinkType.github: - return githubLink - - default: - return githubLink - } -} - -/** - * 图片外链转换为 Markdown 格式 - * @param name 图片名 - * @param url 图片外链 - */ -export const formatMarkdown = (name: string, url: string): string => { - return `![${getFilename(name)}](${url})` -} - -/** - * 复制图片外链 - * @param img 图片对象 - * @param type CDN 类型 - */ -export const copyExternalLink = (img: UploadedImageModel, type: ExternalLinkType) => { - let externalLink = '' - let successInfo = '' - const { name, is_transform_md: isMD } = img - - switch (type) { - case ExternalLinkType.jsdelivr: - if (isMD) { - externalLink = formatMarkdown(name, img.jsdelivr_cdn_url) - successInfo = 'Markdown 格式的 jsDelivr CDN' - } else { - externalLink = img.jsdelivr_cdn_url - successInfo = 'jsDelivr CDN' - } - break - - case ExternalLinkType.staticaly: - if (isMD) { - externalLink = formatMarkdown(name, img.staticaly_cdn_url) - successInfo = 'Markdown 格式的 Staticaly CDN' - } else { - externalLink = img.staticaly_cdn_url - successInfo = 'Staticaly CDN' - } - break - - case ExternalLinkType.cloudflare: - if (isMD) { - externalLink = formatMarkdown(name, img.cloudflare_cdn_url) - successInfo = 'Markdown 格式的 Cloudflare CDN' - } else { - externalLink = img.cloudflare_cdn_url - successInfo = 'Cloudflare CDN' - } - break - - default: - if (isMD) { - externalLink = formatMarkdown(name, img.github_url) - successInfo = 'Markdown 格式的 GitHub' - } else { - externalLink = img.github_url - successInfo = 'GitHub' - } - } - - const externalLinkDom: any = createExternalLinkDom() - - externalLinkDom.value = externalLink - externalLinkDom.select() - document.execCommand('copy') - ElMessage.success(`${successInfo} 外链复制成功!`) -} - -/** - * 批量复制图片外链 - * @param imgCardList 图片列表 - * @param type 当前选择的外链类型 - */ -export const batchCopyExternalLink = ( - imgCardList: Array, - type: ExternalLinkType -) => { - let externalLink = '' - const externalLinkDom: any = createExternalLinkDom() - externalLinkDom.value = '' - if (imgCardList?.length > 0) { - imgCardList.forEach((item: UploadedImageModel, index) => { - const isMD = item.is_transform_md - switch (type) { - case ExternalLinkType.jsdelivr: - externalLink = isMD - ? formatMarkdown(item.name, item.jsdelivr_cdn_url) - : item.jsdelivr_cdn_url - break - - case ExternalLinkType.staticaly: - externalLink = isMD - ? formatMarkdown(item.name, item.staticaly_cdn_url) - : item.staticaly_cdn_url - break - - case ExternalLinkType.cloudflare: - externalLink = isMD - ? formatMarkdown(item.name, item.cloudflare_cdn_url) - : item.cloudflare_cdn_url - break - - default: - externalLink = isMD - ? formatMarkdown(item.name, item.github_url) - : item.github_url - } - - if (index < imgCardList.length - 1) { - // eslint-disable-next-line prefer-template - externalLinkDom.value += externalLink + '\n' - } else { - externalLinkDom.value += externalLink - } - }) - externalLinkDom.select() - document.execCommand('copy') - ElMessage.success(`批量复制图片链接成功`) - } else { - console.warn('请先选择图片') - } -} diff --git a/picx/src/utils/file-handle-helper.ts b/picx/src/utils/file-handle-helper.ts deleted file mode 100644 index 27baf52..0000000 --- a/picx/src/utils/file-handle-helper.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { getUuid } from './common-utils' - -/** - * get filename - * @param filename - */ -export const getFilename = (filename: string) => { - const splitIndex = filename.indexOf('.') - return filename.substr(0, splitIndex).trim().replace(/\s+/g, '-') -} - -/** - * get filename suffix - * @param filename - */ -export const getFileSuffix = (filename: string) => { - const splitIndex = filename.lastIndexOf('.') - return filename.substr(splitIndex + 1, filename.length) -} - -export const isImage = (suffix: string): boolean => { - return /(png|jpg|gif|jpeg|webp|avif|svg\+xml|image\/x-icon)$/.test(suffix) -} - -/** - * get file size (KB) - * @param size - */ -export const getFileSize = (size: number) => { - return Number((size / 1024).toFixed(2)) -} - -/** - * filename handle - * @param filename - */ -export const filenameHandle = (filename: string | undefined) => { - if (filename) { - return { - name: getFilename(filename), - hash: getUuid(), - suffix: getFileSuffix(filename) - } - } - return { - name: '', - hash: '', - suffix: '' - } -} diff --git a/picx/src/utils/image-helper.ts b/picx/src/utils/image-helper.ts deleted file mode 100644 index 1ee88b2..0000000 --- a/picx/src/utils/image-helper.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { computed } from 'vue' -import { UploadedImageModel } from '@/common/model/upload.model' -import { getUuid } from '@/utils/common-utils' -import { generateExternalLink } from '@/utils/external-link-handler' -import ExternalLinkType from '@/common/model/external-link.model' -import { store } from '@/store' - -const userConfigInfo = computed(() => store.getters.getUserConfigInfo).value - -export default function structureImageObject( - item: any, - selectedDir: string -): UploadedImageModel { - return { - type: 'image', - uuid: getUuid(), - dir: selectedDir, - name: item.name, - path: item.path, - sha: item.sha, - deleting: false, - is_transform_md: false, - size: item.size, - checked: false, - github_url: generateExternalLink(ExternalLinkType.github, item, userConfigInfo), - jsdelivr_cdn_url: generateExternalLink( - ExternalLinkType.jsdelivr, - item, - userConfigInfo - ), - staticaly_cdn_url: generateExternalLink( - ExternalLinkType.staticaly, - item, - userConfigInfo - ), - cloudflare_cdn_url: generateExternalLink( - ExternalLinkType.cloudflare, - item, - userConfigInfo - ) - } -} diff --git a/picx/src/utils/object-helper.ts b/picx/src/utils/object-helper.ts deleted file mode 100644 index ea91287..0000000 --- a/picx/src/utils/object-helper.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { getType } from './common-utils' - -/** - * 根据 object 每个 key 上值的数据类型,赋对应的初始值 - * @param object - */ -export const cleanObject = (object: any) => { - // eslint-disable-next-line guard-for-in,no-restricted-syntax - for (const key in object) { - // eslint-disable-next-line default-case - switch (getType(object[key])) { - case 'object': - cleanObject(object[key]) - break - - case 'string': - // eslint-disable-next-line no-param-reassign - object[key] = '' - break - - case 'array': - // eslint-disable-next-line no-param-reassign - object[key] = [] - break - - case 'number': - // eslint-disable-next-line no-param-reassign - object[key] = 0 - break - - case 'boolean': - // eslint-disable-next-line no-param-reassign - object[key] = false - break - } - } -} - -/** - * 将 obj2 对象的值深度赋值给 obj1 对象 - * @param obj1{Object} - * @param obj2{Object} - */ -export const deepAssignObject = (obj1: object, obj2: object): any => { - // eslint-disable-next-line no-restricted-syntax - for (const key in obj2) { - // @ts-ignore - if (getType(obj2[key]) !== 'object') { - if (obj1) { - // @ts-ignore - // eslint-disable-next-line no-param-reassign - obj1[key] = obj2[key] - } - } else { - // @ts-ignore - deepAssignObject(obj1[key], obj2[key]) - } - } -} diff --git a/picx/src/utils/paste.ts b/picx/src/utils/paste.ts deleted file mode 100644 index a9b1678..0000000 --- a/picx/src/utils/paste.ts +++ /dev/null @@ -1,28 +0,0 @@ -import selectedFileHandle from './selected-file-handle' - -const onPaste = (e: any, maxsize: number): Promise | null => { - if (!(e.clipboardData && e.clipboardData.items)) { - return null - } - - // eslint-disable-next-line consistent-return - return new Promise((resolve) => { - // eslint-disable-next-line no-plusplus - for (let i = 0, len = e.clipboardData.items.length; i < len; i++) { - const item = e.clipboardData.items[i] - if (item.kind === 'file') { - const pasteFile = item.getAsFile() - - selectedFileHandle(pasteFile, maxsize)?.then((result) => { - if (!result) { - return - } - const { base64, originalFile, compressFile } = result - resolve({ base64, originalFile, compressFile }) - }) - } - } - }) -} - -export default onPaste diff --git a/picx/src/utils/register-sw.ts b/picx/src/utils/register-sw.ts deleted file mode 100644 index c569ffb..0000000 --- a/picx/src/utils/register-sw.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { registerSW } from 'virtual:pwa-register' - -registerSW() diff --git a/picx/src/utils/rename-image.ts b/picx/src/utils/rename-image.ts deleted file mode 100644 index ce25394..0000000 --- a/picx/src/utils/rename-image.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { computed } from 'vue' -import { store } from '@/store' -import createToUploadImageObject from '@/utils/create-to-upload-image' -import { filenameHandle } from './file-handle-helper' - -/** - * 根据图片链接获取图片 base64 编码 - * @param url 图片路径 - * @param ext 图片格式 - */ -export function getBase64ByImageUrl(url: string, ext: string): Promise { - const canvas = document.createElement('canvas') - const ctx = canvas.getContext('2d') - const img = new Image() - img.crossOrigin = 'Anonymous' - img.src = url - return new Promise((resolve) => { - img.onload = () => { - const { width } = img - const { height } = img - canvas.width = width // 指定画板的高度,自定义 - canvas.height = height // 指定画板的宽度,自定义 - ctx?.drawImage(img, 0, 0, width, height) // 参数可自定义 - const dataURL: string = canvas.toDataURL(`image/${ext}`) - resolve(dataURL) - } - }) -} - -// 获取图片对象 -export function getImage(base64Data: string, file: any) { - const userSettings = computed(() => store.getters.getUserSettings).value - const curImg = createToUploadImageObject() - - curImg.imgData.base64Url = base64Data - // eslint-disable-next-line prefer-destructuring - curImg.imgData.base64Content = base64Data.split(',')[1] - - const { name, hash, suffix } = filenameHandle(file.name) - curImg.uuid = hash - - curImg.fileInfo.size = file.size - curImg.fileInfo.originSize = file.size - curImg.fileInfo.lastModified = file.lastModified - - curImg.filename.name = name - curImg.filename.hash = hash - curImg.filename.suffix = suffix - curImg.filename.now = userSettings.defaultHash - ? `${name}.${hash}.${suffix}` - : `${name}.${suffix}` - curImg.filename.initName = name - curImg.filename.isHashRename = userSettings.defaultHash - - return curImg -} diff --git a/picx/src/utils/selected-file-handle.ts b/picx/src/utils/selected-file-handle.ts deleted file mode 100644 index 7cb1f91..0000000 --- a/picx/src/utils/selected-file-handle.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { store } from '@/store' -import { compress } from './compress' -import { getFileSize, isImage } from './file-handle-helper' - -export type handleResult = { base64: string; originalFile: File; compressFile?: File } - -const selectedFileHandle = async ( - file: File, - maxsize: number -): Promise => { - if (!file) { - return null - } - - if (!isImage(file.type)) { - ElMessage.error('该文件格式不支持!') - return null - } - let compressFile: NonNullable - const { isCompress, compressEncoder } = store.getters.getUserSettings - const isGif = file.type === 'image/gif' - if (!isGif && isCompress) { - const loadingInstance = ElLoading.service({ - target: '.upload-area', - text: '正在压缩图片' - }) - compressFile = await compress(file, compressEncoder) - loadingInstance.close() - } - - return new Promise((resolve) => { - const reader = new FileReader() - reader.readAsDataURL(!isGif && isCompress ? compressFile : file) - reader.onload = (e: ProgressEvent) => { - const base64: any = e.target?.result - const curImgSize = getFileSize(base64.length) - - if (curImgSize >= maxsize) { - // 给出提示,引导用户自行去压缩图片 - ElMessageBox.confirm( - `当前图片 ${(curImgSize / 1024).toFixed( - 2 - )} M,CDN 只能加速小于 50 MB 的图片,建议使用第三方工具 TinyPNG 压缩`, - '图片过大,禁止上传', - { - confirmButtonText: '前往 TinyPNG', - cancelButtonText: '放弃上传' - } - ) - .then(() => { - window.open('https://tinypng.com/') - }) - .catch(() => { - console.log('放弃上传') - }) - } else { - resolve({ - base64, - originalFile: file, - compressFile: !isGif && isCompress ? compressFile : file - }) - } - } - }) -} - -export default selectedFileHandle diff --git a/picx/src/utils/set-theme-mode.ts b/picx/src/utils/set-theme-mode.ts deleted file mode 100644 index 4fcb0e3..0000000 --- a/picx/src/utils/set-theme-mode.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { watch, nextTick } from 'vue' -import { useStore } from '@/store' -import { UserSettingsModel } from '@/common/model/user-settings.model' - -const setThemeMode = () => { - const store = useStore() - - const setBodyClassName = async (theme: 'dark' | 'light') => { - await nextTick(() => { - const body = document.getElementsByTagName('html')[0] - if (theme === 'dark') { - body.classList.remove('light') - body.classList.add('dark') - } else { - body.classList.remove('dark') - body.classList.add('light') - } - }) - } - - const autoThemeModeTimeHandle = (autoLightThemeTime: string[]) => { - const getTimestamp = (i: number) => { - const D = new Date() - const yyyy = D.getFullYear() - const mm = D.getMonth() + 1 - const dd = D.getDate() - return new Date(`${yyyy}/${mm}/${dd} ${autoLightThemeTime[i]}:00`).getTime() - } - const now = Date.now() - return getTimestamp(0) <= now && now <= getTimestamp(1) - } - - const setThemeByConfigFn = (settings: UserSettingsModel) => { - const { themeMode, autoLightThemeTime } = settings - if (themeMode === 'auto') { - setBodyClassName(autoThemeModeTimeHandle(autoLightThemeTime) ? 'light' : 'dark') - } else { - setBodyClassName(themeMode) - } - } - - watch( - (): UserSettingsModel => store.getters.getUserSettings, - (newValue) => { - setThemeByConfigFn(newValue) - }, - { deep: true, immediate: true } - ) -} - -export default setThemeMode diff --git a/picx/src/utils/time-helper.ts b/picx/src/utils/time-helper.ts deleted file mode 100644 index ba84dca..0000000 --- a/picx/src/utils/time-helper.ts +++ /dev/null @@ -1,26 +0,0 @@ -export default class TimeHelper { - private static zerofill(n: number) { - return n < 10 ? `0${n}` : n - } - - static getYyyyMmDd(now: number = Date.now()) { - const date: Date = new Date(now) - const yyyy = date.getFullYear() - const MM = date.getMonth() + 1 - const DD = date.getDate() - return `${yyyy}${this.zerofill(MM)}${this.zerofill(DD)}` - } - - static formatTimestamp(now: number = Date.now()) { - const date: Date = new Date(now) - const YYYY = date.getFullYear() - const MM = date.getMonth() + 1 - const DD = date.getDate() - const hh = date.getHours() - const mm = date.getMinutes() - const ss = date.getSeconds() - return `${YYYY}-${this.zerofill(MM)}-${this.zerofill(DD)} ${this.zerofill( - hh - )}:${this.zerofill(mm)}:${this.zerofill(ss)}` - } -} diff --git a/picx/src/utils/upload-helper.ts b/picx/src/utils/upload-helper.ts deleted file mode 100644 index 982b85b..0000000 --- a/picx/src/utils/upload-helper.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { UserConfigInfoModel } from '@/common/model/user-config-info.model' -import { ToUploadImageModel, UploadedImageModel } from '@/common/model/upload.model' -import axios from '@/utils/axios' -import { store } from '@/store' -import { generateExternalLink } from '@/utils/external-link-handler' -import ExternalLinkType from '@/common/model/external-link.model' - -export const uploadUrlHandle = ( - config: UserConfigInfoModel, - filename: string -): string => { - let path = '' - if (config.selectedDir !== '/') { - path = `${config.selectedDir}/` - } - return `/repos/${config.owner}/${config.selectedRepos}/contents/${path}${filename}` -} - -export function uploadImage_single( - userConfigInfo: UserConfigInfoModel, - img: ToUploadImageModel -): Promise { - const { selectedBranch, email, owner } = userConfigInfo - // eslint-disable-next-line no-param-reassign - img.uploadStatus.uploading = true - - const data: any = { - message: 'Upload picture via PicX(https://github.com/XPoet/picx)', - branch: selectedBranch, - content: img.imgData.base64Content - } - - if (email) { - data.committer = { - name: owner, - email - } - } - - return new Promise((resolve, reject) => { - axios - .put(uploadUrlHandle(userConfigInfo, img.filename.now), data) - .then((res) => { - if (res && res.status === 201) { - // eslint-disable-next-line no-use-before-define - uploadedHandle(res, img, userConfigInfo) - store.dispatch('TO_UPLOAD_IMAGE_UPLOADED', img.uuid) - resolve(true) - } else { - // eslint-disable-next-line no-param-reassign - img.uploadStatus.uploading = false - resolve(false) - } - }) - .catch((error) => { - reject(error) - }) - }) -} - -function uploadedHandle( - res: any, - img: ToUploadImageModel, - userConfigInfo: UserConfigInfoModel -) { - const userSettings = store.getters.getUserSettings - - // 上传状态处理 - // eslint-disable-next-line no-param-reassign - img.uploadStatus.progress = 100 - // eslint-disable-next-line no-param-reassign - img.uploadStatus.uploading = false - - // 生成 GitHub 外链 - // eslint-disable-next-line no-param-reassign - img.externalLink.github = generateExternalLink( - ExternalLinkType.github, - res.data.content, - userConfigInfo - ) - - // 生成 jsDelivr CDN 外链 - // eslint-disable-next-line no-param-reassign - img.externalLink.jsdelivr = generateExternalLink( - ExternalLinkType.jsdelivr, - res.data.content, - userConfigInfo - ) - - // 生成 Staticaly CDN 外链 - // eslint-disable-next-line no-param-reassign - img.externalLink.staticaly = generateExternalLink( - ExternalLinkType.staticaly, - res.data.content, - userConfigInfo - ) - - // 生成 Cloudflare CDN 外链 - // eslint-disable-next-line no-param-reassign - img.externalLink.cloudflare = generateExternalLink( - ExternalLinkType.cloudflare, - res.data.content, - userConfigInfo - ) - - const item: UploadedImageModel = { - checked: false, - type: 'image', - uuid: img.uuid, - dir: userConfigInfo.selectedDir, - name: res.data.content.name, - path: res.data.content.path, - sha: res.data.content.sha, - github_url: img.externalLink.github, - jsdelivr_cdn_url: img.externalLink.jsdelivr, - staticaly_cdn_url: img.externalLink.staticaly, - cloudflare_cdn_url: img.externalLink.cloudflare, - is_transform_md: userSettings.defaultMarkdown, - deleting: false, - size: img.fileInfo.size - } - - // eslint-disable-next-line no-param-reassign - img.uploadedImg = item - - // uploadedList 增加图片 - store.dispatch('UPLOADED_LIST_ADD', item) - - // dirImageList 增加目录 - store.dispatch('DIR_IMAGE_LIST_ADD_DIR', userConfigInfo.selectedDir) - - // dirImageList 增加图片 - store.dispatch('DIR_IMAGE_LIST_ADD_IMAGE', item) -} diff --git a/picx/src/views/about/about.styl b/picx/src/views/about/about.styl deleted file mode 100644 index 99ae5ac..0000000 --- a/picx/src/views/about/about.styl +++ /dev/null @@ -1,25 +0,0 @@ -.feedback-page-container { - - .help-info-item { - font-size: 16rem; - padding: 6rem; - display: flex; - align-items: center; - margin-bottom: 10rem; - - &:last-child { - margin-bottom: 0; - } - - - } - - .description { - font-weight: bold; - line-height: 28rem; - } - - .red-text { - color: #de1a1a; - } -} diff --git a/picx/src/views/about/about.vue b/picx/src/views/about/about.vue deleted file mode 100644 index 6b26e69..0000000 --- a/picx/src/views/about/about.vue +++ /dev/null @@ -1,77 +0,0 @@ - - - - - diff --git a/picx/src/views/config/config.styl b/picx/src/views/config/config.styl deleted file mode 100644 index 095223b..0000000 --- a/picx/src/views/config/config.styl +++ /dev/null @@ -1,13 +0,0 @@ -.config-page-container { - .operation { - text-align right - - .el-button { - margin-left 20rem - - &:first-child { - margin-left 0 - } - } - } -} diff --git a/picx/src/views/config/config.vue b/picx/src/views/config/config.vue deleted file mode 100644 index 8e9b540..0000000 --- a/picx/src/views/config/config.vue +++ /dev/null @@ -1,498 +0,0 @@ - - - - - diff --git a/picx/src/views/management/management.styl b/picx/src/views/management/management.styl deleted file mode 100644 index 2d43c51..0000000 --- a/picx/src/views/management/management.styl +++ /dev/null @@ -1,70 +0,0 @@ -@import "../../style/base.styl" - -$infoBarHeight = 50rem - -.management-page-container { - padding-bottom 0 !important - - .content-container { - position relative - width 100% - height 100% - padding-top $infoBarHeight - box-sizing border-box - - .top { - position absolute - top 0 - left 0 - width 100% - height $infoBarHeight - box-sizing border-box - display flex - align-items center - justify-content space-between - font-size 14rem - padding-bottom 20rem - - .right { - - .btn-icon { - cursor pointer - font-size 22rem - margin-left 10rem - } - - } - } - - - .bottom { - position relative - width 100% - height 100% - box-sizing border-box - border 1rem solid var(--border-color) - - .image-list { - width 100% - //height 100% - //max-height calc(100% - 60rem) - margin 0 - padding 2rem - list-style none - overflow-y auto - box-sizing border-box - - li.image-item { - float left - box-sizing border-box - padding 10rem - - &:last-child { - margin-right 0 - } - } - } - - } - } -} diff --git a/picx/src/views/management/management.util.ts b/picx/src/views/management/management.util.ts deleted file mode 100644 index 4ba691a..0000000 --- a/picx/src/views/management/management.util.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Store } from 'vuex' -import { DirObject } from '@/store/modules/dir-image-list/types' - -function getContent(targetContent: any, dirList: string[], n: number): any { - if (targetContent) { - if (dirList.length === n) { - return targetContent - } - return getContent( - targetContent.childrenDirs?.find((v: any) => v.dir === dirList[n]), - dirList, - // eslint-disable-next-line no-param-reassign,no-plusplus - ++n - ) - } - return null -} - -/** - * 获取当前目录下所有内容(子目录和图片) - * @param dirPath - * @param dirObj - */ -export const getDirContent = (dirPath: string, dirObj: DirObject) => { - if (dirPath === '/') { - return dirObj - } - const dirList: string[] = dirPath.split('/') - return getContent(dirObj, dirList, 0) -} - -/** - * 过滤当前目录的内容(子目录或图片) - * @param dirPath - * @param content - * @param type - */ -export const filterDirContent = (dirPath: string, content: any, type: string): any => { - if (type === 'dir') { - return content.childrenDirs?.filter((x: any) => x.type === 'dir') - } - - if (type === 'image') { - return content.imageList.filter((x: any) => x.type === 'image') - } - - return [] -} - -export const dirModeHandle = (dir: string, store: Store) => { - if (dir === '/') { - store.dispatch('SET_USER_CONFIG_INFO', { - dirMode: 'rootDir', - needPersist: false - }) - } -} diff --git a/picx/src/views/management/management.vue b/picx/src/views/management/management.vue deleted file mode 100644 index 4edcdb5..0000000 --- a/picx/src/views/management/management.vue +++ /dev/null @@ -1,201 +0,0 @@ - - - - - diff --git a/picx/src/views/settings/settings.styl b/picx/src/views/settings/settings.styl deleted file mode 100644 index 43fe857..0000000 --- a/picx/src/views/settings/settings.styl +++ /dev/null @@ -1,44 +0,0 @@ -.setting-title { - font-size 16rem - font-weight bold - margin 40rem 0 20rem 0 - - &:first-child { - margin-top 0 - } -} - -.setting-list { - padding 0 - margin 0 - - .setting-item { - margin-bottom 10rem - - &.last-child { - margin-bottom 0 - } - - .prefix-input { - width calc(100% - 50rem) - margin-left 50rem - margin-top 15rem - } - - .img-encoder-title { - margin-bottom 12rem - } - - :deep() .el-radio-group { - - display inline-block - - .el-radio { - display block - } - - } - - } - -} diff --git a/picx/src/views/settings/settings.vue b/picx/src/views/settings/settings.vue deleted file mode 100644 index 69834c3..0000000 --- a/picx/src/views/settings/settings.vue +++ /dev/null @@ -1,149 +0,0 @@ - - - - - diff --git a/picx/src/views/tutorials/tutorials.styl b/picx/src/views/tutorials/tutorials.styl deleted file mode 100644 index 3ddce1a..0000000 --- a/picx/src/views/tutorials/tutorials.styl +++ /dev/null @@ -1,15 +0,0 @@ -.tutorials-page-container { - - .step-content { - padding-top 30rem - display flex - justify-content center - text-align center - } - - .btn-next-prev { - text-align center - padding-top 30rem - } - -} diff --git a/picx/src/views/tutorials/tutorials.vue b/picx/src/views/tutorials/tutorials.vue deleted file mode 100644 index 72ee2d3..0000000 --- a/picx/src/views/tutorials/tutorials.vue +++ /dev/null @@ -1,64 +0,0 @@ - - - - - diff --git a/picx/src/views/upload/upload.styl b/picx/src/views/upload/upload.styl deleted file mode 100644 index cbc313f..0000000 --- a/picx/src/views/upload/upload.styl +++ /dev/null @@ -1,135 +0,0 @@ -@import "../../style/base.styl" - -.upload-page-container { - width 100% - height 100% - display flex - justify-content space-between - - .upload-page-left { - height 100% - box-sizing border-box - margin-right $component-interval - flex-shrink 0 - - .uploaded-item { - margin-bottom 20rem - - &:last-child { - margin-bottom 0 - } - } - } - - - .upload-page-right { - width 100% - height 100% - box-sizing border-box - overflow-y auto - - .row-item { - width 100% - display flex - justify-content center - margin-bottom 16rem - box-sizing border-box - - &:last-child { - margin-bottom 0 - } - - .content-box { - width 100% - max-width $content-max-width - margin 0 auto - box-sizing border-box - } - - } - - - .upload-status { - position relative - width 100% - padding 10rem - background var(--second-background-color) - color #666 - font-size 12rem - box-sizing border-box - - .info-item { - margin-top 4rem - } - - .file-status { - display flex - justify-content space-between - align-items center - } - - .upload-tips { - - display flex - align-items center - - i { - margin-left 2rem - font-size 20rem - } - } - - .wait-upload { - color var(--await-upload-color) - } - - .uploading { - color var(--uploading-color) - } - - .uploaded { - color var(--uploaded-color) - } - - } - - - .external-link { - width 100% - - .external-link-input { - margin-bottom 10rem - - &:last-child { - margin-bottom 0 - } - - .el-input-group__append { - width 100rem - text-align-last justify - } - } - } - - - .upload-tools { - width 100% - - .repos-dir-info { - margin-bottom 20rem - font-size 12rem - - .repos-dir-info-item { - margin-right 10rem - - &:last-child { - margin-right 0 - } - } - - - } - } - } - -} diff --git a/picx/src/views/upload/upload.vue b/picx/src/views/upload/upload.vue deleted file mode 100644 index 5ce57f5..0000000 --- a/picx/src/views/upload/upload.vue +++ /dev/null @@ -1,151 +0,0 @@ - - - - - diff --git a/picx/tsconfig.json b/picx/tsconfig.json deleted file mode 100644 index b0d1f22..0000000 --- a/picx/tsconfig.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "compilerOptions": { - "target": "esnext", - "module": "esnext", - "moduleResolution": "node", - "strict": true, - "jsx": "preserve", - "sourceMap": true, - "resolveJsonModule": true, - "esModuleInterop": true, - "lib": ["esnext", "dom"], - "types": [ - "vite/client", - "vite-plugin-pwa/client" - ], - "typeRoots": [ - "./node_modules/@types/" - ], - "baseUrl": "src", - "paths": { - "@/*": ["./*"] - } - }, - "include": [ - "src/**/*.ts", - "src/**/*.d.ts", - "src/**/*.tsx", - "src/**/*.vue", - "auto-imports.d.ts" - ], - "exclude": [ - "node_modules", - "dist" - ] -} diff --git a/picx/vite.config.ts b/picx/vite.config.ts deleted file mode 100644 index 98426d5..0000000 --- a/picx/vite.config.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { loadEnv } from 'vite' -import { resolve } from 'path' -import type { UserConfig, ConfigEnv } from 'vite' -import createVitePlugins from './src/plugins' -import wrapperEnv from './src/utils/env' - -function pathResolve(dir: string) { - return resolve(__dirname, '.', dir) -} - -// https://vitejs.dev/config/ -export default ({ command, mode }: ConfigEnv): UserConfig => { - const root = process.cwd() - const env = loadEnv(mode, root) - const isBuild = command === 'build' - - // loadEnv 中返回的是 string 类型的(即使是 boolean),下面的方法可以返回正确的类型 - const viteEnv = wrapperEnv(env) - const { VITE_PORT, VITE_PUBLIC_PATH, VITE_OPEN_BROWSER, VITE_CORS } = viteEnv - - return { - plugins: createVitePlugins(viteEnv, isBuild), - resolve: { - alias: { - '@': pathResolve('src') // 设置 @ 指向 src - } - }, - base: VITE_PUBLIC_PATH, // 设置打包路径 - optimizeDeps: { - exclude: ['@yireen/squoosh-browser'] - }, - server: { - port: VITE_PORT, - open: VITE_OPEN_BROWSER, - cors: VITE_CORS - /** - * proxy 设置代理(解决前端跨域问题) - * /api -> https://xxx.xxx.com - * ^/API -> / - * /api/aa/bb -> https://xxx.xxx.com/aa/bb - * /api/API/aa/bb -> https://xxx.xxx.com/aa/bb - */ - // proxy: { - // '/api': { - // target: 'https://xxx.xxx.com', - // changeOrigin: true, - // secure: true, - // rewrite: (path) => path.replace('^/API', '/') - // } - // } - } - } -}