Имитация стены Вконтакте VK

Имитация упрощённой ленты vk, можно ставить лайки и комментировать посты, не отрываясь от чтения новеллы. Лицензия: creative commons с указанием авторства.



# модуль vk.rpy имитирует упрощённую копию соцсети vk_
# цвета и картинки настраиваются, можно имитировать другую похожую соцсеть
# автор: 7DOTS лицензия: creative commons с указанием авторства

init python:
    # автоматическое объявление изображений
    config.automatic_images_minimum_components = 1
    config.automatic_images = [' ', '_', '/']
    config.automatic_images_strip = ["images"]

init -999 python:
    # цвета фонов можно заменять на конструкции типа Frame("imagename", 0, 0)

    # возможность комментирования по умолчанию включена
    vk_can_comment = True

    # шрифт поста и комментариев
    vk_font = "fonts/Tahoma.ttf"

    # полоса, имитирующая шапку соцсети
    vk_header = "vk header"

    # высота шапки
    vk_headerheight = 60

    # картинка для авы по умолчанию
    vk_avadefault = "vk avadefault"

    # маска для обрезания аватарок
    vk_ava_mask = "vk avamask"

    # размер стороны авы
    vk_avasize = 72

    # картинка для нажатого лайка
    vk_likeon = "vk likeon"

    # картинка для ненажатого лайка
    vk_likeoff = "vk likeoff"

    # суффикс для уменьшенных лайков
    vk_zoom = "2"

    # картинка для комментария
    vk_comment = "vk comment"

    # цвет имени пользователя в шапке
    vk_usercolor = "#fff"

    # цвет для текста заголовка
    vk_nickcolor = "#175490"

    # цвет для счетчика лайков и комментариев
    vk_countcolor = "#96A0B4"

    # цвет для счетчика лайков при нажатом лайке
    vk_likecolor = "#CB272F"

    # цвет текста
    vk_textcolor = "#000"

    # цвет экрана вне поста
    vk_screencolor = "#EDEEF0"

    # цвет экрана внутри поста
    vk_postcolor = "#fff"

    # ширина поста
    vk_postwidth = 1080

    # высота экрана
    vk_screenheight = 840

    # отступ от края поста до содержимого
    # (1080 - 28 - 28 = 1024 - оптимальная ширина для картинки в посте)
    vk_postpadding = 28

    # отступ от аватарки до содержимого комментария
    vk_commpadding = 14

    # ава пользователя
    vk_ava = vk_avadefault

    # имя пользователя
    vk_nickname = _("Анон Аноныч")

    # кегль текста лайков
    vk_likesize = 24

    # кегль текста заголовков
    vk_nicksize = 22

    # кегль прочего текста
    vk_textsize = 20

    # список автозамены текста смайлов на их изображения
    vk_smiles = {":)": "vk smile smile", ":(": "vk smile sad", "xD": "vk smile rofl", ":D": "vk smile rofl", "*up*": "vk smile up", "↑": "vk smile up"}

    # класс для поста
    class VKpost:
        def __init__(self, nick=_("Анон Аноныч"), text="", ava=vk_avadefault, likes=0, user=False, comments=[]):
            # аватарка, обрезанная по маске (по кругу)
            self.ava = AlphaMask(ava, renpy.easy.displayable(vk_ava_mask))
            self.nick = nick # имя автора
            self.text = text # текст поста
            self.likes = likes # лайки поста
            self.comments = comments # комментарии (список экземпляров VKpost)
            self.count = len(comments) # количество комментариев к этому посту
            self.user = user # поставил ли пользователь лайк

        # получить количество комментариев к этому посту
        def get_com_count(self):
            return len(self.comments)

        # ставим/убираем лайк пользователя, если user == True
        # или просто добавляем кучу левых лайков
        def add_likes(self, count=1, user=True):
            if user:
                if self.user:
                    self.likes -= 1
                else:
                    self.likes += 1
                self.user = not self.user
            else:
                self.likes += count

    # список постов в ленте
    vk_posts = []

    # установить аватарку пользователя
    def vk_set_ava(ava):
        global vk_ava
        vk_ava = AlphaMask(ava, renpy.easy.displayable(vk_ava_mask))

    # лайки к посту
    def vk_post_add_like(i, count=1, user=True):
        global vk_posts
        if i >= 0 and i < len(vk_posts):
            vk_posts[i].add_likes(count, user)
    VKPostAddLike = renpy.curry(vk_post_add_like)

    # лайки к комментарию
    def vk_comm_add_like(i, ii, count=1, user=True):
        global vk_posts
        if i >= 0 and i < len(vk_posts):
            if ii >= 0 and ii < len(vk_posts[i].comments):
                vk_posts[i].comments[ii].add_likes(count, user)
    VKCommAddLike = renpy.curry(vk_comm_add_like)

    # обновить экраны
    def repaint():
        renpy.restart_interaction()
    Repaint = renpy.curry(repaint)

    # добавляем один пост (но можно и сразу список)
    def vk_add_post(post=[]):
        global vk_posts
        if not isinstance(post, (list, tuple)):
            post = [post]
        for i in post:
            vk_posts.append(i)
        # для пролистывания
        yadj.value = yadjValue
        renpy.restart_interaction()
    VKAddPost = renpy.curry(vk_add_post)

    # добавить комментарий (или несколько в [списке])
    def vk_add_comm(comm, index=0):
        global vk_posts
        if not isinstance(comm, list):
            comm = [comm]
        for i in comm:
            # убираем пробелы вокруг текста
            i.text = i.text.strip()
            # убираем двойные пробелы
            while i.text.find("  ") >= 0:
                i.text = i.text.replace("  ", " ")
            # заменяем смайлы на картинки смайлов
            keys = vk_smiles.keys()
            for k in keys:
                i.text = i.text.replace(k, "{image=" + vk_smiles[k] + "}")
        # добавляем комментарии
        vk_posts[index].comments = vk_posts[index].comments + comm

    # определить стиль (цвет) лайка
    def vk_like_style(user):
        if user:
            return "vk_like_on"
        return "vk_like_off"

    # определить рисунок комментария
    def vk_comm_text(comments):
        count = len(comments)
        text = "{image=" + vk_comment + "}"
        if count > 0:
            text = text + " " + str(count)
        else:
            text = text + "   "
        return text

    # определить рисунок лайка
    def vk_like_text(user, count=0, zoom=""):
        text = "{image=" + vk_likeoff + zoom + "}"
        if user:
            text = "{image=" + vk_likeon + zoom + "}"
        if count > 0:
            text = text + " " + str(count)
        else:
            text = text + "   "
        return text

    # пролистать в самый верх
    def vk_scroll0():
        yadj.value = 0
        renpy.restart_interaction()

    # чтобы листать вниз при добавлении постов
    yadjValue = float("inf")
    yadj = ui.adjustment()

    # вызвать подпрограмму ввода комментария
    def vk_input(i):
        renpy.call_in_new_context("vkinput", i)
    VKinput = renpy.curry(vk_input)

init 999:
    # стиль для фрейма без отступов
    style vk_empty is frame:
        # без отступов
        xpadding 0 ypadding 0
        xmargin 0 ymargin 0
        # по центру сверху
        align (.5, .0)
        # фон
        background vk_screencolor

    # стиль для экрана
    style vk_screen is vk_empty:
        # на весь экран
        xminimum config.screen_width
        xmaximum config.screen_width
        # высота жестко задана
        yminimum vk_screenheight ymaximum vk_screenheight
        # по центру
        align(.5, .0)
        # фон
        background vk_screencolor

    # стиль для поста
    style vk_post is vk_empty:
        # ширина жестко задана
        xminimum vk_postwidth
        xmaximum vk_postwidth
        # отступы от границы поста до содержимого
        xpadding vk_postpadding
        ypadding vk_postpadding
        # оступы между постами (и комментариями)
        ymargin vk_commpadding
        # по центру
        align(.5, .0)
        # фон
        background vk_postcolor

    # стиль для полосы с лайками
    style vk_likes is vk_empty:
        # ширина жестко задана
        xminimum vk_postwidth
        xmaximum vk_postwidth
        # отступы от границы поста до содержимого
        xpadding 0 ypadding 0
        # оступы по вертикали
        ymargin vk_commpadding
        # по центру
        align(.5, .0)
        # фон
        background vk_postcolor

    # стиль для комментария
    style vk_comm is vk_empty:
        # слева
        xalign .0
        # меньше отступов
        ymargin 0
        # фон
        background None

    # стиль для авытарок
    style vk_avatar is vk_empty:
        # слева по центру
        align(.0, .0)
        # размеры
        xminimum vk_avasize xmaximum vk_avasize 
        yminimum vk_avasize ymaximum vk_avasize 
        # фон
        background None

    # стиль текста
    style vk_text is text:
        size vk_textsize
        color vk_textcolor
        font vk_font

    # стиль текста заголовка/имени
    style vk_nick is text:
        size vk_nicksize
        color vk_nickcolor
        bold True
        font vk_font

    # экран соцсети
    screen vk:
        # экран
        frame:
            style "vk_screen"
            vbox:
                frame:
                    style "vk_empty"
                    yminimum vk_headerheight
                    ymaximum vk_headerheight
                    xfill True
                    # шапка
                    add vk_header align (.5, .0)
                    hbox:
                        xalign .8
                        spacing vk_commpadding
                        text vk_nickname style "vk_nick" color vk_usercolor yalign .5
                        add vk_ava:
                            zoom .75
                            yalign .5
                # вьюпорт для пролистывания постов
                viewport:
                    id "id vk"
                    xinitial 1.0
                    yfill False
                    xfill False
                    mousewheel True
                    draggable True
                    side_xfill False
                    transclude
                    yadjustment yadj
                    xalign .5
                    # все посты
                    vbox:
                        for i in range(len(vk_posts)):
                            # фон поста
                            frame:
                                style "vk_post"
                                vbox:
                                    spacing vk_commpadding # отступ текста от авы
                                    # заголовок поста
                                    hbox:
                                        spacing vk_postpadding # расстояние между авой и заголовком
                                        # аватар автора
                                        frame:
                                            style "vk_avatar"
                                            add vk_posts[i].ava
                                        # имя автора
                                        text vk_posts[i].nick style "vk_nick"
                                    # текст поста
                                    text vk_posts[i].text style "vk_text"
                                    # лайки
                                    frame:
                                        style "vk_likes"
                                        xpadding 0
                                        hbox:
                                            xalign .0
                                            # лайки и количество
                                            textbutton vk_like_text(vk_posts[i].user, vk_posts[i].likes):
                                                action [VKPostAddLike(i), Repaint()]
                                                style "vk_text"
                                                if vk_posts[i].user:
                                                    text_color vk_likecolor
                                                else:
                                                    text_color vk_countcolor
                                                text_size vk_likesize
                                                text_bold True
                                                xminimum 96
                                                yoffset 10
                                            # количество комментариев
                                            textbutton vk_comm_text(vk_posts[i].comments):
                                                if vk_can_comment:
                                                    action VKinput(i)
                                                else:
                                                    action []
                                                style "vk_text"
                                                text_color vk_countcolor
                                                text_size vk_likesize
                                                text_bold True
                                                yoffset 10
                                                xminimum 96
                                    # комментарии
                                    if len(vk_posts[i].comments) > 0:
                                        # окно всех комментариев
                                        frame:
                                            style "vk_comm"
                                            xpadding 0
                                            vbox:
                                                # перебираем комментарии
                                                for ii in range(len(vk_posts[i].comments)):
                                                    # окно очередного комментария
                                                    frame:
                                                        style "vk_comm"
                                                        hbox:
                                                            spacing vk_commpadding
                                                            # аватар комментатора
                                                            frame:
                                                                style "vk_avatar"
                                                                add vk_posts[i].comments[ii].ava
                                                            vbox:
                                                                # имя комментатора
                                                                text vk_posts[i].comments[ii].nick style "vk_nick"
                                                                # текст комментария
                                                                text vk_posts[i].comments[ii].text style "vk_text"
                                                                # лайки комментария
                                                                frame:
                                                                    style "vk_likes"
                                                                    xpadding 0
                                                                    hbox:
                                                                        spacing vk_commpadding
                                                                        xalign .8
                                                                        # лайки и количество
                                                                        textbutton vk_like_text(vk_posts[i].comments[ii].user, vk_posts[i].comments[ii].likes, vk_zoom):
                                                                            action [VKCommAddLike(i, ii), Repaint()]
                                                                            style "vk_text"
                                                                            if vk_posts[i].comments[ii].user:
                                                                                text_color vk_likecolor
                                                                            else:
                                                                                text_color vk_countcolor
                                                                            text_size vk_likesize * 3 / 4
                                                                            text_bold True
                                                                            yoffset 10

# подпрограмма ввода комментария пользователем
label vkinput(post_index):
    scene black
    $ text = renpy.input(_("Введите текст комментария:"))
    if text.strip():
        $ vk_add_comm(VKpost(vk_nickname, text, vk_ava), post_index)
    return

# ПРИМЕР ИСПОЛЬЗОВАНИЯ:
# на экране ленты кроме лайков работает и кнопка комментария рядом
label vk_test:

    scene bg win

    # добавить пост(ы)
    python:
        # аватарка пользователя
        vk_set_ava("7dots")

        # ник пользователя
        vk_nickname = _("«7DOTS» визуальные новеллы")

        # обнуляем все посты
        vk_posts = []

        # добавляем посты
        vk_add_post(VKpost(vk_nickname, "Такая вот сентенция родилась при обсуждении кислотности рувн))\n\n{image=post}", vk_ava, 8))

        # добавление комментария к посту номер 0
        vk_add_comm(VKpost(_("Аноним Анонистыч"), "Твои игры - гавно!", vk_avadefault, 1), 0)

        # добавление комментария к посту номер 0
        vk_add_comm(VKpost("Вован Петров", "Ахахах xD", "ava vovan", 1, True), 0)

        # добавление комментария к посту номер 0
        vk_add_comm(VKpost(vk_nickname, "*up* И эти каменты подтверждают мои слова :)", vk_ava, 3), 0)

    # перемотка в самый верх ленты
    $ vk_scroll0()

    # показать экран vk
    show screen vk
    with dissolve

    # ждём клика мимо ленты
    "Пример работы имитации упрощённой ленты «Вконтакте». Можно ставить лайки постам и комментариям. Так же имеется возможность оставлять комментарии, вводя их с клавиатуры."
    return

Комментарии