Merge branch 'master' of github.com:jeena/Bungloo
This commit is contained in:
commit
d81400ce67
34 changed files with 278 additions and 77 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -4,4 +4,5 @@ dsa_priv.pem
|
||||||
*.pyc
|
*.pyc
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*~
|
*~
|
||||||
Linux/build/
|
Linux/dist
|
||||||
|
Windows/bungloo
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
VERSION="1.3.0"
|
VERSION="1.3.0"
|
||||||
DEPLOYPATH="bungloo-${VERSION}"
|
DEPLOYPATH="bungloo-${VERSION}"
|
||||||
LINUXPATH=".."
|
QTPATH="../Qt"
|
||||||
SHAREDPATH="../.."
|
SHAREDPATH=".."
|
||||||
DISTPATH=dist
|
DISTPATH=dist
|
||||||
|
|
||||||
rm -rf $DEPLOYPATH
|
rm -rf $DEPLOYPATH
|
||||||
|
@ -14,8 +14,8 @@ mkdir -p $DEPLOYPATH/bin
|
||||||
mkdir -p $DEPLOYPATH/bungloo
|
mkdir -p $DEPLOYPATH/bungloo
|
||||||
touch $DEPLOYPATH/bungloo/__init__.py
|
touch $DEPLOYPATH/bungloo/__init__.py
|
||||||
|
|
||||||
cp $LINUXPATH/Bungloo.py $DEPLOYPATH/bin/bungloo
|
cp $QTPATH/Bungloo.py $DEPLOYPATH/bin/bungloo
|
||||||
cp $LINUXPATH/Helper.py $LINUXPATH/Windows.py $DEPLOYPATH/bungloo
|
cp $QTPATH/Helper.py $QTPATH/Windows.py $DEPLOYPATH/bungloo
|
||||||
cat setup.py.exmp | sed -e "s/{VERSION}/${VERSION}/g" > $DEPLOYPATH/setup.py
|
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 Makefile.exmp | sed -e "s/{VERSION}/${VERSION}/g" > $DEPLOYPATH/Makefile
|
||||||
cat bungloo.desktop.exmp | sed -e "s/{VERSION}/${VERSION}/g" > $DEPLOYPATH/bungloo.desktop
|
cat bungloo.desktop.exmp | sed -e "s/{VERSION}/${VERSION}/g" > $DEPLOYPATH/bungloo.desktop
|
|
@ -1,11 +1,12 @@
|
||||||
#!/usr/bin/env python2
|
#!/usr/bin/env python2
|
||||||
|
|
||||||
import os, sys, pickle, subprocess, shutil
|
import os, sys, pickle, subprocess, shutil
|
||||||
from PyQt4 import QtCore, QtGui, QtWebKit
|
from PyQt4 import QtCore, QtGui, QtWebKit, QtNetwork
|
||||||
|
|
||||||
RUNNING_LOCAL = os.path.basename(__file__) == "Bungloo.py"
|
RUNNING_LOCAL = os.path.basename(sys.argv[0]) == "Bungloo.py"
|
||||||
|
RUNNING_ON_WINDOWS = os.name == "nt"
|
||||||
|
|
||||||
if RUNNING_LOCAL:
|
if RUNNING_LOCAL or RUNNING_ON_WINDOWS:
|
||||||
import Windows, Helper
|
import Windows, Helper
|
||||||
else:
|
else:
|
||||||
from bungloo import Windows, Helper
|
from bungloo import Windows, Helper
|
||||||
|
@ -13,6 +14,11 @@ else:
|
||||||
class Bungloo:
|
class Bungloo:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
||||||
|
sslConfig = QtNetwork.QSslConfiguration.defaultConfiguration()
|
||||||
|
sslConfig.setProtocol(QtNetwork.QSsl.TlsV1)
|
||||||
|
QtNetwork.QSslConfiguration.setDefaultConfiguration(sslConfig)
|
||||||
|
|
||||||
self.app = QtGui.QApplication(sys.argv)
|
self.app = QtGui.QApplication(sys.argv)
|
||||||
self.new_message_windows = []
|
self.new_message_windows = []
|
||||||
self.controller = Controller(self)
|
self.controller = Controller(self)
|
||||||
|
@ -30,7 +36,7 @@ class Bungloo:
|
||||||
|
|
||||||
def resources_path(self):
|
def resources_path(self):
|
||||||
if RUNNING_LOCAL:
|
if RUNNING_LOCAL:
|
||||||
return os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
return os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '..'))
|
||||||
else:
|
else:
|
||||||
return Helper.Helper.get_resource_path()
|
return Helper.Helper.get_resource_path()
|
||||||
|
|
||||||
|
@ -83,7 +89,10 @@ class Bungloo:
|
||||||
self.oauth_implementation.log_out()
|
self.oauth_implementation.log_out()
|
||||||
self.timeline.hide()
|
self.timeline.hide()
|
||||||
self.preferences.show()
|
self.preferences.show()
|
||||||
self.timeline.evaluateJavaScript("bungloo.sidebar.logout()")
|
self.timeline.evaluateJavaScript("bungloo.sidebar.logout();")
|
||||||
|
|
||||||
|
def next_show(self):
|
||||||
|
self.timeline.evaluateJavaScript("bungloo.sidebar.showContentForNext();")
|
||||||
|
|
||||||
|
|
||||||
class Controller(QtCore.QObject):
|
class Controller(QtCore.QObject):
|
|
@ -2,17 +2,17 @@ from PyQt4 import QtCore, QtGui, QtWebKit
|
||||||
|
|
||||||
from PyQt4.QtCore import QTimer, QVariant, SIGNAL
|
from PyQt4.QtCore import QTimer, QVariant, SIGNAL
|
||||||
from PyQt4.QtGui import *
|
from PyQt4.QtGui import *
|
||||||
from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
|
from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply, QSslSocket
|
||||||
from PyQt4.QtWebKit import QWebView
|
from PyQt4.QtWebKit import QWebView
|
||||||
|
|
||||||
import os
|
import os, sys
|
||||||
|
|
||||||
import array
|
import array
|
||||||
|
|
||||||
class Helper:
|
class Helper:
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_resource_path(cls):
|
def get_resource_path(cls):
|
||||||
return os.path.dirname(__file__)
|
return os.path.dirname(sys.argv[0])
|
||||||
|
|
||||||
class WebPage(QtWebKit.QWebPage):
|
class WebPage(QtWebKit.QWebPage):
|
||||||
def __init__(self, parent=0, app=None):
|
def __init__(self, parent=0, app=None):
|
||||||
|
@ -43,6 +43,8 @@ class WebViewCreator(QtWebKit.QWebView):
|
||||||
self.customContextMenuRequested.connect(self.context_menu_requested)
|
self.customContextMenuRequested.connect(self.context_menu_requested)
|
||||||
self.actions = []
|
self.actions = []
|
||||||
|
|
||||||
|
self.page().networkAccessManager().sslErrors.connect(lambda reply, errors: self.handleSslErrors(reply, errors))
|
||||||
|
|
||||||
def copy_link():
|
def copy_link():
|
||||||
self.page().triggerAction(QtWebKit.QWebPage.CopyLinkToClipboard)
|
self.page().triggerAction(QtWebKit.QWebPage.CopyLinkToClipboard)
|
||||||
self.action_copy_link = QtGui.QAction('Copy Lin&k', self, triggered=copy_link)
|
self.action_copy_link = QtGui.QAction('Copy Lin&k', self, triggered=copy_link)
|
||||||
|
@ -85,7 +87,10 @@ class WebViewCreator(QtWebKit.QWebView):
|
||||||
def load_finished(self, ok, callback=None):
|
def load_finished(self, ok, callback=None):
|
||||||
frame = self.page().mainFrame()
|
frame = self.page().mainFrame()
|
||||||
if self.is_local:
|
if self.is_local:
|
||||||
frame.evaluateJavaScript("var OS_TYPE = 'linux';")
|
os_type = "linux"
|
||||||
|
if os.name == "nt":
|
||||||
|
os_type = "windows"
|
||||||
|
frame.evaluateJavaScript("var OS_TYPE = '" + os_type + "';")
|
||||||
|
|
||||||
js_plugin_path = os.path.expanduser('~/.config/bungloo/Plugin.js')
|
js_plugin_path = os.path.expanduser('~/.config/bungloo/Plugin.js')
|
||||||
if os.access(js_plugin_path, os.R_OK):
|
if os.access(js_plugin_path, os.R_OK):
|
||||||
|
@ -100,6 +105,12 @@ class WebViewCreator(QtWebKit.QWebView):
|
||||||
if callback:
|
if callback:
|
||||||
callback(ok)
|
callback(ok)
|
||||||
|
|
||||||
|
def handleSslErrors(self, reply, errors):
|
||||||
|
if os.name == "nt": # ignore SSL errors on Windows (yes a uggly workaround, don't know how to fix it yet)
|
||||||
|
for error in errors:
|
||||||
|
print error.errorString()
|
||||||
|
reply.ignoreSslErrors(errors)
|
||||||
|
|
||||||
|
|
||||||
class NetworkAccessManager(QNetworkAccessManager):
|
class NetworkAccessManager(QNetworkAccessManager):
|
||||||
|
|
||||||
|
@ -113,6 +124,7 @@ class NetworkAccessManager(QNetworkAccessManager):
|
||||||
self.setCookieJar(old_manager.cookieJar())
|
self.setCookieJar(old_manager.cookieJar())
|
||||||
self.setProxy(old_manager.proxy())
|
self.setProxy(old_manager.proxy())
|
||||||
self.setProxyFactory(old_manager.proxyFactory())
|
self.setProxyFactory(old_manager.proxyFactory())
|
||||||
|
self.sslErrors.connect(lambda reply, errors: old_manager.sslErrors)
|
||||||
|
|
||||||
def createRequest(self, operation, request, data):
|
def createRequest(self, operation, request, data):
|
||||||
if request.url().scheme() != "bungloo":
|
if request.url().scheme() != "bungloo":
|
|
@ -1,5 +1,5 @@
|
||||||
from PyQt4 import QtCore, QtGui, QtWebKit
|
from PyQt4 import QtCore, QtGui, QtWebKit
|
||||||
import Helper, urllib, urllib2
|
import Helper, urllib, urllib2, os
|
||||||
|
|
||||||
class Preferences:
|
class Preferences:
|
||||||
|
|
||||||
|
@ -154,12 +154,19 @@ class Timeline:
|
||||||
searchAction.setStatusTip("Show Search")
|
searchAction.setStatusTip("Show Search")
|
||||||
searchAction.triggered.connect(self.app.search_show)
|
searchAction.triggered.connect(self.app.search_show)
|
||||||
|
|
||||||
|
nextAction = QtGui.QAction("&Next View", self.window)
|
||||||
|
nextAction.setShortcut("Ctrl+6")
|
||||||
|
nextAction.setStatusTip("Show Next")
|
||||||
|
nextAction.triggered.connect(self.app.next_show)
|
||||||
|
|
||||||
windowMenu = menubar.addMenu("&View")
|
windowMenu = menubar.addMenu("&View")
|
||||||
windowMenu.addAction(timelineAction)
|
windowMenu.addAction(timelineAction)
|
||||||
windowMenu.addAction(mentionsAction)
|
windowMenu.addAction(mentionsAction)
|
||||||
windowMenu.addAction(conversationAction)
|
windowMenu.addAction(conversationAction)
|
||||||
windowMenu.addAction(profileAction)
|
windowMenu.addAction(profileAction)
|
||||||
windowMenu.addAction(searchAction)
|
windowMenu.addAction(searchAction)
|
||||||
|
windowMenu.addSeparator()
|
||||||
|
windowMenu.addAction(nextAction)
|
||||||
|
|
||||||
aboutAction = QtGui.QAction("&About Bungloo", self.window)
|
aboutAction = QtGui.QAction("&About Bungloo", self.window)
|
||||||
aboutAction.setStatusTip("Open about page in Webbrowser")
|
aboutAction.setStatusTip("Open about page in Webbrowser")
|
||||||
|
@ -224,8 +231,10 @@ class Oauth:
|
||||||
old_manager = self.auth_view.page().networkAccessManager()
|
old_manager = self.auth_view.page().networkAccessManager()
|
||||||
new_manager = Helper.NetworkAccessManager(old_manager, self.bungloo_callback)
|
new_manager = Helper.NetworkAccessManager(old_manager, self.bungloo_callback)
|
||||||
new_manager.authenticationRequired.connect(self.authentication_required)
|
new_manager.authenticationRequired.connect(self.authentication_required)
|
||||||
|
new_manager.sslErrors.connect(lambda reply, errors: self.handleSslErrors(reply, errors))
|
||||||
self.auth_view.page().setNetworkAccessManager(new_manager)
|
self.auth_view.page().setNetworkAccessManager(new_manager)
|
||||||
self.auth_view.show()
|
self.auth_view.show()
|
||||||
|
|
||||||
self.auth_view.load_url(url)
|
self.auth_view.load_url(url)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -250,6 +259,13 @@ class Oauth:
|
||||||
if hasattr(self, "auth_view"):
|
if hasattr(self, "auth_view"):
|
||||||
self.auth_view.hide()
|
self.auth_view.hide()
|
||||||
|
|
||||||
|
def handleSslErrors(self, reply, errors):
|
||||||
|
if os.name == "nt": # ignore SSL errors on Windows (yes a uggly workaround, don't know how to fix it yet)
|
||||||
|
for error in errors:
|
||||||
|
print error.errorString()
|
||||||
|
reply.ignoreSslErrors(errors)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Login(QtGui.QDialog):
|
class Login(QtGui.QDialog):
|
||||||
def __init__(self):
|
def __init__(self):
|
|
@ -14,7 +14,7 @@ a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: #00317a;
|
color: #00317a;
|
||||||
outline: 0;
|
outline: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#sidebar {
|
#sidebar {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
@ -214,37 +214,39 @@ p {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
li .from {
|
|
||||||
position: absolute;
|
|
||||||
top: -1.8em;
|
|
||||||
right: 10px;
|
|
||||||
display: none;
|
|
||||||
padding: 0.3em 0.9em;
|
|
||||||
-webkit-border-top-left-radius: 8px;
|
|
||||||
-webkit-border-top-right-radius: 8px;
|
|
||||||
-webkit-box-shadow: 0 -2px 2px rgba(0, 0, 0, 0.1);
|
|
||||||
border: 1px solid white;
|
|
||||||
border-bottom: 0;
|
|
||||||
background: #ddd;
|
|
||||||
font-size: 0.9em;
|
|
||||||
}
|
|
||||||
|
|
||||||
li:hover .from {
|
li:hover .from {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
li .from {
|
||||||
|
position: absolute;
|
||||||
|
right: 3.5em;
|
||||||
|
display: none;
|
||||||
|
padding: 0.3em 0.9em;
|
||||||
|
background: #ddd;
|
||||||
|
font-size: 0.9em;
|
||||||
|
top: auto;
|
||||||
|
bottom: -1.8em;
|
||||||
|
z-index: 2;
|
||||||
|
-webkit-border-top-left-radius: 0;
|
||||||
|
-webkit-border-top-right-radius: 0;
|
||||||
|
-webkit-border-bottom-left-radius: 8px;
|
||||||
|
-webkit-border-bottom-right-radius: 8px;
|
||||||
|
-webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.1);
|
||||||
|
border: 1px solid #b9b9b9;
|
||||||
|
border-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
li:first-child:hover .from {
|
li:last-child:hover .from {
|
||||||
top: auto;
|
top: -1.8em;
|
||||||
bottom: -1.8em;
|
bottom: auto;
|
||||||
z-index: 2;
|
-webkit-border-top-left-radius: 8px;
|
||||||
-webkit-border-top-left-radius: 0;
|
-webkit-border-top-right-radius: 8px;
|
||||||
-webkit-border-top-right-radius: 0;
|
-webkit-border-bottom-left-radius: 0px;
|
||||||
-webkit-border-bottom-left-radius: 8px;
|
-webkit-border-bottom-right-radius: 0px;
|
||||||
-webkit-border-bottom-right-radius: 8px;
|
-webkit-box-shadow: 0 -2px 2px rgba(0, 0, 0, 0.1);
|
||||||
-webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.1);
|
border: 1px solid white;
|
||||||
border: 1px solid #b9b9b9;
|
border-bottom: 0;
|
||||||
border-top: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
aside {
|
aside {
|
||||||
|
|
|
@ -14,21 +14,23 @@ function(HostApp, Core, Paths, URI) {
|
||||||
|
|
||||||
this.action = "conversation";
|
this.action = "conversation";
|
||||||
|
|
||||||
|
this.container = document.createElement("div");
|
||||||
|
this.container.className = this.action;
|
||||||
this.body = document.createElement("ol");
|
this.body = document.createElement("ol");
|
||||||
this.body.className = this.action;
|
this.container.appendChild(this.body)
|
||||||
|
|
||||||
document.getElementById("content").appendChild(this.body);
|
document.getElementById("content").appendChild(this.container);
|
||||||
this.hide();
|
this.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
Conversation.prototype = Object.create(Core.prototype);
|
Conversation.prototype = Object.create(Core.prototype);
|
||||||
|
|
||||||
Conversation.prototype.show = function() {
|
Conversation.prototype.show = function() {
|
||||||
Core.prototype.show.call(this, this.body);
|
Core.prototype.show.call(this, this.container);
|
||||||
}
|
}
|
||||||
|
|
||||||
Conversation.prototype.hide = function() {
|
Conversation.prototype.hide = function() {
|
||||||
Core.prototype.hide.call(this, this.body);
|
Core.prototype.hide.call(this, this.container);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ function(HostApp, Timeline, URI, Paths, Core) {
|
||||||
Timeline.call(this);
|
Timeline.call(this);
|
||||||
|
|
||||||
this.action = "mentions";
|
this.action = "mentions";
|
||||||
this.body.className = this.action;
|
this.container.className = this.action;
|
||||||
|
|
||||||
this.hide();
|
this.hide();
|
||||||
}
|
}
|
||||||
|
@ -25,11 +25,11 @@ function(HostApp, Timeline, URI, Paths, Core) {
|
||||||
Mentions.prototype = Object.create(Timeline.prototype);
|
Mentions.prototype = Object.create(Timeline.prototype);
|
||||||
|
|
||||||
Mentions.prototype.show = function() {
|
Mentions.prototype.show = function() {
|
||||||
Core.prototype.show.call(this, this.body);
|
Core.prototype.show.call(this, this.container);
|
||||||
}
|
}
|
||||||
|
|
||||||
Mentions.prototype.hide = function() {
|
Mentions.prototype.hide = function() {
|
||||||
Core.prototype.hide.call(this, this.body);
|
Core.prototype.hide.call(this, this.container);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,14 @@ function(HostApp, Paths, Hmac) {
|
||||||
"write_followers": "Be able to block people who follow you",
|
"write_followers": "Be able to block people who follow you",
|
||||||
"read_followings": "Display following list and their older posts in conversations",
|
"read_followings": "Display following list and their older posts in conversations",
|
||||||
"write_followings": "Follow ne entities"
|
"write_followings": "Follow ne entities"
|
||||||
}
|
},
|
||||||
|
"tent_profile_info_types": [ "all" ],
|
||||||
|
"tent_post_types": [
|
||||||
|
"https://tent.io/types/post/status/v0.1.0",
|
||||||
|
"https://tent.io/types/post/photo/v0.1.0",
|
||||||
|
"https://tent.io/types/post/repost/v0.1.0",
|
||||||
|
"https://tent.io/types/post/delete/v0.1.0"
|
||||||
|
]
|
||||||
};
|
};
|
||||||
this.register_data = null;
|
this.register_data = null;
|
||||||
this.profile = null;
|
this.profile = null;
|
||||||
|
@ -104,8 +111,8 @@ function(HostApp, Paths, Hmac) {
|
||||||
+ "&redirect_uri=" + this.app_info["redirect_uris"][0]
|
+ "&redirect_uri=" + this.app_info["redirect_uris"][0]
|
||||||
+ "&scope=" + Object.keys(this.app_info["scopes"]).join(",")
|
+ "&scope=" + Object.keys(this.app_info["scopes"]).join(",")
|
||||||
+ "&state=" + this.state
|
+ "&state=" + this.state
|
||||||
+ "&tent_post_types=all"
|
+ "&tent_post_types=" + this.app_info["tent_post_types"].join(",")
|
||||||
+ "&tent_profile_info_types=all";
|
+ "&tent_profile_info_types=" + this.app_info["tent_profile_info_types"].join(",");
|
||||||
|
|
||||||
HostApp.openAuthorizationURL(this.apiRoot() + auth);
|
HostApp.openAuthorizationURL(this.apiRoot() + auth);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ function(HostApp, Core, Paths, URI) {
|
||||||
this.action = "profile";
|
this.action = "profile";
|
||||||
|
|
||||||
this.container = document.createElement("div");
|
this.container = document.createElement("div");
|
||||||
|
this.container.className = this.action;
|
||||||
document.getElementById("content").appendChild(this.container);
|
document.getElementById("content").appendChild(this.container);
|
||||||
|
|
||||||
this.initProfileTemplate();
|
this.initProfileTemplate();
|
||||||
|
|
|
@ -15,6 +15,7 @@ function(HostApp, Core, Paths, URI) {
|
||||||
this.action = "search";
|
this.action = "search";
|
||||||
|
|
||||||
this.container = document.createElement("div");
|
this.container = document.createElement("div");
|
||||||
|
this.container.className = this.action;
|
||||||
document.getElementById("content").appendChild(this.container);
|
document.getElementById("content").appendChild(this.container);
|
||||||
|
|
||||||
this.body = document.createElement("ol");
|
this.body = document.createElement("ol");
|
||||||
|
@ -23,7 +24,7 @@ function(HostApp, Core, Paths, URI) {
|
||||||
this.form.className = this.action;
|
this.form.className = this.action;
|
||||||
this.input = document.createElement("input");
|
this.input = document.createElement("input");
|
||||||
this.input.type = "search";
|
this.input.type = "search";
|
||||||
this.input.placeholder = "Search ...";
|
this.input.placeholder = "Search";
|
||||||
this.form.appendChild(this.input);
|
this.form.appendChild(this.input);
|
||||||
|
|
||||||
var _this = this;
|
var _this = this;
|
||||||
|
|
|
@ -40,6 +40,9 @@ function(HostApp, Paths, Cache) {
|
||||||
|
|
||||||
document.getElementById("sidebar").appendChild(this.body);
|
document.getElementById("sidebar").appendChild(this.body);
|
||||||
|
|
||||||
|
// initial seting of the <body> class
|
||||||
|
document.body.className = "body-timeline";
|
||||||
|
|
||||||
this.setEntityAvatar();
|
this.setEntityAvatar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,6 +154,9 @@ function(HostApp, Paths, Cache) {
|
||||||
|
|
||||||
active_part.show();
|
active_part.show();
|
||||||
|
|
||||||
|
// Replace <body> class
|
||||||
|
document.body.className = "body-" + active_li.className.split("-")[1];
|
||||||
|
|
||||||
// Show active icon
|
// Show active icon
|
||||||
for(var li in this.menu) {
|
for(var li in this.menu) {
|
||||||
if (this.menu[li] != active_part) {
|
if (this.menu[li] != active_part) {
|
||||||
|
@ -163,6 +169,29 @@ function(HostApp, Paths, Cache) {
|
||||||
img.src = img.src_active;
|
img.src = img.src_active;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Sidebar.prototype.showContentForNext = function() {
|
||||||
|
|
||||||
|
var parts = [
|
||||||
|
"timeline",
|
||||||
|
"mentions",
|
||||||
|
"conversation",
|
||||||
|
"entityProfile",
|
||||||
|
"search"
|
||||||
|
];
|
||||||
|
|
||||||
|
for (var i = 0; i < parts.length; i++) {
|
||||||
|
var part = parts[i];
|
||||||
|
var img = this.menu[part].getElementsByTagName("img")[0];
|
||||||
|
if (img.src.endsWith(img.src_active)) {
|
||||||
|
var next = parts[(i+1)%parts.length];
|
||||||
|
this.showContentFor(bungloo[next], this.menu[next]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Sidebar.prototype.setUnreadMentions = function(count) {
|
Sidebar.prototype.setUnreadMentions = function(count) {
|
||||||
this.unreadMentionsSpan.innerHTML = count == 0 ? "" : count;
|
this.unreadMentionsSpan.innerHTML = count == 0 ? "" : count;
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
|
|
|
@ -14,15 +14,17 @@ function(Core, Paths, HostApp, URI) {
|
||||||
this.action = "timeline";
|
this.action = "timeline";
|
||||||
this.reload_blocked = false;
|
this.reload_blocked = false;
|
||||||
|
|
||||||
this.max_length = 200;
|
this.max_length = 20;
|
||||||
this.timeout = 10 * 1000; // every 10 seconds
|
this.timeout = 10 * 1000; // every 10 seconds
|
||||||
this.since_id = null;
|
this.since_id = null;
|
||||||
this.since_id_entity = null;
|
this.since_id_entity = null;
|
||||||
this.since_time = 0;
|
this.since_time = 0;
|
||||||
|
|
||||||
|
this.container = document.createElement("div");
|
||||||
|
this.container.className = this.action;
|
||||||
this.body = document.createElement("ol");
|
this.body = document.createElement("ol");
|
||||||
this.body.className = this.action;
|
this.container.appendChild(this.body)
|
||||||
document.getElementById("content").appendChild(this.body);
|
document.getElementById("content").appendChild(this.container);
|
||||||
|
|
||||||
var _this = this;
|
var _this = this;
|
||||||
this.reloadIntervall = setInterval(function() { _this.getNewData() }, this.timeout);
|
this.reloadIntervall = setInterval(function() { _this.getNewData() }, this.timeout);
|
||||||
|
@ -33,11 +35,11 @@ function(Core, Paths, HostApp, URI) {
|
||||||
Timeline.prototype = Object.create(Core.prototype);
|
Timeline.prototype = Object.create(Core.prototype);
|
||||||
|
|
||||||
Timeline.prototype.show = function() {
|
Timeline.prototype.show = function() {
|
||||||
Core.prototype.show.call(this, this.body);
|
Core.prototype.show.call(this, this.container);
|
||||||
}
|
}
|
||||||
|
|
||||||
Timeline.prototype.hide = function() {
|
Timeline.prototype.hide = function() {
|
||||||
Core.prototype.hide.call(this, this.body);
|
Core.prototype.hide.call(this, this.container);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -166,7 +166,7 @@ function(jQuery, Paths, URI, HostApp, Cache) {
|
||||||
|
|
||||||
var template = this.getTemplate();
|
var template = this.getTemplate();
|
||||||
|
|
||||||
template.item.id = "post-" + status.id;
|
template.item.id = "post-" + status.id + "-" + this.action;
|
||||||
template.item.status = status;
|
template.item.status = status;
|
||||||
|
|
||||||
if (HostApp.stringForKey("entity") == status.entity && typeof status.__repost == "undefined") {
|
if (HostApp.stringForKey("entity") == status.entity && typeof status.__repost == "undefined") {
|
||||||
|
@ -183,6 +183,10 @@ function(jQuery, Paths, URI, HostApp, Cache) {
|
||||||
template.remove.style.display = "none";
|
template.remove.style.display = "none";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (HostApp.stringForKey("entity") == status.entity) {
|
||||||
|
template.item.className += " own";
|
||||||
|
}
|
||||||
|
|
||||||
template.reply_to.onclick = function() {
|
template.reply_to.onclick = function() {
|
||||||
|
|
||||||
var mentions = [];
|
var mentions = [];
|
||||||
|
@ -283,12 +287,7 @@ function(jQuery, Paths, URI, HostApp, Cache) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template.message.innerHTML = this.replaceURLWithHTMLLinks(text, entities, template.message);
|
template.message.innerHTML = this.replaceURLWithHTMLLinks(text, entities, template.message);
|
||||||
|
this.afterChangingTextinMessageHTML(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") {
|
||||||
|
|
||||||
|
@ -373,7 +372,7 @@ function(jQuery, Paths, URI, HostApp, Cache) {
|
||||||
|
|
||||||
Core.prototype.getRepost = function(repost, before_node) {
|
Core.prototype.getRepost = function(repost, before_node) {
|
||||||
|
|
||||||
var post = document.getElementById("post-" + repost.content.id);
|
var post = document.getElementById("post-" + repost.content.id + "-" + this.action);
|
||||||
|
|
||||||
if (post) {
|
if (post) {
|
||||||
|
|
||||||
|
@ -411,7 +410,7 @@ function(jQuery, Paths, URI, HostApp, Cache) {
|
||||||
$(post).find(".reposted_by").show();
|
$(post).find(".reposted_by").show();
|
||||||
|
|
||||||
var li = $("<li/>");
|
var li = $("<li/>");
|
||||||
li.attr("id", "post-" + repost.id)
|
li.attr("id", "post-" + repost.id + "-" + this.action)
|
||||||
var a = $("<a/>");
|
var a = $("<a/>");
|
||||||
|
|
||||||
a.attr("href", repost.entity);
|
a.attr("href", repost.entity);
|
||||||
|
@ -713,12 +712,8 @@ function(jQuery, Paths, URI, HostApp, Cache) {
|
||||||
+ "</a>"
|
+ "</a>"
|
||||||
);
|
);
|
||||||
|
|
||||||
// adding show profile on click
|
|
||||||
node.innerHTML = new_text;
|
node.innerHTML = new_text;
|
||||||
$(node).find("a.name").click(function(e) {
|
_this.afterChangingTextinMessageHTML(node);
|
||||||
HostApp.showProfileForEntity(e.target.title);
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
// adding comma between names when there is only
|
// adding comma between names when there is only
|
||||||
// a space in between.
|
// a space in between.
|
||||||
|
@ -816,7 +811,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 class='hash' href='https://skate.io/search?q=%23$3'>$3</a>");
|
return URI.withinString(text, callback).replace(hash, "$1<a class='hash' href='https://skate.io/search?q=%23$3'>$2$3</a>");
|
||||||
}
|
}
|
||||||
|
|
||||||
Core.prototype.parseForMedia = function(text, images) {
|
Core.prototype.parseForMedia = function(text, images) {
|
||||||
|
@ -996,6 +991,20 @@ function(jQuery, Paths, URI, HostApp, Cache) {
|
||||||
$(images).append('<iframe class="soundcloud" src="https://w.soundcloud.com/player/?url=' + url + '" width="100%" height="166" scrolling="no" frameborder="no"></iframe>');
|
$(images).append('<iframe class="soundcloud" src="https://w.soundcloud.com/player/?url=' + url + '" width="100%" height="166" scrolling="no" frameborder="no"></iframe>');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Core.prototype.afterChangingTextinMessageHTML = function(message_node) {
|
||||||
|
// adding show search on click hash
|
||||||
|
$(message_node).find("a.hash").click(function(e) {
|
||||||
|
bungloo.search.searchFor(e.target.innerHTML);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// adding show profile on click
|
||||||
|
$(message_node).find("a.name").click(function(e) {
|
||||||
|
HostApp.showProfileForEntity(e.target.title);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return Core;
|
return Core;
|
||||||
|
|
|
@ -129,7 +129,10 @@ define(function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
HostApp.osType = function() {
|
HostApp.osType = function() {
|
||||||
return OS_TYPE == "mac" ? "OS X" : "Linux";
|
var os_name = "OS X";
|
||||||
|
if (OS_TYPE == "windows") os_name = "Windows";
|
||||||
|
if (OS_TYPE == "linux") os_name = "Linux"
|
||||||
|
return os_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
HostApp.notificateViewsAboutDeletedPost = function(postId, entity) {
|
HostApp.notificateViewsAboutDeletedPost = function(postId, entity) {
|
||||||
|
|
|
@ -110,6 +110,14 @@ var console = {
|
||||||
|
|
||||||
function loadJsPlugin(js_url) {
|
function loadJsPlugin(js_url) {
|
||||||
if (js_url) {
|
if (js_url) {
|
||||||
|
|
||||||
|
requirejs.config({
|
||||||
|
baseUrl: 'scripts',
|
||||||
|
paths: {
|
||||||
|
plugins: js_url.replace("Plugin.js", '')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var js_plugin = document.createElement("script");
|
var js_plugin = document.createElement("script");
|
||||||
js_plugin.type = "text/javascript";
|
js_plugin.type = "text/javascript";
|
||||||
js_plugin.src = js_url;
|
js_plugin.src = js_url;
|
||||||
|
|
12
Windows/deploy.ps1
Normal file
12
Windows/deploy.ps1
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
mkdir bungloo
|
||||||
|
Copy-Item ../Qt/* bungloo -Recurse
|
||||||
|
Copy-Item ../WebKit bungloo -Recurse
|
||||||
|
Copy-Item ../images bungloo -Recurse
|
||||||
|
Copy-Item setup.py bungloo
|
||||||
|
touch bungloo/__init__.py
|
||||||
|
Copy-Item msvcp90.dll bungloo
|
||||||
|
cd bungloo
|
||||||
|
python setup.py py2exe
|
||||||
|
cd ..
|
||||||
|
rm bungloo
|
55
Windows/installer.iss
Normal file
55
Windows/installer.iss
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
; Script generated by the Inno Setup Script Wizard.
|
||||||
|
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
|
||||||
|
|
||||||
|
#define MyAppName "Bungloo"
|
||||||
|
#define MyAppVersion "1.3.0"
|
||||||
|
#define MyAppPublisher "Jabs Nu"
|
||||||
|
#define MyAppURL "http://jabs.nu/bungloo"
|
||||||
|
#define MyAppExeName "Bungloo.exe"
|
||||||
|
|
||||||
|
[Setup]
|
||||||
|
; NOTE: The value of AppId uniquely identifies this application.
|
||||||
|
; Do not use the same AppId value in installers for other applications.
|
||||||
|
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
|
||||||
|
AppId={{5E44EE00-8ECE-40C8-AF6F-70397DD1DBFE}
|
||||||
|
AppName={#MyAppName}
|
||||||
|
AppVersion={#MyAppVersion}
|
||||||
|
;AppVerName={#MyAppName} {#MyAppVersion}
|
||||||
|
AppPublisher={#MyAppPublisher}
|
||||||
|
AppPublisherURL={#MyAppURL}
|
||||||
|
AppSupportURL={#MyAppURL}
|
||||||
|
AppUpdatesURL={#MyAppURL}
|
||||||
|
DefaultDirName={pf}\{#MyAppName}
|
||||||
|
DefaultGroupName={#MyAppName}
|
||||||
|
AllowNoIcons=yes
|
||||||
|
LicenseFile=C:\Users\Jeena\Documents\GitHub\Bungloo\LICENCE.txt
|
||||||
|
OutputBaseFilename=setup
|
||||||
|
SetupIconFile=C:\Users\Jeena\Documents\GitHub\Bungloo\images\Icon.ico
|
||||||
|
Compression=lzma
|
||||||
|
SolidCompression=yes
|
||||||
|
|
||||||
|
[Languages]
|
||||||
|
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||||
|
|
||||||
|
[Tasks]
|
||||||
|
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
|
||||||
|
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1
|
||||||
|
|
||||||
|
[Files]
|
||||||
|
Source: "C:\Users\Jeena\Documents\GitHub\Bungloo\Windows\bungloo\dist\Bungloo.exe"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
Source: "C:\Users\Jeena\Documents\GitHub\Bungloo\Windows\bungloo\dist\library.zip"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
Source: "C:\Users\Jeena\Documents\GitHub\Bungloo\Windows\bungloo\dist\python27.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
Source: "C:\Users\Jeena\Documents\GitHub\Bungloo\Windows\bungloo\dist\w9xpopen.exe"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
Source: "C:\Users\Jeena\Documents\GitHub\Bungloo\Windows\bungloo\dist\images\*"; DestDir: "{app}\images"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||||
|
Source: "C:\Users\Jeena\Documents\GitHub\Bungloo\Windows\bungloo\dist\WebKit\*"; DestDir: "{app}\WebKit"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||||
|
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
|
||||||
|
|
||||||
|
[Icons]
|
||||||
|
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
|
||||||
|
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
|
||||||
|
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
|
||||||
|
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: quicklaunchicon
|
||||||
|
|
||||||
|
[Run]
|
||||||
|
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
|
||||||
|
|
BIN
Windows/msvcp90.dll
Normal file
BIN
Windows/msvcp90.dll
Normal file
Binary file not shown.
31
Windows/setup.py
Normal file
31
Windows/setup.py
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#!/usr/bin/env python2
|
||||||
|
|
||||||
|
import os
|
||||||
|
from distutils.core import setup
|
||||||
|
import py2exe
|
||||||
|
|
||||||
|
files = []
|
||||||
|
for dirname, dirnames, filenames in os.walk('WebKit'):
|
||||||
|
for filename in filenames:
|
||||||
|
files += [(dirname, [os.path.join(dirname, filename)])]
|
||||||
|
|
||||||
|
for dirname, dirnames, filenames in os.walk('images'):
|
||||||
|
for filename in filenames:
|
||||||
|
files += [(dirname, [os.path.join(dirname, filename)])]
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name = "Bungloo",
|
||||||
|
version = "1.3.0",
|
||||||
|
author = "Jeena Paradies",
|
||||||
|
author_email = "spam@jeenaparadies.net",
|
||||||
|
url = "http://jabs.nu/bungloo",
|
||||||
|
license = "BSD license",
|
||||||
|
data_files = files,
|
||||||
|
windows = ["Bungloo.py"],
|
||||||
|
options = {
|
||||||
|
"py2exe": {
|
||||||
|
"includes": ["sip", "ssl", "PyQt4.QtCore", "PyQt4.QtGui", "PyQt4.QtNetwork"],
|
||||||
|
"bundle_files": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
BIN
images/Icon.ico
Normal file
BIN
images/Icon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 361 KiB |
BIN
images/Icon16.png
Normal file
BIN
images/Icon16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 966 B |
BIN
images/Icon248.png
Normal file
BIN
images/Icon248.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 63 KiB |
BIN
images/Icon32.png
Normal file
BIN
images/Icon32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
BIN
images/Icon48.png
Normal file
BIN
images/Icon48.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.5 KiB |
|
@ -1,7 +1,7 @@
|
||||||
Bungloo
|
Bungloo
|
||||||
=======
|
=======
|
||||||
|
|
||||||
Bungloo is a slim Tent client for OS X and Linux written in mostly JavaScript.
|
Bungloo is a slim Tent client for OS X, Linux and Windows written in mostly JavaScript.
|
||||||
|
|
||||||
For more info check out the Wiki page: https://github.com/jeena/Bungloo/wiki
|
For more info check out the Wiki page: https://github.com/jeena/Bungloo/wiki
|
||||||
|
|
||||||
|
@ -21,3 +21,4 @@ Thanks everyone in the Open Source community! Bungloo is using:
|
||||||
- PyQt - http://wiki.python.org/moin/PyQt
|
- PyQt - http://wiki.python.org/moin/PyQt
|
||||||
- Icon - http://www.fasticon.com
|
- Icon - http://www.fasticon.com
|
||||||
- Linux monochrome icons - http://glyphicons.com
|
- Linux monochrome icons - http://glyphicons.com
|
||||||
|
- py2exe - http://www.py2exe.org
|
||||||
|
|
Reference in a new issue