You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Comrad/comrad/app/screens/feed/feed.py

372 lines
13 KiB
Python

import os,sys; sys.path.append(os.path.abspath(os.path.join(os.path.abspath(os.path.join(os.path.dirname(__file__),'..')),'..')))
from comrad import *
from kivymd.uix.label import MDLabel
from kivy.uix.gridlayout import GridLayout
from kivy.uix.image import AsyncImage, Image
from kivymd.uix.boxlayout import MDBoxLayout
4 years ago
from kivymd.uix.card import MDCard, MDSeparator
from kivy.uix.scrollview import ScrollView
4 years ago
from screens.base import ProtectedScreen,BaseScreen
from kivy.properties import ListProperty
import os,time
from datetime import datetime
from kivy.app import App
from threading import Thread
import asyncio
from misc import *
from kivy.core.window import Window
import logging
logger=logging.getLogger(__name__)
### POST CODE
class PostTitle(MDLabel): pass
class PostGridLayout(GridLayout): pass
class PostImage(AsyncImage): pass
# class PostImage(CoreImage)
class PostImageBytes(Image): pass
class PostContent(MDLabel):
def __init__(self,**kwargs):
super().__init__(**kwargs)
self.bind(width=lambda s, w: s.setter('text_size')(s, (w, None)))
self.bind(texture_size=self.setter('size'))
self.font_name='assets/overpass-mono-regular.otf'
#pass
4 years ago
class PostAuthorLayout(MDBoxLayout):
pass
4 years ago
class PostImageLayout(MDBoxLayout): pass
class PostAuthorLabel(MDLabel):
def __init__(self,**kwargs):
super().__init__(**kwargs)
self.bind(width=lambda s, w: s.setter('text_size')(s, (w, None)))
self.bind(texture_size=self.setter('size'))
self.font_name='assets/overpass-mono-regular.otf'
#self.to_changeable=False
4 years ago
# def on_touch_down(self,*x,**y):
# print('weeeeeee')
# stop
#def on_touch_down(self, touch):
# '''Receive a touch down event.
# :Parameters:
# `touch`: :class:`~kivy.input.motionevent.MotionEvent` class
# Touch received. The touch is in parent coordinates. See
# :mod:`~kivy.uix.relativelayout` for a discussion on
# coordinate systems.
# :Returns: bool
# If True, the dispatching of the touch event will stop.
# If False, the event will continue to be dispatched to the rest
# of the widget tree.
# '''
def on_touch_down(self, touch):
4 years ago
if self.collide_point(*touch.pos):
4 years ago
# username=self.text.strip().split()[1][1:]
4 years ago
app=App.get_running_app()
4 years ago
app.view_profile(self.username)
return True
pass
class PostTimestampLabel(MDLabel):
def __init__(self,**kwargs):
super().__init__(**kwargs)
self.bind(width=lambda s, w: s.setter('text_size')(s, (w, None)))
self.bind(texture_size=self.setter('size'))
self.font_name='assets/overpass-mono-regular.otf'
4 years ago
class PostAuthorAvatar(AsyncImage):
def on_touch_down(self, touch):
if self.collide_point(*touch.pos):
4 years ago
app=App.get_running_app()
app.view_profile(self.username)
4 years ago
return True
# stop
pass
4 years ago
class PostLayout(MDBoxLayout): pass
class PostScrollView(ScrollView): pass
class PostCard(MDCard):
@property
def app(self): return App.get_running_app()
4 years ago
def log(self,*x,**y): self.app.log(*x)
def __init__(self, data):
super().__init__()
# self.log('PostCard() got data: '+str(data))
self.author = data.get('author','[Anonymous]')
self.recipient = data.get('to_name','')
4 years ago
self.post_data = data.get('post_data', {})
4 years ago
self.screen=data.get('screen')
self.post_id=data.get('post_id')
4 years ago
if not self.recipient:
self.recipient=self.app.channel
4 years ago
# self.img_id = data.get('file_id','')
# self.img_ext = data.get('file_ext','')
# self.img_src=self.img_id[:3]+'/'+self.img_id[3:]+'.'+self.img_ext if self.img_id else ''
# self.cache_img_src = os.path.join('cache',self.img_src) if self.img_src else ''
self.cache_img_src = self.img_src = data.get('img_src','')
4 years ago
if not self.cache_img_src:
if self.post_data.get('prompt_id')=='addcontact':
other_data=self.post_data.get('other_data',{})
if other_data:
img_avtr_b=other_data.get('img_avatar')
if img_avtr_b:
tmp_fnfn = os.path.join(PATH_COMRAD_TMP,get_random_id()+'.png')
with open(tmp_fnfn,'wb') as of:
of.write(img_avtr_b)
self.cache_img_src=self.img_src=tmp_fnfn
4 years ago
self.img_loaded = self.img_src and os.path.exists(self.img_src)
self.content = data.get('content','')
self.timestamp = data.get('timestamp',None)
4 years ago
# self.bind(minimum_height=self.setter('height'))
4 years ago
author_prefix=data.get('author_prefix','Comrad @')
author_label_font_size=data.get('author_label_font_size','24sp')
recip_label_font_size=data.get('author_label_font_size','14sp')
4 years ago
# minwidth = 400
# maxwidth = 800
# abouts = int(Window.size[0]/1.5)
# if abouts < minwidth: self.width=f'{minwidth}sp'
# if abouts > maxwidth: self.width=f'{maxwidth}sp'
# self.width=f'{abouts}sp'
# self.log('PostCard.img_id =',self.img_id)
# self.log('PostCard.img_ext =',self.img_ext)
# self.log('PostCard.img_src =',self.img_src)
# self.log('PostCard.cache_img_src =',self.cache_img_src)
# pieces
4 years ago
self.author_section_layout = author_section_layout = PostAuthorLayout()
self.author_label = author_label = PostAuthorLabel(text=author_prefix+self.author)
self.author_label.font_name='assets/overpass-mono-semibold.otf'
if self.recipient:
4 years ago
recip=self.recipient
4 years ago
recip='@'+recip if not recip.startswith('@') else recip #(recip if recip and recip[0].isalpha() else recip[1:])
# recip=author_prefix+recip #(recip if recip and recip[0].isalpha() else recip[1:])
self.author_label.text+=f'\n[size={recip_label_font_size}]to '+recip+'[/size]'
self.author_label.markup=True
self.author_label.font_size = author_label_font_size
4 years ago
self.author_label.username=self.author
4 years ago
avatar_img_src = os.path.join(PATH_AVATARS, f'{self.author}.png')
if not os.path.exists(avatar_img_src):
avatar_img_src = os.path.join(PATH_GUI_ASSETS, 'avatars', f'{self.author}.png')
4 years ago
if not os.path.exists(avatar_img_src):
avatar_img_src=PATH_DEFAULT_AVATAR
self.author_avatar = author_avatar = PostAuthorAvatar(source=avatar_img_src) #self.img_src)
4 years ago
self.author_avatar.username=self.author
4 years ago
self.author_section_layout.add_widget(author_avatar)
self.author_section_layout.add_widget(author_label)
# self.author_section_layout.add_widget(MDSeparator(height='1sp',size_hint=(None,None)))
# self.recipient_label = author_label = PostAuthorLabel(text='--> @'+self.recipient)
# self.recipient_label.font_size = '14sp'
# self.author_label.add_widget(self.recipient_label)
# timestamp
timestr=''
#log(self.timestamp)
if self.timestamp:
dt_object = datetime.fromtimestamp(self.timestamp)
timestr = dt_object.strftime("%-d %b %Y %H:%M")
#log('timestr: '+timestr)
self.timestamp_label=PostTimestampLabel(text=timestr)
self.timestamp_label.font_size='14sp'
author_section_layout.add_widget(self.timestamp_label)
# author_section_layout.add_widget(author_avatar)
4 years ago
# self.add_widget(author_section_layout)
if self.cache_img_src:
4 years ago
image_layout = PostImageLayout()
self.image = image = PostImage(source=self.cache_img_src)
4 years ago
image.height = '300sp'
4 years ago
image_layout.add_widget(image)
4 years ago
image_layout.height='300sp'
# self.log(image.image_ratio)
self.post_content = PostContent(text=self.content)
self.post_content.font_size = '24sp'
4 years ago
# post_layout = PostGridLayout()
#content = PostContent()
# add to screen
4 years ago
# self.add_widget(title)
# post_layout.add_widget(author_section_layout)
# post_layout.add_widget(image_layout)
# post_layout.add_widget(content)
self.scroller = scroller = PostScrollView()
4 years ago
self.add_widget(author_section_layout)
# self.add_widget(MDLabel(text='hello'))
#log('img_src ' + str(bool(self.img_src)))
4 years ago
if self.img_src: self.add_widget(image_layout)
4 years ago
def estimate_height(minlen=100,maxlen=600):
4 years ago
num_chars = len(self.content)
# num_lines = num_chars
height = num_chars*1.1
if height>maxlen: height=maxlen
if height<minlen: height=minlen
return height
4 years ago
scroller.size = ('300sp','%ssp' % estimate_height())
4 years ago
4 years ago
# scroller.bind(size=('300sp',scroller.setter('height'))
scroller.add_widget(self.post_content)
4 years ago
self.add_widget(scroller)
# self.add_widget(post_layout)
4 years ago
###
4 years ago
# Any prompts?
4 years ago
if self.post_data.get('type')=='prompt':
4 years ago
4 years ago
if self.post_data.get('prompt_id')=='addcontact':
def on_touch_down(touch):
if hasattr(self,'_touched') and self._touched: return
if self.collide_point(*touch.pos):
4 years ago
asyncio.create_task(
self.app.prompt_addcontact(
self.post_data,
screen=self.screen,
post_id=self.post_id,
post_card=self,
)
)
# self._touched=True
4 years ago
self.on_touch_down=on_touch_down
# self.log('?????',self.cache_img_src, os.path.exists(self.cache_img_src), os.stat(self.cache_img_src).st_size)
if self.cache_img_src and (not os.path.exists(self.cache_img_src) or not os.stat(self.cache_img_src).st_size):
4 years ago
async def do_download_later():
self.log('downloading...')
4 years ago
await self.app.download(self.img_id, self.cache_img_src)
self.image.reload()
4 years ago
return True
#self.open_dialog('posting')
#Thread(target=do_download).start()
4 years ago
asyncio.create_task(do_download_later())
@property
def app(self):
return App.get_running_app()
def load_image(self):
if not self.img_src: return
if self.img_loaded: return
# otherwise load image...
self.app.get_image(self.img_src)
self.log('done getting image!')
self.image.reload()
self.img_loaded=True
#####
class PostCardPopup(PostCard):
def __init__(self,*x,msg_dialog=None,**y):
super().__init__(*x,**y)
self.ok_to_continue=False
self.msg_dialog=msg_dialog
def on_touch_down(self,touch):
# if self.collide_point(*touch.pos):# and not self.ok_to_continue:
# logger.info('ouch!!!')
# The touch has occurred inside the widgets area. Do stuff!
self.ok_to_continue=True
if self.msg_dialog: self.msg_dialog.ok_to_continue=True
return True
4 years ago
class PostCardInputPopup(PostCardPopup):
def on_touch_down(self,touch):
pass
class FeedScreen(ProtectedScreen):
posts = ListProperty()
4 years ago
updated = None
def on_pre_enter(self):
if not super().on_pre_enter(): return
4 years ago
if self.updated:
4 years ago
if False: # @HACK!!!
# if not self.app.comrad.updated or self.updated>=self.app.comrad.updated:
4 years ago
self.log('NOT UPDATING!')
return
4 years ago
# self.root.clear_widgets()
4 years ago
self.log('UPDATING!')
4 years ago
if self.app.map:
self.app.map.dismiss()
self.root.remove_widget(self.app.map)
if not hasattr(self,'get_posts'): self.get_posts=self.app.comrad.posts
4 years ago
4 years ago
self.carousel = self.ids.post_carousel
for post in self.posts:
self.ids.post_carousel.remove_widget(post)
i=0
lim=25
async def go():
4 years ago
# do not get updates! leave that to refresh button!
# await self.app.get_updates()
posts=self.get_posts()
for i,post in enumerate(posts):
if i>lim: break
data = {
'author':post.from_name,
'to_name':post.to_name,
'content':post.msg.get('txt') if type(post.msg)==dict else str(post.msg),
4 years ago
'timestamp':post.timestamp,
'post_data':post.data,
4 years ago
'screen':self,
'post_id':post.post_id,
}
post_obj = PostCard(data)
self.posts.append(post_obj)
self.ids.post_carousel.add_widget(post_obj)
4 years ago
self.updated = time.time()
asyncio.create_task(go())
return True
# def on_pre_enter(self):
# self.clear_deck()
# # for i,x