Suwayomi / Suwayomi-Server

A rewrite of Tachiyomi for the Desktop
Mozilla Public License 2.0
3.93k stars 201 forks source link

MD like Slate Theme (CSS) + [UserScripts] (Missing chapters alert, search sources) #682

Open Pikcee opened 12 months ago

Pikcee commented 12 months ago

Please note that I wrote those for personal use and there weren't intended for public release so please excuse the messy code If someone is interested in organizing this mess and publishing it for others please feel free to use it however you like

before-1 after-1

(I'm too lazy to take more sc sorry, also about the library and external links icons I had to replace them inside the files, the current icons doesn't look good at all imo (as well as the current theme is incomparable to this imo it's very clear) hopefully the would just change the icons here, the ones I'm using is much better, (from MD)

<svg class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-hjmalu" focusable="false" viewBox="0 0 24 24" aria-hidden="true" data-testid="PublicIcon"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6m4-3h6v6m-11 5L21 3" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"></path></svg> <svg class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-hjmalu" focusable="false" viewBox="0 0 24 24" aria-hidden="true" data-testid="1FavoriteIcon"><path d="M20 6 9 17l-5-5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="feather feather-check icon mr-4"></path></svg>

You need to get the font and put it in the media folder or change the url to an online source (just paste in StyleBot) MD-Slate-Theme.txt

Userscripts: Missing Chapters alert:

// ==UserScript==
// @name         Tachidesk - Missing Chapters alert!
// @namespace    http://tampermonkey.net/
// @version      0.6.4
// @description  Missing Chapters alert!
// @author       You
// @match        http://127.0.0.1/*
// @exclude      http://127.0.0.1:4567/api/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    if (!document.title.startsWith('Reader - Manga ')){
    var PreviousChapter = parseInt(document.title.replace(/.*?(Chapter |ch\.\s?|\s?Ch\s?|: | S\d |Ep\. )( ?- )?(\d+).*?$/gi,'$3'));
    console.log('PreviousChapter:'+PreviousChapter);
    }

    let OutOfReaderNavigation = false;
    if (!location.href.includes('/chapter/')) {
        OutOfReaderNavigation = true;
    }

    const observer = new MutationObserver(mutations => {
        if (location.href.indexOf('/chapter/') === -1) {
            OutOfReaderNavigation = true;
            try{document.querySelector('head style#Blur').remove()}catch{}
            return;
        }

        if (document.title.startsWith('Reader - Manga ')) return;
        console.log(document.title);

        let NewChapter = parseInt(document.title.replace(/.*?(Chapter |ch\.\s?|\s?Ch\s?|: | S\d |Ep\. )( ?- )?(\d+).*?$/gi,'$3'));
        console.log('NewChapter:'+NewChapter+'\nPreviousChapter:'+PreviousChapter);

        if (!isNaN(PreviousChapter) && (NewChapter - PreviousChapter <= 1 )) {
            console.log('No missing pages');
        }
        else if (isNaN(NewChapter)){
            alert("Couldn't extract the chapter number")
        }
        else if (isNaN(PreviousChapter)){
            console.log("PreviousChapter isn't a number");
        }
        else {
            if (OutOfReaderNavigation){
                OutOfReaderNavigation = false;
                PreviousChapter = NewChapter;
                return;
            }
            Blur();
            alert('Possible missing chapter');
        }

        PreviousChapter = NewChapter;

    });

    observer.observe(document.querySelector('title'), { childList: true });

    window.addEventListener('beforeunload', function() {
        observer.disconnect();
    });

    function Blur(){
        if (document.querySelector('#Blur')){return;}
        let styleSheet = document.createElement("style");
        styleSheet.innerText = '.css-1bw3vem {filter: blur(1.5rem);} .css-12vtvjb, .css-1phpt2k {z-index: 2;}';
        styleSheet.id = "Blur";
        document.head.appendChild(styleSheet);
        let ImgsContainer = document.querySelector('.css-1bw3vem');
        let SpoilerElm = '<h1 id="SpoilerElm" style="background-color: red;'+
                                                    'color: white;'+
                                                    'user-select: none;'+
                                                    'font-size: 1.5rem;'+
                                                    'line-height: 2rem;'+
                                                    'font-weight: 500;'+
                                                    'text-align: center;'+
                                                    'overflow-wrap: break-word;'+
                                                    'width: 100%;'+
                                                    'margin-top: .75rem;'+
                                                    'margin-bottom: .75rem;'+
                                                    'position: sticky;'+
                                                    'top: 0px;'+
                                                    'z-index: 1;">'+
            'Double click to show spoiler</h1>'
        ImgsContainer.insertAdjacentHTML('beforebegin', SpoilerElm);
        document.querySelector('.css-1jibhyk').setAttribute("ondblclick","document.querySelector('head style#Blur').remove();"+
                                                                        "document.querySelector('.css-1jibhyk').removeAttribute('ondblclick');"+
                                                                        "document.querySelector('#SpoilerElm').remove();"
                                                           );
        document.querySelector('#SpoilerElm').setAttribute("ondblclick","document.querySelector('head style#Blur').remove();"+
                                                                        "document.querySelector('.css-1jibhyk').removeAttribute('ondblclick');"+
                                                                        "document.querySelector('#SpoilerElm').remove();"
                                                           );
    }

})();
`

userscript:
Add Searchbox to sources

![Sources - Tachidesk](https://github.com/Suwayomi/Tachidesk-Server/assets/99613170/400be981-7efb-46ce-9f31-eef7aa5167ed)

`
// ==UserScript==
// @name         Tachidesk - Add Searchbox to sources.
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  popups must be allowed.
// @author       You
// @match        http://127.0.0.1/*
// @exclude      http://127.0.0.1:4567/api/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    requestIdleCallback(() => {
        if (location.href.match("/sources")){
            AttachSearchBoxies();
        }
        let previousUrl = location.href;
        const observer = new MutationObserver(mutations => {
            if (location.href === previousUrl) return;

            previousUrl = location.href;
            if (location.href.match("/sources")){
                console.log('Navigation detected, url match:'+location.href);
                setTimeout(function(){AttachSearchBoxies();},250);
            }
        });
        observer.observe(document.body, { subtree: true, childList: true });

    });
    function AttachSearchBoxies(){
        let SourceRows = document.querySelectorAll('a.MuiButtonBase-root.MuiCardActionArea-root.css-147p5fy');
        SourceRows.forEach (SourceRow => {
            let SourceName= SourceRow.querySelector('.css-zq6grw').innerText;
            let inputElm = '<div class="inputContainer" style="position: relative;top: -72px;"><input type="text" class="qInput css-9h0458" style="position: absolute; top: 8px; right: 240px;text-transform: none;" placeholder="Search ' + SourceName + '"></div>';
            SourceRow.parentElement.insertAdjacentHTML('afterend',inputElm);
            let qInput = SourceRow.parentElement.nextElementSibling.querySelector('input.qInput');
            qInput.addEventListener("keyup", function(event) {
                if(event.key === "Enter"){
                    let url= SourceRow.href + "?R&query=" + qInput.value;
                    //window.open(url,'_blank');
                    location = url;
                }
            });
        });
    }
})();

There are some more scripts (like pulling and appending comments to chapters, linkfiying author/artist) but they are extension (site) specific, I'm not sure if releasing those could pressure those sites so I'll refrain for now, and some other scripts that I'm not sure if others would be interested in, (ex: correcting the page repositioning, pages count in the chapters rows, simple bookmakring for the current possition in the chapter, if you are interested let me know)

ghost commented 12 months ago

@Pikcee Can you explain in depth what these userscripts do and should I use them seperately or is it ok to use in 1 file as you posted, also i did not understand how can we use the ui?

Kickunio commented 11 months ago

The style is perfect, modified the fonts to use online ones. But I don't know what to do exactly to change the 2 buttons (library and open site)

Pikcee commented 11 months ago

@Pikcee Can you explain in depth what these userscripts do and should I use them seperately or is it ok to use in 1 file as you posted, also i did not understand how can we use the ui?

you need to install StyleBot or Stylus extensions and paste the contents of the txt file there.

as for the Userscripts they are unrelated to the UI, you'll need a script manager extension to use them (ex: ViolentMonkey or TamperMonkey), I'm sorry for not explaining in more detail I hope someone else would be able to help.

The style is perfect, modified the fonts to use online ones. But I don't know what to do exactly to change the 2 buttons (library and open site)

@Kickunio replace the files in "\webUI\static\js" with this js.zip and you are done.

or if you want to do it yourself:

in the file "\webUI\static\js\2.8953c29e.chunk.js" [918kb] after reformat (to reformat using the source map open the chunk.js file in vscodium, right click "Format Document")

Open site icon:

replace this: function(e,t,n){"use strict";var r=n(18);Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var o=r(n(19)),a=n(0),i=(0,o.default)((0,a.jsx)("path",{d:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"}),"Public");t.default=i}

with this: function(e,t,n){"use strict";var r=n(18);Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var o=r(n(19)),a=n(0),i=(0,o.default)((0,a.jsx)("path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6m4-3h6v6m-11 5L21 3",stroke:"currentColor",fill:"none","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"}),"Public");t.default=i}

Favorite icon:

replace this: function(e,t,n){"use strict";var r=n(18);Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var o=r(n(19)),a=n(0),i=(0,o.default)((0,a.jsx)("path",{d:"m12 21.35-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"}),"Favorite");t.default=i}

with this: function(e,t,n){"use strict";var r=n(18);Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var o=r(n(19)),a=n(0),i=(0,o.default)((0,a.jsx)("path",{d:"M20 6 9 17l-5-5",stroke:"currentColor",fill:"none","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",class:"feather feather-check icon mr-4"}),"Favorite");t.default=i}

remove the "Open Site" caption in the the other 130kb (main.9b92ea11) file.