mirror of
https://git.anonymousland.org/anonymousland/synapse-product.git
synced 2024-10-01 08:25:44 -04:00
Merge remote-tracking branch 'origin/develop' into test-sqlite-memory
This commit is contained in:
commit
b0406b9ead
23
CHANGES.rst
23
CHANGES.rst
@ -1,3 +1,26 @@
|
|||||||
|
Changes in synapse 0.2.3 (2014-09-12)
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Homeserver:
|
||||||
|
* Fix bug where we stopped sending events to remote home servers if a
|
||||||
|
user from that home server left, even if there were some still in the
|
||||||
|
room.
|
||||||
|
* Fix bugs in the state conflict resolution where it was incorrectly
|
||||||
|
rejecting events.
|
||||||
|
|
||||||
|
Webclient:
|
||||||
|
* Display room names and topics.
|
||||||
|
* Allow setting/editing of room names and topics.
|
||||||
|
* Display information about rooms on the main page.
|
||||||
|
* Handle ban and kick events in real time.
|
||||||
|
* VoIP UI and reliability improvements.
|
||||||
|
* Add glare support for VoIP.
|
||||||
|
* Improvements to initial startup speed.
|
||||||
|
* Don't display duplicate join events.
|
||||||
|
* Local echo of messages.
|
||||||
|
* Differentiate sending and sent of local echo.
|
||||||
|
* Various minor bug fixes.
|
||||||
|
|
||||||
Changes in synapse 0.2.2 (2014-09-06)
|
Changes in synapse 0.2.2 (2014-09-06)
|
||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
|
@ -5,3 +5,5 @@ Broad-sweeping stuff which would be nice to have
|
|||||||
- homeserver implementation in go
|
- homeserver implementation in go
|
||||||
- homeserver implementation in node.js
|
- homeserver implementation in node.js
|
||||||
- client SDKs
|
- client SDKs
|
||||||
|
- libpurple library
|
||||||
|
- irssi plugin?
|
||||||
|
@ -1182,16 +1182,16 @@ This event is sent by the caller when they wish to establish a call.
|
|||||||
- ``type`` : "string" - The type of session description, in this case 'offer'
|
- ``type`` : "string" - The type of session description, in this case 'offer'
|
||||||
- ``sdp`` : "string" - The SDP text of the session description
|
- ``sdp`` : "string" - The SDP text of the session description
|
||||||
|
|
||||||
``m.call.candidate``
|
``m.call.candidates``
|
||||||
This event is sent by callers after sending an invite and by the callee after answering.
|
This event is sent by callers after sending an invite and by the callee after answering.
|
||||||
Its purpose is to give the other party an additional ICE candidate to try using to
|
Its purpose is to give the other party additional ICE candidates to try using to
|
||||||
communicate.
|
communicate.
|
||||||
|
|
||||||
Required keys:
|
Required keys:
|
||||||
- ``call_id`` : "string" - The ID of the call this event relates to
|
- ``call_id`` : "string" - The ID of the call this event relates to
|
||||||
- ``version`` : "integer" - The version of the VoIP specification this messages
|
- ``version`` : "integer" - The version of the VoIP specification this messages
|
||||||
adheres to. his specification is version 0.
|
adheres to. his specification is version 0.
|
||||||
- ``candidate`` : "candidate object" - Object describing the candidate.
|
- ``candidates`` : "array of candidate objects" - Array of object describing the candidates.
|
||||||
|
|
||||||
``Candidate Object``
|
``Candidate Object``
|
||||||
|
|
||||||
|
@ -16,4 +16,4 @@
|
|||||||
""" This is a reference implementation of a synapse home server.
|
""" This is a reference implementation of a synapse home server.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__version__ = "0.2.2"
|
__version__ = "0.2.3"
|
||||||
|
@ -17,6 +17,18 @@ from synapse.api.errors import SynapseError, Codes
|
|||||||
from synapse.util.jsonobject import JsonEncodedObject
|
from synapse.util.jsonobject import JsonEncodedObject
|
||||||
|
|
||||||
|
|
||||||
|
def serialize_event(hs, e):
|
||||||
|
# FIXME(erikj): To handle the case of presence events and the like
|
||||||
|
if not isinstance(e, SynapseEvent):
|
||||||
|
return e
|
||||||
|
|
||||||
|
d = e.get_dict()
|
||||||
|
if "age_ts" in d:
|
||||||
|
d["age"] = int(hs.get_clock().time_msec()) - d["age_ts"]
|
||||||
|
|
||||||
|
return d
|
||||||
|
|
||||||
|
|
||||||
class SynapseEvent(JsonEncodedObject):
|
class SynapseEvent(JsonEncodedObject):
|
||||||
|
|
||||||
"""Base class for Synapse events. These are JSON objects which must abide
|
"""Base class for Synapse events. These are JSON objects which must abide
|
||||||
@ -43,6 +55,7 @@ class SynapseEvent(JsonEncodedObject):
|
|||||||
"content", # HTTP body, JSON
|
"content", # HTTP body, JSON
|
||||||
"state_key",
|
"state_key",
|
||||||
"required_power_level",
|
"required_power_level",
|
||||||
|
"age_ts",
|
||||||
]
|
]
|
||||||
|
|
||||||
internal_keys = [
|
internal_keys = [
|
||||||
|
@ -59,6 +59,14 @@ class EventFactory(object):
|
|||||||
if "ts" not in kwargs:
|
if "ts" not in kwargs:
|
||||||
kwargs["ts"] = int(self.clock.time_msec())
|
kwargs["ts"] = int(self.clock.time_msec())
|
||||||
|
|
||||||
|
# The "age" key is a delta timestamp that should be converted into an
|
||||||
|
# absolute timestamp the minute we see it.
|
||||||
|
if "age" in kwargs:
|
||||||
|
kwargs["age_ts"] = int(self.clock.time_msec()) - int(kwargs["age"])
|
||||||
|
del kwargs["age"]
|
||||||
|
elif "age_ts" not in kwargs:
|
||||||
|
kwargs["age_ts"] = int(self.clock.time_msec())
|
||||||
|
|
||||||
if etype in self._event_list:
|
if etype in self._event_list:
|
||||||
handler = self._event_list[etype]
|
handler = self._event_list[etype]
|
||||||
else:
|
else:
|
||||||
|
@ -291,6 +291,12 @@ class ReplicationLayer(object):
|
|||||||
def on_incoming_transaction(self, transaction_data):
|
def on_incoming_transaction(self, transaction_data):
|
||||||
transaction = Transaction(**transaction_data)
|
transaction = Transaction(**transaction_data)
|
||||||
|
|
||||||
|
for p in transaction.pdus:
|
||||||
|
if "age" in p:
|
||||||
|
p["age_ts"] = int(self.clock.time_msec()) - int(p["age"])
|
||||||
|
|
||||||
|
pdu_list = [Pdu(**p) for p in transaction.pdus]
|
||||||
|
|
||||||
logger.debug("[%s] Got transaction", transaction.transaction_id)
|
logger.debug("[%s] Got transaction", transaction.transaction_id)
|
||||||
|
|
||||||
response = yield self.transaction_actions.have_responded(transaction)
|
response = yield self.transaction_actions.have_responded(transaction)
|
||||||
@ -303,8 +309,6 @@ class ReplicationLayer(object):
|
|||||||
|
|
||||||
logger.debug("[%s] Transacition is new", transaction.transaction_id)
|
logger.debug("[%s] Transacition is new", transaction.transaction_id)
|
||||||
|
|
||||||
pdu_list = [Pdu(**p) for p in transaction.pdus]
|
|
||||||
|
|
||||||
dl = []
|
dl = []
|
||||||
for pdu in pdu_list:
|
for pdu in pdu_list:
|
||||||
dl.append(self._handle_new_pdu(pdu))
|
dl.append(self._handle_new_pdu(pdu))
|
||||||
@ -405,9 +409,14 @@ class ReplicationLayer(object):
|
|||||||
"""Returns a new Transaction containing the given PDUs suitable for
|
"""Returns a new Transaction containing the given PDUs suitable for
|
||||||
transmission.
|
transmission.
|
||||||
"""
|
"""
|
||||||
|
pdus = [p.get_dict() for p in pdu_list]
|
||||||
|
for p in pdus:
|
||||||
|
if "age_ts" in pdus:
|
||||||
|
p["age"] = int(self.clock.time_msec()) - p["age_ts"]
|
||||||
|
|
||||||
return Transaction(
|
return Transaction(
|
||||||
pdus=[p.get_dict() for p in pdu_list],
|
|
||||||
origin=self.server_name,
|
origin=self.server_name,
|
||||||
|
pdus=pdus,
|
||||||
ts=int(self._clock.time_msec()),
|
ts=int(self._clock.time_msec()),
|
||||||
destination=None,
|
destination=None,
|
||||||
)
|
)
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
|
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
|
||||||
from synapse.api.events import SynapseEvent
|
|
||||||
from synapse.util.logutils import log_function
|
from synapse.util.logutils import log_function
|
||||||
|
|
||||||
from ._base import BaseHandler
|
from ._base import BaseHandler
|
||||||
@ -71,10 +70,7 @@ class EventStreamHandler(BaseHandler):
|
|||||||
auth_user, room_ids, pagin_config, timeout
|
auth_user, room_ids, pagin_config, timeout
|
||||||
)
|
)
|
||||||
|
|
||||||
chunks = [
|
chunks = [self.hs.serialize_event(e) for e in events]
|
||||||
e.get_dict() if isinstance(e, SynapseEvent) else e
|
|
||||||
for e in events
|
|
||||||
]
|
|
||||||
|
|
||||||
chunk = {
|
chunk = {
|
||||||
"chunk": chunks,
|
"chunk": chunks,
|
||||||
@ -92,7 +88,9 @@ class EventStreamHandler(BaseHandler):
|
|||||||
# 10 seconds of grace to allow the client to reconnect again
|
# 10 seconds of grace to allow the client to reconnect again
|
||||||
# before we think they're gone
|
# before we think they're gone
|
||||||
def _later():
|
def _later():
|
||||||
logger.debug("_later stopped_user_eventstream %s", auth_user)
|
logger.debug(
|
||||||
|
"_later stopped_user_eventstream %s", auth_user
|
||||||
|
)
|
||||||
self.distributor.fire(
|
self.distributor.fire(
|
||||||
"stopped_user_eventstream", auth_user
|
"stopped_user_eventstream", auth_user
|
||||||
)
|
)
|
||||||
|
@ -124,7 +124,7 @@ class MessageHandler(BaseHandler):
|
|||||||
)
|
)
|
||||||
|
|
||||||
chunk = {
|
chunk = {
|
||||||
"chunk": [e.get_dict() for e in events],
|
"chunk": [self.hs.serialize_event(e) for e in events],
|
||||||
"start": pagin_config.from_token.to_string(),
|
"start": pagin_config.from_token.to_string(),
|
||||||
"end": next_token.to_string(),
|
"end": next_token.to_string(),
|
||||||
}
|
}
|
||||||
@ -296,7 +296,7 @@ class MessageHandler(BaseHandler):
|
|||||||
end_token = now_token.copy_and_replace("room_key", token[1])
|
end_token = now_token.copy_and_replace("room_key", token[1])
|
||||||
|
|
||||||
d["messages"] = {
|
d["messages"] = {
|
||||||
"chunk": [m.get_dict() for m in messages],
|
"chunk": [self.hs.serialize_event(m) for m in messages],
|
||||||
"start": start_token.to_string(),
|
"start": start_token.to_string(),
|
||||||
"end": end_token.to_string(),
|
"end": end_token.to_string(),
|
||||||
}
|
}
|
||||||
@ -304,7 +304,7 @@ class MessageHandler(BaseHandler):
|
|||||||
current_state = yield self.store.get_current_state(
|
current_state = yield self.store.get_current_state(
|
||||||
event.room_id
|
event.room_id
|
||||||
)
|
)
|
||||||
d["state"] = [c.get_dict() for c in current_state]
|
d["state"] = [self.hs.serialize_event(c) for c in current_state]
|
||||||
except:
|
except:
|
||||||
logger.exception("Failed to get snapshot")
|
logger.exception("Failed to get snapshot")
|
||||||
|
|
||||||
|
@ -335,7 +335,7 @@ class RoomMemberHandler(BaseHandler):
|
|||||||
|
|
||||||
member_list = yield self.store.get_room_members(room_id=room_id)
|
member_list = yield self.store.get_room_members(room_id=room_id)
|
||||||
event_list = [
|
event_list = [
|
||||||
entry.get_dict()
|
self.hs.serialize_event(entry)
|
||||||
for entry in member_list
|
for entry in member_list
|
||||||
]
|
]
|
||||||
chunk_data = {
|
chunk_data = {
|
||||||
|
@ -59,7 +59,7 @@ class EventRestServlet(RestServlet):
|
|||||||
event = yield handler.get_event(auth_user, event_id)
|
event = yield handler.get_event(auth_user, event_id)
|
||||||
|
|
||||||
if event:
|
if event:
|
||||||
defer.returnValue((200, event.get_dict()))
|
defer.returnValue((200, self.hs.serialize_event(event)))
|
||||||
else:
|
else:
|
||||||
defer.returnValue((404, "Event not found."))
|
defer.returnValue((404, "Event not found."))
|
||||||
|
|
||||||
|
@ -378,7 +378,7 @@ class RoomTriggerBackfill(RestServlet):
|
|||||||
handler = self.handlers.federation_handler
|
handler = self.handlers.federation_handler
|
||||||
events = yield handler.backfill(remote_server, room_id, limit)
|
events = yield handler.backfill(remote_server, room_id, limit)
|
||||||
|
|
||||||
res = [event.get_dict() for event in events]
|
res = [self.hs.serialize_event(event) for event in events]
|
||||||
defer.returnValue((200, res))
|
defer.returnValue((200, res))
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
# Imports required for the default HomeServer() implementation
|
# Imports required for the default HomeServer() implementation
|
||||||
from synapse.federation import initialize_http_replication
|
from synapse.federation import initialize_http_replication
|
||||||
|
from synapse.api.events import serialize_event
|
||||||
from synapse.api.events.factory import EventFactory
|
from synapse.api.events.factory import EventFactory
|
||||||
from synapse.notifier import Notifier
|
from synapse.notifier import Notifier
|
||||||
from synapse.api.auth import Auth
|
from synapse.api.auth import Auth
|
||||||
@ -139,6 +140,9 @@ class BaseHomeServer(object):
|
|||||||
object."""
|
object."""
|
||||||
return RoomID.from_string(s, hs=self)
|
return RoomID.from_string(s, hs=self)
|
||||||
|
|
||||||
|
def serialize_event(self, e):
|
||||||
|
return serialize_event(self, e)
|
||||||
|
|
||||||
# Build magic accessors for every dependency
|
# Build magic accessors for every dependency
|
||||||
for depname in BaseHomeServer.DEPENDENCIES:
|
for depname in BaseHomeServer.DEPENDENCIES:
|
||||||
BaseHomeServer._make_dependency_method(depname)
|
BaseHomeServer._make_dependency_method(depname)
|
||||||
|
@ -36,7 +36,7 @@ from .registration import RegistrationStore
|
|||||||
from .room import RoomStore
|
from .room import RoomStore
|
||||||
from .roommember import RoomMemberStore
|
from .roommember import RoomMemberStore
|
||||||
from .stream import StreamStore
|
from .stream import StreamStore
|
||||||
from .pdu import StatePduStore, PduStore
|
from .pdu import StatePduStore, PduStore, PdusTable
|
||||||
from .transactions import TransactionStore
|
from .transactions import TransactionStore
|
||||||
from .keys import KeyStore
|
from .keys import KeyStore
|
||||||
|
|
||||||
@ -140,6 +140,12 @@ class DataStore(RoomMemberStore, RoomStore,
|
|||||||
del cols["content"]
|
del cols["content"]
|
||||||
del cols["prev_pdus"]
|
del cols["prev_pdus"]
|
||||||
cols["content_json"] = json.dumps(pdu.content)
|
cols["content_json"] = json.dumps(pdu.content)
|
||||||
|
|
||||||
|
unrec_keys.update({
|
||||||
|
k: v for k, v in cols.items()
|
||||||
|
if k not in PdusTable.fields
|
||||||
|
})
|
||||||
|
|
||||||
cols["unrecognized_keys"] = json.dumps(unrec_keys)
|
cols["unrecognized_keys"] = json.dumps(unrec_keys)
|
||||||
|
|
||||||
logger.debug("Persisting: %s", repr(cols))
|
logger.debug("Persisting: %s", repr(cols))
|
||||||
|
@ -355,6 +355,10 @@ class SQLBaseStore(object):
|
|||||||
d["content"] = json.loads(d["content"])
|
d["content"] = json.loads(d["content"])
|
||||||
del d["unrecognized_keys"]
|
del d["unrecognized_keys"]
|
||||||
|
|
||||||
|
if "age_ts" not in d:
|
||||||
|
# For compatibility
|
||||||
|
d["age_ts"] = d["ts"] if "ts" in d else 0
|
||||||
|
|
||||||
return self.event_factory.create_event(
|
return self.event_factory.create_event(
|
||||||
etype=d["type"],
|
etype=d["type"],
|
||||||
**d
|
**d
|
||||||
|
@ -66,8 +66,8 @@ class RoomMemberStore(SQLBaseStore):
|
|||||||
# Check if this was the last person to have left.
|
# Check if this was the last person to have left.
|
||||||
member_events = self._get_members_query_txn(
|
member_events = self._get_members_query_txn(
|
||||||
txn,
|
txn,
|
||||||
where_clause="c.room_id = ? AND m.membership = ?",
|
where_clause="c.room_id = ? AND m.membership = ? AND m.user_id != ?",
|
||||||
where_values=(event.room_id, Membership.JOIN,)
|
where_values=(event.room_id, Membership.JOIN, target_user_id,)
|
||||||
)
|
)
|
||||||
|
|
||||||
joined_domains = set()
|
joined_domains = set()
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from synapse.api.ratelimiting import Ratelimiter
|
from synapse.api.ratelimiting import Ratelimiter
|
||||||
|
|
||||||
import unittest
|
from tests import unittest
|
||||||
|
|
||||||
class TestRatelimiter(unittest.TestCase):
|
class TestRatelimiter(unittest.TestCase):
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
from synapse.api.events import SynapseEvent
|
from synapse.api.events import SynapseEvent
|
||||||
|
|
||||||
import unittest
|
from tests import unittest
|
||||||
|
|
||||||
|
|
||||||
class SynapseTemplateCheckTestCase(unittest.TestCase):
|
class SynapseTemplateCheckTestCase(unittest.TestCase):
|
||||||
|
@ -14,11 +14,10 @@
|
|||||||
|
|
||||||
# trial imports
|
# trial imports
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
from twisted.trial import unittest
|
from tests import unittest
|
||||||
|
|
||||||
# python imports
|
# python imports
|
||||||
from mock import Mock
|
from mock import Mock
|
||||||
import logging
|
|
||||||
|
|
||||||
from ..utils import MockHttpResource, MockClock
|
from ..utils import MockHttpResource, MockClock
|
||||||
|
|
||||||
@ -28,9 +27,6 @@ from synapse.federation.units import Pdu
|
|||||||
from synapse.storage.pdu import PduTuple, PduEntry
|
from synapse.storage.pdu import PduTuple, PduEntry
|
||||||
|
|
||||||
|
|
||||||
logging.getLogger().addHandler(logging.NullHandler())
|
|
||||||
|
|
||||||
|
|
||||||
def make_pdu(prev_pdus=[], **kwargs):
|
def make_pdu(prev_pdus=[], **kwargs):
|
||||||
"""Provide some default fields for making a PduTuple."""
|
"""Provide some default fields for making a PduTuple."""
|
||||||
pdu_fields = {
|
pdu_fields = {
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from twisted.trial import unittest
|
from tests import unittest
|
||||||
|
|
||||||
from synapse.federation.pdu_codec import (
|
from synapse.federation.pdu_codec import (
|
||||||
PduCodec, encode_event_id, decode_event_id
|
PduCodec, encode_event_id, decode_event_id
|
||||||
|
@ -14,11 +14,10 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
from twisted.trial import unittest
|
from tests import unittest
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
|
||||||
from mock import Mock
|
from mock import Mock
|
||||||
import logging
|
|
||||||
|
|
||||||
from synapse.server import HomeServer
|
from synapse.server import HomeServer
|
||||||
from synapse.http.client import HttpClient
|
from synapse.http.client import HttpClient
|
||||||
@ -28,9 +27,6 @@ from synapse.storage.directory import RoomAliasMapping
|
|||||||
from tests.utils import SQLiteMemoryDbPool
|
from tests.utils import SQLiteMemoryDbPool
|
||||||
|
|
||||||
|
|
||||||
logging.getLogger().addHandler(logging.NullHandler())
|
|
||||||
|
|
||||||
|
|
||||||
class DirectoryHandlers(object):
|
class DirectoryHandlers(object):
|
||||||
def __init__(self, hs):
|
def __init__(self, hs):
|
||||||
self.directory_handler = DirectoryHandler(hs)
|
self.directory_handler = DirectoryHandler(hs)
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
|
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
from twisted.trial import unittest
|
from tests import unittest
|
||||||
|
|
||||||
from synapse.api.events.room import (
|
from synapse.api.events.room import (
|
||||||
InviteJoinEvent, MessageEvent, RoomMemberEvent
|
InviteJoinEvent, MessageEvent, RoomMemberEvent
|
||||||
@ -26,12 +26,8 @@ from synapse.federation.units import Pdu
|
|||||||
|
|
||||||
from mock import NonCallableMock, ANY
|
from mock import NonCallableMock, ANY
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from ..utils import get_mock_call_args
|
from ..utils import get_mock_call_args
|
||||||
|
|
||||||
logging.getLogger().addHandler(logging.NullHandler())
|
|
||||||
|
|
||||||
|
|
||||||
class FederationTestCase(unittest.TestCase):
|
class FederationTestCase(unittest.TestCase):
|
||||||
|
|
||||||
|
@ -14,11 +14,10 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
from twisted.trial import unittest
|
from tests import unittest
|
||||||
from twisted.internet import defer, reactor
|
from twisted.internet import defer, reactor
|
||||||
|
|
||||||
from mock import Mock, call, ANY
|
from mock import Mock, call, ANY
|
||||||
import logging
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from tests.utils import (
|
from tests.utils import (
|
||||||
@ -36,9 +35,6 @@ UNAVAILABLE = PresenceState.UNAVAILABLE
|
|||||||
ONLINE = PresenceState.ONLINE
|
ONLINE = PresenceState.ONLINE
|
||||||
|
|
||||||
|
|
||||||
logging.getLogger().addHandler(logging.NullHandler())
|
|
||||||
|
|
||||||
|
|
||||||
def _expect_edu(destination, edu_type, content, origin="test"):
|
def _expect_edu(destination, edu_type, content, origin="test"):
|
||||||
return {
|
return {
|
||||||
"origin": origin,
|
"origin": origin,
|
||||||
@ -85,7 +81,6 @@ class PresenceStateTestCase(unittest.TestCase):
|
|||||||
# Mock the RoomMemberHandler
|
# Mock the RoomMemberHandler
|
||||||
room_member_handler = Mock(spec=[])
|
room_member_handler = Mock(spec=[])
|
||||||
hs.handlers.room_member_handler = room_member_handler
|
hs.handlers.room_member_handler = room_member_handler
|
||||||
logging.getLogger().debug("Mocking room_member_handler=%r", room_member_handler)
|
|
||||||
|
|
||||||
# Some local users to test with
|
# Some local users to test with
|
||||||
self.u_apple = hs.parse_userid("@apple:test")
|
self.u_apple = hs.parse_userid("@apple:test")
|
||||||
|
@ -16,11 +16,10 @@
|
|||||||
"""This file contains tests of the "presence-like" data that is shared between
|
"""This file contains tests of the "presence-like" data that is shared between
|
||||||
presence and profiles; namely, the displayname and avatar_url."""
|
presence and profiles; namely, the displayname and avatar_url."""
|
||||||
|
|
||||||
from twisted.trial import unittest
|
from tests import unittest
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
|
||||||
from mock import Mock, call, ANY
|
from mock import Mock, call, ANY
|
||||||
import logging
|
|
||||||
|
|
||||||
from ..utils import MockClock
|
from ..utils import MockClock
|
||||||
|
|
||||||
@ -35,9 +34,6 @@ UNAVAILABLE = PresenceState.UNAVAILABLE
|
|||||||
ONLINE = PresenceState.ONLINE
|
ONLINE = PresenceState.ONLINE
|
||||||
|
|
||||||
|
|
||||||
logging.getLogger().addHandler(logging.NullHandler())
|
|
||||||
|
|
||||||
|
|
||||||
class MockReplication(object):
|
class MockReplication(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.edu_handlers = {}
|
self.edu_handlers = {}
|
||||||
|
@ -14,11 +14,10 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
from twisted.trial import unittest
|
from tests import unittest
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
|
||||||
from mock import Mock
|
from mock import Mock
|
||||||
import logging
|
|
||||||
|
|
||||||
from synapse.api.errors import AuthError
|
from synapse.api.errors import AuthError
|
||||||
from synapse.server import HomeServer
|
from synapse.server import HomeServer
|
||||||
@ -27,9 +26,6 @@ from synapse.handlers.profile import ProfileHandler
|
|||||||
from tests.utils import SQLiteMemoryDbPool
|
from tests.utils import SQLiteMemoryDbPool
|
||||||
|
|
||||||
|
|
||||||
logging.getLogger().addHandler(logging.NullHandler())
|
|
||||||
|
|
||||||
|
|
||||||
class ProfileHandlers(object):
|
class ProfileHandlers(object):
|
||||||
def __init__(self, hs):
|
def __init__(self, hs):
|
||||||
self.profile_handler = ProfileHandler(hs)
|
self.profile_handler = ProfileHandler(hs)
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
|
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
from twisted.trial import unittest
|
from tests import unittest
|
||||||
|
|
||||||
from synapse.api.events.room import (
|
from synapse.api.events.room import (
|
||||||
InviteJoinEvent, RoomMemberEvent, RoomConfigEvent
|
InviteJoinEvent, RoomMemberEvent, RoomConfigEvent
|
||||||
@ -27,10 +27,6 @@ from synapse.server import HomeServer
|
|||||||
|
|
||||||
from mock import Mock, NonCallableMock
|
from mock import Mock, NonCallableMock
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
logging.getLogger().addHandler(logging.NullHandler())
|
|
||||||
|
|
||||||
|
|
||||||
class RoomMemberHandlerTestCase(unittest.TestCase):
|
class RoomMemberHandlerTestCase(unittest.TestCase):
|
||||||
|
|
||||||
|
@ -14,12 +14,11 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
from twisted.trial import unittest
|
from tests import unittest
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
|
||||||
from mock import Mock, call, ANY
|
from mock import Mock, call, ANY
|
||||||
import json
|
import json
|
||||||
import logging
|
|
||||||
|
|
||||||
from ..utils import MockHttpResource, MockClock, DeferredMockCallable
|
from ..utils import MockHttpResource, MockClock, DeferredMockCallable
|
||||||
|
|
||||||
@ -27,9 +26,6 @@ from synapse.server import HomeServer
|
|||||||
from synapse.handlers.typing import TypingNotificationHandler
|
from synapse.handlers.typing import TypingNotificationHandler
|
||||||
|
|
||||||
|
|
||||||
logging.getLogger().addHandler(logging.NullHandler())
|
|
||||||
|
|
||||||
|
|
||||||
def _expect_edu(destination, edu_type, content, origin="test"):
|
def _expect_edu(destination, edu_type, content, origin="test"):
|
||||||
return {
|
return {
|
||||||
"origin": origin,
|
"origin": origin,
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
""" Tests REST events for /events paths."""
|
""" Tests REST events for /events paths."""
|
||||||
from twisted.trial import unittest
|
from tests import unittest
|
||||||
|
|
||||||
# twisted imports
|
# twisted imports
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
@ -27,14 +27,12 @@ from synapse.server import HomeServer
|
|||||||
|
|
||||||
# python imports
|
# python imports
|
||||||
import json
|
import json
|
||||||
import logging
|
|
||||||
|
|
||||||
from ..utils import MockHttpResource, MemoryDataStore
|
from ..utils import MockHttpResource, MemoryDataStore
|
||||||
from .utils import RestTestCase
|
from .utils import RestTestCase
|
||||||
|
|
||||||
from mock import Mock, NonCallableMock
|
from mock import Mock, NonCallableMock
|
||||||
|
|
||||||
logging.getLogger().addHandler(logging.NullHandler())
|
|
||||||
|
|
||||||
PATH_PREFIX = "/_matrix/client/api/v1"
|
PATH_PREFIX = "/_matrix/client/api/v1"
|
||||||
|
|
||||||
|
@ -15,11 +15,10 @@
|
|||||||
|
|
||||||
"""Tests REST events for /presence paths."""
|
"""Tests REST events for /presence paths."""
|
||||||
|
|
||||||
from twisted.trial import unittest
|
from tests import unittest
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
|
||||||
from mock import Mock
|
from mock import Mock
|
||||||
import logging
|
|
||||||
|
|
||||||
from ..utils import MockHttpResource
|
from ..utils import MockHttpResource
|
||||||
|
|
||||||
@ -28,9 +27,6 @@ from synapse.handlers.presence import PresenceHandler
|
|||||||
from synapse.server import HomeServer
|
from synapse.server import HomeServer
|
||||||
|
|
||||||
|
|
||||||
logging.getLogger().addHandler(logging.NullHandler())
|
|
||||||
|
|
||||||
|
|
||||||
OFFLINE = PresenceState.OFFLINE
|
OFFLINE = PresenceState.OFFLINE
|
||||||
UNAVAILABLE = PresenceState.UNAVAILABLE
|
UNAVAILABLE = PresenceState.UNAVAILABLE
|
||||||
ONLINE = PresenceState.ONLINE
|
ONLINE = PresenceState.ONLINE
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
"""Tests REST events for /profile paths."""
|
"""Tests REST events for /profile paths."""
|
||||||
|
|
||||||
from twisted.trial import unittest
|
from tests import unittest
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
|
||||||
from mock import Mock
|
from mock import Mock
|
||||||
@ -28,6 +28,7 @@ from synapse.server import HomeServer
|
|||||||
myid = "@1234ABCD:test"
|
myid = "@1234ABCD:test"
|
||||||
PATH_PREFIX = "/_matrix/client/api/v1"
|
PATH_PREFIX = "/_matrix/client/api/v1"
|
||||||
|
|
||||||
|
|
||||||
class ProfileTestCase(unittest.TestCase):
|
class ProfileTestCase(unittest.TestCase):
|
||||||
""" Tests profile management. """
|
""" Tests profile management. """
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
|
||||||
# trial imports
|
# trial imports
|
||||||
from twisted.trial import unittest
|
from tests import unittest
|
||||||
|
|
||||||
from synapse.api.constants import Membership
|
from synapse.api.constants import Membership
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
from twisted.trial import unittest
|
from tests import unittest
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
|
||||||
from mock import Mock, call
|
from mock import Mock, call
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
from tests import unittest
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
from twisted.trial import unittest
|
|
||||||
|
|
||||||
from mock import Mock, patch
|
from mock import Mock, patch
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
from tests import unittest
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
from twisted.trial import unittest
|
|
||||||
from twisted.python.log import PythonLoggingObserver
|
from twisted.python.log import PythonLoggingObserver
|
||||||
|
|
||||||
from synapse.state import StateHandler
|
from synapse.state import StateHandler
|
||||||
@ -26,7 +26,6 @@ from collections import namedtuple
|
|||||||
|
|
||||||
from mock import Mock
|
from mock import Mock
|
||||||
|
|
||||||
import logging
|
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
import unittest
|
from tests import unittest
|
||||||
|
|
||||||
from synapse.server import BaseHomeServer
|
from synapse.server import BaseHomeServer
|
||||||
from synapse.types import UserID, RoomAlias
|
from synapse.types import UserID, RoomAlias
|
||||||
|
79
tests/unittest.py
Normal file
79
tests/unittest.py
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright 2014 OpenMarket Ltd
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
from twisted.trial import unittest
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
# logging doesn't have a "don't log anything at all EVARRRR setting,
|
||||||
|
# but since the highest value is 50, 1000000 should do ;)
|
||||||
|
NEVER = 1000000
|
||||||
|
|
||||||
|
logging.getLogger().addHandler(logging.StreamHandler())
|
||||||
|
logging.getLogger().setLevel(NEVER)
|
||||||
|
|
||||||
|
|
||||||
|
def around(target):
|
||||||
|
"""A CLOS-style 'around' modifier, which wraps the original method of the
|
||||||
|
given instance with another piece of code.
|
||||||
|
|
||||||
|
@around(self)
|
||||||
|
def method_name(orig, *args, **kwargs):
|
||||||
|
return orig(*args, **kwargs)
|
||||||
|
"""
|
||||||
|
def _around(code):
|
||||||
|
name = code.__name__
|
||||||
|
orig = getattr(target, name)
|
||||||
|
def new(*args, **kwargs):
|
||||||
|
return code(orig, *args, **kwargs)
|
||||||
|
setattr(target, name, new)
|
||||||
|
return _around
|
||||||
|
|
||||||
|
|
||||||
|
class TestCase(unittest.TestCase):
|
||||||
|
"""A subclass of twisted.trial's TestCase which looks for 'loglevel'
|
||||||
|
attributes on both itself and its individual test methods, to override the
|
||||||
|
root logger's logging level while that test (case|method) runs."""
|
||||||
|
|
||||||
|
def __init__(self, methodName, *args, **kwargs):
|
||||||
|
super(TestCase, self).__init__(methodName, *args, **kwargs)
|
||||||
|
|
||||||
|
method = getattr(self, methodName)
|
||||||
|
|
||||||
|
level = getattr(method, "loglevel",
|
||||||
|
getattr(self, "loglevel",
|
||||||
|
NEVER))
|
||||||
|
|
||||||
|
@around(self)
|
||||||
|
def setUp(orig):
|
||||||
|
old_level = logging.getLogger().level
|
||||||
|
|
||||||
|
if old_level != level:
|
||||||
|
@around(self)
|
||||||
|
def tearDown(orig):
|
||||||
|
ret = orig()
|
||||||
|
logging.getLogger().setLevel(old_level)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
logging.getLogger().setLevel(level)
|
||||||
|
return orig()
|
||||||
|
|
||||||
|
|
||||||
|
def DEBUG(target):
|
||||||
|
"""A decorator to set the .loglevel attribute to logging.DEBUG.
|
||||||
|
Can apply to either a TestCase or an individual test method."""
|
||||||
|
target.loglevel = logging.DEBUG
|
||||||
|
return target
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
|
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
from twisted.trial import unittest
|
from tests import unittest
|
||||||
|
|
||||||
from synapse.util.lockutils import LockManager
|
from synapse.util.lockutils import LockManager
|
||||||
|
|
||||||
|
@ -528,8 +528,8 @@ a:active { color: #000; }
|
|||||||
}
|
}
|
||||||
|
|
||||||
.bubble .message {
|
.bubble .message {
|
||||||
/* Break lines when encountering CR+LF */
|
/* Wrap words and break lines on CR+LF */
|
||||||
white-space: pre;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
.bubble .messagePending {
|
.bubble .messagePending {
|
||||||
opacity: 0.3
|
opacity: 0.3
|
||||||
|
@ -38,6 +38,13 @@ angular.module('eventHandlerService', [])
|
|||||||
var TOPIC_EVENT = "TOPIC_EVENT";
|
var TOPIC_EVENT = "TOPIC_EVENT";
|
||||||
var RESET_EVENT = "RESET_EVENT"; // eventHandlerService has been resetted
|
var RESET_EVENT = "RESET_EVENT"; // eventHandlerService has been resetted
|
||||||
|
|
||||||
|
// used for dedupping events - could be expanded in future...
|
||||||
|
// FIXME: means that we leak memory over time (along with lots of the rest
|
||||||
|
// of the app, given we never try to reap memory yet)
|
||||||
|
var eventMap = {};
|
||||||
|
|
||||||
|
$rootScope.presence = {};
|
||||||
|
|
||||||
var initialSyncDeferred;
|
var initialSyncDeferred;
|
||||||
|
|
||||||
var reset = function() {
|
var reset = function() {
|
||||||
@ -46,16 +53,13 @@ angular.module('eventHandlerService', [])
|
|||||||
$rootScope.events = {
|
$rootScope.events = {
|
||||||
rooms: {} // will contain roomId: { messages:[], members:{userid1: event} }
|
rooms: {} // will contain roomId: { messages:[], members:{userid1: event} }
|
||||||
};
|
};
|
||||||
}
|
|
||||||
reset();
|
|
||||||
|
|
||||||
// used for dedupping events - could be expanded in future...
|
|
||||||
// FIXME: means that we leak memory over time (along with lots of the rest
|
|
||||||
// of the app, given we never try to reap memory yet)
|
|
||||||
var eventMap = {};
|
|
||||||
|
|
||||||
$rootScope.presence = {};
|
$rootScope.presence = {};
|
||||||
|
|
||||||
|
eventMap = {};
|
||||||
|
};
|
||||||
|
reset();
|
||||||
|
|
||||||
var initRoom = function(room_id) {
|
var initRoom = function(room_id) {
|
||||||
if (!(room_id in $rootScope.events.rooms)) {
|
if (!(room_id in $rootScope.events.rooms)) {
|
||||||
console.log("Creating new handler entry for " + room_id);
|
console.log("Creating new handler entry for " + room_id);
|
||||||
@ -204,7 +208,7 @@ angular.module('eventHandlerService', [])
|
|||||||
|
|
||||||
var handleCallEvent = function(event, isLiveEvent) {
|
var handleCallEvent = function(event, isLiveEvent) {
|
||||||
$rootScope.$broadcast(CALL_EVENT, event, isLiveEvent);
|
$rootScope.$broadcast(CALL_EVENT, event, isLiveEvent);
|
||||||
if (event.type == 'm.call.invite') {
|
if (event.type === 'm.call.invite') {
|
||||||
$rootScope.events.rooms[event.room_id].messages.push(event);
|
$rootScope.events.rooms[event.room_id].messages.push(event);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -231,7 +235,7 @@ angular.module('eventHandlerService', [])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return index;
|
return index;
|
||||||
}
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ROOM_CREATE_EVENT: ROOM_CREATE_EVENT,
|
ROOM_CREATE_EVENT: ROOM_CREATE_EVENT,
|
||||||
|
@ -47,6 +47,10 @@ angular.module('MatrixCall', [])
|
|||||||
this.call_id = "c" + new Date().getTime();
|
this.call_id = "c" + new Date().getTime();
|
||||||
this.state = 'fledgling';
|
this.state = 'fledgling';
|
||||||
this.didConnect = false;
|
this.didConnect = false;
|
||||||
|
|
||||||
|
// a queue for candidates waiting to go out. We try to amalgamate candidates into a single candidate message where possible
|
||||||
|
this.candidateSendQueue = [];
|
||||||
|
this.candidateSendTries = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
MatrixCall.prototype.createPeerConnection = function() {
|
MatrixCall.prototype.createPeerConnection = function() {
|
||||||
@ -174,12 +178,7 @@ angular.module('MatrixCall', [])
|
|||||||
MatrixCall.prototype.gotLocalIceCandidate = function(event) {
|
MatrixCall.prototype.gotLocalIceCandidate = function(event) {
|
||||||
console.log(event);
|
console.log(event);
|
||||||
if (event.candidate) {
|
if (event.candidate) {
|
||||||
var content = {
|
this.sendCandidate(event.candidate);
|
||||||
version: 0,
|
|
||||||
call_id: this.call_id,
|
|
||||||
candidate: event.candidate
|
|
||||||
};
|
|
||||||
this.sendEventWithRetry('m.call.candidate', content);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,5 +369,53 @@ angular.module('MatrixCall', [])
|
|||||||
}, delayMs);
|
}, delayMs);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Sends candidates with are sent in a special way because we try to amalgamate them into one message
|
||||||
|
MatrixCall.prototype.sendCandidate = function(content) {
|
||||||
|
this.candidateSendQueue.push(content);
|
||||||
|
var self = this;
|
||||||
|
if (this.candidateSendTries == 0) $timeout(function() { self.sendCandidateQueue(); }, 100);
|
||||||
|
};
|
||||||
|
|
||||||
|
MatrixCall.prototype.sendCandidateQueue = function(content) {
|
||||||
|
if (this.candidateSendQueue.length == 0) return;
|
||||||
|
|
||||||
|
var cands = this.candidateSendQueue;
|
||||||
|
this.candidateSendQueue = [];
|
||||||
|
++this.candidateSendTries;
|
||||||
|
var content = {
|
||||||
|
version: 0,
|
||||||
|
call_id: this.call_id,
|
||||||
|
candidates: cands
|
||||||
|
};
|
||||||
|
var self = this;
|
||||||
|
console.log("Attempting to send "+cands.length+" candidates");
|
||||||
|
matrixService.sendEvent(self.room_id, 'm.call.candidates', undefined, content).then(function() { self.candsSent(); }, function(error) { self.candsSendFailed(cands, error); } );
|
||||||
|
};
|
||||||
|
|
||||||
|
MatrixCall.prototype.candsSent = function() {
|
||||||
|
this.candidateSendTries = 0;
|
||||||
|
this.sendCandidateQueue();
|
||||||
|
};
|
||||||
|
|
||||||
|
MatrixCall.prototype.candsSendFailed = function(cands, error) {
|
||||||
|
for (var i = 0; i < cands.length; ++i) {
|
||||||
|
this.candidateSendQueue.push(cands[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.candidateSendTries > 5) {
|
||||||
|
console.log("Failed to send candidates on attempt "+ev.tries+". Giving up for now.");
|
||||||
|
this.candidateSendTries = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var delayMs = 500 * Math.pow(2, this.candidateSendTries);
|
||||||
|
++this.candidateSendTries;
|
||||||
|
console.log("Failed to send candidates. Retrying in "+delayMs+"ms");
|
||||||
|
var self = this;
|
||||||
|
$timeout(function() {
|
||||||
|
self.sendCandidateQueue();
|
||||||
|
}, delayMs);
|
||||||
|
};
|
||||||
|
|
||||||
return MatrixCall;
|
return MatrixCall;
|
||||||
}]);
|
}]);
|
||||||
|
@ -77,13 +77,15 @@ angular.module('matrixPhoneService', [])
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
call.receivedAnswer(msg);
|
call.receivedAnswer(msg);
|
||||||
} else if (event.type == 'm.call.candidate') {
|
} else if (event.type == 'm.call.candidates') {
|
||||||
var call = matrixPhoneService.allCalls[msg.call_id];
|
var call = matrixPhoneService.allCalls[msg.call_id];
|
||||||
if (!call) {
|
if (!call) {
|
||||||
console.log("Got candidate for unknown call ID "+msg.call_id);
|
console.log("Got candidates for unknown call ID "+msg.call_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
call.gotRemoteIceCandidate(msg.candidate);
|
for (var i = 0; i < msg.candidates.length; ++i) {
|
||||||
|
call.gotRemoteIceCandidate(msg.candidates[i]);
|
||||||
|
}
|
||||||
} else if (event.type == 'm.call.hangup') {
|
} else if (event.type == 'm.call.hangup') {
|
||||||
var call = matrixPhoneService.allCalls[msg.call_id];
|
var call = matrixPhoneService.allCalls[msg.call_id];
|
||||||
if (!call) {
|
if (!call) {
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
<td colspan="3" class="recentsRoomSummary">
|
<td colspan="3" class="recentsRoomSummary">
|
||||||
|
|
||||||
<div ng-show="room.membership === 'invite'">
|
<div ng-show="room.membership === 'invite'">
|
||||||
{{ room.lastMsg.inviter | mUserDisplayName: room.room_id }} invited you
|
{{ room.inviter | mUserDisplayName: room.room_id }} invited you
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ng-hide="room.membership === 'invite'" ng-switch="room.lastMsg.type">
|
<div ng-hide="room.membership === 'invite'" ng-switch="room.lastMsg.type">
|
||||||
|
@ -220,7 +220,7 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput'])
|
|||||||
};
|
};
|
||||||
|
|
||||||
var paginate = function(numItems) {
|
var paginate = function(numItems) {
|
||||||
// console.log("paginate " + numItems);
|
//console.log("paginate " + numItems + " and first_pagination is " + $scope.state.first_pagination);
|
||||||
if ($scope.state.paginating || !$scope.room_id) {
|
if ($scope.state.paginating || !$scope.room_id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -260,7 +260,7 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput'])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($scope.state.first_pagination) {
|
if ($scope.state.first_pagination) {
|
||||||
scrollToBottom();
|
scrollToBottom(true);
|
||||||
$scope.state.first_pagination = false;
|
$scope.state.first_pagination = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -598,6 +598,7 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput'])
|
|||||||
promise.then(
|
promise.then(
|
||||||
function(response) {
|
function(response) {
|
||||||
console.log("Request successfully sent");
|
console.log("Request successfully sent");
|
||||||
|
|
||||||
if (echo) {
|
if (echo) {
|
||||||
// Mark this fake message event with its allocated event_id
|
// Mark this fake message event with its allocated event_id
|
||||||
// When the true message event will come from the events stream (in handleMessage),
|
// When the true message event will come from the events stream (in handleMessage),
|
||||||
|
Loading…
Reference in New Issue
Block a user