# HG changeset patch # User Goffi # Date 1594883330 -7200 # Node ID 0a6698714557240e7346876c51165dcb1e741073 # Parent c07112ef01cd27bc21e3308e9ebf815862e09d41 browser: `slideshow` module implementation: this module show a gallery of slides (usually images/videos) with mobile friendly swipe capabilities. Comments are handled using a side panel. diff -r c07112ef01cd -r 0a6698714557 libervia/pages/_browser/slideshow.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libervia/pages/_browser/slideshow.py Thu Jul 16 09:08:50 2020 +0200 @@ -0,0 +1,135 @@ +from browser import document, window, DOMNode +from js_modules.swiper import Swiper +from template import Template + + +class SlideShow: + + def __init__(self): + self.swiper = None + slideshow_tpl = Template('photo/slideshow.html') + self.slideshow_elt = slideshow_tpl.get_elt() + self.comments_count_elt = self.slideshow_elt.select_one('.comments__count') + self.wrapper = self.slideshow_elt.select_one(".swiper-wrapper") + + @property + def current_slide(self): + if self.swiper is None: + return None + try: + return DOMNode(self.swiper.slides[self.swiper.realIndex]) + # getting missing item in JS arrays returns KeyError + except KeyError: + return None + + @property + def current_item(self): + """item attached to the current slide, if any""" + current = self.current_slide + if current is None: + return + try: + return current.js._item + except AttributeError: + return None + + @property + def index(self): + if self.swiper is None: + return None + return self.swiper.realIndex + + @index.setter + def index(self, idx): + if self.swiper is not None: + self.swiper.slideTo(idx, 0) + + def attach(self): + document.body <= self.slideshow_elt + self.swiper = Swiper.new( + ".swiper-container", + { + "pagination": { + "el": ".swiper-pagination", + }, + "navigation": { + "nextEl": ".swiper-button-next", + "prevEl": ".swiper-button-prev", + "hideOnClick": True, + }, + "scrollbar": { + "el": ".swiper-scrollbar", + }, + "grabCursor": True, + "keyboard": { + "enabled": True, + "onlyInViewport": False, + }, + "mousewheel": True, + } + ) + window.addEventListener("keydown", self.on_key_down, True) + self.slideshow_elt.select_one(".click_to_close").bind("click", self.on_close) + self.slideshow_elt.select_one(".click_to_comment").bind("click", self.on_comment) + self.swiper.on("slideChange", self.on_slide_change) + self.on_slide_change() + + def add_slide(self, slide_elt): + self.swiper.appendSlide([slide_elt]) + self.swiper.update() + + def quit(self): + self.slideshow_elt.remove() + self.slideshow_elt = None + self.swiper.destroy(True, True) + self.swiper = None + + def on_key_down(self, evt): + if evt.key == 'Escape': + self.quit() + else: + return + evt.preventDefault() + + def on_slide_change(self): + item = self.current_item + if item is None: + return + comments_count = item.get('comments_count') + self.comments_count_elt.text = comments_count or '' + + def on_close(self, evt): + evt.stopPropagation() + evt.preventDefault() + self.quit() + + def on_comment_close(self, evt): + side_panel = self.comments_panel_elt.select_one('.comments_side_panel') + side_panel.classList.remove('open') + side_panel.bind("transitionend", lambda evt: self.comments_panel_elt.remove()) + + def on_comments_panel_click(self, evt): + # we stop stop propagation to avoid the closing of the panel + evt.stopPropagation() + + def on_comment(self, evt): + item = self.current_item + if item is None: + return + comments_panel_tpl = Template('blog/comments_panel.html') + try: + comments = item['comments']['items'] + except KeyError: + comments = [] + self.comments_panel_elt = comments_panel_tpl.get_elt({ + "comments": comments, + "comments_service": item['comments_service'], + "comments_node": item['comments_node'], + + }) + document.body <= self.comments_panel_elt + side_panel = self.comments_panel_elt.select_one('.comments_side_panel') + window.setTimeout(lambda: side_panel.classList.add("open")) + for close_elt in self.comments_panel_elt.select('.click_to_close'): + close_elt.bind("click", self.on_comment_close) + side_panel.bind("click", self.on_comments_panel_click)