aboutsummaryrefslogtreecommitdiff
path: root/javascript/progressbar.js
blob: d58737c4e4ac3bebd548e46cc95b19c4a7fa24aa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// code related to showing and updating progressbar shown as the image is being made
global_progressbars = {}
galleries = {}
galleryObservers = {}

// this tracks laumnches of window.setTimeout for progressbar to prevent starting a new timeout when the previous is still running
timeoutIds = {}

function check_progressbar(id_part, id_progressbar, id_progressbar_span, id_skip, id_interrupt, id_preview, id_gallery){
    // gradio 3.8's enlightened approach allows them to create two nested div elements inside each other with same id
    // every time you use gr.HTML(elem_id='xxx'), so we handle this here
    var progressbar = gradioApp().querySelector("#"+id_progressbar+" #"+id_progressbar)
    var progressbarParent
    if(progressbar){
        progressbarParent = gradioApp().querySelector("#"+id_progressbar)
    } else{
        progressbar = gradioApp().getElementById(id_progressbar)
        progressbarParent = null
    }

    var skip = id_skip ? gradioApp().getElementById(id_skip) : null
    var interrupt = gradioApp().getElementById(id_interrupt)
    
    if(opts.show_progress_in_title && progressbar && progressbar.offsetParent){
        if(progressbar.innerText){
            let newtitle = '[' + progressbar.innerText.trim() + '] Stable Diffusion';
            if(document.title != newtitle){
                document.title =  newtitle;          
            }
        }else{
            let newtitle = 'Stable Diffusion'
            if(document.title != newtitle){
                document.title =  newtitle;          
            }
        }
    }
    
	if(progressbar!= null && progressbar != global_progressbars[id_progressbar]){
	    global_progressbars[id_progressbar] = progressbar

        var mutationObserver = new MutationObserver(function(m){
            if(timeoutIds[id_part]) return;

            preview = gradioApp().getElementById(id_preview)
            gallery = gradioApp().getElementById(id_gallery)

            if(preview != null && gallery != null){
                preview.style.width = gallery.clientWidth + "px"
                preview.style.height = gallery.clientHeight + "px"
                if(progressbarParent) progressbar.style.width = progressbarParent.clientWidth + "px"

				//only watch gallery if there is a generation process going on
                check_gallery(id_gallery);

                var progressDiv = gradioApp().querySelectorAll('#' + id_progressbar_span).length > 0;
                if(progressDiv){
                    timeoutIds[id_part] = window.setTimeout(function() {
                        timeoutIds[id_part] = null
                        requestMoreProgress(id_part, id_progressbar_span, id_skip, id_interrupt)
                    }, 500)
                } else{
                    if (skip) {
                        skip.style.display = "none"
                    }
                    interrupt.style.display = "none"
			
                    //disconnect observer once generation finished, so user can close selected image if they want
                    if (galleryObservers[id_gallery]) {
                        galleryObservers[id_gallery].disconnect();
                        galleries[id_gallery] = null;
                    }
                }
            }

        });
        mutationObserver.observe( progressbar, { childList:true, subtree:true })
	}
}

function check_gallery(id_gallery){
    let gallery = gradioApp().getElementById(id_gallery)
    // if gallery has no change, no need to setting up observer again.
    if (gallery && galleries[id_gallery] !== gallery){
        galleries[id_gallery] = gallery;
        if(galleryObservers[id_gallery]){
            galleryObservers[id_gallery].disconnect();
        }
        let prevSelectedIndex = selected_gallery_index();
        galleryObservers[id_gallery] = new MutationObserver(function (){
            let galleryButtons = gradioApp().querySelectorAll('#'+id_gallery+' .gallery-item')
            let galleryBtnSelected = gradioApp().querySelector('#'+id_gallery+' .gallery-item.\\!ring-2')
            if (prevSelectedIndex !== -1 && galleryButtons.length>prevSelectedIndex && !galleryBtnSelected) {
                // automatically re-open previously selected index (if exists)
                activeElement = gradioApp().activeElement;
                let scrollX = window.scrollX;
                let scrollY = window.scrollY;

                galleryButtons[prevSelectedIndex].click();
                showGalleryImage();

                // When the gallery button is clicked, it gains focus and scrolls itself into view
                // We need to scroll back to the previous position
                setTimeout(function (){
                    window.scrollTo(scrollX, scrollY);
                }, 50);

                if(activeElement){
                    // i fought this for about an hour; i don't know why the focus is lost or why this helps recover it
                    // if someone has a better solution please by all means
                    setTimeout(function (){
                        activeElement.focus({
                            preventScroll: true // Refocus the element that was focused before the gallery was opened without scrolling to it
                        })
                    }, 1);
                }
            }
        })
        galleryObservers[id_gallery].observe( gallery, { childList:true, subtree:false })
    }
}

onUiUpdate(function(){
    check_progressbar('txt2img', 'txt2img_progressbar', 'txt2img_progress_span', 'txt2img_skip', 'txt2img_interrupt', 'txt2img_preview', 'txt2img_gallery')
    check_progressbar('img2img', 'img2img_progressbar', 'img2img_progress_span', 'img2img_skip', 'img2img_interrupt', 'img2img_preview', 'img2img_gallery')
    check_progressbar('ti', 'ti_progressbar', 'ti_progress_span', '', 'ti_interrupt', 'ti_preview', 'ti_gallery')
})

function requestMoreProgress(id_part, id_progressbar_span, id_skip, id_interrupt){
    btn = gradioApp().getElementById(id_part+"_check_progress");
    if(btn==null) return;

    btn.click();
    var progressDiv = gradioApp().querySelectorAll('#' + id_progressbar_span).length > 0;
    var skip = id_skip ? gradioApp().getElementById(id_skip) : null
    var interrupt = gradioApp().getElementById(id_interrupt)
    if(progressDiv && interrupt){
        if (skip) {
            skip.style.display = "block"
        }
        interrupt.style.display = "block"
    }
}

function requestProgress(id_part){
    btn = gradioApp().getElementById(id_part+"_check_progress_initial");
    if(btn==null) return;

    btn.click();
}