Merge branch 't0.3' because this will be the new master anyway.
|
@ -107,15 +107,12 @@ class Controller(QtCore.QObject):
|
||||||
QtCore.QObject.__init__(self)
|
QtCore.QObject.__init__(self)
|
||||||
self.app = app
|
self.app = app
|
||||||
|
|
||||||
oldpath = os.path.expanduser('~/.bungloo/')
|
name = "bungloo2"
|
||||||
if os.path.isdir(oldpath):
|
|
||||||
shutil.copytree(oldpath, os.path.expanduser('~/.config/bungloo/'))
|
|
||||||
shutil.rmtree(os.path.expanduser('~/.bungloo/'))
|
|
||||||
|
|
||||||
if not os.path.exists(os.path.expanduser("~/.config/bungloo/")):
|
if not os.path.exists(os.path.expanduser("~/.config/" + name + "/")):
|
||||||
os.makedirs(os.path.expanduser("~/.config/bungloo/"))
|
os.makedirs(os.path.expanduser("~/.config/" + name + "/"))
|
||||||
|
|
||||||
self.config_path = os.path.expanduser('~/.config/bungloo/bungloo.cfg')
|
self.config_path = os.path.expanduser('~/.config/' + name + '/bungloo.cfg')
|
||||||
|
|
||||||
if os.access(self.config_path, os.R_OK):
|
if os.access(self.config_path, os.R_OK):
|
||||||
with open(self.config_path, 'r') as f:
|
with open(self.config_path, 'r') as f:
|
||||||
|
@ -173,22 +170,18 @@ class Controller(QtCore.QObject):
|
||||||
except OSError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@QtCore.pyqtSlot(str)
|
@QtCore.pyqtSlot()
|
||||||
def openNewMessageWidow(self, is_private=False, string=""):
|
def openNewMessageWidow(self):
|
||||||
string = str(string)
|
self.openNewMessageWindowInReplyToStatus("")
|
||||||
self.openNewMessageWindowInReplyTostatusIdwithStringIsPrivate(None, None, string, is_private)
|
|
||||||
|
|
||||||
@QtCore.pyqtSlot(str, str, str, bool)
|
@QtCore.pyqtSlot(str)
|
||||||
def openNewMessageWindowInReplyTostatusIdwithStringIsPrivate(self, entity, status_id, string, is_private):
|
def openNewMessageWindowInReplyToStatus(self, status_string):
|
||||||
new_message_window = Windows.NewPost(self.app)
|
new_message_window = Windows.NewPost(self.app, status_string)
|
||||||
new_message_window.inReplyToStatusIdWithString(entity, status_id, string)
|
|
||||||
new_message_window.setIsPrivate(is_private)
|
|
||||||
new_message_window.show()
|
new_message_window.show()
|
||||||
new_message_window.setAttribute(QtCore.Qt.WA_DeleteOnClose)
|
new_message_window.setAttribute(QtCore.Qt.WA_DeleteOnClose)
|
||||||
self.app.new_message_windows.append(new_message_window)
|
self.app.new_message_windows.append(new_message_window)
|
||||||
new_message_window.activateWindow()
|
new_message_window.activateWindow()
|
||||||
new_message_window.setFocus()
|
new_message_window.setFocus()
|
||||||
new_message_window.textInput.setFocus()
|
|
||||||
new_message_window.show()
|
new_message_window.show()
|
||||||
new_message_window.raise_()
|
new_message_window.raise_()
|
||||||
|
|
||||||
|
@ -268,6 +261,16 @@ class Controller(QtCore.QObject):
|
||||||
msgBox.setInformativeText(message)
|
msgBox.setInformativeText(message)
|
||||||
msgBox.exec_()
|
msgBox.exec_()
|
||||||
|
|
||||||
|
@QtCore.pyqtSlot(result=str)
|
||||||
|
def getCachedProfiles(self):
|
||||||
|
entities = self.app.timeline.evaluateJavaScript("JSON.stringify(bungloo.cache.profiles);")
|
||||||
|
return entities.toString()
|
||||||
|
|
||||||
|
@QtCore.pyqtSlot()
|
||||||
|
def getNewData(self):
|
||||||
|
func = "bungloo.timeline.getNewData()"
|
||||||
|
self.app.timeline.evaluateJavaScript(func)
|
||||||
|
|
||||||
def logout(self, sender):
|
def logout(self, sender):
|
||||||
print "logout is not implemented yet"
|
print "logout is not implemented yet"
|
||||||
|
|
||||||
|
@ -297,7 +300,7 @@ class Console(QtCore.QObject):
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
key = 'BUNGLOO'
|
key = 'BUNGLOO2'
|
||||||
|
|
||||||
if len(sys.argv) > 1 and sys.argv[1] == "--help":
|
if len(sys.argv) > 1 and sys.argv[1] == "--help":
|
||||||
print """
|
print """
|
||||||
|
|
129
Qt/Windows.py
|
@ -9,7 +9,7 @@ class Preferences:
|
||||||
|
|
||||||
# window
|
# window
|
||||||
self.window = QtGui.QMainWindow()
|
self.window = QtGui.QMainWindow()
|
||||||
self.window.setWindowTitle("Preferences")
|
self.window.setWindowTitle("Login")
|
||||||
self.window.resize(480, 186)
|
self.window.resize(480, 186)
|
||||||
self.window.setMinimumSize(480, 186)
|
self.window.setMinimumSize(480, 186)
|
||||||
self.window.setMaximumSize(480, 186)
|
self.window.setMaximumSize(480, 186)
|
||||||
|
@ -242,7 +242,7 @@ class Oauth:
|
||||||
new_manager.sslErrors.connect(lambda reply, errors: self.handleSslErrors(reply, errors))
|
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()
|
||||||
|
print url
|
||||||
self.auth_view.load_url(url)
|
self.auth_view.load_url(url)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -329,25 +329,29 @@ class FindEntity(QtGui.QDialog):
|
||||||
|
|
||||||
|
|
||||||
class NewPost(Helper.RestorableWindow):
|
class NewPost(Helper.RestorableWindow):
|
||||||
def __init__(self, app):
|
def __init__(self, app, status_string):
|
||||||
self.app = app
|
self.app = app
|
||||||
|
self.status_string = status_string
|
||||||
|
|
||||||
Helper.RestorableWindow.__init__(self, "newpost", self.app)
|
Helper.RestorableWindow.__init__(self, "newpost", self.app)
|
||||||
|
self.activateWindow()
|
||||||
|
self.raise_()
|
||||||
|
|
||||||
self.setWindowIcon(QtGui.QIcon(self.app.resources_path() + "/images/Icon.png"))
|
self.setWindowIcon(QtGui.QIcon(self.app.resources_path() + "/images/Icon.png"))
|
||||||
|
|
||||||
self.textInput = QtGui.QPlainTextEdit(self)
|
self.webView = Helper.WebViewCreator(self.app, True, self)
|
||||||
self.setCentralWidget(self.textInput)
|
self.webView.load_local(self.load_finished)
|
||||||
self.textInput.textChanged.connect(self.onChanged)
|
self.setCentralWidget(self.webView)
|
||||||
|
|
||||||
|
self.initUI()
|
||||||
|
|
||||||
|
self.webView.triggerPageAction(QtWebKit.QWebPage.InspectElement)
|
||||||
|
frame = self.webView.page().mainFrame()
|
||||||
|
frame.addToJavaScriptWindowObject("new_post_window", self)
|
||||||
|
|
||||||
self.setWindowTitle("New Post")
|
self.setWindowTitle("New Post")
|
||||||
self.resize(300, 150)
|
self.resize(300, 150)
|
||||||
self.setMinimumSize(100, 100)
|
self.setMinimumSize(100, 100)
|
||||||
self.initUI()
|
|
||||||
|
|
||||||
self.setIsPrivate(False)
|
|
||||||
self.status_id = None
|
|
||||||
self.reply_to_entity = None
|
|
||||||
self.imageFilePath = None
|
|
||||||
|
|
||||||
def initUI(self):
|
def initUI(self):
|
||||||
newPostAction = QtGui.QAction("&New Post", self)
|
newPostAction = QtGui.QAction("&New Post", self)
|
||||||
|
@ -396,89 +400,38 @@ class NewPost(Helper.RestorableWindow):
|
||||||
aboutAction.setStatusTip("Open about page in Webbrowser")
|
aboutAction.setStatusTip("Open about page in Webbrowser")
|
||||||
aboutAction.triggered.connect(self.app.open_about)
|
aboutAction.triggered.connect(self.app.open_about)
|
||||||
|
|
||||||
|
developerExtrasAction = QtGui.QAction("&Developer Extras", self)
|
||||||
|
developerExtrasAction.setStatusTip("Activate webkit inspector")
|
||||||
|
developerExtrasAction.triggered.connect(self.developer_extras)
|
||||||
|
|
||||||
helpMenu = menubar.addMenu("&Help")
|
helpMenu = menubar.addMenu("&Help")
|
||||||
helpMenu.addAction(aboutAction)
|
helpMenu.addAction(aboutAction)
|
||||||
|
helpMenu.addAction(developerExtrasAction)
|
||||||
|
|
||||||
|
def load_finished(self, widget):
|
||||||
self.statusBar().showMessage('256')
|
callback = "function() { bungloo.newpost.setStatus('%s'); }" % (self.status_string)
|
||||||
|
script = "function HostAppGo() { start('newpost', " + callback + "); }"
|
||||||
self.addButton = QtGui.QToolButton()
|
self.webView.page().mainFrame().evaluateJavaScript(script)
|
||||||
self.addButton.setToolTip("Add photo")
|
self.webView.setFocus()
|
||||||
self.addButton.clicked.connect(self.openFileDialog)
|
|
||||||
self.addButton.setAutoRaise(True)
|
|
||||||
#addIcon = QtGui.QIcon.fromTheme("insert-image", QtGui.QIcon(self.app.resources_path() + "/images/Actions-insert-image-icon.png"))
|
|
||||||
addIcon = QtGui.QIcon(self.app.resources_path() + "/images/glyphicons_138_picture.png")
|
|
||||||
self.addButton.setIcon(addIcon)
|
|
||||||
self.statusBar().addPermanentWidget(self.addButton)
|
|
||||||
|
|
||||||
self.isPrivateButton = QtGui.QToolButton()
|
|
||||||
self.isPrivateButton.setToolTip("Make private")
|
|
||||||
self.isPrivateButton.clicked.connect(self.toggleIsPrivate)
|
|
||||||
self.isPrivateButton.setAutoRaise(True)
|
|
||||||
#self.isPrivateIcon = QtGui.QIcon(self.app.resources_path() + "/images/Lock-Lock-icon.png")
|
|
||||||
self.isPrivateIcon = QtGui.QIcon(self.app.resources_path() + "/images/glyphicons_203_lock.png")
|
|
||||||
#self.isNotPrivateIcon = QtGui.QIcon(self.app.resources_path() + "/images/Lock-Unlock-icon.png")
|
|
||||||
self.isNotPrivateIcon = QtGui.QIcon(self.app.resources_path() + "/images/glyphicons_204_unlock.png")
|
|
||||||
self.isPrivateButton.setIcon(self.isNotPrivateIcon)
|
|
||||||
self.statusBar().addPermanentWidget(self.isPrivateButton)
|
|
||||||
|
|
||||||
self.sendButton = QtGui.QToolButton()
|
|
||||||
self.sendButton.setToolTip("Send")
|
|
||||||
self.sendButton.clicked.connect(self.sendMessage)
|
|
||||||
self.sendButton.setAutoRaise(True)
|
|
||||||
#sendIcon = QtGui.QIcon.fromTheme("mail-send", QtGui.QIcon(self.app.resources_path() + "/images/send-icon.png"))
|
|
||||||
sendIcon = QtGui.QIcon(self.app.resources_path() + "/images/glyphicons_123_message_out.png")
|
|
||||||
self.sendButton.setIcon(sendIcon)
|
|
||||||
self.statusBar().addPermanentWidget(self.sendButton)
|
|
||||||
|
|
||||||
def setIsPrivate(self, is_private):
|
|
||||||
self.isPrivate = is_private
|
|
||||||
icon = self.isNotPrivateIcon
|
|
||||||
if self.isPrivate:
|
|
||||||
icon = self.isPrivateIcon
|
|
||||||
|
|
||||||
self.isPrivateButton.setIcon(icon)
|
|
||||||
|
|
||||||
def toggleIsPrivate(self):
|
def toggleIsPrivate(self):
|
||||||
self.setIsPrivate(not self.isPrivate)
|
script = "bungloo.newpost.toggleIsPrivate();"
|
||||||
|
self.webView.page().mainFrame().evaluateJavaScript(script)
|
||||||
def setString(self, string):
|
|
||||||
self.inReplyToStatusIdWithString(None, None, string)
|
|
||||||
|
|
||||||
def inReplyToStatusIdWithString(self, reply_to, status_id, string):
|
|
||||||
self.reply_to_entity = reply_to
|
|
||||||
self.status_id = status_id
|
|
||||||
self.textInput.setPlainText(string)
|
|
||||||
|
|
||||||
cursor = self.textInput.textCursor()
|
|
||||||
cursor.movePosition(QtGui.QTextCursor.End, QtGui.QTextCursor.MoveAnchor)
|
|
||||||
cursor.movePosition(QtGui.QTextCursor.Start, QtGui.QTextCursor.KeepAnchor)
|
|
||||||
cursor.movePosition(QtGui.QTextCursor.EndOfLine, QtGui.QTextCursor.KeepAnchor)
|
|
||||||
self.textInput.setTextCursor(cursor)
|
|
||||||
|
|
||||||
def onChanged(self):
|
|
||||||
count = 256 - len(self.textInput.toPlainText())
|
|
||||||
self.statusBar().showMessage(str(count))
|
|
||||||
|
|
||||||
def sendMessage(self):
|
def sendMessage(self):
|
||||||
count = len(self.textInput.toPlainText())
|
script = "bungloo.newpost.send()"
|
||||||
if count > 0 and count <= 256:
|
self.webView.page().mainFrame().evaluateJavaScript(script)
|
||||||
message = Helper.PostModel()
|
|
||||||
message.text = unicode(self.textInput.toPlainText().toUtf8(), "utf-8")
|
def developer_extras(self, widget):
|
||||||
message.inReplyTostatusId = self.status_id
|
QtWebKit.QWebSettings.globalSettings().setAttribute(QtWebKit.QWebSettings.DeveloperExtrasEnabled, True)
|
||||||
message.inReplyToEntity = self.reply_to_entity
|
|
||||||
message.location = None
|
|
||||||
message.imageFilePath = self.imageFilePath
|
|
||||||
message.isPrivate = self.isPrivate
|
|
||||||
self.app.controller.sendMessage(message)
|
|
||||||
self.close()
|
|
||||||
else:
|
|
||||||
QtGui.qApp.beep()
|
|
||||||
|
|
||||||
def openFileDialog(self):
|
def openFileDialog(self):
|
||||||
fileNamePath = QtGui.QFileDialog.getOpenFileName(self, "Choose a image", "", "Images (*.png *.gif *.jpg *.jpeg)")
|
print "openFileDialog Not implemented yet"
|
||||||
if len(fileNamePath) > 0:
|
|
||||||
self.imageFilePath = str(fileNamePath)
|
|
||||||
else:
|
|
||||||
self.imageFilePath = None
|
|
||||||
|
|
||||||
|
@QtCore.pyqtSlot()
|
||||||
|
def closeWindow(self):
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
@QtCore.pyqtSlot()
|
||||||
|
def beep(self):
|
||||||
|
QtGui.qApp.beep()
|
|
@ -18,6 +18,15 @@ a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: #00317a;
|
color: #00317a;
|
||||||
outline: 0;
|
outline: 0;
|
||||||
|
outline : none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
background: transparent;
|
||||||
|
border: 0;
|
||||||
|
margin: 0;
|
||||||
|
padding: 4px 5px 0 5px;
|
||||||
|
outline : none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#sidebar {
|
#sidebar {
|
||||||
|
@ -446,4 +455,23 @@ form.search input {
|
||||||
p.noresult {
|
p.noresult {
|
||||||
padding : 10px;
|
padding : 10px;
|
||||||
text-align : center;
|
text-align : center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.new_post #sidebar, .new_post #content { display: none; }
|
||||||
|
.new_post { height: 100%; }
|
||||||
|
#new_post_container { position: absolute; border-collapse: collapse; height: 100%; width: 100%; }
|
||||||
|
#new_post_container td { position: relative; height: 90%; }
|
||||||
|
#new_post_container .text td { background: white; }
|
||||||
|
#new_post_container textarea { resize: none; box-sizing: border-box; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0; background: transparent; outline: none; }
|
||||||
|
#new_post_container div { box-sizing: border-box; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0; background: white; color: white; padding: 2px; }
|
||||||
|
|
||||||
|
#new_post_container div span { background: #D8DFEA; }
|
||||||
|
#suggestions { width: 100%; position: absolute; left: 0; bottom: 0; background: #efefef; list-style-type: none; padding: 0; margin: 0; border-top: 1px solid #ccc; }
|
||||||
|
#suggestions li { border-top: 1px solid #fefefe; border-bottom: #c9c9c9; padding: 0 0.5em; }
|
||||||
|
#suggestions strong { font-weight: normal; color: #555; }
|
||||||
|
#suggestions .active { background: #dedede; }
|
||||||
|
#suggestions .active strong { color: black; }
|
||||||
|
#status_bar { height: 1em; border-top: 1px solid #ccc; }
|
||||||
|
#status_bar p { float: right; margin: 0; padding: 0; }
|
||||||
|
#status_bar span { display: inline-block; margin: 4px 5px 0 5px; }
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 338 B After Width: | Height: | Size: 338 B |
Before Width: | Height: | Size: 325 B After Width: | Height: | Size: 325 B |
Before Width: | Height: | Size: 231 B After Width: | Height: | Size: 231 B |
Before Width: | Height: | Size: 320 B After Width: | Height: | Size: 320 B |
|
@ -1,11 +1,11 @@
|
||||||
define([
|
define([
|
||||||
"helper/HostApp",
|
"helper/HostApp",
|
||||||
"helper/Core",
|
"helper/Core",
|
||||||
"helper/Paths",
|
"helper/APICalls",
|
||||||
"lib/URI"
|
"lib/URI"
|
||||||
],
|
],
|
||||||
|
|
||||||
function(HostApp, Core, Paths, URI) {
|
function(HostApp, Core, APICalls, URI) {
|
||||||
|
|
||||||
|
|
||||||
function Conversation(standalone) {
|
function Conversation(standalone) {
|
||||||
|
@ -86,15 +86,15 @@ function(HostApp, Core, Paths, URI) {
|
||||||
|
|
||||||
function getRemoteStatus(profile) {
|
function getRemoteStatus(profile) {
|
||||||
var server = profile["https://tent.io/types/info/core/v0.1.0"].servers[0];
|
var server = profile["https://tent.io/types/info/core/v0.1.0"].servers[0];
|
||||||
Paths.getURL(URI(server + "/posts/" + id).toString(), "GET", callback, null, false);
|
APICalls.http_call(URI(server + "/posts/" + id).toString(), "GET", callback, null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
var profile = this.cache.profiles.getItem(entity);
|
var profile = this.cache.profiles.getItem(entity);
|
||||||
|
|
||||||
if (entity == HostApp.stringForKey("entity")) {
|
if (entity == HostApp.stringForKey("entity")) {
|
||||||
|
|
||||||
var url = URI(Paths.mkApiRootPath("/posts/" + id));
|
var url = URI(APICalls.mkApiRootPath("/posts/" + id));
|
||||||
Paths.getURL(url.toString(), "GET", callback, null);
|
APICalls.http_call(url.toString(), "GET", callback, null);
|
||||||
|
|
||||||
} else if(profile) {
|
} else if(profile) {
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ function(HostApp, Core, Paths, URI) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
Paths.findProfileURL(entity, function(profile_url) {
|
APICalls.findProfileURL(entity, function(profile_url) {
|
||||||
|
|
||||||
if (profile_url) {
|
if (profile_url) {
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ function(HostApp, Core, Paths, URI) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
Paths.getURL(profile_url, "GET", function(resp) {
|
APICalls.http_call(profile_url, "GET", function(resp) {
|
||||||
|
|
||||||
var profile = JSON.parse(resp.responseText)
|
var profile = JSON.parse(resp.responseText)
|
||||||
this.cache.profiles.setItem(entity, profile);
|
this.cache.profiles.setItem(entity, profile);
|
||||||
|
@ -128,7 +128,7 @@ function(HostApp, Core, Paths, URI) {
|
||||||
|
|
||||||
Conversation.prototype.appendMentioned = function(id, entity, node) {
|
Conversation.prototype.appendMentioned = function(id, entity, node) {
|
||||||
|
|
||||||
var url = URI(Paths.mkApiRootPath("/posts"));
|
var url = URI(APICalls.mkApiRootPath("/posts"));
|
||||||
url.addSearch("mentioned_post", id);
|
url.addSearch("mentioned_post", id);
|
||||||
url.addSearch("post_types", "https%3A%2F%2Ftent.io%2Ftypes%2Fpost%2Fstatus%2Fv0.1.0");
|
url.addSearch("post_types", "https%3A%2F%2Ftent.io%2Ftypes%2Fpost%2Fstatus%2Fv0.1.0");
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ function(HostApp, Core, Paths, URI) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Paths.getURL(url.toString(), "GET", callback);
|
APICalls.http_call(url.toString(), "GET", callback);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,11 @@ define([
|
||||||
"helper/HostApp",
|
"helper/HostApp",
|
||||||
"controller/Timeline",
|
"controller/Timeline",
|
||||||
"lib/URI",
|
"lib/URI",
|
||||||
"helper/Paths",
|
"helper/APICalls",
|
||||||
"helper/Core"
|
"helper/Core"
|
||||||
],
|
],
|
||||||
|
|
||||||
function(HostApp, Timeline, URI, Paths, Core) {
|
function(HostApp, Timeline, URI, APICalls, Core) {
|
||||||
|
|
||||||
|
|
||||||
function Mentions() {
|
function Mentions() {
|
||||||
|
@ -36,7 +36,7 @@ function(HostApp, Timeline, URI, Paths, Core) {
|
||||||
Mentions.prototype.newStatus = function(statuses, append) {
|
Mentions.prototype.newStatus = function(statuses, append) {
|
||||||
|
|
||||||
Timeline.prototype.newStatus.call(this, statuses, append);
|
Timeline.prototype.newStatus.call(this, statuses, append);
|
||||||
|
/*
|
||||||
if(this.is_not_init) {
|
if(this.is_not_init) {
|
||||||
|
|
||||||
for (var i = 0; i < statuses.length; i++) {
|
for (var i = 0; i < statuses.length; i++) {
|
||||||
|
@ -51,21 +51,21 @@ function(HostApp, Timeline, URI, Paths, Core) {
|
||||||
if(!append) HostApp.notificateUserAboutMention(status.content.text, name || status.entity, status.id, status.entity);
|
if(!append) HostApp.notificateUserAboutMention(status.content.text, name || status.entity, status.id, status.entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
this.is_not_init = true;
|
this.is_not_init = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mentions.prototype.getNewData = function(add_to_search, append) {
|
Mentions.prototype.getNewData = function(add_to_search, append, query) {
|
||||||
|
|
||||||
add_to_search = add_to_search || {};
|
add_to_search = add_to_search || {};
|
||||||
|
|
||||||
if (!add_to_search["mentioned_entity"]) {
|
if (!add_to_search["mentions"]) {
|
||||||
add_to_search["mentioned_entity"] = HostApp.stringForKey("entity");
|
add_to_search["mentions"] = HostApp.stringForKey("entity");
|
||||||
}
|
}
|
||||||
|
|
||||||
Timeline.prototype.getNewData.call(this, add_to_search, append);
|
Timeline.prototype.getNewData.call(this, add_to_search, append, query);
|
||||||
|
|
||||||
this.getLatestMentionRead();
|
//this.getLatestMentionRead();
|
||||||
}
|
}
|
||||||
|
|
||||||
Mentions.prototype.mentionRead = function(id, entity) {
|
Mentions.prototype.mentionRead = function(id, entity) {
|
||||||
|
@ -90,7 +90,7 @@ function(HostApp, Timeline, URI, Paths, Core) {
|
||||||
if (!status.__repost) {
|
if (!status.__repost) {
|
||||||
if (status && status.type == "https://tent.io/types/post/status/v0.1.0") {
|
if (status && status.type == "https://tent.io/types/post/status/v0.1.0") {
|
||||||
|
|
||||||
var url = URI(Paths.mkApiRootPath("/profile/" + encodeURIComponent("https://tent.io/types/info/cursor/v0.1.0")));
|
var url = URI(APICalls.mkApiRootPath("/profile/" + encodeURIComponent("https://tent.io/types/info/cursor/v0.1.0")));
|
||||||
var body = {
|
var body = {
|
||||||
"mentions": {
|
"mentions": {
|
||||||
"https://tent.io/types/post/status/v0.1.0": {
|
"https://tent.io/types/post/status/v0.1.0": {
|
||||||
|
@ -104,7 +104,7 @@ function(HostApp, Timeline, URI, Paths, Core) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Paths.getURL(url.toString(), "PUT", callback, JSON.stringify(body));
|
APICalls.http_call(url.toString(), "PUT", callback, JSON.stringify(body));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -115,11 +115,11 @@ function(HostApp, Timeline, URI, Paths, Core) {
|
||||||
|
|
||||||
Mentions.prototype.getLatestMentionRead = function() {
|
Mentions.prototype.getLatestMentionRead = function() {
|
||||||
|
|
||||||
var cursor_url = URI(Paths.mkApiRootPath("/profile/" + encodeURIComponent("https://tent.io/types/info/cursor/v0.1.0")));
|
var cursor_url = URI(APICalls.mkApiRootPath("/profile/" + encodeURIComponent("https://tent.io/types/info/cursor/v0.1.0")));
|
||||||
|
|
||||||
Paths.getURL(cursor_url.toString(), "GET", function(resp) {
|
APICalls.http_call(cursor_url.toString(), "GET", function(resp) {
|
||||||
|
|
||||||
var url = URI(Paths.mkApiRootPath("/posts/count"));
|
var url = URI(APICalls.mkApiRootPath("/posts/count"));
|
||||||
var post_types = [
|
var post_types = [
|
||||||
"https://tent.io/types/post/status/v0.1.0",
|
"https://tent.io/types/post/status/v0.1.0",
|
||||||
];
|
];
|
||||||
|
@ -139,7 +139,7 @@ function(HostApp, Timeline, URI, Paths, Core) {
|
||||||
HostApp.unreadMentions(this.unread_mentions);
|
HostApp.unreadMentions(this.unread_mentions);
|
||||||
}
|
}
|
||||||
|
|
||||||
Paths.getURL(url.toString(), "GET", callback); // FIXME: error callback
|
APICalls.http_call(url.toString(), "GET", callback); // FIXME: error callback
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
395
WebKit/scripts/controller/NewPost.js
Normal file
|
@ -0,0 +1,395 @@
|
||||||
|
define([
|
||||||
|
"helper/APICalls",
|
||||||
|
"helper/HostApp"
|
||||||
|
],
|
||||||
|
|
||||||
|
function(APICalls, HostApp) {
|
||||||
|
|
||||||
|
function NewPost() {
|
||||||
|
|
||||||
|
this.profiles = JSON.parse(controller.getCachedProfiles());
|
||||||
|
for (var key in this.profiles) {
|
||||||
|
var item = this.profiles[key];
|
||||||
|
if(!item.entity) item.entity = key;
|
||||||
|
if(!item.name) item.name = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mentions = [];
|
||||||
|
document.body.className = "new_post";
|
||||||
|
this.is_private = false;
|
||||||
|
|
||||||
|
// Textarea
|
||||||
|
|
||||||
|
this.container = $("<table id='new_post_container'><tr class='text'><td><div></div><textarea></textarea></td></tr><tr><td id='status_bar'></td></tr></table>");
|
||||||
|
this.textarea = this.container.find("textarea");
|
||||||
|
this.highlighter = this.container.find("div");
|
||||||
|
|
||||||
|
$(document.body).append(this.container);
|
||||||
|
|
||||||
|
this.textarea.keyup(this.keyup.bind(this));
|
||||||
|
this.textarea.keydown(this.keydown.bind(this));
|
||||||
|
|
||||||
|
this.suggestions = $("<ul id='suggestions'></ul>");
|
||||||
|
|
||||||
|
$(document.body).append(this.suggestions);
|
||||||
|
|
||||||
|
// Status bar
|
||||||
|
this.counter = $("<span>256</span>");
|
||||||
|
var buttons = $(
|
||||||
|
"<p>" +
|
||||||
|
//"<button id='images'><img src='images/images.png'></button>" +
|
||||||
|
"<button id='private'><img src='img/public.png'></button>" +
|
||||||
|
"<button id='send'><img src='img/send.png'></button>" +
|
||||||
|
"</p>");
|
||||||
|
|
||||||
|
this.buttons = {
|
||||||
|
images: buttons.find("#images"),
|
||||||
|
is_private: buttons.find("#private"),
|
||||||
|
send: buttons.find("#send")
|
||||||
|
}
|
||||||
|
|
||||||
|
//this.buttons.images.bind("click", this.addImage.bind(this));
|
||||||
|
this.buttons.is_private.bind("click", this.toggleIsPrivate.bind(this));
|
||||||
|
this.buttons.send.bind("click", this.send.bind(this));
|
||||||
|
|
||||||
|
this.container.find("#status_bar").append(this.counter);
|
||||||
|
this.container.find("#status_bar").append(buttons);
|
||||||
|
|
||||||
|
this.textarea.focus();
|
||||||
|
this.setIsPrivate(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
NewPost.prototype.setStatus = function(status_string) {
|
||||||
|
if (status_string && status_string.length > 0) {
|
||||||
|
this.status = JSON.parse(status_string);
|
||||||
|
this.setIsPrivate(this.status.permissions && !this.status.permissions.public);
|
||||||
|
this.setMentions(this.status);
|
||||||
|
} else {
|
||||||
|
this.status = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME set string, private, mentions, etc.
|
||||||
|
};
|
||||||
|
|
||||||
|
NewPost.prototype.setString = function(string) {
|
||||||
|
this.textarea.val(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
NewPost.prototype.setMentions = function(status) {
|
||||||
|
|
||||||
|
var mentions = [this.profiles[status.entity]];
|
||||||
|
var text = this.profiles[status.entity].name + " ";
|
||||||
|
var start = text.length;
|
||||||
|
|
||||||
|
if(status.mentions && status.mentions.length > 0) {
|
||||||
|
|
||||||
|
var mentions_text = ""
|
||||||
|
for (var i = 0; i < status.mentions.length; i++) {
|
||||||
|
|
||||||
|
var entity = status.mentions[i].entity;
|
||||||
|
|
||||||
|
// Sometimes there are mentions without entity, don't know why
|
||||||
|
if(entity) {
|
||||||
|
// fix broken profiles
|
||||||
|
var profile = this.profiles[entity];
|
||||||
|
if(!profile) {
|
||||||
|
profile = {};
|
||||||
|
this.profiles[entity] = profile;
|
||||||
|
}
|
||||||
|
if(!profile.entity) profile.entity = entity;
|
||||||
|
if(!profile.name) profile.name = entity;
|
||||||
|
|
||||||
|
// add profile to mentions and textarea
|
||||||
|
mentions.push(profile);
|
||||||
|
mentions_text += profile.name;
|
||||||
|
|
||||||
|
// add space after mention
|
||||||
|
if(i < status.mentions.length) {
|
||||||
|
mentions_text += " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mentions_text.length > 0) {
|
||||||
|
text += "\n\n/cc " + mentions_text;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mentions = mentions;
|
||||||
|
this.textarea.val(text);
|
||||||
|
this.parseText(text);
|
||||||
|
|
||||||
|
// Select other mentions so user can start writing and removing them
|
||||||
|
var end = text.length;
|
||||||
|
this.textarea.get(0).setSelectionRange(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
NewPost.prototype.setIsPrivate = function(is_private) {
|
||||||
|
this.is_private = is_private;
|
||||||
|
if (this.is_private) {
|
||||||
|
this.buttons.is_private.find("img").attr("src", "img/private.png");
|
||||||
|
} else {
|
||||||
|
this.buttons.is_private.find("img").attr("src", "img/public.png");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NewPost.prototype.toggleIsPrivate = function() {
|
||||||
|
this.setIsPrivate(!this.is_private);
|
||||||
|
}
|
||||||
|
|
||||||
|
NewPost.prototype.keyup = function(e) {
|
||||||
|
if(!e) return;
|
||||||
|
|
||||||
|
var key = e.which;
|
||||||
|
if(key != 38 && key != 40 && key != 13) {
|
||||||
|
|
||||||
|
this.applyText($(this.textarea).val());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
var lis = this.suggestions.find("li");
|
||||||
|
|
||||||
|
if (lis.length > 0) {
|
||||||
|
e.preventDefault();
|
||||||
|
var active = this.suggestions.find(".active");
|
||||||
|
if(key == 38) { // up
|
||||||
|
var prev = active.prev();
|
||||||
|
if(active.lentgh == 0) {
|
||||||
|
lis.last().addClass("active");
|
||||||
|
} else if(prev) {
|
||||||
|
active.removeClass("active");
|
||||||
|
prev.addClass("active");
|
||||||
|
}
|
||||||
|
} else if(key == 40) { // down
|
||||||
|
var next = active.next();
|
||||||
|
if(active.length == 0) {
|
||||||
|
lis.first().addClass("active");
|
||||||
|
} else if(next) {
|
||||||
|
active.removeClass("active");
|
||||||
|
next.addClass("active");
|
||||||
|
}
|
||||||
|
} else if(key == 13) { // enter
|
||||||
|
if(active.length > 0) {
|
||||||
|
this.replaceWithName(this.textarea.val(), this.suggestions.find("li.active").get(0).item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NewPost.prototype.keydown = function(e) {
|
||||||
|
var key = e.which;
|
||||||
|
var lis = this.suggestions.find("li");
|
||||||
|
if(lis.length > 0 && (key == 38 || key == 40 || key == 13)) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NewPost.prototype.replaceAll = function(txt, replace, with_this) {
|
||||||
|
return txt.replace(new RegExp(replace, 'g'),with_this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NewPost.prototype.replaceWithName = function(txt, with_item) {
|
||||||
|
var words = txt.match(/(^|\s)\^([^\s]+)/);
|
||||||
|
var replace = words[2];
|
||||||
|
|
||||||
|
var original = txt.replace("^" + replace, with_item.name + " ");
|
||||||
|
this.textarea.val(original);
|
||||||
|
|
||||||
|
this.mentions.push(with_item);
|
||||||
|
|
||||||
|
this.applyText(original);
|
||||||
|
}
|
||||||
|
|
||||||
|
NewPost.prototype.applyText = function (text) {
|
||||||
|
var words = text.match(/(^|\s)\^([^\s]+)/);
|
||||||
|
this.suggestions.html("");
|
||||||
|
|
||||||
|
if(words) {
|
||||||
|
var name = words[2];
|
||||||
|
for (var key in this.profiles) {
|
||||||
|
var item = this.profiles[key];
|
||||||
|
if((item.name.toLowerCase().indexOf(name.toLowerCase()) != -1) || item.entity.toLowerCase().indexOf(name.toLowerCase()) != -1) {
|
||||||
|
var li = $("<li><strong title='" + item.entity + "'>" + item.name + "</strong></li>")
|
||||||
|
li.get(0).item = item;
|
||||||
|
this.suggestions.append(li);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.suggestions.find("li:first-child").addClass("active");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.parseText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
NewPost.prototype.parseText = function(text) {
|
||||||
|
// parse the text:
|
||||||
|
// replace all the line braks by <br/>, and all the double spaces by the html version
|
||||||
|
text = this.replaceAll(text,'\n','<br/>');
|
||||||
|
text = this.replaceAll(text,' ',' ');
|
||||||
|
|
||||||
|
// replace the words by a highlighted version of the words
|
||||||
|
|
||||||
|
var remove = [];
|
||||||
|
|
||||||
|
for (var i=0;i<this.mentions.length; i++) {
|
||||||
|
var name = this.mentions[i].name;
|
||||||
|
if(text.match(new RegExp(name))) {
|
||||||
|
text = this.replaceAll(text, name, '<span>' + name + '</span>');
|
||||||
|
} else {
|
||||||
|
remove.push(this.mentions[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < remove.length; i++) {
|
||||||
|
this.mentions.splice(this.mentions.indexOf(remove[i]), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// re-inject the processed text into the div
|
||||||
|
this.highlighter.html(text);
|
||||||
|
|
||||||
|
var count = 256 - this.textarea.val().length + (this.mentions.length * 6);
|
||||||
|
this.counter.html(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
NewPost.prototype.send = function() {
|
||||||
|
|
||||||
|
var count = 256 - this.textarea.val().length + (this.mentions.length * 6);
|
||||||
|
if(count >= 0 && count <= 256) {
|
||||||
|
this.sendNewMessage();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
debug("BEEP");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NewPost.prototype.sendNewMessage = function() {
|
||||||
|
|
||||||
|
var content = this.textarea.val();
|
||||||
|
|
||||||
|
var type = "https://tent.io/types/status/v0#";
|
||||||
|
var data = {
|
||||||
|
type: type,
|
||||||
|
content: {
|
||||||
|
text: content
|
||||||
|
},
|
||||||
|
permissions: {
|
||||||
|
public: !this.is_private
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var mentions = [];
|
||||||
|
for (var i = 0; i < this.mentions.length; i++) {
|
||||||
|
var mention = this.mentions[i];
|
||||||
|
if(this.status && this.status.entity == mention.entity) {
|
||||||
|
mentions.push({
|
||||||
|
entity: this.status.entity,
|
||||||
|
post: this.status.id,
|
||||||
|
type: this.status.type
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
mentions.push({
|
||||||
|
entity: mention.entity
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data.mentions = mentions;
|
||||||
|
|
||||||
|
// Make tent flavored markdown mentions
|
||||||
|
for (var i = 0; i < this.mentions.length; i++) {
|
||||||
|
var mention = this.mentions[i];
|
||||||
|
data.content.text = this.replaceAll(data.content.text, mention.name, "^[" + mention.name + "](" + i + ")")
|
||||||
|
}
|
||||||
|
|
||||||
|
APICalls.post(HostApp.serverUrl("new_post"), JSON.stringify(data), {
|
||||||
|
content_type: data.type,
|
||||||
|
accept: 'application/vnd.tent.post.v0+json; type="https://tent.io/types/status/v0#"',
|
||||||
|
callback: function(resp) {
|
||||||
|
if (resp.status >= 200 < 300) {
|
||||||
|
new_post_window.closeWindow();
|
||||||
|
controller.getNewData();
|
||||||
|
} else {
|
||||||
|
new_post_window.beep();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
NewPost.prototype.sendNewMessageWithImage = function(content, in_reply_to_status_id, in_reply_to_entity, location, image_data_uri, is_private, callback) {
|
||||||
|
|
||||||
|
var url = URI(APICalls.mkApiRootPath("/posts"));
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
"type": "https://tent.io/types/post/photo/v0.1.0",
|
||||||
|
"published_at": parseInt(new Date().getTime() / 1000, 10),
|
||||||
|
"permissions": {
|
||||||
|
"public": !is_private
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"caption": content,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (location) {
|
||||||
|
data["content"]["location"] = { "type": "Point", "coordinates": location }
|
||||||
|
}
|
||||||
|
|
||||||
|
var mentions = this.parseMentions(content, in_reply_to_status_id, in_reply_to_entity);
|
||||||
|
if (mentions.length > 0) {
|
||||||
|
data["mentions"] = mentions;
|
||||||
|
if (is_private) {
|
||||||
|
var entities = {};
|
||||||
|
for (var i = 0; i < mentions.length; i++) {
|
||||||
|
var entity = mentions[i]["entity"]
|
||||||
|
entities[entity] = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
data["permissions"]["entities"] = entities;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var data_string = JSON.stringify(data);
|
||||||
|
|
||||||
|
var boundary = "TentAttachment----------TentAttachment";
|
||||||
|
var post = "--" + boundary + "\r\n";
|
||||||
|
|
||||||
|
post += 'Content-Disposition: form-data; name="post"; filename="post.json"\r\n';
|
||||||
|
post += 'Content-Length: ' + data_string.length + '\r\n';
|
||||||
|
post += 'Content-Type: application/vnd.tent.v0+json\r\n';
|
||||||
|
post += 'Content-Transfer-Encoding: binary\r\n\r\n';
|
||||||
|
post += data_string;
|
||||||
|
|
||||||
|
post += "\r\n--" + boundary + "\r\n";
|
||||||
|
|
||||||
|
var blob_string = image_data_uri.split(',')[1];
|
||||||
|
var mime_type = image_data_uri.split(',')[0].split(':')[1].split(';')[0];
|
||||||
|
var ext = "png";
|
||||||
|
if (mime_type == "image/jpeg") {
|
||||||
|
ext = "jpeg";
|
||||||
|
} else if (mime_type == "image/gif") {
|
||||||
|
ext = "gif";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
post += 'Content-Disposition: form-data; name="photos[0]"; filename="photo.' + ext + '"\r\n';
|
||||||
|
post += 'Content-Length: ' + blob_string.length + "\r\n";
|
||||||
|
post += 'Content-Type: ' + mime_type + "\r\n";
|
||||||
|
post += 'Content-Transfer-Encoding: base64\r\n\r\n';
|
||||||
|
post += blob_string;
|
||||||
|
post += "\r\n--" + boundary + "--\r\n";
|
||||||
|
|
||||||
|
var newCallback = function(resp) {
|
||||||
|
if (resp.status == 403) {
|
||||||
|
var err = JSON.parse(resp.responseText);
|
||||||
|
HostApp.alertTitleWithMessage(resp.statusText, err.error);
|
||||||
|
}
|
||||||
|
callback(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
APICalls.postMultipart(url.toString(), newCallback, post, boundary);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
return NewPost;
|
||||||
|
})
|
|
@ -1,38 +1,46 @@
|
||||||
define([
|
define([
|
||||||
"helper/HostApp",
|
"helper/HostApp",
|
||||||
"helper/Paths",
|
"helper/APICalls",
|
||||||
"helper/Hmac"
|
"helper/Hmac"
|
||||||
],
|
],
|
||||||
|
|
||||||
function(HostApp, Paths, Hmac) {
|
function(HostApp, APICalls, Hmac) {
|
||||||
|
|
||||||
function Oauth() {
|
function Oauth() {
|
||||||
this.app_info = {
|
this.app_info = {
|
||||||
"id": null,
|
"type": "https://tent.io/types/app/v0#",
|
||||||
"name": "Bungloo on " + HostApp.osType(),
|
"content": {
|
||||||
"description": "A small TentStatus client.",
|
"name": "Bungloo on " + HostApp.osType(),
|
||||||
"url": "http://jabs.nu/bungloo/",
|
"url": "http://jabs.nu/bungloo/",
|
||||||
"icon": "http://jabs.nu/bungloo/icon.png",
|
"description": "A desktop Tent client.",
|
||||||
"redirect_uris": [
|
"redirect_uri": "bungloo://oauthtoken",
|
||||||
"bungloo://oauthtoken"
|
"types": {
|
||||||
],
|
"read": [
|
||||||
"scopes": {
|
"https://tent.io/types/meta/v0",
|
||||||
"read_posts": "Uses posts to show them in a list",
|
"https://tent.io/types/relationship/v0",
|
||||||
"write_posts": "Posts on users behalf",
|
"https://tent.io/types/subscription/v0",
|
||||||
"read_profile": "Displays your own profile",
|
"https://tent.io/types/delete/v0",
|
||||||
"write_profile": "Updating profile and mentions pointer",
|
"https://tent.io/types/status/v0",
|
||||||
"read_followers": "Display a list of people who follow you",
|
"https://tent.io/types/repost/v0",
|
||||||
"write_followers": "Be able to block people who follow you",
|
"https://tent.io/types/photo/v0",
|
||||||
"read_followings": "Display following list and their older posts in conversations",
|
"https://tent.io/types/cursor/v0",
|
||||||
"write_followings": "Follow ne entities"
|
"https://tent.io/types/basic-profile/v0"
|
||||||
|
],
|
||||||
|
"write": [
|
||||||
|
"https://tent.io/types/relationship/v0",
|
||||||
|
"https://tent.io/types/subscription/v0",
|
||||||
|
"https://tent.io/types/delete/v0",
|
||||||
|
"https://tent.io/types/status/v0",
|
||||||
|
"https://tent.io/types/repost/v0",
|
||||||
|
"https://tent.io/types/photo/v0",
|
||||||
|
"https://tent.io/types/cursor/v0"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"scopes": ["permissions"]
|
||||||
},
|
},
|
||||||
"tent_profile_info_types": [ "all" ],
|
"permissions": {
|
||||||
"tent_post_types": [
|
"public": false
|
||||||
"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;
|
||||||
|
@ -61,13 +69,9 @@ function(HostApp, Paths, Hmac) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Oauth.prototype.apiRoot = function() {
|
|
||||||
return this.profile["https://tent.io/types/info/core/v0.1.0"]["servers"][0];
|
|
||||||
}
|
|
||||||
|
|
||||||
Oauth.prototype.requestProfileURL = function (entity) {
|
Oauth.prototype.requestProfileURL = function (entity) {
|
||||||
var those = this;
|
var those = this;
|
||||||
Paths.findProfileURL(entity,
|
APICalls.findProfileURL(entity,
|
||||||
function(profile_url) {
|
function(profile_url) {
|
||||||
if (profile_url && (profile_url.startsWith("http://") || profile_url.startsWith("https://"))) {
|
if (profile_url && (profile_url.startsWith("http://") || profile_url.startsWith("https://"))) {
|
||||||
those.register(profile_url);
|
those.register(profile_url);
|
||||||
|
@ -76,6 +80,7 @@ function(HostApp, Paths, Hmac) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
function(errorMessage) { // error callback
|
function(errorMessage) { // error callback
|
||||||
|
HostApp.authentificationDidNotSucceed(errorMessage);
|
||||||
HostApp.authentificationDidNotSucceed("Could not find profile for: " + entity);
|
HostApp.authentificationDidNotSucceed("Could not find profile for: " + entity);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -84,72 +89,76 @@ function(HostApp, Paths, Hmac) {
|
||||||
Oauth.prototype.register = function (url) {
|
Oauth.prototype.register = function (url) {
|
||||||
var those = this;
|
var those = this;
|
||||||
|
|
||||||
Paths.getURL(url, "GET", function(resp) {
|
APICalls.get(url, {
|
||||||
|
no_auth: true,
|
||||||
|
callback: function(resp) {
|
||||||
|
|
||||||
those.profile = JSON.parse(resp.responseText);
|
those.profile = JSON.parse(resp.responseText).post;
|
||||||
those.entity = those.profile["https://tent.io/types/info/core/v0.1.0"].entity;
|
those.entity = those.profile.content.entity;
|
||||||
HostApp.setStringForKey(those.entity, "entity")
|
HostApp.setStringForKey(those.entity, "entity")
|
||||||
HostApp.setStringForKey(those.apiRoot(), "api_root");
|
HostApp.setServerUrls(those.profile.content.servers[0].urls);
|
||||||
|
APICalls.post(HostApp.serverUrl("new_post"), JSON.stringify(those.app_info), {
|
||||||
|
content_type: "https://tent.io/types/app/v0#",
|
||||||
|
no_auth: true,
|
||||||
|
callback: function(resp) {
|
||||||
|
var app_id = JSON.parse(resp.responseText).post.id;
|
||||||
|
var header_string = resp.getAllResponseHeaders();
|
||||||
|
var regexp = /https:\/\/tent.io\/rels\/credentials/i
|
||||||
|
var url = APICalls.parseHeaderForLink(header_string, regexp);
|
||||||
|
|
||||||
var callback = function(resp) {
|
APICalls.get(url, {
|
||||||
var data = JSON.parse(resp.responseText);
|
content_type: "https://tent.io/types/app/v0#",
|
||||||
those.authRequest(data);
|
no_auth: true,
|
||||||
}
|
callback: function(resp) {
|
||||||
Paths.getURL(Paths.mkApiRootPath("/apps"), "POST", callback, JSON.stringify(those.app_info), false);
|
var data = JSON.parse(resp.responseText);
|
||||||
}, null, false);
|
those.authRequest(data.post, app_id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}});
|
||||||
|
|
||||||
|
}});
|
||||||
}
|
}
|
||||||
|
|
||||||
Oauth.prototype.authRequest = function(register_data) {
|
Oauth.prototype.authRequest = function(credentials, app_id) {
|
||||||
// id
|
|
||||||
// mac_key_id
|
HostApp.setStringForKey(app_id, "app_id");
|
||||||
// mac_key
|
HostApp.setStringForKey(credentials.id, "app_hawk_id");
|
||||||
// mac_algorithm
|
HostApp.setStringForKey(credentials.content.hawk_key, "app_hawk_key");
|
||||||
this.register_data = register_data;
|
HostApp.setStringForKey(credentials.content.hawk_algorithm, "app_hawk_algorithm");
|
||||||
|
|
||||||
// Needed for later App Registration Modification
|
|
||||||
HostApp.setStringForKey(register_data["mac_key"], "app_mac_key");
|
|
||||||
HostApp.setStringForKey(register_data["mac_key_id"], "app_mac_key_id");
|
|
||||||
HostApp.setStringForKey(register_data["id"], "app_id");
|
|
||||||
HostApp.setStringForKey(register_data["mac_algorithm"], "app_mac_algorithm");
|
|
||||||
|
|
||||||
this.state = Hmac.makeid(19);
|
this.state = Hmac.makeid(19);
|
||||||
var auth = "/oauth/authorize?client_id=" + register_data["id"]
|
var url = HostApp.serverUrl("oauth_auth") + "?client_id=" + app_id + "&state=" + this.state;
|
||||||
+ "&redirect_uri=" + this.app_info["redirect_uris"][0]
|
HostApp.openAuthorizationURL(url);
|
||||||
+ "&scope=" + Object.keys(this.app_info["scopes"]).join(",")
|
|
||||||
+ "&state=" + this.state
|
|
||||||
+ "&tent_post_types=" + this.app_info["tent_post_types"].join(",")
|
|
||||||
+ "&tent_profile_info_types=" + this.app_info["tent_profile_info_types"].join(",");
|
|
||||||
|
|
||||||
HostApp.openAuthorizationURL(this.apiRoot() + auth);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Oauth.prototype.requestAccessToken = function(responseBody) {
|
Oauth.prototype.requestAccessToken = function(responseBody) {
|
||||||
// /oauthtoken?code=51d0115b04d1ed94001dde751c5b360f&state=aQfH1VEohYsQr86qqyv
|
// /oauthtoken?code=51d0115b04d1ed94001dde751c5b360f&state=aQfH1VEohYsQr86qqyv
|
||||||
|
// https://app.example.com/oauth?code=K4m2J2bGI9rcICBqmUCYuQ&state=d173d2bb868a
|
||||||
|
|
||||||
var urlVars = Paths.getUrlVars(responseBody);
|
var urlVars = APICalls.getUrlVars(responseBody);
|
||||||
if(this.state && this.state != "" && urlVars["state"] == this.state) {
|
if(this.state && this.state != "" && urlVars["state"] == this.state) {
|
||||||
|
|
||||||
var url = Paths.mkApiRootPath("/apps/") + this.register_data["id"] + "/authorizations";
|
var url = HostApp.serverUrl("oauth_token");
|
||||||
|
|
||||||
var requestBody = JSON.stringify({
|
var requestBody = JSON.stringify({
|
||||||
'code' : urlVars["code"],
|
'code' : urlVars["code"],
|
||||||
'token_type' : "mac"
|
'token_type': "https://tent.io/oauth/hawk-token"
|
||||||
});
|
});
|
||||||
|
|
||||||
var those = this;
|
var those = this;
|
||||||
var http_method = "POST";
|
var auth_header = Hmac.makeHawkAuthHeader(
|
||||||
var callback = function(resp) {
|
|
||||||
those.requestAccessTokenTicketFinished(resp.responseText);
|
|
||||||
};
|
|
||||||
|
|
||||||
var auth_header = Hmac.makeAuthHeader(
|
|
||||||
url,
|
url,
|
||||||
http_method,
|
"POST",
|
||||||
HostApp.stringForKey("app_mac_key"),
|
HostApp.stringForKey("app_hawk_id"),
|
||||||
HostApp.stringForKey("app_mac_key_id")
|
HostApp.stringForKey("app_hawk_key")
|
||||||
);
|
);
|
||||||
|
|
||||||
Paths.getURL(url, http_method, callback, requestBody, auth_header);
|
APICalls.post(url, requestBody, {
|
||||||
|
content_type: "application/json",
|
||||||
|
auth_header: auth_header,
|
||||||
|
callback: function(resp) {
|
||||||
|
those.requestAccessTokenTicketFinished(resp.responseText);
|
||||||
|
}});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
console.error("State is not the same: {" + this.state + "} vs {" + urlVars["state"] + "}")
|
console.error("State is not the same: {" + this.state + "} vs {" + urlVars["state"] + "}")
|
||||||
|
@ -163,16 +172,16 @@ function(HostApp, Paths, Hmac) {
|
||||||
var access = JSON.parse(responseBody);
|
var access = JSON.parse(responseBody);
|
||||||
|
|
||||||
HostApp.setStringForKey(access["access_token"], "user_access_token");
|
HostApp.setStringForKey(access["access_token"], "user_access_token");
|
||||||
HostApp.setSecret(access["mac_key"]);
|
HostApp.setSecret(access["hawk_key"]);
|
||||||
HostApp.setStringForKey(access["mac_algorithm"], "user_mac_algorithm");
|
HostApp.setStringForKey(access["hawk_algorithm"], "user_hawk_algorithm");
|
||||||
HostApp.setStringForKey(access["token_type"], "user_token_type");
|
HostApp.setStringForKey(access["token_type"], "user_token_type");
|
||||||
|
|
||||||
HostApp.loggedIn();
|
HostApp.loggedIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
Oauth.prototype.logout = function() {
|
Oauth.prototype.logout = function() { // FIXME
|
||||||
|
|
||||||
var url = Paths.mkApiRootPath("/apps/" + HostApp.stringForKey("app_id"));
|
var url = APICalls.mkApiRootPath("/apps/" + HostApp.stringForKey("app_id"));
|
||||||
var http_method = "DELETE";
|
var http_method = "DELETE";
|
||||||
var auth_header = Hmac.makeAuthHeader(
|
var auth_header = Hmac.makeAuthHeader(
|
||||||
url,
|
url,
|
||||||
|
@ -181,7 +190,7 @@ function(HostApp, Paths, Hmac) {
|
||||||
HostApp.stringForKey("app_mac_key_id")
|
HostApp.stringForKey("app_mac_key_id")
|
||||||
);
|
);
|
||||||
|
|
||||||
Paths.getURL(url, http_method, function(resp) {
|
APICalls.http_call(url, http_method, function(resp) {
|
||||||
HostApp.setStringForKey(null, "app_mac_key");
|
HostApp.setStringForKey(null, "app_mac_key");
|
||||||
HostApp.setStringForKey(null, "app_mac_key_id");
|
HostApp.setStringForKey(null, "app_mac_key_id");
|
||||||
HostApp.setStringForKey(null, "app_id");
|
HostApp.setStringForKey(null, "app_id");
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
define([
|
define([
|
||||||
"helper/HostApp",
|
"helper/HostApp",
|
||||||
"helper/Core",
|
"helper/Core",
|
||||||
"helper/Paths",
|
"helper/APICalls",
|
||||||
"lib/URI"
|
"lib/URI"
|
||||||
],
|
],
|
||||||
|
|
||||||
function(HostApp, Core, Paths, URI) {
|
function(HostApp, Core, APICalls, URI) {
|
||||||
|
|
||||||
|
|
||||||
function Search() {
|
function Search() {
|
||||||
|
@ -79,7 +79,7 @@ function(HostApp, Core, Paths, URI) {
|
||||||
|
|
||||||
var _this = this;
|
var _this = this;
|
||||||
|
|
||||||
Paths.getURL(url.toString(), "GET", function(resp) {
|
APICalls.http_call(url.toString(), "GET", function(resp) {
|
||||||
|
|
||||||
var results = JSON.parse(resp.responseText).results;
|
var results = JSON.parse(resp.responseText).results;
|
||||||
if (results && results.length > 0) {
|
if (results && results.length > 0) {
|
||||||
|
|
|
@ -1,16 +1,13 @@
|
||||||
define([
|
define([
|
||||||
"helper/HostApp",
|
"helper/HostApp",
|
||||||
"helper/Paths",
|
"helper/APICalls",
|
||||||
"helper/Cache"
|
|
||||||
],
|
],
|
||||||
|
|
||||||
function(HostApp, Paths, Cache) {
|
function(HostApp, APICalls) {
|
||||||
|
|
||||||
|
|
||||||
function Sidebar() {
|
function Sidebar() {
|
||||||
|
|
||||||
this.cache = new Cache();
|
|
||||||
|
|
||||||
this.body = document.createElement("ul");
|
this.body = document.createElement("ul");
|
||||||
this.body.class = "sidebar";
|
this.body.class = "sidebar";
|
||||||
|
|
||||||
|
@ -84,57 +81,39 @@ function(HostApp, Paths, Cache) {
|
||||||
var entity = HostApp.stringForKey("entity");
|
var entity = HostApp.stringForKey("entity");
|
||||||
this.menu.user.title = entity;
|
this.menu.user.title = entity;
|
||||||
|
|
||||||
var img = this.menu.user.getElementsByTagName("img")[0];
|
var avatar = this.menu.user.getElementsByTagName("img")[0];
|
||||||
|
|
||||||
var _this = this;
|
var _this = this;
|
||||||
|
|
||||||
var profile_callback = function(p) {
|
var url = HostApp.serverUrl("posts_feed") + "?types=" + encodeURIComponent("https://tent.io/types/meta/v0") + "&entities=" + encodeURIComponent(entity);
|
||||||
|
APICalls.get(url, { callback: function(resp) {
|
||||||
|
var profiles = JSON.parse(resp.responseText);
|
||||||
|
|
||||||
var basic = p["https://tent.io/types/info/basic/v0.1.0"];
|
if(profiles.posts.length < 1) return;
|
||||||
|
var profile = profiles.posts[0];
|
||||||
|
bungloo.cache.profiles[entity] = profile;
|
||||||
|
|
||||||
if (p && basic) {
|
// Find and apply avatar
|
||||||
if(basic.name) {
|
if(profile.attachments) {
|
||||||
_this.menu.user.title = basic.name;
|
|
||||||
}
|
|
||||||
if(basic.avatar_url) {
|
|
||||||
|
|
||||||
img.onerror = function() {
|
var digest = null;
|
||||||
img.src = "img/sidebar/user.png";
|
for (var i = 0; i < profile.attachments.length; i++) {
|
||||||
img.src_inactive = img.src;
|
var attachment = profile.attachments[i];
|
||||||
img.src_active = img.src;
|
if(attachment.category == "avatar") {
|
||||||
|
digest = attachment.digest;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
img.src = basic.avatar_url;
|
if(digest) {
|
||||||
img.src_inactive = basic.avatar_url;
|
var _this = this;
|
||||||
img.src_active = basic.avatar_url;
|
avatar.onerror = function() { avatar.src = 'img/default-avatar.png' };
|
||||||
|
var avatar_url = profile.content.servers[0].urls.attachment.replace(/\{entity\}/, encodeURIComponent(profile.entity));
|
||||||
|
avatar.src = avatar_url.replace(/\{digest\}/, digest);
|
||||||
|
avatar.src_inactive = avatar.src;
|
||||||
|
avatar.src_active = avatar.src;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}});
|
||||||
}
|
|
||||||
|
|
||||||
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() {
|
Sidebar.prototype.removeEntityAvatar = function() {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
define([
|
define([
|
||||||
"helper/Core",
|
"helper/Core",
|
||||||
"helper/Paths",
|
"helper/APICalls",
|
||||||
"helper/HostApp",
|
"helper/HostApp",
|
||||||
"lib/URI"
|
"lib/URI"
|
||||||
],
|
],
|
||||||
|
|
||||||
function(Core, Paths, HostApp, URI) {
|
function(Core, APICalls, HostApp, URI) {
|
||||||
|
|
||||||
function Timeline() {
|
function Timeline() {
|
||||||
|
|
||||||
|
@ -21,6 +21,8 @@ function(Core, Paths, HostApp, URI) {
|
||||||
this.since_id_entity = null;
|
this.since_id_entity = null;
|
||||||
this.since_time = 0;
|
this.since_time = 0;
|
||||||
|
|
||||||
|
this.pages = {};
|
||||||
|
|
||||||
this.before = {id: null, entity: null, loading: false};
|
this.before = {id: null, entity: null, loading: false};
|
||||||
|
|
||||||
this.container = document.createElement("div");
|
this.container = document.createElement("div");
|
||||||
|
@ -46,8 +48,19 @@ function(Core, Paths, HostApp, URI) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Timeline.prototype.newStatus = function(statuses, append) {
|
Timeline.prototype.newStatus = function(_statuses, append) {
|
||||||
|
|
||||||
|
for (var entity in _statuses.profiles) {
|
||||||
|
if (_statuses.profiles[entity] != null) {
|
||||||
|
bungloo.cache.profiles[entity] = _statuses.profiles[entity];
|
||||||
|
} else {
|
||||||
|
bungloo.cache.profiles[entity] = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pages = _statuses.pages;
|
||||||
|
|
||||||
|
statuses = _statuses.posts;
|
||||||
if(statuses != null && statuses.length > 0) {
|
if(statuses != null && statuses.length > 0) {
|
||||||
|
|
||||||
this.before.loading = false;
|
this.before.loading = false;
|
||||||
|
@ -62,7 +75,7 @@ function(Core, Paths, HostApp, URI) {
|
||||||
this.since_id_entity = status.entity;
|
this.since_id_entity = status.entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status.type == "https://tent.io/types/post/status/v0.1.0" || status.type == "https://tent.io/types/post/photo/v0.1.0") {
|
if (status.type == "https://tent.io/types/status/v0#") {
|
||||||
|
|
||||||
var new_node = this.getStatusDOMElement(status);
|
var new_node = this.getStatusDOMElement(status);
|
||||||
|
|
||||||
|
@ -95,68 +108,69 @@ function(Core, Paths, HostApp, URI) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Timeline.prototype.getNewData = function(add_to_search, append) {
|
Timeline.prototype.getNewData = function(add_to_search, append, query) {
|
||||||
|
|
||||||
add_to_search = add_to_search || {};
|
add_to_search = add_to_search || {};
|
||||||
|
|
||||||
var those = this;
|
var those = this;
|
||||||
var url = URI(Paths.mkApiRootPath("/posts"));
|
var url = HostApp.serverUrl("posts_feed");
|
||||||
|
|
||||||
var post_types = [
|
if(!query) {
|
||||||
"https://tent.io/types/post/repost/v0.1.0",
|
|
||||||
"https://tent.io/types/post/status/v0.1.0",
|
|
||||||
"https://tent.io/types/post/delete/v0.1.0",
|
|
||||||
"https://tent.io/types/post/photo/v0.1.0"
|
|
||||||
];
|
|
||||||
url.addSearch("post_types", post_types.join(","));
|
|
||||||
//url.addSearch("sort_by", "published_at");
|
|
||||||
url.addSearch("limit", this.posts_limit);
|
|
||||||
|
|
||||||
if(this.since_id && !append) {
|
var uri = URI(url);
|
||||||
url.addSearch("since_id", this.since_id);
|
|
||||||
url.addSearch("since_id_entity", this.since_id_entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (key in add_to_search) {
|
var post_types = [
|
||||||
url.addSearch(key, add_to_search[key]);
|
"https://tent.io/types/status/v0#",
|
||||||
}
|
"https://tent.io/types/status/v0#reply",
|
||||||
|
"https://tent.io/types/repost/v0#",
|
||||||
|
"https://tent.io/types/delete/v0#",
|
||||||
|
//"https://tent.io/types/post/photo/v0.1.0"
|
||||||
|
];
|
||||||
|
uri.addSearch("types", post_types.join(","));
|
||||||
|
//uri.addSearch("sort_by", "published_at");
|
||||||
|
uri.addSearch("limit", this.posts_limit);
|
||||||
|
uri.addSearch("max_refs", 20);
|
||||||
|
uri.addSearch("profiles", "entity");
|
||||||
|
|
||||||
var http_method = "GET";
|
for (key in add_to_search) {
|
||||||
var callback = function(resp) {
|
uri.addSearch(key, add_to_search[key]);
|
||||||
|
|
||||||
those.reload_blocked = false;
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
var json = JSON.parse(resp.responseText);
|
|
||||||
those.newStatus(json, append);
|
|
||||||
|
|
||||||
} catch (e) {
|
|
||||||
console.error(url + " JSON parse error");
|
|
||||||
throw e;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var data = null;
|
url = uri.toString();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
url += query;
|
||||||
|
}
|
||||||
|
|
||||||
if (HostApp.stringForKey("user_access_token")) {
|
if (HostApp.stringForKey("user_access_token")) {
|
||||||
|
|
||||||
if (!this.reload_blocked) {
|
if (!this.reload_blocked) {
|
||||||
this.reload_blocked = true;
|
this.reload_blocked = true;
|
||||||
Paths.getURL(url.toString(), http_method, callback, data); // FIXME: error callback
|
|
||||||
|
APICalls.get(url, { callback: function(resp) {
|
||||||
|
// FIXME this is getting data when it shouldn't debug(resp.responseText)
|
||||||
|
|
||||||
|
those.reload_blocked = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
var json = JSON.parse(resp.responseText);
|
||||||
|
those.newStatus(json, append);
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
console.error(url + " JSON parse error");
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
} });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Timeline.prototype.getMoreStatusPosts = function() {
|
Timeline.prototype.getMoreStatusPosts = function() {
|
||||||
if (!this.before.loading) {
|
if (!this.before.loading) {
|
||||||
this.before.loading = true;
|
if (this.pages.next) {
|
||||||
var add_search = {
|
this.before.loading = true;
|
||||||
"before_id": this.body.lastChild.status.id,
|
this.getNewData({}, true, this.pages.next);
|
||||||
"before_id_entity": this.body.lastChild.status.entity
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getNewData(add_search, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
319
WebKit/scripts/helper/APICalls.js
Normal file
|
@ -0,0 +1,319 @@
|
||||||
|
define([
|
||||||
|
"jquery",
|
||||||
|
"helper/HostApp",
|
||||||
|
"helper/Hmac",
|
||||||
|
"helper/Cache"
|
||||||
|
],
|
||||||
|
|
||||||
|
function(jQuery, HostApp, Hmac, Cache) {
|
||||||
|
var APICalls = {};
|
||||||
|
|
||||||
|
APICalls.cache = new Cache();
|
||||||
|
|
||||||
|
APICalls.getUrlVars = function(url) {
|
||||||
|
var vars = [], hash;
|
||||||
|
if(url.indexOf("#") > -1) url = url.slice(0, url.indexOf("#"));
|
||||||
|
var hashes = url.slice(url.indexOf('?') + 1).split('&');
|
||||||
|
for(var i = 0; i < hashes.length; i++)
|
||||||
|
{
|
||||||
|
hash = hashes[i].split('=');
|
||||||
|
vars.push(hash[0]);
|
||||||
|
vars[hash[0]] = hash[1];
|
||||||
|
}
|
||||||
|
return vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
APICalls.http_call = function(options) {
|
||||||
|
|
||||||
|
if (typeof options === "string") {
|
||||||
|
console.error(options + " not implemented yet")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var content_type = null;
|
||||||
|
|
||||||
|
if((options.http_method == "POST" || options.http_method == "PUT") && !options.content_type) {
|
||||||
|
console.error("No content type for " + options.url);
|
||||||
|
return;
|
||||||
|
} else if(options.content_type != "AAA") {
|
||||||
|
if(options.content_type == "application/json") {
|
||||||
|
content_type = "application/json";
|
||||||
|
} else if(options.content_type) {
|
||||||
|
content_type = "application/vnd.tent.post.v0+json; charset=UTF-8; type=\"" + options.content_type + "\"";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
content_type = 'application/vnd.tent.post.v0+json; charset=UTF-8; type="https://tent.io/types/status/v0#"';
|
||||||
|
}
|
||||||
|
|
||||||
|
var settings = {
|
||||||
|
beforeSend: function(xhr) {
|
||||||
|
if (options.data) xhr.setRequestHeader("Content-Length", options.data.length);
|
||||||
|
|
||||||
|
if (options.accept) xhr.setRequestHeader("Accept", options.accept);
|
||||||
|
else xhr.setRequestHeader("Accept", "application/vnd.tent.post.v0+json");
|
||||||
|
|
||||||
|
var user_access_token = HostApp.stringForKey("user_access_token");
|
||||||
|
if (!options.auth_header && !options.no_auth && user_access_token) {
|
||||||
|
var auth_header = Hmac.makeHawkAuthHeader(
|
||||||
|
options.url,
|
||||||
|
options.http_method,
|
||||||
|
user_access_token,
|
||||||
|
HostApp.secret()//,
|
||||||
|
//HostApp.stringForKey("app_id")
|
||||||
|
);
|
||||||
|
xhr.setRequestHeader("Authorization", auth_header);
|
||||||
|
} else if(options.auth_header) {
|
||||||
|
xhr.setRequestHeader("Authorization", options.auth_header);
|
||||||
|
} else if(!options.no_auth) {
|
||||||
|
console.error("No user_access_token yet - " + options.url);
|
||||||
|
}
|
||||||
|
xhr.setRequestHeader("Cache-Control", "no-proxy");
|
||||||
|
},
|
||||||
|
url: options.url,
|
||||||
|
contentType: content_type,
|
||||||
|
type: options.http_method,
|
||||||
|
complete: options.callback,
|
||||||
|
data: options.data,
|
||||||
|
processData: false,
|
||||||
|
error: function(xhr, ajaxOptions, thrownError) {
|
||||||
|
console.error("HTTP CALL (" + xhr.status + ") " + xhr.statusText + " " + options.http_method + " URL(" + options.url + "): '" + xhr.responseText + "'");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
jQuery.ajax(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
APICalls.head = function(url, options) {
|
||||||
|
var settings = {
|
||||||
|
url: url,
|
||||||
|
http_method: "HEAD",
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var key in options) {
|
||||||
|
settings[key] = options[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
APICalls.http_call(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
APICalls.get = function(url, options) {
|
||||||
|
var settings = {
|
||||||
|
url: url,
|
||||||
|
http_method: "GET",
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var key in options) {
|
||||||
|
settings[key] = options[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
APICalls.http_call(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
APICalls.post = function(url, data, options) {
|
||||||
|
var settings = {
|
||||||
|
url: url,
|
||||||
|
http_method: "POST",
|
||||||
|
data: data
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var key in options) {
|
||||||
|
settings[key] = options[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
APICalls.http_call(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
APICalls.delete = function(url, options) {
|
||||||
|
var settings = {
|
||||||
|
url: url,
|
||||||
|
http_method: "DELETE"
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var key in options) {
|
||||||
|
settings[key] = options[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
APICalls.http_call(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
APICalls.put = function(url, data, options) {
|
||||||
|
var settings = {
|
||||||
|
url: url,
|
||||||
|
http_method: "PUT",
|
||||||
|
data: data
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var key in options) {
|
||||||
|
settings[key] = options[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
APICalls.http_call(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
APICalls.postMultipart = function(url, callback, data, boundary, accepts) {
|
||||||
|
|
||||||
|
accepts = accepts || "application/vnd.tent.v0+json";
|
||||||
|
|
||||||
|
jQuery.ajax({
|
||||||
|
|
||||||
|
beforeSend: function(xhr) {
|
||||||
|
xhr.setRequestHeader("Accept", accepts);
|
||||||
|
|
||||||
|
if (data) xhr.setRequestHeader("Content-Length", data.length);
|
||||||
|
|
||||||
|
var user_access_token = HostApp.stringForKey("user_access_token");
|
||||||
|
|
||||||
|
if (user_access_token) {
|
||||||
|
|
||||||
|
auth_header = Hmac.makeAuthHeader(
|
||||||
|
url,
|
||||||
|
"POST",
|
||||||
|
HostApp.secret(),
|
||||||
|
user_access_token
|
||||||
|
);
|
||||||
|
|
||||||
|
xhr.setRequestHeader("Authorization", auth_header);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
url: url,
|
||||||
|
contentType: "multipart/form-data;boundary=" + boundary,
|
||||||
|
type: "POST",
|
||||||
|
complete: callback,
|
||||||
|
data: data,
|
||||||
|
processData: false,
|
||||||
|
error: function(xhr, ajaxOptions, thrownError) {
|
||||||
|
console.error("postMultipart (" + xhr.status + ")" + xhr.statusText + " (" + url + "): '" + xhr.responseText + "'");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
APICalls.findProfileURL = function(entity, callback, errorCallback) {
|
||||||
|
var profile_url = APICalls.cache.profile_urls.getItem(entity);
|
||||||
|
|
||||||
|
if (profile_url && profile_url != "null") {
|
||||||
|
|
||||||
|
callback(profile_url);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
jQuery.ajax({
|
||||||
|
url: entity,
|
||||||
|
type: "HEAD",
|
||||||
|
complete: function(resp) {
|
||||||
|
if(resp) {
|
||||||
|
var headers = resp.getAllResponseHeaders();
|
||||||
|
|
||||||
|
var profile_urls = APICalls.parseHeaderForProfiles(headers);
|
||||||
|
var profile_url = null;
|
||||||
|
if(profile_urls.length > 0) {
|
||||||
|
var profile_url = profile_urls[0];
|
||||||
|
if (!profile_url.startsWith("http")) {
|
||||||
|
profile_url = entity + profile_url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (profile_url) {
|
||||||
|
APICalls.cache.profile_urls.setItem(entity, profile_url);
|
||||||
|
callback(profile_url);
|
||||||
|
} else {
|
||||||
|
APICalls.http_call(entity, "GET", function(resp) {
|
||||||
|
|
||||||
|
if (resp.status >= 200 && resp.status < 300) {
|
||||||
|
var doc = document.implementation.createHTMLDocument("");
|
||||||
|
doc.documentElement.innerHTML = resp.responseText;
|
||||||
|
var links = $(doc).find("link[rel='https://tent.io/rels/meta-post']");
|
||||||
|
|
||||||
|
if (links.length > 0) {
|
||||||
|
var href = links.get(0).href;
|
||||||
|
APICalls.cache.profile_urls.setItem(entity, href);
|
||||||
|
if (!href.startsWith("http")) {
|
||||||
|
href = entity + href;
|
||||||
|
}
|
||||||
|
callback(href);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if(errorCallback) errorCallback(entity + " has no profile URL");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(errorCallback) errorCallback(entity + " has no profile URL");
|
||||||
|
}
|
||||||
|
|
||||||
|
}, null, false, false);
|
||||||
|
|
||||||
|
//if(errorCallback) errorCallback(entity + " has no profile URL");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function(xhr, ajaxOptions, thrownError) {
|
||||||
|
console.error("findProfileURL " + xhr.statusText + " (" + entity + "): " + xhr.responseText);
|
||||||
|
if (errorCallback) errorCallback(xhr.statusText + " - " + xhr.responseText)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
APICalls.mkApiRootPath = function(path) {
|
||||||
|
|
||||||
|
var api_root = HostApp.stringForKey("api_root");
|
||||||
|
|
||||||
|
if((api_root.substring(api_root.length - 1, api_root.length) != "/") && (path.substring(0, 1) != "/")) {
|
||||||
|
api_root += "/";
|
||||||
|
} else if((api_root.substring(api_root.length - 1, api_root.length) == "/") && (path.substring(0, 1) == "/")) {
|
||||||
|
api_root = api_root.substring(0, api_root.length -1);
|
||||||
|
}
|
||||||
|
return api_root + path;
|
||||||
|
}
|
||||||
|
|
||||||
|
APICalls.parseHeaderForProfiles = function(header_string) {
|
||||||
|
var regexp = /https:\/\/tent.io\/rels\/meta-post/i;
|
||||||
|
return APICalls.parseHeaderForLink(header_string, regexp);
|
||||||
|
}
|
||||||
|
|
||||||
|
APICalls.parseHeader = function(header_string) {
|
||||||
|
var header_strings = header_string.split(/\n/);
|
||||||
|
var headers = {};
|
||||||
|
for (var i = 0; i < header_strings.length; i++) {
|
||||||
|
var hs = header_strings[i].split(/:(.+)?/);
|
||||||
|
headers[hs[0]] = hs[1];
|
||||||
|
}
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
APICalls.getCount = function(resp) {
|
||||||
|
var count = 0;
|
||||||
|
var headers = APICalls.parseHeader(resp.getAllResponseHeaders());
|
||||||
|
if(headers["Count"]) count = parseInt(headers["Count"], 10);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
APICalls.parseHeaderForLink = function(header_string, match) {
|
||||||
|
var headers = header_string.split(/\n/);
|
||||||
|
var links = [];
|
||||||
|
for (var i = 0; i < headers.length; i++) {
|
||||||
|
var header = headers[i];
|
||||||
|
if (header.match(/^Link:(.*)/i)) {
|
||||||
|
links.push(header.replace(/\r/, "").substr(5).trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var items = [];
|
||||||
|
for (var i = 0; i < links.length; i++) {
|
||||||
|
items = items.concat(links[i].split(","));
|
||||||
|
}
|
||||||
|
var things = [];
|
||||||
|
for (var i = 0; i < items.length; i++) {
|
||||||
|
var item = items[i];
|
||||||
|
if (item.match(match)) {
|
||||||
|
var n = item.match(/<([^>]*)>/);
|
||||||
|
if (n) {
|
||||||
|
things.push(n[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return things;
|
||||||
|
}
|
||||||
|
|
||||||
|
return APICalls;
|
||||||
|
});
|
|
@ -40,12 +40,12 @@ function(URI, CacheStorage, require) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var url = URI(require("helper/Paths").mkApiRootPath("/followings"));
|
var url = URI(require("helper/APICalls").mkApiRootPath("/followings"));
|
||||||
if (this.followings_before_id) {
|
if (this.followings_before_id) {
|
||||||
url.addSearch("before_id", this.followings_before_id);
|
url.addSearch("before_id", this.followings_before_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
require("helper/Paths").getURL(url, "GET", callback);
|
require("helper/APICalls").getURL(url, "GET", callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
Cache.prototype.periodicallyGetFollowings = function() {
|
Cache.prototype.periodicallyGetFollowings = function() {
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
define([
|
define([
|
||||||
"jquery",
|
"jquery",
|
||||||
"helper/Paths",
|
"helper/APICalls",
|
||||||
"lib/URI",
|
"lib/URI",
|
||||||
"helper/HostApp",
|
"helper/HostApp",
|
||||||
"helper/Cache",
|
|
||||||
"lib/Timeago",
|
"lib/Timeago",
|
||||||
"lib/SingleDoubleClick"
|
"lib/SingleDoubleClick"
|
||||||
],
|
],
|
||||||
|
|
||||||
function(jQuery, Paths, URI, HostApp, Cache) {
|
function(jQuery, APICalls, URI, HostApp) {
|
||||||
|
|
||||||
function Core() {
|
function Core() {
|
||||||
this.cache = new Cache();
|
|
||||||
this.saveScrollTop = 0;
|
this.saveScrollTop = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,6 +67,7 @@ function(jQuery, Paths, URI, HostApp, Cache) {
|
||||||
image.className = "image";
|
image.className = "image";
|
||||||
image.src = "img/default-avatar.png";
|
image.src = "img/default-avatar.png";
|
||||||
image.onmousedown = function(e) { e.preventDefault(); };
|
image.onmousedown = function(e) { e.preventDefault(); };
|
||||||
|
image.onerror = function() { this.src = 'img/default-avatar.png' };
|
||||||
item.appendChild(image);
|
item.appendChild(image);
|
||||||
|
|
||||||
var image_username = a.cloneNode();
|
var image_username = a.cloneNode();
|
||||||
|
@ -162,7 +161,28 @@ function(jQuery, Paths, URI, HostApp, Cache) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Core.prototype.getStatusDOMElement = function(status) {
|
Core.prototype.getStatusDOMElement = function(status) {
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
"app": {
|
||||||
|
"id": "P8FJjaiRv0AKXfjUMd_4YQ",
|
||||||
|
"name": "Bungloo on Linux",
|
||||||
|
"url": "http:\/\/jabs.nu\/bungloo\/"
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"text": "jeena test"
|
||||||
|
},
|
||||||
|
"entity": "http:\/\/155969d81672.alpha.attic.is",
|
||||||
|
"id": "HlSXe8MREzU4h2fGLGSnCA",
|
||||||
|
"published_at": 1369566009,
|
||||||
|
"received_at": 1369566008799,
|
||||||
|
"type": "https:\/\/tent.io\/types\/status\/v0#",
|
||||||
|
"version": {
|
||||||
|
"id": "a2f702b4615c7d7dd0f98c73d7b55749880bf6e437a77349454ff10745d134c6",
|
||||||
|
"published_at": 1369566009,
|
||||||
|
"received_at": 1369566008799
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
var _this = this;
|
var _this = this;
|
||||||
|
|
||||||
var template = this.getTemplate();
|
var template = this.getTemplate();
|
||||||
|
@ -191,7 +211,8 @@ function(jQuery, Paths, URI, HostApp, Cache) {
|
||||||
template.reply_to.onclick = function() {
|
template.reply_to.onclick = function() {
|
||||||
|
|
||||||
var mentions = [];
|
var mentions = [];
|
||||||
var status_mentions = status.mentions.slice(0);
|
var status_mentions = [];
|
||||||
|
if(status.mentions) status_mentions = status.mentions.slice(0);
|
||||||
|
|
||||||
if (typeof status.__repost != "undefined") {
|
if (typeof status.__repost != "undefined") {
|
||||||
status_mentions.push({entity:status.__repost.entity});
|
status_mentions.push({entity:status.__repost.entity});
|
||||||
|
@ -202,7 +223,7 @@ function(jQuery, Paths, URI, HostApp, Cache) {
|
||||||
mentions.push(mention);
|
mentions.push(mention);
|
||||||
}
|
}
|
||||||
|
|
||||||
_this.replyTo(status.entity, status.id, mentions, (status && status.permissions && !status.permissions.public));
|
_this.replyTo(status);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +233,8 @@ function(jQuery, Paths, URI, HostApp, Cache) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template.username.innerText = status.entity;
|
if(bungloo.cache.profiles[status.entity].name) template.username.innerText = bungloo.cache.profiles[status.entity].name;
|
||||||
|
else template.username.innerText = status.entity;
|
||||||
template.username.href = status.entity;
|
template.username.href = status.entity;
|
||||||
template.username.title = status.entity;
|
template.username.title = status.entity;
|
||||||
template.username.onclick = function() {
|
template.username.onclick = function() {
|
||||||
|
@ -220,47 +242,12 @@ function(jQuery, Paths, URI, HostApp, Cache) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(bungloo.cache.profiles[status.entity].avatar_digest) {
|
||||||
|
template.image.src = HostApp.serverUrl("attachment").replace(/\{entity\}/, encodeURIComponent(status.entity)).replace(/\{digest\}/, bungloo.cache.profiles[status.entity].avatar_digest);
|
||||||
|
}
|
||||||
|
|
||||||
template.image.onclick = template.username.onclick;
|
template.image.onclick = template.username.onclick;
|
||||||
|
|
||||||
var profile_callback = function(p) {
|
|
||||||
|
|
||||||
var basic = p["https://tent.io/types/info/basic/v0.1.0"];
|
|
||||||
|
|
||||||
if (p && basic) {
|
|
||||||
if(basic.name) {
|
|
||||||
template.username.title = template.username.innerText;
|
|
||||||
template.username.innerText = basic.name;
|
|
||||||
}
|
|
||||||
if(basic.avatar_url) {
|
|
||||||
template.image.onerror = function() { template.image.src = 'img/default-avatar.png' };
|
|
||||||
template.image.src = basic.avatar_url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
var p = this.cache.profiles.getItem(status.entity);
|
|
||||||
|
|
||||||
if (p && p != "null") {
|
|
||||||
|
|
||||||
profile_callback(p);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
Paths.findProfileURL(status.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(status.entity, p);
|
|
||||||
profile_callback(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
}, null, false); // do not send auth-headers
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status && status.permissions && !status.permissions.public) {
|
if (status && status.permissions && !status.permissions.public) {
|
||||||
template.is_private.style.display = '';
|
template.is_private.style.display = '';
|
||||||
|
@ -290,6 +277,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)
|
this.afterChangingTextinMessageHTML(template.message)
|
||||||
|
|
||||||
|
/*
|
||||||
if (status.type == "https://tent.io/types/post/photo/v0.1.0") {
|
if (status.type == "https://tent.io/types/post/photo/v0.1.0") {
|
||||||
|
|
||||||
for (var i = 0; i < status.attachments.length; i++) {
|
for (var i = 0; i < status.attachments.length; i++) {
|
||||||
|
@ -308,18 +296,19 @@ function(jQuery, Paths, URI, HostApp, Cache) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status.entity == HostApp.stringForKey("entity")) {
|
if (status.entity == HostApp.stringForKey("entity")) {
|
||||||
var url = Paths.mkApiRootPath("/posts/" + status.id + "/attachments/" + attachment.name);
|
var url = APICalls.mkApiRootPath("/posts/" + status.id + "/attachments/" + attachment.name);
|
||||||
Paths.getURL(url, "GET", callback, null, null, attachment.type);
|
APICalls.http_call(url, "GET", callback, null, null, attachment.type);
|
||||||
} else {
|
} else {
|
||||||
var url = Paths.mkApiRootPath("/posts/" + encodeURIComponent(status.entity) + "/" + status.id + "/attachments/" + attachment.name);
|
var url = APICalls.mkApiRootPath("/posts/" + encodeURIComponent(status.entity) + "/" + status.id + "/attachments/" + attachment.name);
|
||||||
Paths.getURL(url, "GET", callback, null, null, attachment.type);
|
APICalls.http_call(url, "GET", callback, null, null, attachment.type);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
this.findMentions(template.message, status.mentions);
|
this.findMentions(template.message, status.mentions);
|
||||||
|
|
||||||
|
/*
|
||||||
for (var i = 0; i < status.mentions.length; i++) {
|
for (var i = 0; i < status.mentions.length; i++) {
|
||||||
var mention = status.mentions[i];
|
var mention = status.mentions[i];
|
||||||
if (mention.entity == HostApp.stringForKey("entity")) {
|
if (mention.entity == HostApp.stringForKey("entity")) {
|
||||||
|
@ -327,10 +316,10 @@ function(jQuery, Paths, URI, HostApp, Cache) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
var published_at = typeof status.__repost == "undefined" ? status.published_at : status.__repost.published_at;
|
var published_at = typeof status.__repost == "undefined" ? status.version.published_at : status.__repost.published_at;
|
||||||
var time = document.createElement("abbr");
|
var time = document.createElement("abbr");
|
||||||
time.innerText = this.ISODateString(new Date(published_at * 1000));
|
time.innerText = this.ISODateString(new Date(published_at));
|
||||||
time.title = time.innerText;
|
time.title = time.innerText;
|
||||||
time.className = "timeago";
|
time.className = "timeago";
|
||||||
jQuery(time).timeago();
|
jQuery(time).timeago();
|
||||||
|
@ -366,9 +355,11 @@ function(jQuery, Paths, URI, HostApp, Cache) {
|
||||||
template.source.innerHTML = status.__repost.app.name;
|
template.source.innerHTML = status.__repost.app.name;
|
||||||
template.source.title = status.__repost.app.url;
|
template.source.title = status.__repost.app.url;
|
||||||
} else {
|
} else {
|
||||||
template.source.href = status.app.url;
|
if(status.app) {
|
||||||
template.source.innerHTML = status.app.name;
|
template.source.href = status.app.url;
|
||||||
template.source.title = status.app.url;
|
template.source.innerHTML = status.app.name;
|
||||||
|
template.source.title = status.app.url;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return template.item;
|
return template.item;
|
||||||
|
@ -431,9 +422,9 @@ function(jQuery, Paths, URI, HostApp, Cache) {
|
||||||
});
|
});
|
||||||
|
|
||||||
var _this = this;
|
var _this = this;
|
||||||
Paths.findProfileURL(repost.entity, function(profile_url) {
|
APICalls.findProfileURL(repost.entity, function(profile_url) {
|
||||||
if (profile_url) {
|
if (profile_url) {
|
||||||
Paths.getURL(profile_url, "GET", function(resp) {
|
APICalls.http_call(profile_url, "GET", function(resp) {
|
||||||
if (resp.status >= 200 && resp.status < 400) {
|
if (resp.status >= 200 && resp.status < 400) {
|
||||||
var _p = JSON.parse(resp.responseText);
|
var _p = JSON.parse(resp.responseText);
|
||||||
_this.cache.profiles.setItem(repost.entity, _p);
|
_this.cache.profiles.setItem(repost.entity, _p);
|
||||||
|
@ -460,14 +451,14 @@ function(jQuery, Paths, URI, HostApp, Cache) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Paths.findProfileURL(repost.content.entity, function(profile_url) {
|
APICalls.findProfileURL(repost.content.entity, function(profile_url) {
|
||||||
if (profile_url) {
|
if (profile_url) {
|
||||||
|
|
||||||
Paths.getURL(profile_url, "GET", function(resp) {
|
APICalls.http_call(profile_url, "GET", function(resp) {
|
||||||
|
|
||||||
var profile = JSON.parse(resp.responseText);
|
var profile = JSON.parse(resp.responseText);
|
||||||
var server = profile["https://tent.io/types/info/core/v0.1.0"].servers[0];
|
var server = profile["https://tent.io/types/info/core/v0.1.0"].servers[0];
|
||||||
Paths.getURL(URI(server + "/posts/" + repost.content.id).toString(), "GET", callback, null, false);
|
APICalls.http_call(URI(server + "/posts/" + repost.content.id).toString(), "GET", callback, null, false);
|
||||||
|
|
||||||
}, null, false); // do not send auth-headers
|
}, null, false); // do not send auth-headers
|
||||||
}
|
}
|
||||||
|
@ -475,55 +466,8 @@ function(jQuery, Paths, URI, HostApp, Cache) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Core.prototype.sendNewMessage = function(content, in_reply_to_status_id, in_reply_to_entity, location, image_data_uri, is_private, callback) {
|
|
||||||
|
|
||||||
if (image_data_uri) {
|
|
||||||
|
|
||||||
this.sendNewMessageWithImage(content, in_reply_to_status_id, in_reply_to_entity, location, image_data_uri, is_private, callback);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
var url = URI(Paths.mkApiRootPath("/posts"));
|
|
||||||
|
|
||||||
var http_method = "POST";
|
|
||||||
|
|
||||||
var data = {
|
|
||||||
"type": "https://tent.io/types/post/status/v0.1.0",
|
|
||||||
"published_at": parseInt(new Date().getTime() / 1000, 10),
|
|
||||||
"permissions": {
|
|
||||||
"public": !is_private
|
|
||||||
},
|
|
||||||
"content": {
|
|
||||||
"text": content,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
if (location) {
|
|
||||||
data["content"]["location"] = { "type": "Point", "coordinates": location }
|
|
||||||
}
|
|
||||||
|
|
||||||
var mentions = this.parseMentions(content, in_reply_to_status_id, in_reply_to_entity);
|
|
||||||
|
|
||||||
if (mentions.length > 0) {
|
|
||||||
data["mentions"] = mentions;
|
|
||||||
if (is_private) {
|
|
||||||
var entities = {};
|
|
||||||
for (var i = 0; i < mentions.length; i++) {
|
|
||||||
var entity = mentions[i]["entity"]
|
|
||||||
entities[entity] = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
data["permissions"]["entities"] = entities;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Paths.getURL(url.toString(), http_method, callback, JSON.stringify(data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Core.prototype.repost = function(id, entity, callback) {
|
Core.prototype.repost = function(id, entity, callback) {
|
||||||
var url = URI(Paths.mkApiRootPath("/posts"));
|
var url = URI(APICalls.mkApiRootPath("/posts"));
|
||||||
|
|
||||||
var data = {
|
var data = {
|
||||||
"type": "https://tent.io/types/post/repost/v0.1.0",
|
"type": "https://tent.io/types/post/repost/v0.1.0",
|
||||||
|
@ -549,88 +493,14 @@ function(jQuery, Paths, URI, HostApp, Cache) {
|
||||||
_this.highlight(id);
|
_this.highlight(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
Paths.getURL(url.toString(), "POST", new_callback, JSON.stringify(data));
|
APICalls.http_call(url.toString(), "POST", new_callback, JSON.stringify(data));
|
||||||
}
|
|
||||||
|
|
||||||
Core.prototype.sendNewMessageWithImage = function(content, in_reply_to_status_id, in_reply_to_entity, location, image_data_uri, is_private, callback) {
|
|
||||||
|
|
||||||
var url = URI(Paths.mkApiRootPath("/posts"));
|
|
||||||
|
|
||||||
var data = {
|
|
||||||
"type": "https://tent.io/types/post/photo/v0.1.0",
|
|
||||||
"published_at": parseInt(new Date().getTime() / 1000, 10),
|
|
||||||
"permissions": {
|
|
||||||
"public": !is_private
|
|
||||||
},
|
|
||||||
"content": {
|
|
||||||
"caption": content,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
if (location) {
|
|
||||||
data["content"]["location"] = { "type": "Point", "coordinates": location }
|
|
||||||
}
|
|
||||||
|
|
||||||
var mentions = this.parseMentions(content, in_reply_to_status_id, in_reply_to_entity);
|
|
||||||
if (mentions.length > 0) {
|
|
||||||
data["mentions"] = mentions;
|
|
||||||
if (is_private) {
|
|
||||||
var entities = {};
|
|
||||||
for (var i = 0; i < mentions.length; i++) {
|
|
||||||
var entity = mentions[i]["entity"]
|
|
||||||
entities[entity] = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
data["permissions"]["entities"] = entities;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var data_string = JSON.stringify(data);
|
|
||||||
|
|
||||||
var boundary = "TentAttachment----------TentAttachment";
|
|
||||||
var post = "--" + boundary + "\r\n";
|
|
||||||
|
|
||||||
post += 'Content-Disposition: form-data; name="post"; filename="post.json"\r\n';
|
|
||||||
post += 'Content-Length: ' + data_string.length + '\r\n';
|
|
||||||
post += 'Content-Type: application/vnd.tent.v0+json\r\n';
|
|
||||||
post += 'Content-Transfer-Encoding: binary\r\n\r\n';
|
|
||||||
post += data_string;
|
|
||||||
|
|
||||||
post += "\r\n--" + boundary + "\r\n";
|
|
||||||
|
|
||||||
var blob_string = image_data_uri.split(',')[1];
|
|
||||||
var mime_type = image_data_uri.split(',')[0].split(':')[1].split(';')[0];
|
|
||||||
var ext = "png";
|
|
||||||
if (mime_type == "image/jpeg") {
|
|
||||||
ext = "jpeg";
|
|
||||||
} else if (mime_type == "image/gif") {
|
|
||||||
ext = "gif";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
post += 'Content-Disposition: form-data; name="photos[0]"; filename="photo.' + ext + '"\r\n';
|
|
||||||
post += 'Content-Length: ' + blob_string.length + "\r\n";
|
|
||||||
post += 'Content-Type: ' + mime_type + "\r\n";
|
|
||||||
post += 'Content-Transfer-Encoding: base64\r\n\r\n';
|
|
||||||
post += blob_string;
|
|
||||||
post += "\r\n--" + boundary + "--\r\n";
|
|
||||||
|
|
||||||
var newCallback = function(resp) {
|
|
||||||
if (resp.status == 403) {
|
|
||||||
var err = JSON.parse(resp.responseText);
|
|
||||||
HostApp.alertTitleWithMessage(resp.statusText, err.error);
|
|
||||||
}
|
|
||||||
callback(resp);
|
|
||||||
}
|
|
||||||
|
|
||||||
Paths.postMultipart(url.toString(), newCallback, post, boundary);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Core.prototype.remove = function(id, callback, type) {
|
Core.prototype.remove = function(id, callback, type) {
|
||||||
type = type || "post";
|
type = type || "post";
|
||||||
if (confirm("Really delete this " + type + "?")) {
|
if (confirm("Really delete this " + type + "?")) {
|
||||||
var url = URI(Paths.mkApiRootPath("/posts/" + id));
|
var url = URI(APICalls.mkApiRootPath("/posts/" + id));
|
||||||
Paths.getURL(url.toString(), "DELETE", callback);
|
APICalls.http_call(url.toString(), "DELETE", callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -738,9 +608,9 @@ function(jQuery, Paths, URI, HostApp, Cache) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
Paths.findProfileURL(mention.entity, function(profile_url) {
|
APICalls.findProfileURL(mention.entity, function(profile_url) {
|
||||||
if (profile_url) {
|
if (profile_url) {
|
||||||
Paths.getURL(profile_url, "GET", function(resp) {
|
APICalls.http_call(profile_url, "GET", function(resp) {
|
||||||
if (resp.status >= 200 && resp.status < 400) {
|
if (resp.status >= 200 && resp.status < 400) {
|
||||||
var p = JSON.parse(resp.responseText);
|
var p = JSON.parse(resp.responseText);
|
||||||
_this.cache.profiles.setItem(mention.entity, p);
|
_this.cache.profiles.setItem(mention.entity, p);
|
||||||
|
@ -796,27 +666,14 @@ function(jQuery, Paths, URI, HostApp, Cache) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Core.prototype.replaceURLWithHTMLLinks = function(text, entities, message_node) {
|
Core.prototype.replaceURLWithHTMLLinks = function(text, entities, message_node) {
|
||||||
|
// FIXME: this has to be done better so one can nest that stuff and escape with \
|
||||||
var callback = function(url) {
|
return text.replace(/_([^_]+)_/g, "<em>$1</em>")
|
||||||
|
.replace(/\*([^\*]+)\*/g, "<strong>$1</strong>")
|
||||||
var result;
|
.replace(/`([^`]+)`/g, "<code>$1</code>")
|
||||||
|
.replace(/~([^~]+)~/g, "<del>$1</del>")
|
||||||
if (entities && entities.some(function(x) { return x == url })) {
|
.replace(/\#([^\s]+)/g, "<a class='hash' href=\"javascript:bungloo.search.searchFor('$1')\">#$1</a>")
|
||||||
result = url;
|
.replace(/(^|[^\^])\[([^\]]+)\]\(([^\)]+)\)/g, "<a class='link' href='javascript:controller.openURL(\"$3\");'>$2</a>")
|
||||||
} else {
|
.replace(/\^\[([^\]]+)\]\((\d+)\)/g, "<a class='name' href='#' onclick='bungloo.entityProfile.showEntity(this, $2); return false;'>$1</a>");
|
||||||
|
|
||||||
result = url;
|
|
||||||
if (url.startsWith("http://") || url.startsWith("https://")) {
|
|
||||||
result = '<a href="' + url + '">' + url + '</a>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
var hash = /(^|\s)(#)(\w+)/ig;
|
|
||||||
|
|
||||||
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) {
|
||||||
|
@ -838,7 +695,7 @@ function(jQuery, Paths, URI, HostApp, Cache) {
|
||||||
|
|
||||||
} else if(word.startsWith("http://youtube.com/") || word.startsWith("http://www.youtube.com/") || word.startsWith("https://youtube.com/") || word.startsWith("https://www.youtube.com/")) {
|
} else if(word.startsWith("http://youtube.com/") || word.startsWith("http://www.youtube.com/") || word.startsWith("https://youtube.com/") || word.startsWith("https://www.youtube.com/")) {
|
||||||
|
|
||||||
var v = Paths.getUrlVars(word)["v"];
|
var v = APICalls.getUrlVars(word)["v"];
|
||||||
this.addYouTube(v, images);
|
this.addYouTube(v, images);
|
||||||
|
|
||||||
} else if (word.startsWith("http://youtu.be/") || word.startsWith("https://youtu.be/")) {
|
} else if (word.startsWith("http://youtu.be/") || word.startsWith("https://youtu.be/")) {
|
||||||
|
@ -890,19 +747,8 @@ function(jQuery, Paths, URI, HostApp, Cache) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Core.prototype.replyTo = function(entity, status_id, mentions, is_private) {
|
Core.prototype.replyTo = function(status) {
|
||||||
|
HostApp.openNewMessageWidow(status);
|
||||||
var string = "^" + entity.replace("https://", "") + " ";
|
|
||||||
|
|
||||||
var ms = "";
|
|
||||||
for (var i = 0; i < mentions.length; i++) {
|
|
||||||
var e = mentions[i].entity.replace("https://", "");
|
|
||||||
if(string.indexOf(e) == -1) ms += " ^" + e;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ms.length > 0) string += "\n\n/cc" + ms;
|
|
||||||
|
|
||||||
HostApp.openNewMessageWidow(entity, status_id, string, is_private);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Core.prototype.postDeleted = function(post_id, entity) {
|
Core.prototype.postDeleted = function(post_id, entity) {
|
||||||
|
@ -1001,21 +847,22 @@ function(jQuery, Paths, URI, HostApp, Cache) {
|
||||||
|
|
||||||
Core.prototype.afterChangingTextinMessageHTML = function(message_node) {
|
Core.prototype.afterChangingTextinMessageHTML = function(message_node) {
|
||||||
// adding show search on click hash
|
// adding show search on click hash
|
||||||
|
/*
|
||||||
$(message_node).find("a.hash").click(function(e) {
|
$(message_node).find("a.hash").click(function(e) {
|
||||||
|
|
||||||
if(bungloo.search) bungloo.search.searchFor(e.target.innerHTML);
|
if(bungloo.search) bungloo.search.searchFor(e.target.innerHTML);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
// adding show profile on click
|
// adding show profile on click
|
||||||
|
/*
|
||||||
$(message_node).find("a.name").click(function(e) {
|
$(message_node).find("a.name").click(function(e) {
|
||||||
HostApp.showProfileForEntity(e.target.title);
|
HostApp.showProfileForEntity(e.target.title);
|
||||||
return false;
|
return false;
|
||||||
});
|
});*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return Core;
|
return Core;
|
||||||
|
|
||||||
});
|
});
|
|
@ -7,7 +7,7 @@ function(URI, CryptoJS) {
|
||||||
|
|
||||||
var Hmac = {};
|
var Hmac = {};
|
||||||
|
|
||||||
Hmac.makeAuthHeader = function(url, http_method, mac_key, mac_key_id) {
|
Hmac.makeHawkAuthHeader = function(url, http_method, hawk_id, key, app_id) {
|
||||||
|
|
||||||
url = URI(url);
|
url = URI(url);
|
||||||
var nonce = Hmac.makeid(8);
|
var nonce = Hmac.makeid(8);
|
||||||
|
@ -18,26 +18,47 @@ function(URI, CryptoJS) {
|
||||||
port = url.protocol() == "https" ? "443" : "80";
|
port = url.protocol() == "https" ? "443" : "80";
|
||||||
}
|
}
|
||||||
|
|
||||||
var normalizedRequestString = ""
|
var normalizedRequestString = "hawk.1.header\n" // header
|
||||||
+ time_stamp + '\n'
|
+ time_stamp + '\n' // ts
|
||||||
+ nonce + '\n'
|
+ nonce + '\n' // nonce
|
||||||
+ http_method + '\n'
|
+ http_method.toUpperCase() + '\n' // method
|
||||||
+ url.path() + url.search() + url.hash() + '\n'
|
+ url.path() + url.search() + url.hash() + '\n' // request uri
|
||||||
+ url.hostname() + '\n'
|
+ url.hostname().toLowerCase() + '\n' // host
|
||||||
+ port + '\n'
|
+ port + '\n' // port
|
||||||
+ '\n' ;
|
+ '\n' // Hmac.calculatePayloadHash(payload) + '\n' // hash // FIXME implement payload validation
|
||||||
|
+ '\n' // ext (we don't use it)
|
||||||
|
|
||||||
var hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, mac_key);
|
var app = "";
|
||||||
|
|
||||||
|
if(app_id) {
|
||||||
|
app = ', app="' + app_id + "'";
|
||||||
|
normalizedRequestString += app_id + "\n" + // app
|
||||||
|
'\n'; // dlg should be empty
|
||||||
|
}
|
||||||
|
|
||||||
|
var hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, key);
|
||||||
hmac.update(normalizedRequestString);
|
hmac.update(normalizedRequestString);
|
||||||
var hash = hmac.finalize();
|
var hash = hmac.finalize();
|
||||||
var mac = hash.toString(CryptoJS.enc.Base64);
|
var mac = hash.toString(CryptoJS.enc.Base64);
|
||||||
|
|
||||||
return 'MAC id="' + mac_key_id +
|
return 'Hawk id="' + hawk_id +
|
||||||
|
'", mac="' + mac +
|
||||||
'", ts="' + time_stamp +
|
'", ts="' + time_stamp +
|
||||||
'", nonce="' + nonce +
|
'", nonce="' + nonce + '"' +
|
||||||
'", mac="' + mac + '"';
|
app
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Hmac.calculatePayloadHash = function (payload) {
|
||||||
|
if (!payload) return "";
|
||||||
|
|
||||||
|
var hash = CryptoJS.algo.SHA256.create();
|
||||||
|
hash.update('hawk.1.payload\n');
|
||||||
|
hash.update('application/vnd.tent.post.v0+json\n');
|
||||||
|
hash.update(payload || '');
|
||||||
|
hash.update('\n');
|
||||||
|
return hash.finalize().toString(CryptoJS.enc.Base64);
|
||||||
|
},
|
||||||
|
|
||||||
Hmac.makeid = function(len) {
|
Hmac.makeid = function(len) {
|
||||||
var text = "";
|
var text = "";
|
||||||
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
|
|
@ -37,6 +37,14 @@ define(function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HostApp.setServerUrls = function(server_urls) {
|
||||||
|
HostApp.setStringForKey(JSON.stringify(server_urls), "server_urls");
|
||||||
|
}
|
||||||
|
|
||||||
|
HostApp.serverUrl = function(key) {
|
||||||
|
return JSON.parse(HostApp.stringForKey("server_urls"))[key];
|
||||||
|
}
|
||||||
|
|
||||||
HostApp.openURL = function(url) {
|
HostApp.openURL = function(url) {
|
||||||
|
|
||||||
if (OS_TYPE == "mac") {
|
if (OS_TYPE == "mac") {
|
||||||
|
@ -77,13 +85,12 @@ define(function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HostApp.openNewMessageWidow = function(entity, status_id, string, is_private) {
|
HostApp.openNewMessageWidow = function(status) {
|
||||||
|
|
||||||
if (OS_TYPE == "mac") {
|
if (OS_TYPE == "mac") {
|
||||||
controller.openNewMessageWindowInReplyTo_statusId_withString_isPrivate_(entity, status_id, string, is_private);
|
controller.openNewMessageWindowInReplyToStatus_(JSON.stringify(status));
|
||||||
} else {
|
} else {
|
||||||
is_private = is_private == true
|
controller.openNewMessageWindowInReplyToStatus(JSON.stringify(status).escapeSpecialChars());
|
||||||
controller.openNewMessageWindowInReplyTostatusIdwithStringIsPrivate(entity, status_id, string, is_private);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ function(jQuery, HostApp, Hmac, Cache) {
|
||||||
|
|
||||||
Paths.getURL = function(url, http_method, callback, data, auth_header, accepts) {
|
Paths.getURL = function(url, http_method, callback, data, auth_header, accepts) {
|
||||||
|
|
||||||
if(accepts !== false) accepts = accepts || "application/vnd.tent.v0+json; charset=utf-8";
|
if(accepts !== false) accepts = accepts || "application/vnd.tent.post.v0+json";
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ function(jQuery, HostApp, Hmac, Cache) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
url: url,
|
url: url,
|
||||||
contentType: "application/vnd.tent.v0+json",
|
contentType: 'application/vnd.tent.post.v0+json; type="https://tent.io/types/app/v0#"',
|
||||||
type: http_method,
|
type: http_method,
|
||||||
complete: callback,
|
complete: callback,
|
||||||
data: data,
|
data: data,
|
||||||
|
@ -65,7 +65,7 @@ function(jQuery, HostApp, Hmac, Cache) {
|
||||||
console.error("getURL (" + xhr.status + ")" + xhr.statusText + " " + http_method + " (" + url + "): '" + xhr.responseText + "'");
|
console.error("getURL (" + xhr.status + ")" + xhr.statusText + " " + http_method + " (" + url + "): '" + xhr.responseText + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jQuery.ajax(options);
|
jQuery.ajax(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ function(jQuery, HostApp, Hmac, Cache) {
|
||||||
if(profile_urls.length > 0) {
|
if(profile_urls.length > 0) {
|
||||||
var profile_url = profile_urls[0];
|
var profile_url = profile_urls[0];
|
||||||
if (!profile_url.startsWith("http")) {
|
if (!profile_url.startsWith("http")) {
|
||||||
profile_url = entity + "/profile";
|
profile_url = entity + profile_url;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,13 +140,13 @@ function(jQuery, HostApp, Hmac, Cache) {
|
||||||
if (resp.status >= 200 && resp.status < 300) {
|
if (resp.status >= 200 && resp.status < 300) {
|
||||||
var doc = document.implementation.createHTMLDocument("");
|
var doc = document.implementation.createHTMLDocument("");
|
||||||
doc.documentElement.innerHTML = resp.responseText;
|
doc.documentElement.innerHTML = resp.responseText;
|
||||||
var links = $(doc).find("link[rel='https://tent.io/rels/profile']");
|
var links = $(doc).find("link[rel='https://tent.io/rels/meta-post']");
|
||||||
|
|
||||||
if (links.length > 0) {
|
if (links.length > 0) {
|
||||||
var href = links.get(0).href;
|
var href = links.get(0).href;
|
||||||
Paths.cache.profile_urls.setItem(entity, href);
|
Paths.cache.profile_urls.setItem(entity, href);
|
||||||
if (!href.startsWith("http")) {
|
if (!href.startsWith("http")) {
|
||||||
href = entity + "/profile";
|
href = entity + href;
|
||||||
}
|
}
|
||||||
callback(href);
|
callback(href);
|
||||||
|
|
||||||
|
@ -184,6 +184,11 @@ function(jQuery, HostApp, Hmac, Cache) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Paths.parseHeaderForProfiles = function(header_string) {
|
Paths.parseHeaderForProfiles = function(header_string) {
|
||||||
|
var regexp = /https:\/\/tent.io\/rels\/meta-post/i;
|
||||||
|
return Paths.parseHeaderForLink(header_string, regexp);
|
||||||
|
}
|
||||||
|
|
||||||
|
Paths.parseHeaderForLink = function(header_string, match) {
|
||||||
var headers = header_string.split(/\n/);
|
var headers = header_string.split(/\n/);
|
||||||
var links = [];
|
var links = [];
|
||||||
for (var i = 0; i < headers.length; i++) {
|
for (var i = 0; i < headers.length; i++) {
|
||||||
|
@ -197,18 +202,18 @@ function(jQuery, HostApp, Hmac, Cache) {
|
||||||
for (var i = 0; i < links.length; i++) {
|
for (var i = 0; i < links.length; i++) {
|
||||||
items = items.concat(links[i].split(","));
|
items = items.concat(links[i].split(","));
|
||||||
}
|
}
|
||||||
var profiles = [];
|
var things = [];
|
||||||
for (var i = 0; i < items.length; i++) {
|
for (var i = 0; i < items.length; i++) {
|
||||||
var item = items[i];
|
var item = items[i];
|
||||||
if (item.match(/https:\/\/tent.io\/rels\/profile/i)) {
|
if (item.match(match)) {
|
||||||
var n = item.match(/<([^>]*)>/);
|
var n = item.match(/<([^>]*)>/);
|
||||||
if (n) {
|
if (n) {
|
||||||
profiles.push(n[1]);
|
things.push(n[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return profiles;
|
return things;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Paths;
|
return Paths;
|
||||||
|
|
|
@ -7,7 +7,8 @@ var bungloo = {
|
||||||
entityProfile: null,
|
entityProfile: null,
|
||||||
conversation: null,
|
conversation: null,
|
||||||
search: null,
|
search: null,
|
||||||
cache: {}
|
cache: { profiles: {}},
|
||||||
|
newpost: null
|
||||||
};
|
};
|
||||||
|
|
||||||
requirejs.config({
|
requirejs.config({
|
||||||
|
@ -33,6 +34,15 @@ function start(view, callback) {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
} else if (view == "newpost") {
|
||||||
|
|
||||||
|
require(["controller/NewPost"], function(NewPost) {
|
||||||
|
|
||||||
|
bungloo.newpost = new NewPost();
|
||||||
|
if(callback) callback();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,33 +64,12 @@ function start(view, callback) {
|
||||||
bungloo.search = new Search();
|
bungloo.search = new Search();
|
||||||
|
|
||||||
bungloo.sidebar.showContentForTimeline();
|
bungloo.sidebar.showContentForTimeline();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
String.prototype.startsWith = function(prefix) {
|
|
||||||
return this.indexOf(prefix) === 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
String.prototype.endsWith = function(suffix) {
|
|
||||||
return this.match(suffix+"$") == suffix;
|
|
||||||
};
|
|
||||||
|
|
||||||
var __entityMap = {
|
|
||||||
"&": "&",
|
|
||||||
"<": "<",
|
|
||||||
">": ">"
|
|
||||||
};
|
|
||||||
|
|
||||||
String.prototype.escapeHTML = function() {
|
|
||||||
return String(this).replace(/[&<>]/g, function (s) {
|
|
||||||
return __entityMap[s];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var console = {
|
var console = {
|
||||||
log: function(s) {
|
log: function(s) {
|
||||||
if (OS_TYPE == "mac") {
|
if (OS_TYPE == "mac") {
|
||||||
|
@ -172,4 +161,42 @@ function go() { // wait untill everything is loaded
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
go();
|
go();
|
||||||
|
|
||||||
|
|
||||||
|
// String stuff
|
||||||
|
String.prototype.startsWith = function(prefix) {
|
||||||
|
return this.indexOf(prefix) === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
String.prototype.endsWith = function(suffix) {
|
||||||
|
return this.match(suffix+"$") == suffix;
|
||||||
|
};
|
||||||
|
|
||||||
|
var __entityMap = {
|
||||||
|
"&": "&",
|
||||||
|
"<": "<",
|
||||||
|
">": ">"
|
||||||
|
};
|
||||||
|
|
||||||
|
String.prototype.escapeHTML = function() {
|
||||||
|
return String(this).replace(/[&<>]/g, function (s) {
|
||||||
|
return __entityMap[s];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
String.prototype.hasArabicCharacter = function() {
|
||||||
|
var arregex = /[\u0600-\u06FF]/;
|
||||||
|
return arregex.test(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
String.prototype.escapeSpecialChars = function() {
|
||||||
|
return this.replace(/[\\]/g, '\\\\')
|
||||||
|
.replace(/[\"]/g, '\\\"')
|
||||||
|
.replace(/[\/]/g, '\\/')
|
||||||
|
.replace(/[\b]/g, '\\b')
|
||||||
|
.replace(/[\f]/g, '\\f')
|
||||||
|
.replace(/[\n]/g, '\\n')
|
||||||
|
.replace(/[\r]/g, '\\r')
|
||||||
|
.replace(/[\t]/g, '\\t');
|
||||||
|
}
|
Before Width: | Height: | Size: 719 B |
Before Width: | Height: | Size: 617 B |
Before Width: | Height: | Size: 516 B |