resolved merge conflict

This commit is contained in:
Jeena Paradies 2013-03-27 10:36:41 +01:00
commit 030fa044e9
45 changed files with 12402 additions and 314 deletions

View file

@ -49,23 +49,42 @@ class Bungloo:
self.init_web_views() self.init_web_views()
def init_web_views(self): def init_web_views(self):
self.timeline = Windows.Timeline(self) if not hasattr(self, "timeline"):
self.mentions = Windows.Timeline(self, "mentions", "Mentions") self.timeline = Windows.Timeline(self)
else:
self.timeline.evaluateJavaScript("start('timeline')")
self.timeline.show() self.timeline.show()
self.conversation = Windows.Timeline(self, "conversation", "Conversation")
self.profile = Windows.Timeline(self, "profile", "Profile")
self.find_entity = Windows.FindEntity(self) self.find_entity = Windows.FindEntity(self)
def timeline_show(self):
self.timeline.show()
def mentions_show(self):
self.controller.unreadMentions(0)
self.mentions.show()
def find_entity_show(self): def find_entity_show(self):
self.find_entity.show() self.find_entity.show()
def timeline_show(self):
self.timeline.show()
self.timeline.evaluateJavaScript("bungloo.sidebar.onTimeline();")
def mentions_show(self):
self.controller.unreadMentions(0)
self.timeline.evaluateJavaScript("bungloo.sidebar.onMentions();")
def conversation_show(self):
self.timeline.evaluateJavaScript("bungloo.sidebar.onConversation();")
def profile_show(self):
self.timeline.evaluateJavaScript("bungloo.sidebar.onEntityProfile();")
def search_show(self):
self.timeline.evaluateJavaScript("bungloo.sidebar.onSearch();")
def open_about(self):
self.controller.openURL("http://jabs.nu/bungloo")
def log_out(self):
self.oauth_implementation.log_out()
self.timeline.hide()
self.preferences.show()
self.timeline.evaluateJavaScript("bungloo.sidebar.logout()")
class Controller(QtCore.QObject): class Controller(QtCore.QObject):
@ -126,12 +145,8 @@ class Controller(QtCore.QObject):
@QtCore.pyqtSlot(int) @QtCore.pyqtSlot(int)
def unreadMentions(self, count): def unreadMentions(self, count):
i = int(count) script = "bungloo.sidebar.setUnreadMentions({});".format(int(count))
if i > 0: self.app.timeline.evaluateJavaScript(script)
self.app.timeline.set_window_title("Bungloo (^" + str(i) + ")")
else:
self.app.timeline.set_window_title("Bungloo")
self.app.mentions.evaluateJavaScript("bungloo_instance.unread_mentions = 0;")
@QtCore.pyqtSlot(str, str, str, str) @QtCore.pyqtSlot(str, str, str, str)
def notificateUserAboutMentionFromNameWithPostIdAndEntity(self, text, name, post_id, entity): def notificateUserAboutMentionFromNameWithPostIdAndEntity(self, text, name, post_id, entity):
@ -188,28 +203,29 @@ class Controller(QtCore.QObject):
if message.isPrivate: if message.isPrivate:
isPrivate = "true" isPrivate = "true"
func = u"bungloo_instance.sendNewMessage(\"{}\", \"{}\", \"{}\", {}, {}, {});".format(text, in_reply_to_status_id, in_reply_to_entity, locationObject, imageFilePath, isPrivate) func = u"bungloo.timeline.sendNewMessage(\"{}\", \"{}\", \"{}\", {}, {}, {});".format(text, in_reply_to_status_id, in_reply_to_entity, locationObject, imageFilePath, isPrivate)
self.app.timeline.evaluateJavaScript(func) self.app.timeline.evaluateJavaScript(func)
@QtCore.pyqtSlot(str, str) @QtCore.pyqtSlot(str, str)
def showConversationForPostIdandEntity(self, postId, entity): def showConversationForPostIdandEntity(self, postId, entity):
func = "bungloo_instance.showStatus('{}', '{}');".format(postId, entity) func = "bungloo.sidebar.onConversation(); bungloo.conversation.showStatus('{}', '{}');".format(postId, entity)
self.app.conversation.evaluateJavaScript(func) self.app.timeline.evaluateJavaScript(func)
self.app.conversation.show() self.app.timeline.show()
@QtCore.pyqtSlot(str) @QtCore.pyqtSlot(str)
def showProfileForEntity(self, entity): def showProfileForEntity(self, entity):
func = "bungloo_instance.showProfileForEntity('{}');".format(entity) func = "bungloo.sidebar.onEntityProfile(); bungloo.entityProfile.showProfileForEntity('{}');".format(entity)
self.app.profile.evaluateJavaScript(func) self.app.timeline.evaluateJavaScript(func)
self.app.profile.show()
@QtCore.pyqtSlot(str, str) @QtCore.pyqtSlot(str, str)
def notificateViewsAboutDeletedPostWithIdbyEntity(self, post_id, entity): def notificateViewsAboutDeletedPostWithIdbyEntity(self, post_id, entity):
func = "bungloo_instance.postDeleted('{}', '{}')".format(post_id, entity); f = ".postDeleted('{}', '{}')".format(post_id, entity);
func = "bungloo.timeline" + f + ";"
func += "bungloo.mentions" + f + ";"
func += "bungloo.conversation" + f + ";"
func += "bungloo.entityProfile" + f + ";"
self.app.timeline.evaluateJavaScript(func) self.app.timeline.evaluateJavaScript(func)
self.app.mentions.evaluateJavaScript(func)
self.app.conversation.evaluateJavaScript(func)
self.app.profile.evaluateJavaScript(func)
@QtCore.pyqtSlot(str) @QtCore.pyqtSlot(str)
def authentificationDidNotSucceed(self, errorMessage): def authentificationDidNotSucceed(self, errorMessage):
@ -232,23 +248,23 @@ class Console(QtCore.QObject):
@QtCore.pyqtSlot(str) @QtCore.pyqtSlot(str)
def log(self, string): def log(self, string):
print "<js>: " + string print "<js>: " + unicode(string)
@QtCore.pyqtSlot(str) @QtCore.pyqtSlot(str)
def error(self, string): def error(self, string):
print "<js ERROR>: " + string print "<js ERROR>: " + unicode(string)
@QtCore.pyqtSlot(str) @QtCore.pyqtSlot(str)
def warn(self, string): def warn(self, string):
print "<js WARN>: " + string print "<js WARN>: " + unicode(string)
@QtCore.pyqtSlot(str) @QtCore.pyqtSlot(str)
def notice(self, string): def notice(self, string):
print "<js NOTICE>: " + string print "<js NOTICE>: " + unicode(string)
@QtCore.pyqtSlot(str) @QtCore.pyqtSlot(str)
def debug(self, string): def debug(self, string):
print "<js DEBUG>: " + string print "<js DEBUG>: " + unicode(string)
if __name__ == "__main__": if __name__ == "__main__":

View file

@ -39,6 +39,33 @@ class WebViewCreator(QtWebKit.QWebView):
self.connect(self, SIGNAL("linkClicked (const QUrl&)"), self.app.controller.openQURL) self.connect(self, SIGNAL("linkClicked (const QUrl&)"), self.app.controller.openQURL)
self.setPage(WebPage(self, self.app)) self.setPage(WebPage(self, self.app))
self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self.context_menu_requested)
self.actions = []
def copy_link():
self.page().triggerAction(QtWebKit.QWebPage.CopyLinkToClipboard)
self.action_copy_link = QtGui.QAction('Copy Lin&k', self, triggered=copy_link)
def context_menu_requested(self, point):
context_menu = QtGui.QMenu()
for action in self.actions:
if action.isEnabled():
context_menu.addAction(action)
frame = self.page().currentFrame()
hit_test = frame.hitTestContent(point)
if unicode(hit_test.linkUrl().toString()):
context_menu.addAction(self.action_copy_link)
if self.settings().testAttribute(QtWebKit.QWebSettings.DeveloperExtrasEnabled):
context_menu.addSeparator()
context_menu.addAction(self.pageAction(QtWebKit.QWebPage.InspectElement))
context_menu.exec_(self.mapToGlobal(point))
def load_local(self, callback=None): def load_local(self, callback=None):
self.page().settings().setAttribute(QtWebKit.QWebSettings.LocalContentCanAccessRemoteUrls, True) self.page().settings().setAttribute(QtWebKit.QWebSettings.LocalContentCanAccessRemoteUrls, True)
self.page().settings().setAttribute(QtWebKit.QWebSettings.LocalStorageEnabled, True) self.page().settings().setAttribute(QtWebKit.QWebSettings.LocalStorageEnabled, True)

View file

@ -91,6 +91,8 @@ class Timeline:
self.initUI() self.initUI()
self.webView.triggerPageAction(QtWebKit.QWebPage.InspectElement)
def moveWindow(self, x=0, y=0): def moveWindow(self, x=0, y=0):
self.show() self.show()
geo = self.window.geometry() geo = self.window.geometry()
@ -99,19 +101,32 @@ class Timeline:
def initUI(self): def initUI(self):
menubar = self.window.menuBar()
newPostAction = QtGui.QAction("&New Post", self.window) newPostAction = QtGui.QAction("&New Post", self.window)
newPostAction.setShortcut("Ctrl+N") newPostAction.setShortcut("Ctrl+N")
newPostAction.setStatusTip("Open new post window") newPostAction.setStatusTip("Open new post window")
newPostAction.triggered.connect(self.app.controller.openNewMessageWidow) newPostAction.triggered.connect(self.app.controller.openNewMessageWidow)
findEntityAction = QtGui.QAction("&Open Profile for Entity ...", self.window)
findEntityAction.setShortcut("Ctrl+u")
findEntityAction.setStatusTip("Find entity and open its profile view")
findEntityAction.triggered.connect(self.app.find_entity_show)
logOutAction = QtGui.QAction("&Log Out", self.window)
logOutAction.setStatusTip("Log out from this entity")
logOutAction.triggered.connect(self.app.log_out)
exitAction = QtGui.QAction("&Exit", self.window) exitAction = QtGui.QAction("&Exit", self.window)
exitAction.setShortcut("Ctrl+Q") exitAction.setShortcut("Ctrl+Q")
exitAction.setStatusTip("Exit Bungloo") exitAction.setStatusTip("Exit Bungloo")
exitAction.triggered.connect(QtGui.qApp.quit) exitAction.triggered.connect(QtGui.qApp.quit)
menubar = self.window.menuBar()
fileMenu = menubar.addMenu("&File") fileMenu = menubar.addMenu("&File")
fileMenu.addAction(newPostAction) fileMenu.addAction(newPostAction)
fileMenu.addAction(findEntityAction)
fileMenu.addSeparator()
fileMenu.addAction(logOutAction)
fileMenu.addAction(exitAction) fileMenu.addAction(exitAction)
timelineAction = QtGui.QAction("&Timeline", self.window) timelineAction = QtGui.QAction("&Timeline", self.window)
@ -124,26 +139,46 @@ class Timeline:
mentionsAction.setStatusTip("Show Mentions") mentionsAction.setStatusTip("Show Mentions")
mentionsAction.triggered.connect(self.app.mentions_show) mentionsAction.triggered.connect(self.app.mentions_show)
findEntityAction = QtGui.QAction("&Open Profile", self.window) conversationAction = QtGui.QAction("&Conversation", self.window)
findEntityAction.setShortcut("Ctrl+u") conversationAction.setShortcut("Ctrl+3")
findEntityAction.setStatusTip("Find entity and open its profile view") conversationAction.setStatusTip("Show Conversation")
findEntityAction.triggered.connect(self.app.find_entity_show) conversationAction.triggered.connect(self.app.conversation_show)
hideAction = QtGui.QAction("&Hide window", self.window) profileAction = QtGui.QAction("&Profile", self.window)
hideAction.setShortcut("Ctrl+W") profileAction.setShortcut("Ctrl+4")
hideAction.setStatusTip("Hide this window") profileAction.setStatusTip("Show Profile")
hideAction.triggered.connect(self.hide) profileAction.triggered.connect(self.app.profile_show)
windowMenu = menubar.addMenu("&Windows") searchAction = QtGui.QAction("&Search", self.window)
searchAction.setShortcut("Ctrl+F")
searchAction.setStatusTip("Show Search")
searchAction.triggered.connect(self.app.search_show)
windowMenu = menubar.addMenu("&View")
windowMenu.addAction(timelineAction) windowMenu.addAction(timelineAction)
windowMenu.addAction(mentionsAction) windowMenu.addAction(mentionsAction)
windowMenu.addAction(hideAction) windowMenu.addAction(conversationAction)
windowMenu.addAction(findEntityAction) windowMenu.addAction(profileAction)
windowMenu.addAction(searchAction)
aboutAction = QtGui.QAction("&About Bungloo", self.window)
aboutAction.setStatusTip("Open about page in Webbrowser")
aboutAction.triggered.connect(self.app.open_about)
developerExtrasAction = QtGui.QAction("&Developer Extras", self.window)
developerExtrasAction.setStatusTip("Activate webkit inspector")
developerExtrasAction.triggered.connect(self.developer_extras)
helpMenu = menubar.addMenu("&Help")
helpMenu.addAction(aboutAction)
helpMenu.addAction(developerExtrasAction)
def show(self): def show(self):
self.window.show() self.window.show()
#self.window.raise_() #self.window.raise_()
#QtGui.qApp.setActiveWindow(self.window) #QtGui.qApp.setActiveWindow(self.window)
def close(self):
self.window.close()
def hide(self): def hide(self):
self.window.hide() self.window.hide()
@ -158,6 +193,9 @@ class Timeline:
def evaluateJavaScript(self, func): def evaluateJavaScript(self, func):
return self.webView.page().mainFrame().evaluateJavaScript(func) return self.webView.page().mainFrame().evaluateJavaScript(func)
def developer_extras(self, widget):
QtWebKit.QWebSettings.globalSettings().setAttribute(QtWebKit.QWebSettings.DeveloperExtrasEnabled, True)
class Oauth: class Oauth:
@ -172,7 +210,11 @@ class Oauth:
self.core.page().mainFrame().evaluateJavaScript(script) self.core.page().mainFrame().evaluateJavaScript(script)
def login(self): def login(self):
script = "bungloo_instance.authenticate();" script = "bungloo.oauth.authenticate();"
self.core.page().mainFrame().evaluateJavaScript(script)
def log_out(self):
script = "bungloo.oauth.logout()";
self.core.page().mainFrame().evaluateJavaScript(script) self.core.page().mainFrame().evaluateJavaScript(script)
def handle_authentication(self, url): def handle_authentication(self, url):
@ -201,7 +243,7 @@ class Oauth:
dialog.exec_() dialog.exec_()
def bungloo_callback(self, url): def bungloo_callback(self, url):
script = "bungloo_instance.requestAccessToken('" + url.toString() + "');" script = "bungloo.oauth.requestAccessToken('" + url.toString() + "');"
self.core.page().mainFrame().evaluateJavaScript(script) self.core.page().mainFrame().evaluateJavaScript(script)
def hide(self): def hide(self):
@ -294,10 +336,10 @@ class NewPost(Helper.RestorableWindow):
sendPostAction.setStatusTip("Send post") sendPostAction.setStatusTip("Send post")
sendPostAction.triggered.connect(self.sendMessage) sendPostAction.triggered.connect(self.sendMessage)
togglePrivateAction = QtGui.QAction("&Toggle private", self) hideAction = QtGui.QAction("&Close Window", self)
togglePrivateAction.setShortcut("Ctrl+P") hideAction.setShortcut("Ctrl+W")
togglePrivateAction.setStatusTip("Toogle if private post") hideAction.setStatusTip("Close this window")
togglePrivateAction.triggered.connect(self.toggleIsPrivate) hideAction.triggered.connect(self.close)
exitAction = QtGui.QAction("&Exit", self) exitAction = QtGui.QAction("&Exit", self)
exitAction.setShortcut("Ctrl+Q") exitAction.setShortcut("Ctrl+Q")
@ -308,34 +350,31 @@ class NewPost(Helper.RestorableWindow):
fileMenu = menubar.addMenu("&File") fileMenu = menubar.addMenu("&File")
fileMenu.addAction(newPostAction) fileMenu.addAction(newPostAction)
fileMenu.addAction(sendPostAction) fileMenu.addAction(sendPostAction)
fileMenu.addAction(togglePrivateAction) fileMenu.addAction(hideAction)
fileMenu.addSeparator()
fileMenu.addAction(exitAction) fileMenu.addAction(exitAction)
timelineAction = QtGui.QAction("&Timeline", self) togglePrivateAction = QtGui.QAction("&Toggle Private", self)
timelineAction.setShortcut("Ctrl+1") togglePrivateAction.setShortcut("Ctrl+P")
timelineAction.setStatusTip("Show Timeline") togglePrivateAction.setStatusTip("Toogle if private post")
timelineAction.triggered.connect(self.app.timeline_show) togglePrivateAction.triggered.connect(self.toggleIsPrivate)
mentionsAction = QtGui.QAction("&Mentions", self) addImageAction = QtGui.QAction("Add &Image", self)
mentionsAction.setShortcut("Ctrl+2") addImageAction.setShortcut("Ctrl+I")
mentionsAction.setStatusTip("Show Mentions") addImageAction.setStatusTip("Add image to post")
mentionsAction.triggered.connect(self.app.mentions_show) addImageAction.triggered.connect(self.openFileDialog)
findEntityAction = QtGui.QAction("&Open Profile", self) editMenu = menubar.addMenu("&Edit")
findEntityAction.setShortcut("Ctrl+u") editMenu.addAction(togglePrivateAction)
findEntityAction.setStatusTip("Find entity and open its profile view") editMenu.addAction(addImageAction)
findEntityAction.triggered.connect(self.app.find_entity_show)
hideAction = QtGui.QAction("&Hide window", self) aboutAction = QtGui.QAction("&About Bungloo", self)
hideAction.setShortcut("Ctrl+W") aboutAction.setStatusTip("Open about page in Webbrowser")
hideAction.setStatusTip("Hide this window") aboutAction.triggered.connect(self.app.open_about)
hideAction.triggered.connect(self.close)
helpMenu = menubar.addMenu("&Help")
helpMenu.addAction(aboutAction)
windowMenu = menubar.addMenu("&Windows")
windowMenu.addAction(timelineAction)
windowMenu.addAction(mentionsAction)
windowMenu.addAction(findEntityAction)
windowMenu.addAction(hideAction)
self.statusBar().showMessage('256') self.statusBar().showMessage('256')

View file

@ -1,14 +0,0 @@
#!/bin/bash
mkdir -p build
mkdir -p build/bin
mkdir -p build/bungloo
touch build/bungloo/__init__.py
cp Bungloo.py build/bin/bungloo
cp Helper.py Windows.py build/bungloo
cp setup.py build/
cp -r ../WebKit build/bungloo/
cp -r ../images build/bungloo/
# eof

View file

@ -0,0 +1,38 @@
# $Id: Makefile,v 1.6 2008/10/29 01:01:35 ghantoos Exp $
#
PYTHON=`which python2`
DESTDIR=/
BUILDIR=$(CURDIR)/debian/bungloo
PROJECT=bungloo
VERSION={VERSION}
all:
@echo "make source - Create source package"
@echo "make install - Install on local system"
@echo "make buildrpm - Generate a rpm package"
@echo "make builddeb - Generate a deb package"
@echo "make clean - Get rid of scratch and byte files"
source:
$(PYTHON) setup.py sdist $(COMPILE)
install:
$(PYTHON) setup.py install --root $(DESTDIR) $(COMPILE)
buildrpm:
$(PYTHON) setup.py bdist_rpm
builddeb:
# build the source package in the parent directory
# then rename it to project_version.orig.tar.gz
$(PYTHON) setup.py sdist $(COMPILE) --dist-dir=../ --prune
rename -f 's/$(PROJECT)-(.*)\.tar\.gz/$(PROJECT)_$$1\.orig\.tar\.gz/' ../*
# build the package
dpkg-buildpackage -i -I -rfakeroot
clean:
$(PYTHON) setup.py clean
$(MAKE) -f $(CURDIR)/debian/rules clean
rm -rf build/ MANIFEST
find . -name '*.pyc' -delete

View file

@ -0,0 +1,12 @@
[Desktop Entry]
Version={VERSION}
Comment=Tent is a distributed social network protocol and Bungloo is one of the clients using it.
Exec=/usr/bin/bungloo
GenericName=Tent Client
Icon=/usr/share/pixmaps/bungloo.xpm
Name=Bungloo
NoDisplay=false
StartupNotify=true
Terminal=false
Type=Application
Categories=Network;Qt

View file

@ -0,0 +1,15 @@
bungloo (2.0.0) quantal; urgency=low
[ Jeena Paradies ]
* Changed to one window
* Added search (skate.io)
* Added log out
-- Jeena <spam@jeenaparadies.net> Tue, 26 Mar 2013 21:50:00 +0100
bungloo (1.2.0) quantal; urgency=low
[ Jeena Paradies ]
* Initial release.
-- Jeena <spam@jeenaparadies.net> Tue, 05 Mar 2013 17:57:47 +0100

View file

@ -0,0 +1 @@
9

View file

@ -0,0 +1,15 @@
Source: bungloo
Section: Miscellaneous
Priority: optional
Maintainer: Jeena Paradies <spam@jeenaparadies.net>
Build-Depends: debhelper (>=7.0.50~), python-support (>= 0.6), cdbs (>= 0.4.49), python-all-dev
Standards-Version: 3.9.4
Package: bungloo
Architecture: all
Homepage: http://jabs.nu/bungloo
Depends: ${misc:Depends}, ${python:Depends}, python-qt4
Provides: tent
Description: A desktop Tent client
This desktop Tent client makes it possible to use the Tent protocol. More
information about this protocol can be found at https://tent.io

View file

@ -0,0 +1,17 @@
This package was debianized by Jeena Paradies (jeena) on Tue, 5 Mar 2013 18:38
License: BSD
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
- Neither the name of Bungloo nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
On Debian systems, the complete text of the GNU General
Public License can be found in `/usr/share/common-licenses/BSD'.

17
Linux/deploy/debian/rules Executable file
View file

@ -0,0 +1,17 @@
#!/usr/bin/make -f
# -*- makefile -*-
DEB_PYTHON_SYSTEM := pysupport
include /usr/share/cdbs/1/rules/debhelper.mk
include /usr/share/cdbs/1/class/python-distutils.mk
install/bungloo::
mkdir -p debian/bungloo/usr/share/applications/
cp bungloo.desktop debian/bungloo/usr/share/applications/
mkdir -p debian/bungloo/usr/share/pixmaps/
cp bungloo/images/bungloo.xpm debian/bungloo/usr/share/pixmaps/
clean::
rm -rf build build-stamp configure-stamp build/ MANIFEST
dh_clean

49
Linux/deploy/deploy.sh Executable file
View file

@ -0,0 +1,49 @@
#!/bin/bash
VERSION="2.0.0"
DEPLOYPATH="bungloo-${VERSION}"
LINUXPATH=".."
SHAREDPATH="../.."
DISTPATH=dist
rm -rf $DEPLOYPATH
rm -rf $DISTPATH
mkdir -p $DEPLOYPATH
mkdir -p $DEPLOYPATH/bin
mkdir -p $DEPLOYPATH/bungloo
touch $DEPLOYPATH/bungloo/__init__.py
cp $LINUXPATH/Bungloo.py $DEPLOYPATH/bin/bungloo
cp $LINUXPATH/Helper.py $LINUXPATH/Windows.py $DEPLOYPATH/bungloo
cat setup.py.exmp | sed -e "s/{VERSION}/${VERSION}/g" > $DEPLOYPATH/setup.py
cat Makefile.exmp | sed -e "s/{VERSION}/${VERSION}/g" > $DEPLOYPATH/Makefile
cat bungloo.desktop.exmp | sed -e "s/{VERSION}/${VERSION}/g" > $DEPLOYPATH/bungloo.desktop
cp -r $SHAREDPATH/WebKit $DEPLOYPATH/bungloo/
cp -r $SHAREDPATH/images $DEPLOYPATH/bungloo/
cp $SHAREDPATH/readme.md $DEPLOYPATH/README
cp $SHAREDPATH/LICENCE.txt $DEPLOYPATH/COPYING
cp -r debian $DEPLOYPATH/
cp bungloo.desktop $DEPLOYPATH/
cd $DEPLOYPATH
make builddeb
make buildrpm
echo "Cleaning up ..."
mv $DISTPATH ..
cd ..
mv bungloo_${VERSION}_all.deb $DISTPATH
rm bungloo_${VERSION}_amd64.changes
rm bungloo_${VERSION}.diff.gz
rm bungloo_${VERSION}.dsc
rm bungloo_${VERSION}.orig.tar.gz
rm -rf $DEPLOYPATH
rm $DISTPATH/bungloo-${VERSION}-1.src.rpm
echo "Done."
# eof

View file

@ -14,7 +14,7 @@ for dirname, dirnames, filenames in os.walk('bungloo/images'):
setup( setup(
name = "bungloo", name = "bungloo",
version = "1.2.0", version = "{VERSION}",
author = "Jeena Paradies", author = "Jeena Paradies",
author_email = "spam@jeenaparadies.net", author_email = "spam@jeenaparadies.net",
url = "http://jabs.nu/bungloo", url = "http://jabs.nu/bungloo",

View file

@ -42,7 +42,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.2.2</string> <string>2.0.0</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleURLTypes</key> <key>CFBundleURLTypes</key>
@ -57,7 +57,7 @@
</dict> </dict>
</array> </array>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.2.2</string> <string>2.0.0</string>
<key>LSApplicationCategoryType</key> <key>LSApplicationCategoryType</key>
<string>public.app-category.social-networking</string> <string>public.app-category.social-networking</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>

View file

@ -19,12 +19,6 @@
@interface Controller : NSObject <GrowlApplicationBridgeDelegate> { @interface Controller : NSObject <GrowlApplicationBridgeDelegate> {
IBOutlet WebView *timelineView; IBOutlet WebView *timelineView;
IBOutlet NSWindow *timelineViewWindow; IBOutlet NSWindow *timelineViewWindow;
IBOutlet WebView *mentionsView;
IBOutlet NSWindow *mentionsViewWindow;
IBOutlet WebView *conversationView;
IBOutlet NSWindow *conversationViewWindow;
WebView *profileView;
NSWindow *profileViewWindow;
NSPanel *openProfileWindow; NSPanel *openProfileWindow;
NSWindow *loginViewWindow; NSWindow *loginViewWindow;
NSTextField *loginEntityTextField; NSTextField *loginEntityTextField;
@ -40,12 +34,6 @@
@property (assign) IBOutlet WebView *timelineView; @property (assign) IBOutlet WebView *timelineView;
@property (assign) IBOutlet NSWindow *timelineViewWindow; @property (assign) IBOutlet NSWindow *timelineViewWindow;
@property (assign) IBOutlet WebView *mentionsView;
@property (assign) IBOutlet NSWindow *mentionsViewWindow;
@property (assign) IBOutlet WebView *conversationView;
@property (assign) IBOutlet NSWindow *conversationViewWindow;
@property (assign) IBOutlet WebView *profileView;
@property (assign) IBOutlet NSWindow *profileViewWindow;
@property (assign) IBOutlet NSPanel *openProfileWindow; @property (assign) IBOutlet NSPanel *openProfileWindow;
@property (assign) IBOutlet NSWindow *loginViewWindow; @property (assign) IBOutlet NSWindow *loginViewWindow;

View file

@ -17,7 +17,7 @@
@synthesize loginViewWindow; @synthesize loginViewWindow;
@synthesize loginEntityTextField; @synthesize loginEntityTextField;
@synthesize loginActivityIndicator; @synthesize loginActivityIndicator;
@synthesize timelineView, timelineViewWindow, mentionsView, mentionsViewWindow, conversationView, conversationViewWindow, profileView, profileViewWindow; @synthesize timelineView, timelineViewWindow;
@synthesize globalHotkeyMenuItem, viewDelegate; @synthesize globalHotkeyMenuItem, viewDelegate;
@synthesize logoLayer; @synthesize logoLayer;
@synthesize oauthView, accessToken; @synthesize oauthView, accessToken;
@ -25,7 +25,6 @@
- (void)awakeFromNib - (void)awakeFromNib
{ {
[timelineViewWindow setExcludedFromWindowsMenu:YES]; [timelineViewWindow setExcludedFromWindowsMenu:YES];
[mentionsViewWindow setExcludedFromWindowsMenu:YES];
[self initHotKeys]; [self initHotKeys];
@ -70,7 +69,6 @@
if (forceLogin || ![accessToken stringForKey:@"user_access_token"] || ![accessToken secret]) { if (forceLogin || ![accessToken stringForKey:@"user_access_token"] || ![accessToken secret]) {
[timelineViewWindow performClose:self]; [timelineViewWindow performClose:self];
[mentionsViewWindow performClose:self];
[self.loginViewWindow makeKeyAndOrderFront:self]; [self.loginViewWindow makeKeyAndOrderFront:self];
[self initOauth]; [self initOauth];
} else { } else {
@ -125,47 +123,11 @@
[timelineView setPolicyDelegate:viewDelegate]; [timelineView setPolicyDelegate:viewDelegate];
[timelineView setUIDelegate:viewDelegate]; [timelineView setUIDelegate:viewDelegate];
[[timelineView windowScriptObject] setValue:self forKey:@"controller"]; [[timelineView windowScriptObject] setValue:self forKey:@"controller"];
//WebPreferences* prefs = [timelineView preferences];
//[prefs _setLocalStorageDatabasePath:localStoragePath];
//[prefs setLocalStorageEnabled:YES];
viewDelegate.mentionsView = mentionsView;
[[mentionsView mainFrame] loadHTMLString:index_string baseURL:url];
[mentionsView setFrameLoadDelegate:viewDelegate];
[mentionsView setPolicyDelegate:viewDelegate];
[mentionsView setUIDelegate:viewDelegate];
[[mentionsView windowScriptObject] setValue:self forKey:@"controller"];
//prefs = [mentionsView preferences];
//[prefs _setLocalStorageDatabasePath:localStoragePath];
//[prefs setLocalStorageEnabled:YES];
viewDelegate.conversationView = conversationView;
[[conversationView mainFrame] loadHTMLString:index_string baseURL:url];
[conversationView setFrameLoadDelegate:viewDelegate];
[conversationView setPolicyDelegate:viewDelegate];
[conversationView setUIDelegate:viewDelegate];
[[conversationView windowScriptObject] setValue:self forKey:@"controller"];
//prefs = [conversationView preferences];
//[prefs _setLocalStorageDatabasePath:localStoragePath];
//[prefs setLocalStorageEnabled:YES];
viewDelegate.profileView = profileView;
[[profileView mainFrame] loadHTMLString:index_string baseURL:url];
[profileView setFrameLoadDelegate:viewDelegate];
[profileView setPolicyDelegate:viewDelegate];
[profileView setUIDelegate:viewDelegate];
[[profileView windowScriptObject] setValue:self forKey:@"controller"];
//prefs = [profileView preferences];
//[prefs _setLocalStorageDatabasePath:localStoragePath];
//[prefs setLocalStorageEnabled:YES];
} }
else else
{ {
[timelineView stringByEvaluatingJavaScriptFromString:@"start('timeline')"]; [timelineView stringByEvaluatingJavaScriptFromString:@"start('timeline')"];
[mentionsView stringByEvaluatingJavaScriptFromString:@"start('mentions')"];
[conversationView stringByEvaluatingJavaScriptFromString:@"start('conversation')"];
[profileView stringByEvaluatingJavaScriptFromString:@"start('profile')"];
} }
} }
@ -312,7 +274,7 @@
if (range.length > 0) if (range.length > 0)
{ {
[oauthView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"bungloo_instance.requestAccessToken('%@')", aString]]; [oauthView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"bungloo.oauth.requestAccessToken('%@')", aString]];
} }
else else
{ {
@ -353,7 +315,7 @@
isPrivate = @"true"; isPrivate = @"true";
} }
NSString *func = [NSString stringWithFormat:@"bungloo_instance.sendNewMessage(\"%@\", \"%@\", \"%@\", %@, %@, %@)", NSString *func = [NSString stringWithFormat:@"bungloo.timeline.sendNewMessage(\"%@\", \"%@\", \"%@\", %@, %@, %@)",
text, text,
post.inReplyTostatusId, post.inReplyTostatusId,
post.inReplyToEntity, post.inReplyToEntity,
@ -378,17 +340,17 @@
- (void)unreadMentions:(int)count - (void)unreadMentions:(int)count
{ {
if (![mentionsViewWindow isVisible] && count > 0) if (count > 0)
{ {
[timelineViewWindow setTitle:[NSString stringWithFormat:@"Bungloo (^%i)", count]];
[[[NSApplication sharedApplication] dockTile] setBadgeLabel:[NSString stringWithFormat:@"%i", count]]; [[[NSApplication sharedApplication] dockTile] setBadgeLabel:[NSString stringWithFormat:@"%i", count]];
} }
else else
{ {
[timelineViewWindow setTitle:[NSString stringWithFormat:@"Bungloo"]];
[[[NSApplication sharedApplication] dockTile] setBadgeLabel:nil]; [[[NSApplication sharedApplication] dockTile] setBadgeLabel:nil];
[mentionsView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.unread_mentions = 0;"];
} }
NSString *script = [NSString stringWithFormat:@"bungloo.sidebar.setUnreadMentions(%i);", count];
[timelineView stringByEvaluatingJavaScriptFromString:script];
} }
- (void)notificateUserAboutMention:(NSString *)text fromName:(NSString *)name withPostId:(NSString *)postId andEntity:(NSString *)entity - (void)notificateUserAboutMention:(NSString *)text fromName:(NSString *)name withPostId:(NSString *)postId andEntity:(NSString *)entity
@ -414,35 +376,21 @@
{ {
NSString *entity = [self.showProfileTextField stringValue]; NSString *entity = [self.showProfileTextField stringValue];
if ([entity rangeOfString:@"."].location != NSNotFound && ([entity hasPrefix:@"http://"] || [entity hasPrefix:@"https://"])) { if ([entity rangeOfString:@"."].location != NSNotFound && ([entity hasPrefix:@"http://"] || [entity hasPrefix:@"https://"])) {
NSString *func = [NSString stringWithFormat:@"bungloo_instance.showProfileForEntity('%@')", entity]; NSString *func = [NSString stringWithFormat:@"bungloo.sidebar.onEntityProfile(); bungloo.entityProfile.showProfileForEntity('%@')", entity];
[profileView stringByEvaluatingJavaScriptFromString:func]; [timelineView stringByEvaluatingJavaScriptFromString:func];
[profileViewWindow makeKeyAndOrderFront:self];
[openProfileWindow performClose:self];
} }
} }
- (void)notificateViewsAboutDeletedPostWithId:(NSString *)postId byEntity:(NSString*)entity - (void)notificateViewsAboutDeletedPostWithId:(NSString *)postId byEntity:(NSString*)entity
{ {
NSString *fun = [NSString stringWithFormat:@"bungloo_instance.postDeleted('%@', '%@')", postId, entity]; NSString *f = [NSString stringWithFormat:@".postDeleted('%@', '%@');", postId, entity];
NSMutableString *fun = [NSMutableString stringWithFormat:@"bungloo.timeline%@", f];
[fun appendFormat:@"bungloo.mentions%@", f];
[fun appendFormat:@"bungloo.conversation%@", f];
[fun appendFormat:@"bungloo.entityProfile%@", f];
[timelineView stringByEvaluatingJavaScriptFromString:fun]; [timelineView stringByEvaluatingJavaScriptFromString:fun];
[mentionsView stringByEvaluatingJavaScriptFromString:fun];
[conversationView stringByEvaluatingJavaScriptFromString:fun];
[profileView stringByEvaluatingJavaScriptFromString:fun];
} }
/*
- (void)storeAccessToken:(NSString *)_accessToken secret:(NSString *)secret userId:(NSString *)userId andScreenName:(NSString *)screenName
{
self.accessToken.accessToken = _accessToken;
self.accessToken.secret = secret;
self.accessToken.userId = userId;
self.accessToken.screenName = screenName;
[timelineViewWindow makeKeyAndOrderFront:self];
[[NSNotificationCenter defaultCenter] postNotificationName:@"authentificationSucceded" object:nil];
}*/
- (void)loggedIn - (void)loggedIn
{ {
[loginActivityIndicator stopAnimation:self]; [loginActivityIndicator stopAnimation:self];
@ -456,58 +404,47 @@
if ([[loginEntityTextField stringValue] length] > 0) { if ([[loginEntityTextField stringValue] length] > 0) {
[[loginEntityTextField window] makeFirstResponder:nil]; [[loginEntityTextField window] makeFirstResponder:nil];
[loginActivityIndicator startAnimation:self]; [loginActivityIndicator startAnimation:self];
[oauthView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.authenticate();"]; [oauthView stringByEvaluatingJavaScriptFromString:@"bungloo.oauth.authenticate();"];
} }
} }
- (IBAction)logout:(id)sender - (IBAction)logout:(id)sender
{ {
[oauthView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.logout();"]; [oauthView stringByEvaluatingJavaScriptFromString:@"bungloo.oauth.logout();"];
[timelineViewWindow performClose:self]; [timelineViewWindow performClose:self];
[mentionsViewWindow performClose:self];
[conversationViewWindow performClose:self];
[profileViewWindow performClose:self];
[self.loginViewWindow makeKeyAndOrderFront:self]; [self.loginViewWindow makeKeyAndOrderFront:self];
[timelineView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.logout();"]; [timelineView stringByEvaluatingJavaScriptFromString:@"bungloo.sidebar.logout();"];
[mentionsView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.logout();"];
} }
// Mentions window has been visible // Mentions window has been visible
- (void)windowDidBecomeKey:(NSNotification *)notification - (void)windowDidBecomeKey:(NSNotification *)notification
{ {
if ([notification object] == mentionsViewWindow)
{
//[self unreadMentions:0];
[mentionsView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.setAllMentionsRead();"];
}
} }
- (void)getPostUpdates:(id)sender - (void)getPostUpdates:(id)sender
{ {
[timelineView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.getNewData(true)"]; [timelineView stringByEvaluatingJavaScriptFromString:@"bungloo.timeline.getNewData(true)"];
[mentionsView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.getNewData(true)"]; [timelineView stringByEvaluatingJavaScriptFromString:@"bungloo.mentions.getNewData(true)"];
} }
- (IBAction)showConversationForPostId:(NSString *)postId andEntity:(NSString *)entity - (IBAction)showConversationForPostId:(NSString *)postId andEntity:(NSString *)entity
{ {
NSString *js = [NSString stringWithFormat:@"bungloo_instance.showStatus('%@', '%@');", postId, entity]; NSString *js = [NSString stringWithFormat:@"bungloo.sidebar.onConversation(); bungloo.conversation.showStatus('%@', '%@');", postId, entity];
[conversationView stringByEvaluatingJavaScriptFromString:js]; [timelineView stringByEvaluatingJavaScriptFromString:js];
[conversationViewWindow makeKeyAndOrderFront:self];
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
} }
- (IBAction)clearCache:(id)sender - (IBAction)clearCache:(id)sender
{ {
[timelineView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.cache.clear()"]; [timelineView stringByEvaluatingJavaScriptFromString:@"bungloo.timeline.cache.clear()"];
} }
- (IBAction)showProfileForEntity:(NSString *)entity - (IBAction)showProfileForEntity:(NSString *)entity
{ {
NSString *js = [NSString stringWithFormat:@"bungloo_instance.showProfileForEntity('%@');", entity]; NSString *js = [NSString stringWithFormat:@"bungloo.sidebar.onEntityProfile(); bungloo.entityProfile.showProfileForEntity('%@');", entity];
[profileView stringByEvaluatingJavaScriptFromString:js]; [timelineView stringByEvaluatingJavaScriptFromString:js];
[profileViewWindow makeKeyAndOrderFront:self];
} }
- (void)growlNotificationWasClicked:(id)clickContext - (void)growlNotificationWasClicked:(id)clickContext
@ -518,8 +455,8 @@
[self showConversationForPostId:postId andEntity:entity]; [self showConversationForPostId:postId andEntity:entity];
NSString *js = [NSString stringWithFormat:@"bungloo_instance.mentionRead('%@', '%@');", postId, entity]; NSString *js = [NSString stringWithFormat:@"bungloo.sidebar.onMentions(); bungloo.mentions.mentionRead('%@', '%@');", postId, entity];
[mentionsView stringByEvaluatingJavaScriptFromString:js]; [timelineView stringByEvaluatingJavaScriptFromString:js];
} }
- (NSString *) applicationNameForGrowl - (NSString *) applicationNameForGrowl

View file

@ -1,4 +1,4 @@
{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340 {\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf370
{\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;} {\colortbl;\red255\green255\blue255;}
\viewkind0 \viewkind0
@ -16,7 +16,7 @@
\b Documentation: \b Documentation:
\b0 \ \b0 \
http://github.com/jeena/bungloo/wiki\ http://jabs.nu/bungloo\
\ \
\b With special thanks to: \b With special thanks to:

View file

@ -11,17 +11,9 @@
#import "Constants.h" #import "Constants.h"
@interface ViewDelegate : NSObject { @interface ViewDelegate : NSObject {
WebView *timelineView; WebView *timelineView; WebView *oauthView;
WebView *mentionsView;
WebView *conversationView;
WebView *profileView;
WebView *oauthView;
} }
@property (nonatomic, assign) WebView *timelineView; @property (nonatomic, assign) WebView *timelineView;@property (nonatomic, assign) WebView *oauthView;
@property (nonatomic, assign) WebView *mentionsView;
@property (nonatomic, assign) WebView *conversationView;
@property (nonatomic, assign) WebView *profileView;
@property (nonatomic, assign) WebView *oauthView;
@end @end

View file

@ -11,18 +11,15 @@
@implementation ViewDelegate @implementation ViewDelegate
@synthesize timelineView, mentionsView, conversationView, profileView, oauthView; @synthesize timelineView, oauthView;
- (void)webView:(WebView *)sender addMessageToConsole:(NSDictionary *)message { - (void)webView:(WebView *)sender addMessageToConsole:(NSDictionary *)message {
if (![message isKindOfClass:[NSDictionary class]]) return; if (![message isKindOfClass:[NSDictionary class]]) return;
NSString *viewName = @"TimelineView"; NSString *viewName = @"TimelineView";
if (sender == mentionsView) viewName = @"MentionsView";
if (sender == conversationView) viewName = @"ConversationView";
if (sender == oauthView) viewName = @"OauthView"; if (sender == oauthView) viewName = @"OauthView";
if (sender == profileView) viewName = @"ProfileView";
NSLog(@"js<%@>: %@:%@: %@", NSLog(@"js<%@>: %@:%@: %@",
viewName, viewName,
[[message objectForKey:@"sourceURL"] lastPathComponent], [[message objectForKey:@"sourceURL"] lastPathComponent],
@ -33,8 +30,6 @@
- (void)webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame { - (void)webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame {
NSString *viewName = @"TimelineView"; NSString *viewName = @"TimelineView";
if (sender == mentionsView) viewName = @"MentionsView";
if (sender == conversationView) viewName = @"ConversationView";
if (sender == oauthView) viewName = @"OauthView"; if (sender == oauthView) viewName = @"OauthView";
NSLog(@"jsa<%@>: %@", viewName, message); NSLog(@"jsa<%@>: %@", viewName, message);
@ -52,7 +47,7 @@
- (void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id <WebPolicyDecisionListener>)listener { - (void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id <WebPolicyDecisionListener>)listener {
NSArray *frames = [NSArray arrayWithObjects:timelineView.mainFrame, mentionsView.mainFrame, conversationView.mainFrame, oauthView.mainFrame, profileView.mainFrame, nil]; NSArray *frames = [NSArray arrayWithObjects:timelineView.mainFrame, oauthView.mainFrame, nil];
// If it is clicked from one of the views the open default browser // If it is clicked from one of the views the open default browser
if ([frames indexOfObject:frame] != NSNotFound) { if ([frames indexOfObject:frame] != NSNotFound) {
@ -85,25 +80,9 @@
[oauthView stringByEvaluatingJavaScriptFromString:@"function HostAppGo() { start('oauth') }"]; [oauthView stringByEvaluatingJavaScriptFromString:@"function HostAppGo() { start('oauth') }"];
} else if(sender == conversationView) {
[conversationView stringByEvaluatingJavaScriptFromString:@"function HostAppGo() { start('conversation') }"];
} else if(sender == profileView) {
[profileView stringByEvaluatingJavaScriptFromString:@"function HostAppGo() { start('profile') }"];
} else { } else {
NSString *action = @"timeline"; [sender stringByEvaluatingJavaScriptFromString:@"function HostAppGo() { start('timeline') }"];
NSString *delay = @"1";
if (sender == mentionsView) {
action = @"mentions";
delay = @"1000";
}
[sender stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"function HostAppGo() { start('%@') }", action]];
} }
} }
@ -126,8 +105,7 @@
} }
- (void)reload:(id)sender { - (void)reload:(id)sender {
[timelineView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.getNewData();"]; [timelineView stringByEvaluatingJavaScriptFromString:@"bungloo.timeline.getNewData();"];
[mentionsView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.getNewData();"];
} }
- (NSString *)pluginURL - (NSString *)pluginURL

View file

@ -16,6 +16,53 @@ a {
outline: 0; outline: 0;
} }
#sidebar {
position: fixed;
top: 0;
left: 0;
width: 62px;
height: 100%;
background: #333;
}
#sidebar ul {
list-style-type: none;
margin: 0;
padding: 7px 0 0 0;
text-align: center;
}
#siedebar a {
color: #5b5b5b;
}
#sidebar .sidebar-user img {
max-width: 50px;
max-height: 50px;
border-radius: 8px;
}
#sidebar .unread_mentions {
color: white;
background: red;
border: 2px solid white;
border-radius: 1em;
box-shadow: 0 0 1em black;
padding: 0 0.3em;
position: absolute;
top: 100px;
right: 10px;
font-weight: bold;
}
#sidebar .unread_mentions:empty {
/*display: none;*/
}
#content {
margin-left: 62px;
}
ol { ol {
list-style-type: none; list-style-type: none;
margin: 0; margin: 0;
@ -39,37 +86,37 @@ ol li, .error, header.profile {
color: red; color: red;
} }
body > ol > li { #content ol > li {
} }
body > ol > li:first-child { #content ol > li:first-child {
border-top: 0; border-top: 0;
} }
body > ol > li:nth-child(odd), .error, header.profile { #content ol > li:nth-child(odd), .error, header.profile {
background: #fafafa; background: #fafafa;
} }
body > ol > li:nth-child(even) { #content ol > li:nth-child(even) {
background: #f2f2f2; background: #f2f2f2;
} }
body > ol > li:hover { #content ol > li:hover {
background: #dedede; background: #dedede;
} }
body > ol > li.highlighteffect { #content ol > li.highlighteffect {
background-color: #FFFBD0; background-color: #FFFBD0;
-webkit-transition: background-color 200ms linear; -webkit-transition: background-color 200ms linear;
} }
body > ol > li.highlighteffect-after { #content ol > li.highlighteffect-after {
-webkit-transition: background-color 1000ms linear; -webkit-transition: background-color 1000ms linear;
} }
body > ol > li:after, header.profile:after { #content ol > li:after, header.profile:after {
content: "."; content: ".";
display: block; display: block;
clear: both; clear: both;
@ -189,7 +236,7 @@ li:hover .from {
li:first-child:hover .from { li:first-child:hover .from {
top: auto; top: auto;
bottom: -1.9em; bottom: -1.8em;
z-index: 2; z-index: 2;
-webkit-border-top-left-radius: 0; -webkit-border-top-left-radius: 0;
-webkit-border-top-right-radius: 0; -webkit-border-top-right-radius: 0;
@ -366,4 +413,15 @@ a.youtube:before {
iframe { iframe {
max-width: 500px; max-width: 500px;
}
form.search {
text-align: center;
padding: 5px 10%;
}
form.search input {
width: 100%;
padding: 10px;
font-size: 1.2em;
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 783 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
WebKit/img/sidebar/user.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

View file

@ -7,5 +7,11 @@
<script data-main="scripts/main" src="scripts/lib/vendor/require-jquery.js"></script> <script data-main="scripts/main" src="scripts/lib/vendor/require-jquery.js"></script>
</head> </head>
<body> <body>
<div id="sidebar">
</div>
<article id="content">
</article>
</body> </body>
</html> </html>

View file

@ -14,15 +14,23 @@ function(HostApp, Core, Paths, URI) {
this.action = "conversation"; this.action = "conversation";
document.body.innerHTML = "";
this.body = document.createElement("ol"); this.body = document.createElement("ol");
this.body.className = this.action; this.body.className = this.action;
document.body.appendChild(this.body);
document.getElementById("content").appendChild(this.body);
this.hide();
} }
Conversation.prototype = Object.create(Core.prototype); Conversation.prototype = Object.create(Core.prototype);
Conversation.prototype.show = function() {
Core.prototype.show.call(this, this.body);
}
Conversation.prototype.hide = function() {
Core.prototype.hide.call(this, this.body);
}
Conversation.addStatus = function(status) { Conversation.addStatus = function(status) {

View file

@ -2,10 +2,11 @@ define([
"helper/HostApp", "helper/HostApp",
"controller/Timeline", "controller/Timeline",
"lib/URI", "lib/URI",
"helper/Paths" "helper/Paths",
"helper/Core"
], ],
function(HostApp, Timeline, URI, Paths) { function(HostApp, Timeline, URI, Paths, Core) {
function Mentions() { function Mentions() {
@ -17,11 +18,21 @@ function(HostApp, Timeline, URI, Paths) {
this.action = "mentions"; this.action = "mentions";
this.body.className = this.action; this.body.className = this.action;
this.hide();
} }
Mentions.prototype = Object.create(Timeline.prototype); Mentions.prototype = Object.create(Timeline.prototype);
Mentions.prototype.show = function() {
Core.prototype.show.call(this, this.body);
}
Mentions.prototype.hide = function() {
Core.prototype.hide.call(this, this.body);
}
Mentions.prototype.newStatus = function(statuses) { Mentions.prototype.newStatus = function(statuses) {
Timeline.prototype.newStatus.call(this, statuses); Timeline.prototype.newStatus.call(this, statuses);

View file

@ -14,12 +14,30 @@ function(HostApp, Core, Paths, URI) {
this.action = "profile"; this.action = "profile";
document.body.innerHTML = ""; this.container = document.createElement("div");
document.getElementById("content").appendChild(this.container);
this.initProfileTemplate(); this.initProfileTemplate();
this.hide();
var _this = this;
setTimeout(function() { _this.showProfileForEntity() }, 5000); // Load users profile on start
} }
Profile.prototype = Object.create(Core.prototype); Profile.prototype = Object.create(Core.prototype);
Profile.prototype.show = function() {
Core.prototype.show.call(this, this.container);
}
Profile.prototype.hide = function() {
Core.prototype.hide.call(this, this.container);
}
Profile.prototype.logout = function() {
this.container = "";
}
Profile.prototype.showList = function(list) { Profile.prototype.showList = function(list) {
$(this.body).hide(); $(this.body).hide();
@ -30,6 +48,10 @@ function(HostApp, Core, Paths, URI) {
Profile.prototype.showProfileForEntity = function(entity) { Profile.prototype.showProfileForEntity = function(entity) {
if (!entity) {
entity = HostApp.stringForKey("entity");
};
this.clear(); this.clear();
this.entity = entity; this.entity = entity;
this.following = null; this.following = null;
@ -46,8 +68,9 @@ function(HostApp, Core, Paths, URI) {
var _this = this; var _this = this;
var header = document.createElement("header"); var header = document.createElement("header");
header.className = "profile" header.className = "profile";
document.body.appendChild(header);
this.container.appendChild(header);
this.profile_template = { this.profile_template = {
avatar: document.createElement("img"), avatar: document.createElement("img"),
@ -139,15 +162,15 @@ function(HostApp, Core, Paths, URI) {
this.body = document.createElement("ol"); this.body = document.createElement("ol");
this.body.className = this.action; this.body.className = this.action;
document.body.appendChild(this.body); this.container.appendChild(this.body);
this.followingsBody = document.createElement("ol"); this.followingsBody = document.createElement("ol");
this.followingsBody.className = this.action + " followings"; this.followingsBody.className = this.action + " followings";
document.body.appendChild(this.followingsBody); this.container.appendChild(this.followingsBody);
this.followersBody = document.createElement("ol"); this.followersBody = document.createElement("ol");
this.followersBody.className = this.action + " folloewds"; this.followersBody.className = this.action + " folloewds";
document.body.appendChild(this.followersBody); this.container.appendChild(this.followersBody);
} }
@ -229,18 +252,23 @@ function(HostApp, Core, Paths, URI) {
} }
Profile.prototype.getFollowing = function() { Profile.prototype.getFollowing = function() {
var url = Paths.mkApiRootPath("/followings") + "/" + encodeURIComponent(this.entity); if(this.entity != HostApp.stringForKey("entity")) {
var _this = this; var url = Paths.mkApiRootPath("/followings") + "/" + encodeURIComponent(this.entity);
Paths.getURL(url, "GET", function(resp) { var _this = this;
if (resp.status >= 200 && resp.status < 400) { Paths.getURL(url, "GET", function(resp) {
var following = JSON.parse(resp.responseText); if (resp.status >= 200 && resp.status < 400) {
_this.following_id = following.id var following = JSON.parse(resp.responseText);
_this.setFollowingButton(true); _this.following_id = following.id
} else { _this.setFollowingButton(true);
_this.setFollowingButton(false); } else {
_this.following_id = null; _this.setFollowingButton(false);
} _this.following_id = null;
}) }
})
} else {
this.setFollowingButton(false);
this.following_id = null;
}
} }
Profile.prototype.showProfile = function(profile) { Profile.prototype.showProfile = function(profile) {
@ -302,21 +330,25 @@ function(HostApp, Core, Paths, URI) {
_this.populate(_this.profile_template.followed, resp.responseText); _this.populate(_this.profile_template.followed, resp.responseText);
}, null, false); }, null, false);
Paths.getURL(URI(root_url + "/followers/" + encodeURIComponent(HostApp.stringForKey("entity"))).toString(), "GET", function(resp) { if (this.entity != HostApp.stringForKey("entity")) {
if (resp.status == 200) { Paths.getURL(URI(root_url + "/followers/" + encodeURIComponent(HostApp.stringForKey("entity"))).toString(), "GET", function(resp) {
_this.relationships.following_you = true; if (resp.status == 200) {
} _this.relationships.following_you = true;
_this.setRelationships(); }
_this.setRelationships();
}, null, false); }, null, false);
Paths.getURL(URI(Paths.mkApiRootPath("/followings/" + encodeURIComponent(this.entity))), "GET", function(resp) { Paths.getURL(URI(Paths.mkApiRootPath("/followings/" + encodeURIComponent(this.entity))), "GET", function(resp) {
if (resp.status == 200) { if (resp.status == 200) {
_this.relationships.followed_by_you = true; _this.relationships.followed_by_you = true;
} }
_this.setRelationships(); _this.setRelationships();
});
});
} else {
this.setRelationships();
}
var url = URI(root_url + "/posts/count"); var url = URI(root_url + "/posts/count");
var post_types = [ var post_types = [

View file

@ -0,0 +1,111 @@
define([
"helper/HostApp",
"helper/Core",
"helper/Paths",
"lib/URI"
],
function(HostApp, Core, Paths, URI) {
function Search() {
Core.call(this);
this.action = "search";
this.container = document.createElement("div");
document.getElementById("content").appendChild(this.container);
this.body = document.createElement("ol");
this.form = document.createElement("form");
this.form.className = this.action;
this.input = document.createElement("input");
this.input.type = "search";
this.input.placeholder = "Search ...";
this.form.appendChild(this.input);
var _this = this;
this.form.onsubmit = function() { _this.doSearch(_this.input.value); return false; };
this.form.action = "#";
this.container.appendChild(this.form);
this.container.appendChild(this.body);
this.hide();
}
Search.prototype = Object.create(Core.prototype);
Search.prototype.show = function() {
Core.prototype.show.call(this, this.container);
this.input.focus();
}
Search.prototype.hide = function() {
Core.prototype.hide.call(this, this.container);
}
Search.prototype.doSearch = function(query) {
this.body.innerHTML = ""; // remove old results
if (query == "") return;
this.input.value = query;
var endpoint = "https://skate.io/api/search";
var api_key = "15cbec6445887eff3408";
var url = URI(endpoint);
url.addSearch("api_key", api_key);
url.addSearch("text", query);
var _this = this;
Paths.getURL(url.toString(), "GET", function(resp) {
var results = JSON.parse(resp.responseText).results;
var statuses = [];
for (var i = 0; i < results.length; i++) {
var result = results[i].source;
var status = {
entity: result.entity,
content: {
text: result.content
},
published_at: result.published_at,
id: result.public_id,
type: result.post_type,
version: result.post_version,
app: {
url: "http://skate.io",
name: "skate.io"
},
mentions: []
}
statuses.push(status);
}
for(var i = 0; i < statuses.length; i++) {
var status = statuses[i];
if (status.type == "https://tent.io/types/post/status/v0.1.0") {
var new_node = _this.getStatusDOMElement(status);
_this.body.appendChild(new_node);
}
}
}, null, false);
}
Search.prototype.searchFor = function(query) {
this.doSearch(query);
bungloo.sidebar.onSearch();
}
return Search;
});

View file

@ -0,0 +1,215 @@
define([
"helper/HostApp",
"helper/Paths",
"helper/Cache"
],
function(HostApp, Paths, Cache) {
function Sidebar() {
this.cache = new Cache();
this.body = document.createElement("ul");
this.body.class = "sidebar";
var _this = this;
this.menu = {};
this.menu.user = this.createItem("User", function() { _this.onEntity(); return false; }, "img/sidebar/user.png", "img/sidebar/user.png");
this.menu.timeline = this.createItem("Timeline", function() { _this.onTimeline(); return false; }, "img/sidebar/timeline.png", "img/sidebar/timeline_active.png", true);
this.menu.mentions = this.createItem("Mentions", function() { _this.onMentions(); return false; }, "img/sidebar/mentions.png", "img/sidebar/mentions_active.png");
this.menu.conversation = this.createItem("Conversation", function() { _this.onConversation(); return false; }, "img/sidebar/conversation.png", "img/sidebar/conversation_active.png");
this.menu.entityProfile = this.createItem("Profile", function() { _this.onEntityProfile(); return false; }, "img/sidebar/profile.png", "img/sidebar/profile_active.png");
this.menu.search = this.createItem("Search", function() { _this.onSearch(); return false; }, "img/sidebar/search.png", "img/sidebar/search_active.png")
this.body.appendChild(this.menu.user);
this.body.appendChild(this.menu.timeline);
this.body.appendChild(this.menu.mentions);
this.body.appendChild(this.menu.conversation);
this.body.appendChild(this.menu.entityProfile);
this.body.appendChild(this.menu.search);
this.unreadMentionsSpan = document.createElement("span");
this.unreadMentionsSpan.className = "unread_mentions";
this.menu.mentions.appendChild(this.unreadMentionsSpan);
this.setUnreadMentions(0);
document.getElementById("sidebar").appendChild(this.body);
this.setEntityAvatar();
}
Sidebar.prototype.createItem = function(name, callback, src_inactive, src_active, active) {
var li = document.createElement("li");
li.className = "sidebar-" + name.toLowerCase();
li.active = false;
li.title = name;
li.name = name;
var a = document.createElement("a");
a.href = "#";
a.onclick = callback;
var img = document.createElement("img");
img.src = active ? src_active : src_inactive;
img.src_inactive = src_inactive;
img.src_active = src_active;
img.alt = name;
a.appendChild(img);
li.appendChild(a);
return li;
}
Sidebar.prototype.setEntityAvatar = function() {
var entity = HostApp.stringForKey("entity");
this.menu.user.title = entity;
var img = this.menu.user.getElementsByTagName("img")[0];
var _this = this;
var profile_callback = function(p) {
var basic = p["https://tent.io/types/info/basic/v0.1.0"];
if (p && basic) {
if(basic.name) {
_this.menu.user.title = basic.name;
}
if(basic.avatar_url) {
img.onerror = function() {
img.src = "img/sidebar/user.png";
img.src_inactive = img.src;
img.src_active = img.src;
}
img.src = basic.avatar_url;
img.src_inactive = basic.avatar_url;
img.src_active = basic.avatar_url;
}
}
}
var p = this.cache.profiles.getItem(entity);
if (p && p != "null") {
profile_callback(p);
} else {
Paths.findProfileURL(entity, function(profile_url) {
if (profile_url) {
Paths.getURL(profile_url, "GET", function(resp) {
var p = JSON.parse(resp.responseText);
if (p && p != "null") {
_this.cache.profiles.setItem(entity, p);
profile_callback(p);
}
}, null, false); // do not send auth-headers
}
});
}
}
Sidebar.prototype.removeEntityAvatar = function() {
var img = this.menu.user.getElementsByTagName("img")[0];
img.src = "img/sidebar/user.png";
img.src_inactive = img.src;
img.src_active = img.src;
}
Sidebar.prototype.showContentFor = function(active_part, active_li) {
// Show active content
var parts = [
bungloo.timeline,
bungloo.mentions,
bungloo.conversation,
bungloo.entityProfile,
bungloo.search
];
for (var i = 0; i < parts.length; i++) {
if (parts[i] != active_part && parts[i] != null) {
parts[i].hide();
}
}
active_part.show();
// Show active icon
for(var li in this.menu) {
if (this.menu[li] != active_part) {
var img = this.menu[li].getElementsByTagName("img")[0];
img.src = img.src_inactive;
}
}
var img = active_li.getElementsByTagName("img")[0];
img.src = img.src_active;
}
Sidebar.prototype.setUnreadMentions = function(count) {
this.unreadMentionsSpan.innerHTML = count == 0 ? "" : count;
if (count > 0) {
$(this.unreadMentionsSpan).show();
} else {
$(this.unreadMentionsSpan).hide();
}
}
Sidebar.prototype.onEntity = function() {
bungloo.entityProfile.showProfileForEntity();
this.onEntityProfile();
}
Sidebar.prototype.onTimeline = function() {
this.showContentFor(bungloo.timeline, this.menu.timeline);
}
Sidebar.prototype.onMentions = function() {
this.showContentFor(bungloo.mentions, this.menu.mentions);
bungloo.mentions.setAllMentionsRead();
}
Sidebar.prototype.onConversation = function() {
this.showContentFor(bungloo.conversation, this.menu.conversation);
}
Sidebar.prototype.onEntityProfile = function() {
this.showContentFor(bungloo.entityProfile, this.menu.entityProfile);
}
Sidebar.prototype.onSearch = function() {
this.showContentFor(bungloo.search, this.menu.search);
}
Sidebar.prototype.logout = function() {
this.removeEntityAvatar();
bungloo.timeline.logout();
bungloo.mentions.logout();
bungloo.conversation.logout();
bungloo.entityProfile.logout();
bungloo.search.logout();
document.getElementById("sidebar").innerHTML = "";
document.getElementById("content").innerHTML = "";
}
return Sidebar;
});

View file

@ -22,7 +22,7 @@ function(Core, Paths, HostApp, URI) {
this.body = document.createElement("ol"); this.body = document.createElement("ol");
this.body.className = this.action; this.body.className = this.action;
document.body.appendChild(this.body); document.getElementById("content").appendChild(this.body);
var _this = this; var _this = this;
this.reloadIntervall = setInterval(function() { _this.getNewData() }, this.timeout); this.reloadIntervall = setInterval(function() { _this.getNewData() }, this.timeout);
@ -32,6 +32,14 @@ function(Core, Paths, HostApp, URI) {
Timeline.prototype = Object.create(Core.prototype); Timeline.prototype = Object.create(Core.prototype);
Timeline.prototype.show = function() {
Core.prototype.show.call(this, this.body);
}
Timeline.prototype.hide = function() {
Core.prototype.hide.call(this, this.body);
}
Timeline.prototype.newStatus = function(statuses) { Timeline.prototype.newStatus = function(statuses) {

View file

@ -11,6 +11,22 @@ function(jQuery, Paths, URI, HostApp, Cache) {
function Core() { function Core() {
this.cache = new Cache(); this.cache = new Cache();
this.saveScrollTop = 0;
}
Core.prototype.show = function(container) {
if (container) {
$(container).show();
document.body.scrollTop = this.saveScrollTop;
}
}
Core.prototype.hide = function(container) {
if (container && $(container).is(":visible")) {
this.saveScrollTop = document.body.scrollTop;
$(container).hide();
}
} }
Core.prototype.getTemplate = function() { Core.prototype.getTemplate = function() {
@ -106,7 +122,6 @@ function(jQuery, Paths, URI, HostApp, Cache) {
head.appendChild(reposted_by) head.appendChild(reposted_by)
var message = document.createElement("p"); var message = document.createElement("p");
message.className = "message"; message.className = "message";
data.appendChild(message); data.appendChild(message);
@ -261,11 +276,19 @@ function(jQuery, Paths, URI, HostApp, Cache) {
text = text.escapeHTML().replace(/\n/g, "<br>"); text = text.escapeHTML().replace(/\n/g, "<br>");
var entities = [status.entity]; var entities = [status.entity];
status.mentions.map(function (mention) { if (status.mentions) {
entities.push(mention.entity) status.mentions.map(function (mention) {
}); entities.push(mention.entity)
});
}
template.message.innerHTML = this.replaceURLWithHTMLLinks(text, entities, template.message); template.message.innerHTML = this.replaceURLWithHTMLLinks(text, entities, template.message);
// adding show search on click hash
$(template.message).find("a.hash").click(function(e) {
bungloo.search.searchFor("#" + e.target.innerHTML);
return false;
});
if (status.type == "https://tent.io/types/post/photo/v0.1.0") { if (status.type == "https://tent.io/types/post/photo/v0.1.0") {
@ -610,7 +633,7 @@ function(jQuery, Paths, URI, HostApp, Cache) {
Core.prototype.logout = function() { Core.prototype.logout = function() {
this.body.innerHTML = ""; if(this.body) this.body.innerHTML = "";
} }
@ -793,7 +816,7 @@ function(jQuery, Paths, URI, HostApp, Cache) {
var hash = /(^|\s)(#)(\w+)/ig; var hash = /(^|\s)(#)(\w+)/ig;
return URI.withinString(text, callback).replace(hash, "$1$2<a href='https://skate.io/search?q=%23$3'>$3</a>"); return URI.withinString(text, callback).replace(hash, "$1$2<a class='hash' href='https://skate.io/search?q=%23$3'>$3</a>");
} }
Core.prototype.parseForMedia = function(text, images) { Core.prototype.parseForMedia = function(text, images) {

Binary file not shown.

Binary file not shown.

View file

@ -1,5 +1,14 @@
var bungloo_instance;
var bungloo_cache = {}; var bungloo = {
oauth: null,
sidebar: null,
timeline: null,
mentions: null,
entityProfile: null,
conversation: null,
search: null,
cache: {}
};
requirejs.config({ requirejs.config({
baseUrl: 'scripts' baseUrl: 'scripts'
@ -8,43 +17,32 @@ requirejs.config({
function start(view) { function start(view) {
if (view == "oauth") { if (view == "oauth") {
require(["controller/Oauth"], function(Oauth) { require(["controller/Oauth"], function(Oauth) {
bungloo_instance = new Oauth(); bungloo.oauth = new Oauth();
}); });
} else if (view == "timeline") { } else {
require(["controller/Timeline"], function(Timeline) {
bungloo_instance = new Timeline(); require([
"controller/Sidebar",
"controller/Timeline",
"controller/Mentions",
"controller/Profile",
"controller/Conversation",
"controller/Search"
}); ], function(Sidebar, Timeline, Mentions, Profile, Conversation, Search) {
} else if (view == "mentions") { bungloo.sidebar = new Sidebar();
bungloo.timeline = new Timeline();
require(["controller/Mentions"], function(Mentions) { bungloo.mentions = new Mentions();
bungloo.entityProfile = new Profile();
bungloo_instance = new Mentions(); bungloo.conversation = new Conversation();
bungloo.search = new Search();
});
} else if (view == "profile") {
require(["controller/Profile"], function(Profile) {
bungloo_instance = new Profile();
});
} else if (view == "follow") {
} else if (view == "conversation") {
require(["controller/Conversation"], function(Conversation) {
bungloo_instance = new Conversation();
}); });

11491
images/bungloo.xpm Normal file

File diff suppressed because it is too large Load diff