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()
def init_web_views(self):
self.timeline = Windows.Timeline(self)
self.mentions = Windows.Timeline(self, "mentions", "Mentions")
if not hasattr(self, "timeline"):
self.timeline = Windows.Timeline(self)
else:
self.timeline.evaluateJavaScript("start('timeline')")
self.timeline.show()
self.conversation = Windows.Timeline(self, "conversation", "Conversation")
self.profile = Windows.Timeline(self, "profile", "Profile")
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):
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):
@ -126,12 +145,8 @@ class Controller(QtCore.QObject):
@QtCore.pyqtSlot(int)
def unreadMentions(self, count):
i = int(count)
if i > 0:
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;")
script = "bungloo.sidebar.setUnreadMentions({});".format(int(count))
self.app.timeline.evaluateJavaScript(script)
@QtCore.pyqtSlot(str, str, str, str)
def notificateUserAboutMentionFromNameWithPostIdAndEntity(self, text, name, post_id, entity):
@ -188,28 +203,29 @@ class Controller(QtCore.QObject):
if message.isPrivate:
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)
@QtCore.pyqtSlot(str, str)
def showConversationForPostIdandEntity(self, postId, entity):
func = "bungloo_instance.showStatus('{}', '{}');".format(postId, entity)
self.app.conversation.evaluateJavaScript(func)
self.app.conversation.show()
func = "bungloo.sidebar.onConversation(); bungloo.conversation.showStatus('{}', '{}');".format(postId, entity)
self.app.timeline.evaluateJavaScript(func)
self.app.timeline.show()
@QtCore.pyqtSlot(str)
def showProfileForEntity(self, entity):
func = "bungloo_instance.showProfileForEntity('{}');".format(entity)
self.app.profile.evaluateJavaScript(func)
self.app.profile.show()
func = "bungloo.sidebar.onEntityProfile(); bungloo.entityProfile.showProfileForEntity('{}');".format(entity)
self.app.timeline.evaluateJavaScript(func)
@QtCore.pyqtSlot(str, str)
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.mentions.evaluateJavaScript(func)
self.app.conversation.evaluateJavaScript(func)
self.app.profile.evaluateJavaScript(func)
@QtCore.pyqtSlot(str)
def authentificationDidNotSucceed(self, errorMessage):
@ -232,23 +248,23 @@ class Console(QtCore.QObject):
@QtCore.pyqtSlot(str)
def log(self, string):
print "<js>: " + string
print "<js>: " + unicode(string)
@QtCore.pyqtSlot(str)
def error(self, string):
print "<js ERROR>: " + string
print "<js ERROR>: " + unicode(string)
@QtCore.pyqtSlot(str)
def warn(self, string):
print "<js WARN>: " + string
print "<js WARN>: " + unicode(string)
@QtCore.pyqtSlot(str)
def notice(self, string):
print "<js NOTICE>: " + string
print "<js NOTICE>: " + unicode(string)
@QtCore.pyqtSlot(str)
def debug(self, string):
print "<js DEBUG>: " + string
print "<js DEBUG>: " + unicode(string)
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.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):
self.page().settings().setAttribute(QtWebKit.QWebSettings.LocalContentCanAccessRemoteUrls, True)
self.page().settings().setAttribute(QtWebKit.QWebSettings.LocalStorageEnabled, True)

View file

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

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(
name = "bungloo",
version = "1.2.0",
version = "{VERSION}",
author = "Jeena Paradies",
author_email = "spam@jeenaparadies.net",
url = "http://jabs.nu/bungloo",

View file

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

View file

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

View file

@ -17,7 +17,7 @@
@synthesize loginViewWindow;
@synthesize loginEntityTextField;
@synthesize loginActivityIndicator;
@synthesize timelineView, timelineViewWindow, mentionsView, mentionsViewWindow, conversationView, conversationViewWindow, profileView, profileViewWindow;
@synthesize timelineView, timelineViewWindow;
@synthesize globalHotkeyMenuItem, viewDelegate;
@synthesize logoLayer;
@synthesize oauthView, accessToken;
@ -25,7 +25,6 @@
- (void)awakeFromNib
{
[timelineViewWindow setExcludedFromWindowsMenu:YES];
[mentionsViewWindow setExcludedFromWindowsMenu:YES];
[self initHotKeys];
@ -70,7 +69,6 @@
if (forceLogin || ![accessToken stringForKey:@"user_access_token"] || ![accessToken secret]) {
[timelineViewWindow performClose:self];
[mentionsViewWindow performClose:self];
[self.loginViewWindow makeKeyAndOrderFront:self];
[self initOauth];
} else {
@ -125,47 +123,11 @@
[timelineView setPolicyDelegate:viewDelegate];
[timelineView setUIDelegate:viewDelegate];
[[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
{
[timelineView stringByEvaluatingJavaScriptFromString:@"start('timeline')"];
[mentionsView stringByEvaluatingJavaScriptFromString:@"start('mentions')"];
[conversationView stringByEvaluatingJavaScriptFromString:@"start('conversation')"];
[profileView stringByEvaluatingJavaScriptFromString:@"start('profile')"];
}
}
@ -312,7 +274,7 @@
if (range.length > 0)
{
[oauthView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"bungloo_instance.requestAccessToken('%@')", aString]];
[oauthView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"bungloo.oauth.requestAccessToken('%@')", aString]];
}
else
{
@ -353,7 +315,7 @@
isPrivate = @"true";
}
NSString *func = [NSString stringWithFormat:@"bungloo_instance.sendNewMessage(\"%@\", \"%@\", \"%@\", %@, %@, %@)",
NSString *func = [NSString stringWithFormat:@"bungloo.timeline.sendNewMessage(\"%@\", \"%@\", \"%@\", %@, %@, %@)",
text,
post.inReplyTostatusId,
post.inReplyToEntity,
@ -378,17 +340,17 @@
- (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]];
}
else
{
[timelineViewWindow setTitle:[NSString stringWithFormat:@"Bungloo"]];
[[[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
@ -414,35 +376,21 @@
{
NSString *entity = [self.showProfileTextField stringValue];
if ([entity rangeOfString:@"."].location != NSNotFound && ([entity hasPrefix:@"http://"] || [entity hasPrefix:@"https://"])) {
NSString *func = [NSString stringWithFormat:@"bungloo_instance.showProfileForEntity('%@')", entity];
[profileView stringByEvaluatingJavaScriptFromString:func];
[profileViewWindow makeKeyAndOrderFront:self];
[openProfileWindow performClose:self];
NSString *func = [NSString stringWithFormat:@"bungloo.sidebar.onEntityProfile(); bungloo.entityProfile.showProfileForEntity('%@')", entity];
[timelineView stringByEvaluatingJavaScriptFromString:func];
}
}
- (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];
[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
{
[loginActivityIndicator stopAnimation:self];
@ -456,58 +404,47 @@
if ([[loginEntityTextField stringValue] length] > 0) {
[[loginEntityTextField window] makeFirstResponder:nil];
[loginActivityIndicator startAnimation:self];
[oauthView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.authenticate();"];
[oauthView stringByEvaluatingJavaScriptFromString:@"bungloo.oauth.authenticate();"];
}
}
- (IBAction)logout:(id)sender
{
[oauthView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.logout();"];
[oauthView stringByEvaluatingJavaScriptFromString:@"bungloo.oauth.logout();"];
[timelineViewWindow performClose:self];
[mentionsViewWindow performClose:self];
[conversationViewWindow performClose:self];
[profileViewWindow performClose:self];
[self.loginViewWindow makeKeyAndOrderFront:self];
[timelineView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.logout();"];
[mentionsView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.logout();"];
[timelineView stringByEvaluatingJavaScriptFromString:@"bungloo.sidebar.logout();"];
}
// Mentions window has been visible
- (void)windowDidBecomeKey:(NSNotification *)notification
{
if ([notification object] == mentionsViewWindow)
{
//[self unreadMentions:0];
[mentionsView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.setAllMentionsRead();"];
}
}
- (void)getPostUpdates:(id)sender
{
[timelineView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.getNewData(true)"];
[mentionsView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.getNewData(true)"];
[timelineView stringByEvaluatingJavaScriptFromString:@"bungloo.timeline.getNewData(true)"];
[timelineView stringByEvaluatingJavaScriptFromString:@"bungloo.mentions.getNewData(true)"];
}
- (IBAction)showConversationForPostId:(NSString *)postId andEntity:(NSString *)entity
{
NSString *js = [NSString stringWithFormat:@"bungloo_instance.showStatus('%@', '%@');", postId, entity];
[conversationView stringByEvaluatingJavaScriptFromString:js];
[conversationViewWindow makeKeyAndOrderFront:self];
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
NSString *js = [NSString stringWithFormat:@"bungloo.sidebar.onConversation(); bungloo.conversation.showStatus('%@', '%@');", postId, entity];
[timelineView stringByEvaluatingJavaScriptFromString:js];
}
- (IBAction)clearCache:(id)sender
{
[timelineView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.cache.clear()"];
[timelineView stringByEvaluatingJavaScriptFromString:@"bungloo.timeline.cache.clear()"];
}
- (IBAction)showProfileForEntity:(NSString *)entity
{
NSString *js = [NSString stringWithFormat:@"bungloo_instance.showProfileForEntity('%@');", entity];
[profileView stringByEvaluatingJavaScriptFromString:js];
[profileViewWindow makeKeyAndOrderFront:self];
NSString *js = [NSString stringWithFormat:@"bungloo.sidebar.onEntityProfile(); bungloo.entityProfile.showProfileForEntity('%@');", entity];
[timelineView stringByEvaluatingJavaScriptFromString:js];
}
- (void)growlNotificationWasClicked:(id)clickContext
@ -518,8 +455,8 @@
[self showConversationForPostId:postId andEntity:entity];
NSString *js = [NSString stringWithFormat:@"bungloo_instance.mentionRead('%@', '%@');", postId, entity];
[mentionsView stringByEvaluatingJavaScriptFromString:js];
NSString *js = [NSString stringWithFormat:@"bungloo.sidebar.onMentions(); bungloo.mentions.mentionRead('%@', '%@');", postId, entity];
[timelineView stringByEvaluatingJavaScriptFromString:js];
}
- (NSString *) applicationNameForGrowl

View file

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

View file

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

View file

@ -11,17 +11,14 @@
@implementation ViewDelegate
@synthesize timelineView, mentionsView, conversationView, profileView, oauthView;
@synthesize timelineView, oauthView;
- (void)webView:(WebView *)sender addMessageToConsole:(NSDictionary *)message {
if (![message isKindOfClass:[NSDictionary class]]) return;
NSString *viewName = @"TimelineView";
if (sender == mentionsView) viewName = @"MentionsView";
if (sender == conversationView) viewName = @"ConversationView";
if (sender == oauthView) viewName = @"OauthView";
if (sender == profileView) viewName = @"ProfileView";
NSLog(@"js<%@>: %@:%@: %@",
viewName,
@ -33,8 +30,6 @@
- (void)webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame {
NSString *viewName = @"TimelineView";
if (sender == mentionsView) viewName = @"MentionsView";
if (sender == conversationView) viewName = @"ConversationView";
if (sender == oauthView) viewName = @"OauthView";
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 {
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 ([frames indexOfObject:frame] != NSNotFound) {
@ -85,25 +80,9 @@
[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 {
NSString *action = @"timeline";
NSString *delay = @"1";
if (sender == mentionsView) {
action = @"mentions";
delay = @"1000";
}
[sender stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"function HostAppGo() { start('%@') }", action]];
[sender stringByEvaluatingJavaScriptFromString:@"function HostAppGo() { start('timeline') }"];
}
}
@ -126,8 +105,7 @@
}
- (void)reload:(id)sender {
[timelineView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.getNewData();"];
[mentionsView stringByEvaluatingJavaScriptFromString:@"bungloo_instance.getNewData();"];
[timelineView stringByEvaluatingJavaScriptFromString:@"bungloo.timeline.getNewData();"];
}
- (NSString *)pluginURL

View file

@ -16,6 +16,53 @@ a {
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 {
list-style-type: none;
margin: 0;
@ -39,37 +86,37 @@ ol li, .error, header.profile {
color: red;
}
body > ol > li {
#content ol > li {
}
body > ol > li:first-child {
#content ol > li:first-child {
border-top: 0;
}
body > ol > li:nth-child(odd), .error, header.profile {
#content ol > li:nth-child(odd), .error, header.profile {
background: #fafafa;
}
body > ol > li:nth-child(even) {
#content ol > li:nth-child(even) {
background: #f2f2f2;
}
body > ol > li:hover {
#content ol > li:hover {
background: #dedede;
}
body > ol > li.highlighteffect {
#content ol > li.highlighteffect {
background-color: #FFFBD0;
-webkit-transition: background-color 200ms linear;
}
body > ol > li.highlighteffect-after {
#content ol > li.highlighteffect-after {
-webkit-transition: background-color 1000ms linear;
}
body > ol > li:after, header.profile:after {
#content ol > li:after, header.profile:after {
content: ".";
display: block;
clear: both;
@ -189,7 +236,7 @@ li:hover .from {
li:first-child:hover .from {
top: auto;
bottom: -1.9em;
bottom: -1.8em;
z-index: 2;
-webkit-border-top-left-radius: 0;
-webkit-border-top-right-radius: 0;
@ -367,3 +414,14 @@ a.youtube:before {
iframe {
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>
</head>
<body>
<div id="sidebar">
</div>
<article id="content">
</article>
</body>
</html>

View file

@ -14,15 +14,23 @@ function(HostApp, Core, Paths, URI) {
this.action = "conversation";
document.body.innerHTML = "";
this.body = document.createElement("ol");
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.show = function() {
Core.prototype.show.call(this, this.body);
}
Conversation.prototype.hide = function() {
Core.prototype.hide.call(this, this.body);
}
Conversation.addStatus = function(status) {

View file

@ -2,10 +2,11 @@ define([
"helper/HostApp",
"controller/Timeline",
"lib/URI",
"helper/Paths"
"helper/Paths",
"helper/Core"
],
function(HostApp, Timeline, URI, Paths) {
function(HostApp, Timeline, URI, Paths, Core) {
function Mentions() {
@ -18,10 +19,20 @@ function(HostApp, Timeline, URI, Paths) {
this.action = "mentions";
this.body.className = this.action;
this.hide();
}
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) {
Timeline.prototype.newStatus.call(this, statuses);

View file

@ -14,13 +14,31 @@ function(HostApp, Core, Paths, URI) {
this.action = "profile";
document.body.innerHTML = "";
this.container = document.createElement("div");
document.getElementById("content").appendChild(this.container);
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.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) {
$(this.body).hide();
$(this.followingsBody).hide();
@ -30,6 +48,10 @@ function(HostApp, Core, Paths, URI) {
Profile.prototype.showProfileForEntity = function(entity) {
if (!entity) {
entity = HostApp.stringForKey("entity");
};
this.clear();
this.entity = entity;
this.following = null;
@ -46,8 +68,9 @@ function(HostApp, Core, Paths, URI) {
var _this = this;
var header = document.createElement("header");
header.className = "profile"
document.body.appendChild(header);
header.className = "profile";
this.container.appendChild(header);
this.profile_template = {
avatar: document.createElement("img"),
@ -139,15 +162,15 @@ function(HostApp, Core, Paths, URI) {
this.body = document.createElement("ol");
this.body.className = this.action;
document.body.appendChild(this.body);
this.container.appendChild(this.body);
this.followingsBody = document.createElement("ol");
this.followingsBody.className = this.action + " followings";
document.body.appendChild(this.followingsBody);
this.container.appendChild(this.followingsBody);
this.followersBody = document.createElement("ol");
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() {
var url = Paths.mkApiRootPath("/followings") + "/" + encodeURIComponent(this.entity);
var _this = this;
Paths.getURL(url, "GET", function(resp) {
if (resp.status >= 200 && resp.status < 400) {
var following = JSON.parse(resp.responseText);
_this.following_id = following.id
_this.setFollowingButton(true);
} else {
_this.setFollowingButton(false);
_this.following_id = null;
}
})
if(this.entity != HostApp.stringForKey("entity")) {
var url = Paths.mkApiRootPath("/followings") + "/" + encodeURIComponent(this.entity);
var _this = this;
Paths.getURL(url, "GET", function(resp) {
if (resp.status >= 200 && resp.status < 400) {
var following = JSON.parse(resp.responseText);
_this.following_id = following.id
_this.setFollowingButton(true);
} else {
_this.setFollowingButton(false);
_this.following_id = null;
}
})
} else {
this.setFollowingButton(false);
this.following_id = null;
}
}
Profile.prototype.showProfile = function(profile) {
@ -302,21 +330,25 @@ function(HostApp, Core, Paths, URI) {
_this.populate(_this.profile_template.followed, resp.responseText);
}, null, false);
Paths.getURL(URI(root_url + "/followers/" + encodeURIComponent(HostApp.stringForKey("entity"))).toString(), "GET", function(resp) {
if (resp.status == 200) {
_this.relationships.following_you = true;
}
_this.setRelationships();
if (this.entity != HostApp.stringForKey("entity")) {
Paths.getURL(URI(root_url + "/followers/" + encodeURIComponent(HostApp.stringForKey("entity"))).toString(), "GET", function(resp) {
if (resp.status == 200) {
_this.relationships.following_you = true;
}
_this.setRelationships();
}, null, false);
}, null, false);
Paths.getURL(URI(Paths.mkApiRootPath("/followings/" + encodeURIComponent(this.entity))), "GET", function(resp) {
if (resp.status == 200) {
_this.relationships.followed_by_you = true;
}
_this.setRelationships();
Paths.getURL(URI(Paths.mkApiRootPath("/followings/" + encodeURIComponent(this.entity))), "GET", function(resp) {
if (resp.status == 200) {
_this.relationships.followed_by_you = true;
}
_this.setRelationships();
});
});
} else {
this.setRelationships();
}
var url = URI(root_url + "/posts/count");
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.className = this.action;
document.body.appendChild(this.body);
document.getElementById("content").appendChild(this.body);
var _this = this;
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.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) {

View file

@ -11,6 +11,22 @@ function(jQuery, Paths, URI, HostApp, Cache) {
function Core() {
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() {
@ -106,7 +122,6 @@ function(jQuery, Paths, URI, HostApp, Cache) {
head.appendChild(reposted_by)
var message = document.createElement("p");
message.className = "message";
data.appendChild(message);
@ -261,12 +276,20 @@ function(jQuery, Paths, URI, HostApp, Cache) {
text = text.escapeHTML().replace(/\n/g, "<br>");
var entities = [status.entity];
status.mentions.map(function (mention) {
entities.push(mention.entity)
});
if (status.mentions) {
status.mentions.map(function (mention) {
entities.push(mention.entity)
});
}
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") {
for (var i = 0; i < status.attachments.length; i++) {
@ -610,7 +633,7 @@ function(jQuery, Paths, URI, HostApp, Cache) {
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;
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) {

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({
baseUrl: 'scripts'
@ -8,43 +17,32 @@ requirejs.config({
function start(view) {
if (view == "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") {
require(["controller/Mentions"], function(Mentions) {
bungloo_instance = new Mentions();
});
} 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();
bungloo.sidebar = new Sidebar();
bungloo.timeline = new Timeline();
bungloo.mentions = new Mentions();
bungloo.entityProfile = new Profile();
bungloo.conversation = new Conversation();
bungloo.search = new Search();
});

11491
images/bungloo.xpm Normal file

File diff suppressed because it is too large Load diff