clean up and bug fixes

This commit is contained in:
nnduc
2026-11-07 15:29:40 +07:00
parent 978dd5b5da
commit 0d8107a0a7
374 changed files with 98 additions and 5593 deletions
-11
View File
@@ -1,11 +0,0 @@
[about]
thanks = Thanks
developers = Developers
translators = Translators
translators_text = "Thanks to all the translators"
software = Software
resources = Resources
api = API
info = Movim is an XMPP-based communication platform. All the project, except the following software and resources, is under
sourcecode_title = Sourcecode
sourcecode_text = Check out the sourcecode on the Github repository
-1
View File
@@ -188,5 +188,4 @@ var Account = {
MovimWebsocket.attach(function () {
if (OMEMO_ENABLED) Account.refreshFingerprints();
Account_ajaxHttpGetPresences();
Account_ajaxGetGateways();
});
-54
View File
@@ -1,54 +0,0 @@
var AdHoc = {
refresh: function () {
var items = document.querySelectorAll('.adhoc_widget .actions li:not(.subheader)');
var i = 0;
while (i < items.length) {
items[i].onclick = function () {
Drawer.clear();
AdHoc_ajaxCommand(this.dataset.jid, this.dataset.node);
};
i++;
}
},
initForm: function () {
var form = document.querySelector('#dialog form[name=command]');
if (form) {
form.addEventListener('input', e => AdHoc.checkFormValidity());
}
AdHoc.checkFormValidity();
},
submit: function (jid, action) {
var form = document.querySelector('#dialog form[name=command]');
AdHoc_ajaxSubmit(
jid,
form.dataset.node,
MovimUtils.formToJson('command'),
form.dataset.sessionid,
action
);
},
checkFormValidity: function () {
var form = document.querySelector('#dialog form[name=command]');
var action = document.querySelector('#dialog #adhoc_action');
if (form && action) {
if (form.checkValidity()) {
action.classList.remove('disabled');
} else {
action.classList.add('disabled');
}
}
}
}
MovimWebsocket.attach(function () {
var parts = MovimUtils.urlParts();
if (parts.page === "configuration") {
AdHoc_ajaxGet();
}
});
-10
View File
@@ -1,10 +0,0 @@
[adhoc]
title = Actions
completed = Action completed
[tools]
title = Developer Tools
sdp_to_jingle = Convert SDP to Jingle
sdp_title = SDP
jingle_to_sdp = Convert Jingle to SDP
jingle_title = Jingle stanza
-72
View File
@@ -1,72 +0,0 @@
[admin]
general = General Settings
[general]
theme = Theme
language = Default language
log_verbosity = Log verbosity
join_title = Your instance is public?
join_text = Register your instance on join.movim.eu and join the Movim federation!
[restrictsuggestions]
title = Restrict suggestions
text = "Only suggest chatrooms, Communities, and other contents that are available on the user's XMPP server and related services"
[chatonly]
title = Chat only
text = Disable all the social feature (Communities, Blog…) and keep only the chat ones
[credentials]
title = Administration Credential
username = Username
password = Password
re_password = Retype password
[disableregistration]
title = Disable the XMPP registration feature
text = Remove the XMPP registration flow and buttons from the interface
[whitelist]
title = Allowed XMPP Servers
info1 = If you want to specify a list of authorized XMPP servers on your Movim pod and forbid the connection on all the others please put their domain name(s) here, with comma (ex: movim.eu,jabber.fr)
info2 = Leave this field blank if you allow the access to all the XMPP accounts.
label = List of allowed XMPP servers
[ssrfwhitelist]
title = Whitelisted Domains for SSRF Protection
info1 = Movim is protecting you against SSRF vulnerabilities. This means that Movim blocks all URLs (shared links, avatars, and pictures) that point to your local network IPs.
info2 = See the related SSRF documentation on developer.mozilla.org.
info3 = Add all domains hosted locally here (for example, if you host a blog, an XMPP file upload service, or other web services).
info4 = This setting will be applied after a daemon restart.
label = List of Locally Authorized Domains
[information]
description = Description
description_placeholder = General description of the instance
banner = Main banner
banner_info = Ensure that the picture is not too large and can be reached from any webpages
info1 = This message will be displayed on the login page. It can be used to link the Terms and Conditions of your Movim instance for example.
info2 = Leave this field blank if you don’t want to show any message.
label = Information Message
[xmpp]
title = Default XMPP server
domain = Main XMPP server domain
description = Main XMPP server description
country = Main XMPP server country
country_pick= Pick a country in the list
[tenor]
title = Tenor integration
label = Your Tenor API Key
info1 = Movim integrates the Tenor API to allow GIF search and publication in Chat
info2 = Access Tenor and get your API key
[log]
empty = Empty
syslog = Syslog
syslog_files = Syslog and files
[maxsessions]
title = Maximum of connected sessions
info = Movim will forbid new users to connect when the limit is reached, set it to 0 to disable
@@ -1,3 +0,0 @@
#blocked_widget_list:not(:empty) ~ .placeholder {
display: none;
}
@@ -1,3 +0,0 @@
MovimWebsocket.attach(function() {
AdminReported_ajaxHttpGet();
});
@@ -1,4 +0,0 @@
[adminreported]
reported_by = "Reported by %s users"
info = Those accounts were reported by some Movim users
info2 = You can choose to block them for all the other users
@@ -1,3 +0,0 @@
[adminsessions]
title = Sessions
text = Currently connected users on the pod
-3
View File
@@ -1,3 +0,0 @@
[blog]
title = "%s’s blog"
private = This content is private, please login to see it
@@ -1,30 +0,0 @@
var Communities = {
init: function() {
let parts = MovimUtils.urlParts();
let page = parts.params[0] !== undefined ? parseInt(parts.params[0]) : 0;
if (parts.hash != '') {
switch (parts.hash) {
case 'communities':
Communities_ajaxHttpGetCommunities(page);
break;
case 'contacts':
Communities_ajaxHttpGetContacts(page);
break;
}
} else {
Communities_ajaxHttpGetAll(page);
}
},
morePosts: function(button, page, type) {
button.remove();
Communities_ajaxHttpGetPosts(page, type);
}
}
MovimWebsocket.attach(function() {
Notif.current('community');
});
MovimWebsocket.initiate(() => Communities.init());
-8
View File
@@ -1,8 +0,0 @@
[communities]
empty_text = Discover, follow and share
counter = "%s communities"
search_server = Search for a new server
servers = Communities servers
servers_text = Discover the Communities by servers
disco = Communities server discovered
disco_error = "This server doesn’t exists"
@@ -1,2 +0,0 @@
[communitiesinteresting]
about = Communities you might like
@@ -1,7 +0,0 @@
MovimWebsocket.attach(function() {
Notif.current('community');
var parts = MovimUtils.urlParts();
if (parts.params.length > 0) {
CommunitiesServer_ajaxDisco(parts.params[0]);
}
});
@@ -1,10 +0,0 @@
[communitiesserver]
created = Community created successfully
empty_server = "There is no Communities yet on this server."
add = Create a new community on %s
name = Community name
name_example = My Little Pony - Fan Club
name_error = Please provide a valid community name (4 characters minimum)
no_creation = You cannot create a new community on this server
disco_error = Issue when trying to discover the items
remoteservernotfound = "The server %s cannot be reached"
@@ -1,5 +0,0 @@
MovimWebsocket.initiate(() => CommunitiesServers_ajaxHttpGet());
MovimWebsocket.attach(function () {
Notif.current('explore');
});
@@ -1,3 +0,0 @@
[communitiesservers]
empty_title = No Communities Servers yet…
empty_text = "It seems that we can't find any communities for the moment"
@@ -1,20 +0,0 @@
var CommunityAffiliations = {
update : function(jid) {
var parts = MovimUtils.urlParts();
if (parts.params.length > 0) {
CommunityAffiliations_ajaxChangeAffiliation(
parts.params[0],
parts.params[1],
MovimUtils.formToJson(jid)
);
}
}
}
MovimWebsocket.attach(function() {
var parts = MovimUtils.urlParts();
if (parts.params.length > 0) {
CommunityAffiliations_ajaxGetSubscriptions(parts.params[0], parts.params[1]);
CommunityAffiliations_ajaxGetAffiliations(parts.params[0], parts.params[1]);
}
});
@@ -1,16 +0,0 @@
[communityaffiliation]
configuration = Configuration
subscriptions = Subscriptions
public_subscriptions= Public subscriptions
subscriptions_text = My Communities subscriptions
deleted = Community deleted successfully
delete_title = Delete the community
delete_text = You are going to delete the following community. Please confirm your action.
delete_clean_text = "It seems that this community doesn’t exists anymore. Do you want to remove it from your subscriptions?"
delete_error = Error during the node deletion
config_saved = Configuration saved
config_error = Error during the application of the node configuration
owners = Owners
publishers = Publishers
roles = Roles
role_set = Role correctly set
@@ -1,14 +0,0 @@
[communityconfig]
description = Description
publication = Publication
publish_model_open_title = Public
publish_model_open_text = Everyone can publish
publish_model_publishers_title = Publishers
publish_model_publishers_text = The publishers can publish
publish_model_subscribers_title = Subscribers
publish_model_subscribers_text = The subscribers can publish
type = Community type
type_articles_title = Articles
type_articles_text = Publish and read articles
type_gallery_title = Gallery
type_gallery_text = Publish and browse pictures
@@ -1,4 +0,0 @@
#community_data li:first-child img.avatar,
#community_data li:first-child span.avatar {
display: inline-block;
}
@@ -1,8 +0,0 @@
MovimWebsocket.attach(function() {
if (!MovimUtils.isMobile()) {
var parts = MovimUtils.urlParts();
if (parts.params.length > 0) {
CommunityData_ajaxGetAvatar(parts.params[0], parts.params[1]);
}
}
});
@@ -1,6 +0,0 @@
[communitydata]
sub = %s subscribers
num = %s posts
public = Public page
publishmodel_publishers = Only publishers can publish
publishmodel_subscribers = Only subscribers can publish
@@ -1,13 +0,0 @@
var CommunityHeader = {
getMetadata: function () {
var parts = MovimUtils.urlParts();
if (parts.params.length > 0) {
CommunityHeader_ajaxGetMetadata(parts.params[0], parts.params[1]);
}
}
}
MovimWebsocket.attach(function () {
Notif.current('community');
CommunityHeader.getMetadata();
});
@@ -1,12 +0,0 @@
[communityheader]
follow = Follow
unfollow = Unfollow
followed = Followed
unfollowed = Unfollowed
subscription_unsupported = The subscriptions are disabled for this community
label_label = Give a label for this community
label_placeholder = My Community Name
share_follow = Share this follow to everyone
share_follow_text = It will appear on your profile
unfollow_text = You are going to unfollow this community
sure = Are you sure?
@@ -1,16 +0,0 @@
var CommunityPosts = {
getItems: function () {
var parts = MovimUtils.urlParts();
if (parts.params.length > 0) {
var node = (parts.params[1] == undefined || parts.params[1] == '')
? 'urn:xmpp:microblog:0'
: parts.params[1];
CommunityPosts_ajaxGetItems(parts.params[0], node, parts.params[2]);
}
}
}
MovimWebsocket.attach(function () {
CommunityPosts.getItems();
});
@@ -1,7 +0,0 @@
[communityposts]
empty_me_text = No publication yet? Write your first post to make people discover your profile
empty_me_button = Publish my first post
presencerequired = Private account
presencerequired_text = Ask %s to be in your contacts to see the publications
subscribe_presencerequired = Send an invitation request before following the contact
subscribe_unsupported = "You can't follow the contact at the moment"
@@ -1,5 +0,0 @@
@media screen and (max-width: 1024px) {
#subscriptions {
padding: 0 0.75rem;
}
}
@@ -1 +0,0 @@
MovimWebsocket.attach(() => CommunitySubscriptions_ajaxHttpGet());
@@ -1,5 +0,0 @@
[communitysubscriptions]
subscriptions = Subscribed Communities
empty_title = Hello
empty_text1 = Here you will be able to manage all your subscriptions.
empty_text2 = You don’t have any community subscriptions yet.
-1
View File
@@ -16,5 +16,4 @@ MovimWebsocket.attach(function () {
Notif.current('configuration');
Config_ajaxMAMGetConfig();
Config_ajaxBlogGetConfig();
});
@@ -1,3 +0,0 @@
MovimWebsocket.attach(() => {
ContactBlogConfig_ajaxCheckAccessModel(MovimUtils.urlParts().params[0]);
});
@@ -1,13 +0,0 @@
MovimWebsocket.attach(function() {
Notif.current('contact');
if (!MovimUtils.isMobile()) {
var parts = MovimUtils.urlParts();
ContactData_ajaxGet(parts.params[0]);
if (parts.params.length > 0) {
ContactData_ajaxRefresh(parts.params[0]);
}
}
});
-65
View File
@@ -1,65 +0,0 @@
[general]
legend = General Information
name = Name
pronouns = Pronouns
pronouns_example = "he/she/they/…"
nickname = Nickname
date_of_birth = Date of Birth
gender = Gender
marital = Marital Status
email = Email
website = Website
about = About Me
accounts = Other Accounts
tune = Is Listening
pictures = Pictures
links = Links
private_account_title = Your account is private
private_account_text = Go to the Settings page to create a public blog and allow the other users to find you
[position]
legend = Geographic Position
locality = Locality
country = Country
[listen]
title = Listening
[last]
title = Last seen
[clients]
title = Clients
title_full = Clients information
[explore]
last_registered = Last registered
explore = Find some new contacts
[edit]
title = Edit
alias = Alias
group = Group
[delete]
title = Are you sure?
text = You are going to remove one of your contacts, please confirm your action
[age]
years = %s years
[blog]
last = Last public post
visit = Visit the public blog
[subscription]
to = You can see this contact status
to_button = Share my status
to_text = But this contact cannot see yours
from = You are not subscribed to this contact
from_button = Ask to subscribe
from_text = But this contact can still see if you are online
nil = You are not subscribed to anyone
nil_button = Invite
nil_text = This contact is in your contact list but you are not subscribed to each other
@@ -1,6 +0,0 @@
var ContactHeader = {
submit: function (button) {
button.innerHTML = '<i class="material-symbols spin">progress_activity</i>';
button.classList.add('inactive');
}
}
@@ -1,8 +0,0 @@
MovimWebsocket.attach(function() {
if (!MovimUtils.isMobile()) {
var parts = MovimUtils.urlParts();
if (parts.params.length > 0) {
ContactSubscriptions_ajaxRefresh(parts.params[0]);
}
}
});
@@ -1,10 +0,0 @@
var ContactsSuggestions = {
submit: function (button) {
button.innerHTML = '<i class="material-symbols spin">progress_activity</i>';
button.classList.add('inactive');
}
};
if (!MovimUtils.isMobile()) {
ContactsSuggestions_ajaxHttpGet();
}
@@ -1,2 +0,0 @@
[contactssuggestions]
for_you = Suggestions for you
@@ -1,26 +0,0 @@
#emojisconfig_widget .pack {
padding-bottom: 1rem;
}
#emojisconfig_widget .pack:not(:last-child) {
border-bottom: 1px solid rgba(var(--movim-font), 0.12);
}
#emojisconfig_widget .pack .emojis {
text-align: center;
}
#emojisconfig_widget .pack .emojis img {
padding: 0.5rem;
}
#emojisconfig_widget .pack .emojis img:hover {
cursor: pointer;
background-color: rgba(var(--movim-font), 0.05);
border-radius: 0.5rem;
}
#emojisconfig_widget .pack .emojis img.favorite {
opacity: 0.05;
pointer-events: none;
}
@@ -1,3 +0,0 @@
MovimWebsocket.attach(function () {
EmojisConfig_ajaxHttpGet();
});
@@ -1,9 +0,0 @@
[emojisconfig]
title = Emojis
favorites_title = My favorite emojis
favorites_text = Pick emojis from the packs bellow that you want to add to your favorites ones
dialog_title = Manage a favorite emoji
alias_error = The shortcut should only contains lowercase letters, numbers and dashes
new_added = New favorite emoji added
alias_conflict = The shortcut is already used on another emoji
no_emojis_yet = No favorites yet, check the settings page to add some
-22
View File
@@ -1,22 +0,0 @@
[faq]
title = Frequently Asked Questions
permission_title = What does the permission setting do?
permission_text = By default the content is only available to your contacts. You can make your profile and publications public by enabling the related setting.
permission_community_title = How does it apply to Communities posts?
permission_community_text = Similary to your blog publications except that, by default, the posts are only available to the members or subscribers of the Community (except if you explicitly open all the Community content)
chatrooms_title = Where can I find a list of group chats?
find_contacts_title = Where can I find my contacts?
find_contacts_text = By opening the search panel.
[apps]
title = Applications
install = Movim App
install_text = Install Movim on your device
recommend = We also recommend
[contact]
title = Administrators & Contact
[chatroom]
question = Chat with the Movim team?
button = Add the chatroom
-8
View File
@@ -1,8 +0,0 @@
[menu]
empty_title = No news yet…
empty = Welcome to your news feed, here you will see all the posts published by your contacts and in the communities you have subscribed.
all = All
mine = My publications
contacts = Contacts
add_post = Write a new post…
-23
View File
@@ -1,23 +0,0 @@
#menu_widget {
margin-top: 0.5rem;
}
#menu_refresh {
margin: 0.5rem 0;
}
@media screen and (max-width: 1024px) {
#menu_widget > div {
padding: 0 0.75rem;
}
}
#menu_refresh li.refreshing {
background: linear-gradient(to right, rgb(var(--movim-background-main)) 8%, rgba(var(--movim-background), 0.5) 18%, rgb(var(--movim-background-main)) 33%);
animation: 1.5s shine linear infinite;
background-size: 200% 100%;
}
#menu_refresh li.refreshing span.primary i {
animation: spin 2s linear infinite;
}
-34
View File
@@ -1,34 +0,0 @@
var Menu = {
init: function() {
let parts = MovimUtils.urlParts();
let page = parts.params[0] !== undefined ? parseInt(parts.params[0]) : 0;
if (parts.hash != '') {
switch (parts.hash) {
case 'communities':
Menu_ajaxHttpGetCommunities(page);
break;
case 'contacts':
Menu_ajaxHttpGetContacts(page);
break;
}
} else {
Menu_ajaxHttpGetAll(page);
}
},
refresh: function() {
document.querySelector('#menu_refresh li').classList.add('refreshing');
Menu_ajaxHttpGetAll();
},
setLoad: function(tab) {
tab.innerHTML = '<i class="material-symbols spin">autorenew</i>';
}
};
MovimWebsocket.attach(function() {
Menu.init();
Notif_ajaxClear('news');
Notif.current('news');
});
-8
View File
@@ -1,8 +0,0 @@
MovimWebsocket.initiate(() => {
if (!MovimUtils.isMobile()) {
NewsNav_ajaxHttpGet(
MovimUtils.urlParts().page,
MovimUtils.urlParts().params[0]
)
}
});
-7
View File
@@ -1,7 +0,0 @@
[onboarding]
notifications_title = Notifications
notifications_text = Movim can notify you when a new post is published or if you receive messages
notifications_text_second = You can always disable them afterwards
public_title = Public profile
public_text = Make your profile public and allow other users to find you and make new contacts more easily
public_text_second = You can always disable this in the configuration afterwards
-15
View File
@@ -1,15 +0,0 @@
var Onboarding = {
check: function() {
if (localStorage.getItem('onboardingPublic') === null) {
Onboarding_ajaxAskPublic();
}
},
setPublic: function() {
localStorage.setItem('onboardingPublic', true);
}
}
MovimWebsocket.attach(function() {
Onboarding.check();
});
-56
View File
@@ -1,56 +0,0 @@
[post]
publish_something = Publish something
news_feed = News Feed
placeholder = Discover and register to the groups you are interested in
content = Content
published = Post published
deleted = Post deleted
hot_text = Posts recently published in communities that you are not subscribed (yet)
new_blog = New blog post
repost = This is a re-post from %s
see_profile = See %s profile
unknown_contact= Unknown contact
read_time_singular = %s minute
read_time_plural = %s minutes
public_preview = Preview URL: %s
public_yes = This post is public
public_no = This post is private
public_url = Public URL of this post
comments_disabled_title = Disable the comments
comments_disabled_text = Nobody will be able to like or comment
comments_disabled_yes = Comments disabled for this post
comments_disabled_no = Comments enabled for this post
delete_title = Delete this post
delete_text = You are going to delete this post, please confirm your action
delete_comment = Are you sure that you want to delete this comment?
discover = Discover more posts on the communities page
more = Read more
comments_disabled = Comments disabled
comment_published = Comment published
comment_like_published = Liked
comment_publish_error = The comment cannot be published
comment_deleted = Comment deleted
liked = Liked your publication
commented = Commented
subscription_required = You must be subscribed to %s to see this publication
[hello]
contact_post = Contact post
share_title = Universal share button
share_text = Bookmark or drag and drop the following button in your toolbar and use it on all the pages you want to share on Movim
share_button = Share on Movim
enter_title = Oh! Hello!
enter_paragraph = It seems that you are new here! Welcome to Movim!
menu_title = Check the Menu
menu_paragraph = All the main Movim features are accessible there. Don’t hesitate to navigate through the pages to discover more!
profile_title = Looks like you didn’t complete your profile yet
profile_paragraph = You can go in the Configuration page to describe yourself and put a nice picture
-7
View File
@@ -1,7 +0,0 @@
#comments {
margin-top: 2rem;
}
#comments li.mine ~ li button#like {
display: none;
}
-39
View File
@@ -1,39 +0,0 @@
var Post = {
comment: function() {
document.querySelector('#comment_add').classList.remove('hide');
document.querySelector('#comment_add textarea').focus();
document.querySelector('#comment_add').scrollIntoView();
},
share : function() {
var parts = MovimUtils.urlParts();
if (parts.params.length) {
Post_ajaxShare(parts.params[0], parts.params[1], parts.params[2]);
}
},
refreshComments : function() {
var parts = MovimUtils.urlParts();
if (parts.params.length) {
Post_ajaxGetPostComments(parts.params[0], parts.params[1], parts.params[2]);
}
},
checkCommentAction: function() {
var parts = MovimUtils.urlParts();
if (parts.hash == 'comment') {
Post.comment();
}
}
};
MovimWebsocket.attach(function() {
Notif.current('post');
var parts = MovimUtils.urlParts();
if (parts.params.length == 3) {
Post_ajaxGetPost(parts.params[0], parts.params[1], parts.params[2]);
} else {
Post_ajaxGetNotFound();
}
});
@@ -1,8 +0,0 @@
var PostActions = {
handleDelete : function(url) {
var page = MovimUtils.urlParts().page;
if (page == 'post') {
MovimUtils.redirect(url);
}
}
}
@@ -1,3 +0,0 @@
#publicnavigation a.button {
margin: 0;
}
-30
View File
@@ -1,30 +0,0 @@
[publish]
placeholder = "What’s new?"
brief_title = Brief
post_title = Post
post = Write a post
add_link = Add a link
add_snap = Take a picture
no_title = Please provide a title
no_picture = At least one picture is required
preview = Preview
attach = Add a file or a picture
no_publication = You cannot publish a post here
#no_content_preview = No content to preview
new = New post
title = Post title
content = Markdown content
valid_url = Please enter a valid URL
content_text= You can format your content using Markdown
draft_saved = Draft saved
rich_editor = Rich text editor
help_hashtag = "Add #hashtags in your title or content to allow your post to be discovered"
publish_error_forbidden = You are not authorized to publish there
publish_error_payload_to_big = Your post is too big to be published
too_long = Your text is too long, %s characters max
blog_presence = "Your blog is only accessible to your subscribers. You can make it accessible to anyone in the settings page."
embedded_link = The media will be embedded
web_title = Create a public HTTP URL from this publication
web_text = This will allow anyone outside Movim to have access to your publication
-89
View File
@@ -1,89 +0,0 @@
#publishembeds li {
border: 1px solid rgba(var(--movim-font), 0.12);
border-radius: 0.5rem;
}
#publishembeds li {
padding-right: 0;
}
#publishpreview h3:first-child {
margin: 1rem 2rem 0;
}
#publish label span.save {
display: none;
}
#publish>div.block {
margin: 0 0.75rem;
padding-bottom: 1rem;
}
#publish label span.save.saved {
display: initial;
}
#publish textarea[name=content] {
min-height: 25rem;
}
#publish span.privacy form>div .checkbox>input[type="checkbox"]+label,
#publish span.comments_disabled form>div .checkbox>input[type="checkbox"]+label {
top: 0.5rem;
left: 0.5rem;
height: 3rem;
width: 3rem;
}
section#sidebar:has(+#publish) {
opacity: 0;
transition: opacity 0.3s ease-in-out;
}
section#sidebar:has(+#publish div[data-type="article"] textarea[name="content"]:focus),
section#sidebar:has(+#publish div[data-type="article"]):hover {
opacity: 1;
}
#publish span.privacy form>div .checkbox>input[type="checkbox"]:checked+label,
#publish span.comments_disabled form>div .checkbox>input[type="checkbox"]:checked+label {
left: 2.5rem;
}
#publish span.privacy form>div .checkbox>input[type="checkbox"]+label i:before {
content: 'lock';
}
#publish span.privacy form>div .checkbox>input[type="checkbox"]:checked+label i:before {
content: 'wifi_tethering';
}
#publish span.comments_disabled form>div .checkbox>input[type="checkbox"]+label i:before {
content: 'insert_comment';
}
#publish span.comments_disabled form>div .checkbox>input[type="checkbox"]:checked+label i:before {
content: 'comments_disabled';
}
#publishreply {
margin-bottom: -1rem;
}
#publish form[data-type="brief"] div#title textarea {
min-height: 10rem;
padding-top: 1rem;
margin-bottom: 2rem;
}
#publish form[data-type="brief"] div#title label {
top: initial;
bottom: -3rem;
right: 0;
}
#publish #publish_open_link_preview:empty,
#publish form[data-type="brief"] div#content {
display: none;
}
-118
View File
@@ -1,118 +0,0 @@
var Publish = {
titleTimeout: null,
contentTimeout: null,
get: function(type) {
let parts = MovimUtils.urlParts();
Publish_ajaxHttpGet(
type ?? null,
parts.params[0],
parts.params[1],
parts.params[2],
parts.params[3],
parts.params[4],
parts.params[5],
)
},
init: function () {
let id = document.querySelector('#publish input[name=id]').value;
Publish_ajaxTryResolveShareUrl(id);
document.querySelector('#publish textarea[name=title]').addEventListener('keyup', function (event) {
if (Publish.titleTimeout) clearTimeout(Publish.titleTimeout);
document.querySelector('#publish textarea[name=title] + label span.save').classList.remove('saved');
Publish.titleTimeout = setTimeout(function () {
Publish.saveTitle();
Publish_ajaxOpenlinkPreview(id);
}, 1000);
});
document.querySelector('#publish textarea[name=content]').addEventListener('keyup', function (event) {
if (Publish.contentTimeout) clearTimeout(Publish.contentTimeout);
document.querySelector('#publish textarea[name=content] + label span.save').classList.remove('saved');
Publish.contentTimeout = setTimeout(function () {
Publish.saveContent();
}, 1000);
});
Publish_ajaxOpenlinkPreview(id);
Publish_ajaxCheckPrivacy(id);
},
saveTitle: function () {
let id = document.querySelector('#publish input[name=id]').value;
return Publish_ajaxHttpSaveTitle(id, document.querySelector('#publish textarea[name=title]').value);
},
saveContent: function () {
let id = document.querySelector('#publish input[name=id]').value;
return Publish_ajaxHttpSaveContent(id, document.querySelector('#publish textarea[name=content]').value);
},
enableSend: function () {
document.querySelector('.button.send').classList.remove('disabled');
document.querySelector('.button.send i').classList.remove('spin');
document.querySelector('.button.send i').innerText = 'send';
},
disableSend: function () {
document.querySelector('.button.send').classList.add('disabled');
document.querySelector('.button.send i').classList.add('spin');
document.querySelector('.button.send i').innerText = 'autorenew';
},
preview: function () {
Publish.saveTitle().then(e => {
Publish.saveContent().then(e => {
let id = document.querySelector('#publish input[name=id]').value;
Publish_ajaxPreview(id);
});
});
},
publish: function () {
Publish.saveTitle().then(e => {
Publish.saveContent().then(e => {
let id = document.querySelector('#publish input[name=id]').value;
Publish_ajaxPublish(id);
});
});
},
clearReply: function () {
let id = document.querySelector('#publish input[name=id]').value;
Publish_ajaxClearReply(id);
},
addUrl: function () {
let id = document.querySelector('#publish input[name=id]').value;
var url = document.querySelector('#url').value;
Publish_ajaxAddUrl(id, url);
}
}
MovimWebsocket.attach(() => {
Publish.get('brief');
});
MovimEvents.registerWindow('loaded', 'publish', () => {
if (typeof Upload != 'undefined') {
Upload.attach((file) => {
if (MovimUtils.urlParts().page == 'publish') {
Publish_ajaxAddUpload(document.querySelector('#publish input[name=id]').value, file.id);
}
});
Upload.initiate((file) => {
if (MovimUtils.urlParts().page == 'publish') {
Upload.prependName = 'post';
}
});
}
});
-4
View File
@@ -1,4 +0,0 @@
[publishhelp]
title = Help
more = More help
manual = Markdown syntax manual
@@ -1,9 +0,0 @@
[story]
new = New story
new_edit = Edit your story
new_publish = Publish your story
to_roster = Publish to my contacts
uploading = Uploading the story
publishing = Publishing the story
publishing_text = Almost there…
published = Story published
@@ -1,180 +0,0 @@
#publishstories {
top: 0;
left: 0;
background-color: rgb(var(--movim-background-main));
width: 100%;
height: 100%;
z-index: 2;
position: absolute;
transform: translateX(-100%);
}
#publishstories #publishstoriesswitch,
#publishstories #publishstoriesgallery {
width: 5.5rem;
height: 5.5rem;
line-height: 5.5rem;
margin-top: 0.75rem;
font-size: 2.5rem;
}
#publishstories.show,
#publishstories.shoot,
#publishstories.edit {
transform: translateX(0);
transition: transform 0.4s var(--decelerate-easing);
}
#publishstories #publishstoriesbackedit,
#publishstories #publishstoriesback {
margin-left: 0;
padding: 1rem 0;
}
#publishstories #publishstoriesshoot,
#publishstories #publishstoriesgallery,
#publishstories #publishstoriesswitch,
#publishstories #publishstoriessource,
#publishstories #publishstoriesnext,
#publishstories #publishactions,
#publishstories #publishstoriesbackedit,
#publishstories #publishstoriespreview,
#publishstories.edit.publish #publishstoriesback,
#publishstories.edit.publish #publishstoriesnext,
#publishstories.shoot #publishstoriesheadedit,
#publishstories.edit #publishstorieshead,
#publishstories.edit.publish #publishstorieshead,
#publishstories.edit.publish #publishstoriesheadedit,
#publishstories.shoot.error video,
#publishstories form {
display: none;
}
#publishstories.shoot.error:before {
font-family: 'Material Symbols';
content: '\e04c';
color: var(--movim-font);
font-size: 7rem;
opacity: 0.5;
display: block;
position: absolute;
left: calc(50% - 3.5rem);
top: calc(50% - 3.5rem);
}
#publishstories.shoot:not(.error) #publishstoriesshoot,
#publishstories.shoot #publishstoriesgallery,
#publishstories.shoot:not(.error) #publishstoriesswitch.enabled,
#publishstories.edit form,
#publishstories.edit #publishstoriesnext,
#publishstories.edit.publish #publishactions,
#publishstories.edit.publish #publishstoriespreview,
#publishstories.edit.publish #publishstoriesbackedit {
display: initial;
}
#publishstories input[type=file] {
display: none;
}
#publishstories #publishactions,
#publishstories form {
position: absolute;
width: 100%;
bottom: 3rem;
left: 50%;
translate: -50%;
max-width: calc(56.25vh - 8.25rem);
/* 16:9 */
}
#publishstories form {
background-image: linear-gradient(to bottom, transparent, rgba(var(--movim-background-main), 1) 100%);
padding: 1.5rem 2rem;
box-sizing: border-box;
bottom: 7.25rem;
border-radius: 2rem;
animation: fadeIn 0.5s;
transition: bottom 0.3s, max-width 0.3s;
}
#publishstories canvas,
#publishstories video {
aspect-ratio: 9 / 16;
height: 100%;
position: absolute;
left: 50%;
top: 50%;
translate: -50% -50%;
animation: zoom 0.3s;
transition: top 0.3s, height 0.3s;
}
#publishstories .bottom_center {
width: 100%;
position: absolute;
bottom: 2rem;
display: flex;
justify-content: center;
}
#publishstories .bottom_center>button {
position: relative;
margin-left: 1rem;
margin-right: 1rem;
right: 0;
}
#publishstories video {
background-image: url(../theme/img/cloud_spinner.svg);
background-repeat: no-repeat;
background-position: center center;
background-size: 9rem;
object-fit: cover;
}
#publishstories.shoot canvas,
#publishstories.edit video {
display: none;
}
#publishstories.edit canvas {
animation: zoomOut 0.3s;
border-radius: 2rem;
height: calc(100% - 15rem);
box-shadow: var(--elevation-5);
}
#publishstories #publishactions {
animation: fadeIn 0.5s;
max-height: 7rem;
overflow: hidden;
}
#publishstories #publishactions ul {
transition: transform 0.3s;
}
#publishstories #publishactions.uploading ul {
transform: translateY(-7rem);
}
#publishstories #publishactions.publishing ul {
transform: translateY(-14rem);
}
#publishstories.edit.publish canvas {
top: calc(50% - 2rem);
height: calc(100% - 21rem);
pointer-events: none;
}
#publishstories.edit.publish form {
bottom: 12.5rem;
max-width: calc(56.25vh - 11.5rem);
}
#publishstories.edit.publish form textarea {
pointer-events: none;
box-shadow: none;
}
@@ -1,401 +0,0 @@
MAX_ZOOM = 5;
MIN_ZOOM = 0.1;
SCROLL_SENSITIVITY = 0.0005;
var PublishStories = {
main: undefined,
back: undefined,
video: undefined,
videoSelect: undefined,
canvas: undefined,
imageCanvas: undefined,
canvasMinWidth: 1080,
canvasMinHeight: 1920,
cameraOffset: { x: 0, y: 0 },
cameraZoom: 1,
isDragging: false,
dragStart: { x: 0, y: 0 },
initialPinchDistance: null,
lastZoom: 1,
init: function () {
PublishStories_ajaxGetContactsCount();
MovimTpl.loadingPage();
MovimTpl.pushAnchorState('story', function () {
document.querySelector('#publishstories').classList = '';
PublishStories.close();
});
PublishStories.main = document.querySelector('#publishstories');
PublishStories.back = document.querySelector("#publishstories #publishstoriesback");
PublishStories.video = document.querySelector("#publishstories video");
PublishStories.videoSelect = document.querySelector("#publishstories select#publishstoriessource");
PublishStories.canvas = document.querySelector('#publishstories canvas');
PublishStories.main.addEventListener('mousemove', PublishStories.onMainPointerMove);
PublishStories.canvas.addEventListener('mousedown', PublishStories.onPointerDown);
PublishStories.canvas.addEventListener('touchstart', (e) => PublishStories.handleTouch(e, PublishStories.onPointerDown));
PublishStories.canvas.addEventListener('mouseup', PublishStories.onPointerUp);
PublishStories.canvas.addEventListener('touchend', (e) => PublishStories.handleTouch(e, PublishStories.onPointerUp));
PublishStories.canvas.addEventListener('mousemove', PublishStories.onPointerMove);
PublishStories.canvas.addEventListener('touchmove', (e) => PublishStories.handleTouch(e, PublishStories.onPointerMove));
PublishStories.canvas.addEventListener('wheel', (e) => PublishStories.adjustZoom(e.deltaY * SCROLL_SENSITIVITY));
PublishStories.main.querySelector('#publishstoriesswitch').onclick = () => {
PublishStories.videoSelect.selectedIndex++;
if (PublishStories.videoSelect.selectedIndex == -1) {
PublishStories.videoSelect.selectedIndex = 0;
}
Toast.send(PublishStories.videoSelect.options[PublishStories.videoSelect.selectedIndex].label);
PublishStories.getStream();
};
PublishStories.main.classList = 'show';
PublishStories.back.onclick = () => { history.back(); };
PublishStories.close();
PublishStories.getStream(true);
},
draw: function () {
if (PublishStories.imageCanvas == undefined) return;
PublishStories.canvas.width = PublishStories.canvasMinWidth;
PublishStories.canvas.height = PublishStories.canvasMinHeight;
let context = PublishStories.canvas.getContext('2d');
ctx.clearRect(0, 0, PublishStories.canvas.width, PublishStories.canvas.height)
context.fillStyle = MovimUtils.imageToHex(PublishStories.imageCanvas);
context.fillRect(0, 0, PublishStories.canvas.width, PublishStories.canvas.height);
// Let's move!
context.translate(PublishStories.canvas.width / 2, PublishStories.canvas.height / 2);
context.scale(PublishStories.cameraZoom, PublishStories.cameraZoom);
context.translate(
-PublishStories.canvas.width / 2 + PublishStories.cameraOffset.x,
-PublishStories.canvas.height / 2 + PublishStories.cameraOffset.y
);
let adjustedHeight = PublishStories.canvas.height > PublishStories.imageCanvas.height
? PublishStories.imageCanvas.height
: PublishStories.canvas.height;
let ratio = adjustedHeight / PublishStories.imageCanvas.height;
context.drawImage(
PublishStories.imageCanvas,
PublishStories.canvas.width / 2 - PublishStories.imageCanvas.width * ratio / 2,
PublishStories.canvas.height / 2 - adjustedHeight / 2,
PublishStories.imageCanvas.width * ratio,
adjustedHeight
);
requestAnimationFrame(PublishStories.draw);
},
goToPublish: function () {
let title = PublishStories.main.querySelector('form textarea[name=title]');
if (title.value == '') {
PublishStories_ajaxNoTitle();
return;
}
PublishStories.main.classList.add('publish');
},
goToEdit: function () {
PublishStories.main.classList.remove('publish');
},
publish: function () {
PublishStories.main.querySelector('#publishactions').classList.add('uploading');
PublishStories.canvas.toBlob(
function (blob) {
Upload.prepare(blob);
Upload.name = 'story.jpg';
Upload.init(true);
},
'image/jpeg',
0.85
);
},
close: function () {
if (!PublishStories.video) return;
let stream = PublishStories.video.srcObject;
if (stream) {
stream.getTracks().forEach(track => track.stop());
}
PublishStories.video.srcObject = null;
PublishStories.imageCanvas = undefined;
PublishStories.main.querySelector('form').reset();
PublishStories.main.querySelector('#publishactions').classList = '';
PublishStories.reset();
PublishStories.main.classList = '';
PublishStories.main == undefined;
},
openImage: function () {
PublishStories.main.querySelector('input[type=file]').click();
},
applyImage: function () {
file = PublishStories.main.querySelector('input[type=file]').files[0];
if (!file.type.match(/image.*/)) {
console.log("Not a picture !");
PublishStories.reset();
} else {
var reader = new FileReader();
reader.readAsDataURL(file);
reader.addEventListener('load', function (ev) {
var image = new Image();
image.src = reader.result;
image.onload = function () {
PublishStories.drawMediaToImageCanvas(image, image.width, image.height, 1);
PublishStories.draw();
PublishStories.main.classList = 'edit';
}
});
};
},
shoot: function () {
if (PublishStories.imageCapture) {
PublishStories.imageCapture.grabFrame()
.then(image => {
PublishStories.drawMediaToImageCanvas(
image,
image.width,
image.height,
PublishStories.getRatioFromHeight(image.height)
);
PublishStories.draw();
})
.catch(error => console.log(error));
} else {
PublishStories.drawMediaToImageCanvas(
PublishStories.video,
PublishStories.video.videoWidth,
PublishStories.video.videoHeight,
PublishStories.getRatioFromHeight(PublishStories.video.videoHeight)
);
PublishStories.video.pause();
PublishStories.draw();
}
PublishStories.main.classList = 'edit';
},
getRatioFromHeight: function (height) {
let ratio = PublishStories.canvasMinHeight / height;
if (ratio < 1) ratio = 1;
return ratio;
},
drawMediaToImageCanvas: function (media, width, height, ratio) {
PublishStories.imageCanvas = document.createElement('canvas');
PublishStories.imageCanvas.width = width * ratio;
PublishStories.imageCanvas.height = height * ratio;
var context = PublishStories.imageCanvas.getContext('2d');
context.drawImage(media, 0, 0, PublishStories.imageCanvas.width, PublishStories.imageCanvas.height);
},
reset: function () {
if (PublishStories.videoSelect.options.length > 0) {
PublishStories.main.classList = 'shoot';
PublishStories.video.play();
} else {
PublishStories.main.classList = 'shoot error';
}
PublishStories.cameraOffset = { x: 0, y: 0 };
PublishStories.cameraZoom = PublishStories.lastZoom = 1;
},
getStream: function (init) {
PublishStories.main.classList = 'wait';
if (PublishStories.video.srcObject) {
PublishStories.video.srcObject.getTracks().forEach(track => track.stop());
}
const videoSource = PublishStories.videoSelect.value;
const constraints = {
video: {
deviceId: videoSource ? { exact: videoSource } : undefined,
width: { ideal: 1920 },
height: { ideal: 1920 }
}
};
navigator.mediaDevices.getUserMedia(constraints)
.then(stream => {
MovimTpl.finishedPage();
PublishStories.gotStream(stream);
if (init) {
navigator.mediaDevices.enumerateDevices().then(PublishStories.gotDevices);
}
})
.catch(e => {
MovimTpl.finishedPage();
PublishStories.noStream()
});
},
noStream: function (stream) {
PublishStories.main.classList = 'shoot error';
},
gotStream: function (stream) {
PublishStories.main.classList = 'shoot';
PublishStories.videoSelect.selectedIndex = [...PublishStories.videoSelect.options].
findIndex(option => option.text === stream.getVideoTracks()[0].label);
PublishStories.video.srcObject = stream;
PublishStories.video.play();
// We try to use ImageCapture
if (typeof (ImageCapture) != 'undefined') {
const track = stream.getVideoTracks()[0];
PublishStories.imageCapture = new ImageCapture(track);
}
// If we cancel after the authorization was given
if (PublishStories.main.classList == '') {
PublishStories.close();
};
},
gotDevices: function (devicesInfo) {
PublishStories.videoSelect.innerHTML = '';
for (const deviceInfo of devicesInfo) {
if (deviceInfo.kind === 'videoinput') {
const option = document.createElement('option');
option.value = deviceInfo.deviceId;
option.text = deviceInfo.label || `Camera ${PublishStories.videoSelect.length + 1}`;
if (!PublishStories.videoSelect.querySelector('option[value="' + deviceInfo.deviceId + '"]')) {
PublishStories.videoSelect.appendChild(option);
}
}
}
if (PublishStories.videoSelect.options.length >= 2) {
document.querySelector("#publishstories #publishstoriesswitch").classList.add('enabled');
}
},
onPointerDown: function (e) {
PublishStories.isDragging = true
PublishStories.dragStart.x = MovimUtils.getEventLocation(e).x / PublishStories.cameraZoom - PublishStories.cameraOffset.x
PublishStories.dragStart.y = MovimUtils.getEventLocation(e).y / PublishStories.cameraZoom - PublishStories.cameraOffset.y
},
onPointerUp: function (e) {
PublishStories.isDragging = false
PublishStories.initialPinchDistance = null
PublishStories.lastZoom = PublishStories.cameraZoom
},
onMainPointerMove: function (e) {
if (!PublishStories.main.classList.contains('edit') || !MovimUtils.getEventLocation(e)) return;
let borders = PublishStories.canvas.getBoundingClientRect();
if (MovimUtils.getEventLocation(e).x < borders.left
|| MovimUtils.getEventLocation(e).x > borders.right
|| MovimUtils.getEventLocation(e).y < borders.top
|| MovimUtils.getEventLocation(e).y > borders.bottom) {
PublishStories.onPointerUp(e);
}
},
onPointerMove: function (e) {
if (PublishStories.isDragging) {
PublishStories.cameraOffset.x = MovimUtils.getEventLocation(e).x / PublishStories.cameraZoom - PublishStories.dragStart.x
PublishStories.cameraOffset.y = MovimUtils.getEventLocation(e).y / PublishStories.cameraZoom - PublishStories.dragStart.y
}
},
handleTouch: function (e, singleTouchHandler) {
if (e.touches.length == 1) {
singleTouchHandler(e)
}
else if (e.type == "touchmove" && e.touches.length == 2) {
PublishStories.isDragging = false
PublishStories.handlePinch(e)
}
},
handlePinch: function (e) {
e.preventDefault()
let touch1 = { x: e.touches[0].clientX, y: e.touches[0].clientY }
let touch2 = { x: e.touches[1].clientX, y: e.touches[1].clientY }
// This is distance squared, but no need for an expensive sqrt as it's only used in ratio
let currentDistance = (touch1.x - touch2.x) ** 2 + (touch1.y - touch2.y) ** 2
if (PublishStories.initialPinchDistance == null) {
PublishStories.initialPinchDistance = currentDistance
}
else {
PublishStories.adjustZoom(null, currentDistance / PublishStories.initialPinchDistance)
}
},
adjustZoom: function (zoomAmount, zoomFactor) {
if (!PublishStories.isDragging) {
if (zoomAmount) {
PublishStories.cameraZoom += zoomAmount
}
else if (zoomFactor) {
PublishStories.cameraZoom = zoomFactor * PublishStories.lastZoom
}
PublishStories.cameraZoom = Math.min(PublishStories.cameraZoom, MAX_ZOOM)
PublishStories.cameraZoom = Math.max(PublishStories.cameraZoom, MIN_ZOOM)
}
}
}
MovimEvents.registerWindow('loaded', 'publishstories', () => {
Upload.attach((file) => {
if (PublishStories.main && PublishStories.main.classList.contains('publish')) {
PublishStories.main.querySelector('#publishactions').classList.remove('uploading');
PublishStories.main.querySelector('#publishactions').classList.add('publishing');
PublishStories_ajaxPublish(MovimUtils.formToJson('metadata'), file.id);
}
});
Upload.fail(() => {
PublishStories.main.querySelector('#publishactions').classList.remove('uploading');
});
Upload.progress((percent) => {
if (PublishStories.main != undefined && PublishStories.main.classList.contains('publish')) {
PublishStories.main.querySelector('#publishactionsprogress').innerHTML =
percent + '%';
}
});
});
@@ -1,6 +0,0 @@
[roomsexplore]
no_local = No chatrooms found locally
global_title = Channels
no_global = No chatrooms found globally
find_more = Find more channels
find_more_text = "%s in total"
@@ -1,29 +0,0 @@
var RoomsExplore = {
timer: null,
init: function () {
if (window.matchMedia("(min-width: 1025px)").matches) {
document.querySelector('#roomsexplore_bar input[name=keyword]').focus();
}
},
setKeyword: function (keyword) {
document.querySelector('#roomsexplore_bar input[name=keyword]').value = keyword;
},
searchSomething: function (value) {
clearTimeout(RoomsExplore.timer);
if (value !== '') {
document.querySelector('#roomsexplore_bar li.search').classList.add('searching');
}
RoomsExplore.timer = setTimeout(() => {
RoomsExplore_ajaxSearchRooms(value);
}, 700);
},
searchClear: function () {
document.querySelector('#roomsexplore_bar li.search').classList.remove('searching');
}
}
-11
View File
@@ -1,11 +0,0 @@
[sendto]
attach = Attach to a blog publication
share = Share in a new publication
selected = contacts selected
pick = Pick the contacts you want to share this content with
shared_with = Post shared
shared_contacts = Post shared with %s contacts
more_contacts = More contacts
os_share = Share outside Movim
sharing_post = Post shared using Movim
sharing_story = Story shared using Movim
-19
View File
@@ -1,19 +0,0 @@
#sendto ul.list:first-child li.block:not(.story) {
margin: 0 1rem;
}
#sendto ul.list.flex.fourth.gallery:first-child {
grid-template-columns: 1fr auto;
}
#sendto ul.list.flex.fourth.gallery:first-child li:not(.subheader):not(.story) {
padding: 0;
}
#sendto ul.list span.share i::before {
content: 'add';
}
#sendto ul.list span.share.sharing i::before {
content: 'remove';
}
-46
View File
@@ -1,46 +0,0 @@
var SendTo = {
contacts: {},
init: function () {
SendTo.contacts = {};
document.querySelectorAll('#sendto_share_contacts > li[data-jid]').forEach(li => {
var store = new ChatOmemoStorage();
store.getContactState(li.dataset.jid).then(enabled => {
if (enabled) li.classList.add('disabled');
});
});
},
shareArticle: function (link) {
SendTo_ajaxShareArticle(link, typeof navigator.share == 'function');
},
toggleSend: function (contact) {
if (contact.classList.contains('sharing')) {
contact.classList.remove('sharing');
delete SendTo.contacts[contact.dataset.jid];
} else {
contact.classList.add('sharing');
SendTo.contacts[contact.dataset.jid] = Boolean(contact.dataset.muc);
}
var button = document.getElementById('sendto_button');
var contactsCount = Object.keys(SendTo.contacts).length;
document.getElementById('sendto_counter').innerText = contactsCount;
button.classList.remove('disabled');
if (contactsCount == 0) {
button.classList.add('disabled');
}
},
sendToContacts: function(uri) {
SendTo_ajaxSend(SendTo.contacts, uri);
SendTo.contacts = {};
},
shareOs(object) {
navigator.share(object);
},
}
-22
View File
@@ -1,22 +0,0 @@
var Share = {
get: function () {
var parts = MovimUtils.urlParts();
if (parts.params[0]) {
uri = parts.params[0].substr(0, 5) == 'xmpp:'
? parts.params[0]
: atob(parts.params[0]);
Share.openUri(uri);
}
},
openUri: function (uri) {
document.querySelector('h4').innerHTML = uri;
Share_ajaxGet(uri);
}
};
MovimWebsocket.attach(function () {
Share.get();
});
-25
View File
@@ -1,25 +0,0 @@
[spaceinfo]
config_title = Space configuration
config_saved = Space configuration saved
config_error = Space configuration error
admin_title = Space administration
destroy_title = Destroy the space
destroy_text = You are going to destroy the following Space, all the chatrooms within it will also be destroyed
invite_title = Invite new contacts
invite_text = A moderator will have to approve the join request
invite_uri_title = Send an invitation key to your contacts
leave_title = Leave the space
add_room_title = Add a room
add_directory_title = Add a directory
edit_directory_title = Edit a directory
remove_directory_title = Remove a directory
remove_directory_confirm = Do you really want to remove this directory?
remove_directory_text = The %s rooms will be preserved
edited_directories = Edited directories
edited_room = Edited room
pending_approvals = %s subscriptions requests are waiting for your approval
pending_request = %s is waiting for your approval to join the space
pending_action = Manage the request
pinned = Pin this space in the bar
owner_cannot_leave = An owner cannot leave his own Space
affiliation_none = Remove from the space
-16
View File
@@ -1,16 +0,0 @@
#spaceinfo_affiliations ul.list.flex {
grid-template-columns: 50% 50%;
}
#spaceinfo_affiliations ul.list.flex form > div {
min-height: 0;
}
#spaceinfo_affiliations ul.list.flex form > div .select,
#spaceinfo_affiliations ul.list.flex form > div input {
margin-bottom: 0;
}
#spaceinfo_widget li.subheader span.second.notify {
font-weight: normal;
}
-8
View File
@@ -1,8 +0,0 @@
MovimWebsocket.attach(function () {
if (MovimUtils.urlParts().page == 'space') {
SpaceInfo_ajaxHttpGet(
MovimUtils.urlParts().params[0],
MovimUtils.urlParts().params[1]
);
}
});
@@ -1,70 +0,0 @@
ul#spacerooms_widget {
overflow: hidden;
}
ul#spacerooms_widget>li {
user-select: none;
}
ul#spacerooms_widget li div.controls {
position: absolute;
right: 0;
top: 0;
transform: translateX(100%);
background-color: rgb(var(--movim-background));
transition: transform 0.2s var(--accelerate-easing);
box-shadow: var(--elevation-1);
height: 5.25rem;
}
ul#spacerooms_widget li div.controls span {
padding: 0 1rem;
line-height: 5.25rem;
height: 5.25rem;
display: inline-block;
}
ul#spacerooms_widget li div.controls span:hover {
cursor: pointer;
user-select: none;
background-color: rgba(var(--movim-element-action), 0.1);
font-variation-settings: 'FILL' 1;
}
ul#spacerooms_widget li:hover div.controls {
transform: translateX(0);
transition: transform 0.2s var(--decelerate-easing) 0.75s;
}
ul#spacerooms_widget li.dragging:active {
cursor: grabbing;
}
ul#spacerooms_widget:has(li.subheader.dragging) li:not(.dragging):not(.subheader) div {
opacity: 0.15;
}
ul#spacerooms_widget li.dragging {
opacity: 0.5;
}
ul#spacerooms_widget li {
transition: padding-bottom 0.1s ease;
}
ul#spacerooms_widget li.dropping {
padding-bottom: 2rem;
}
ul#spacerooms_widget li.dropping:before {
animation: fadeIn 0.3s;
content: '';
display: block;
width: calc(100% - 3rem);
height: 0.5rem;
background-color: var(--movim-accent);
border-radius: 1rem;
position: absolute;
top: 6rem;
left: 1.5rem;
}
-126
View File
@@ -1,126 +0,0 @@
var SpaceRooms = {
draggingDirectory: false,
init: function () {
document.querySelectorAll('ul#spacerooms_widget > li > ul.list > li:not(.subheader)[data-jid]').forEach(li => {
const jid = li.dataset.jid;
li.onclick = () => Chat.getRoom(jid);
if (MovimUtils.isMobile()) {
let touchTimer;
let isMoving = false;
li.ontouchstart = () => {
isMoving = false;
touchTimer = setTimeout(() => {
if (!isMoving) SpaceRooms_ajaxAskEdit(jid);
}, 500);
};
li.ontouchmove = () => { isMoving = true; };
li.ontouchend = () => clearTimeout(touchTimer);
}
});
},
editable: function () {
var items = document.querySelectorAll('ul#spacerooms_widget > li');
items.forEach(item => {
item.addEventListener('dragstart', () => item.classList.add('dragging'));
item.addEventListener("dragend", () => {
let dropped = document.querySelector('li.dropping');
item.classList.remove("dragging");
items.forEach(subheader => subheader.classList.remove('dropping'));
if (dropped) {
dropped.after(item);
const [server, node] = MovimUtils.urlParts().params;
if (SpaceRooms.draggingDirectory == true) {
if (dropped.classList.contains('subheader')) {
SpaceRooms_ajaxSortDirectories(
server,
node,
Array.from(
document.querySelectorAll('ul#spacerooms_widget > li.subheader'),
node => node.dataset.id
)
);
}
} else {
let firstItem = item;
let directoryId = null;
// Find the first item and see if its a directory
while (firstItem.previousElementSibling && !firstItem.previousElementSibling.classList.contains('subheader')) {
firstItem = firstItem.previousElementSibling;
}
if (firstItem.previousElementSibling?.classList.contains('subheader')) {
directoryId = firstItem.previousElementSibling.dataset.id;
}
// Then we iterate on the items of the directory
if (firstItem) {
let currentItem = firstItem;
let weight = 0;
// Extract URL parameters once to avoid repeating the function calls inside a loop
while (currentItem && !currentItem.classList.contains('subheader')) {
SpaceRooms_ajaxSetHierarchy(
server,
node,
currentItem.dataset.jid,
weight++,
directoryId
);
currentItem = currentItem.nextElementSibling;
}
}
}
}
SpaceRooms.draggingDirectory = false;
});
item.addEventListener('dragover', (event) => {
event.preventDefault();
let elements = document.querySelectorAll('ul#spacerooms_widget > li:not(.dragging)');
let siblings = [...elements];
let nextSibling = siblings.reduce((closest, child) => {
const box = child.getBoundingClientRect();
const offset = event.clientY - box.top - box.height / 2;
if (offset < 0 && offset > closest.offset) {
return { offset: offset, element: child };
} else {
return closest;
}
}, { offset: Number.NEGATIVE_INFINITY }).element;
elements.forEach(subheader => {
if (!subheader.isSameNode(nextSibling)) {
subheader.classList.remove('dropping')
}
});
if (nextSibling) {
if ((SpaceRooms.draggingDirectory && nextSibling.classList.contains('subheader'))
|| (SpaceRooms.draggingDirectory == false)) {
nextSibling.classList.add('dropping');
}
}
})
});
var directories = document.querySelectorAll('ul#spacerooms_widget > li.subheader');
directories.forEach(directory => {
directory.addEventListener('dragstart', () => SpaceRooms.draggingDirectory = true);
});
}
}
-23
View File
@@ -1,23 +0,0 @@
[spacesmenu]
create_space_title = Create a space
add_space_title = Add a new space
join_space_title = Join a space
invite_space_title = You got an invite?
space_title = Space title
space_title_empty = Your Space title is empty
space_created = Space created
loading_space_info = Loading the space
subscribed = Subscribed to the space
invitation_key = Use an invitation key
key_required = A valid key is required
locked_title = Locked space
locked_text = You are not authorized to join the space at the moment
locked_try_again = Try again
leave_title = Leave the space
leave_text = Are you sure that you want to leave the space?
pending_subscription_title = A request has been send to a moderator.
pending_subscription_text = You will be able to join the space once its accepted.
pending_subscription_add_title = Add %s to the space
pending_subscription_refuse_title = Deny the access
contact_added = Contact added in the space
contact_denied = Contact denied in the space
@@ -1,67 +0,0 @@
ul#spacesmenu_widget {
overflow: auto;
min-height: 18rem;
flex-shrink: initial;
padding-bottom: 1rem;
}
ul#spacesmenu_widget li span.primary.space_add:before {
content: '';
display: block;
width: 5.5rem;
height: 5.5rem;
background-color: rgba(var(--movim-font), 0.04);
position: absolute;
top: -0.25rem;
left: -0.25rem;
border-radius: 2rem;
}
ul#spacesmenu_widget li.enabled span.primary img {
outline: 2px solid rgba(var(--movim-font), 0.3);
outline-offset: 2px;
box-shadow: var(--elevation-3);
}
ul#spacesmenu_widget li.pinned span:not(.locked).primary::before {
display: inline-block;
position: absolute;
bottom: 0;
left: -0.5rem;
font-family: 'Material Symbols';
color: rgb(var(--movim-font));
font-variation-settings: 'FILL' 1;
content: '\e6aa';
font-size: 1.25rem;
border-radius: 1rem;
line-height: 2rem;
width: 2rem;
height: auto;
background-color: rgb(var(--movim-background-main), 0.7);
backdrop-filter: blur(1rem);
box-shadow: var(--elevation-1);
}
ul#spacesmenu_widget li span.primary[data-counter]:after {
content: '\e0ca';
}
/* If we have messages _and_ quote notifications, we prioritize the second one */
ul#spacesmenu_widget li span.primary[data-counter]:has(span.counter:not(:empty)):after {
display: none;
}
ul#spacesmenu_widget li span.primary.locked::before {
display: inline-block;
position: absolute;
width: 5rem;
height: 5rem;
font-family: 'Material Symbols';
color: rgb(var(--movim-font));
font-variation-settings: 'FILL' 1;
content: '\e897';
background-color: rgb(var(--movim-background-main), 0.2);
backdrop-filter: blur(0.2rem) brightness(80%);
border-radius: 2rem;
left: 0;
}
-21
View File
@@ -1,21 +0,0 @@
var SpacesMenu = {
get: function (server, node, route) {
if (MovimUtils.urlParts().page == 'space') {
SpacesMenu_ajaxHttpGet(server, node, null, MovimUtils.isMobile());
} else {
MovimUtils.reload(route);
}
}
}
MovimWebsocket.attach(() => {
if (MovimUtils.urlParts().page == 'space') {
SpacesMenu_ajaxHttpGet(
MovimUtils.urlParts().params[0],
MovimUtils.urlParts().params[1],
MovimUtils.urlParts().params[2],
MovimUtils.isMobile());
};
Notif.current('space');
});
-11
View File
@@ -1,11 +0,0 @@
[stories]
publish = New Story
title = Stories
new_story = New Story from %s
forbidden = "You don't have access to this story, send an invitation to the author to access it"
share_title = Some of your contacts might not have access to this story
share_text = They might have to subscribe to the publisher account
comment = Send a comment to %s
delete_title= Story deletion
delete_text = Are you sure that you want to delete this story?
deleted = Story deleted
-61
View File
@@ -1,61 +0,0 @@
#stories {
min-height: 17.5rem;
}
#stories div.lists {
display: flex;
max-width: 100%;
overflow-x: auto;
}
#stories div.lists ul.list {
grid-template-columns: repeat(1, 1fr);
padding-bottom: 0.5rem;
height: 14.5rem;
}
#stories div.lists ul.list:first-child {
padding-inline-end: 0;
}
#stories ul.list.flex li.block {
grid-row: 1;
grid-column: auto;
order: 0;
margin-bottom: 0.25rem;
animation: none;
}
#stories ul.list.flex li.block.add {
display: flex;
align-items: center;
flex-direction: row;
background-color: rgba(var(--movim-element-action), 0.2);
width: 7rem;
transition: transform .3s;
}
#stories ul.list.flex li.block.add i {
font-size: 2.5rem;
}
#stories ul.list.flex li.block.add:hover {
background-color: rgba(var(--movim-element-action), 0.1);
transform: scale(0.975);
}
#stories ul.list.flex li.block.add:active {
background-color: rgba(var(--movim-element-action), 0.2);
transform: scale(0.95);
}
#stories ul.list.flex li.block.add>div {
margin-top: 0;
display: block;
text-align: center;
}
#stories ul.list.flex li.block.seen {
order: 1;
filter: grayscale(0.5);
}
-3
View File
@@ -1,3 +0,0 @@
MovimWebsocket.attach(() => {
Stories_ajaxHttpGet();
});
@@ -1,174 +0,0 @@
#storiesviewer {
position: fixed;
width: 100%;
justify-content: center;
display: flex;
opacity: 0;
pointer-events: none;
z-index: 3;
backdrop-filter: blur(1rem);
color: white;
}
#dialog:not(:empty) ~ #storiesviewer {
filter: blur(1rem);
}
#storiesviewer a:link,
#storiesviewer a:visited {
color: #EEE;
}
#storiesviewer p {
text-shadow: 0 0 0.5rem rgba(0, 0, 0, 0.1), 0 0 2rem rgba(0, 0, 0, 0.3);
}
#storiesviewer p.title {
font-size: 2.5rem;
line-height: 3.5rem;
}
#storiesviewer:empty {
display: none;
}
#storiesviewer ul.list.controls {
z-index: 2;
}
#storiesviewer ul.list li > div > p:not(:first-of-type):not(.main) {
color: white;
}
#storiesviewer ul.list.controls li span.primary {
margin-left: 0;
}
#storiesviewer:before {
content: '';
display: block;
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
opacity: 0;
background-color: #111;
}
#storiesviewer:not(:empty) {
opacity: 1;
pointer-events: initial;
}
#storiesviewer article.story {
height: calc(100% - 14rem);
margin: 1rem;
margin-top: 7rem;
margin-bottom: 0;
border-radius: 2rem;
box-shadow: var(--elevation-4);
background-color: rgb(var(--movim-gray));
position: relative;
}
#storiesviewer article.story:before,
#storiesviewer article.story:after {
content: '';
display: block;
width: calc(100% - 3rem);
height: 0.4rem;
background-color: white;
position: absolute;
top: 2rem;
left: 1.5rem;
z-index: 1;
opacity: 0.25;
border-radius: 1rem;
}
#storiesviewer article.story:after {
opacity: 1;
animation: widthProgress linear 6s;
}
#storiesviewer article.story.paused:after {
animation-play-state: paused;
}
#storiesviewer article.story div.next {
position: absolute;
top: 10rem;
right: 0;
height: calc(100% - 20rem);
width: 7rem;
font-size: 5rem;
display: flex;
align-items: center;
}
#storiesviewer article.story div.next:hover {
cursor: pointer;
}
#storiesviewer article.story div.next i {
text-align: center;
width: 100%;
}
#storiesviewer article.story > img {
height: 100%;
mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.25), black 12rem, black calc(100% - 20rem), rgba(0, 0, 0, 0.25));
user-select: none;
object-fit: cover;
}
#storiesviewer article.story ul.list {
position: absolute;
bottom: 0.5rem;
width: 100%;
}
#storiesviewer article.story ul.list.head {
bottom: unset;
top: 3rem;
width: calc(100% - 1rem)
}
#storiesviewer article.story ul.list.head li span.icon.small {
margin-right: 0.5rem;
}
#storiesviewer article.story ul.list.head li {
padding: 0 0.5rem;
}
#storiesviewer article.story.paused ul.list.head li span.control:hover {
cursor: pointer;
}
#storiesviewer article.story:not(.paused) ul.list.head li span.control.pause,
#storiesviewer article.story.paused ul.list.head li span.control.play {
display: none;
}
@keyframes widthProgress {
from {
width: 0;
}
to {
width: calc(100% - 3rem);
}
}
#storiesviewer form[name=storycomment] input {
margin-bottom: 0;
color: white;
z-index: 1;
position: relative;
}
#storiesviewer form[name=storycomment] div:after {
backdrop-filter: blur(0.5rem);
}
@@ -1,84 +0,0 @@
var StoriesViewer = {
story: undefined,
timer: undefined,
timeout: 6000,
startDate: undefined,
consumed: 0,
before: undefined,
launch: function (before) {
MovimTpl.pushAnchorState('stories', function () {
StoriesViewer.close();
});
StoriesViewer.story = document.querySelector('article.story');
StoriesViewer.before = before;
let image = StoriesViewer.story.querySelector('img');
image.addEventListener('mousedown', e => { e.preventDefault(); StoriesViewer.pause() });
image.addEventListener('touchstart', e => { e.preventDefault(); StoriesViewer.pause() });
image.addEventListener('mouseup', e => { e.preventDefault(), StoriesViewer.start() });
image.addEventListener('touchend', e => { e.preventDefault(), StoriesViewer.start() });
let next = StoriesViewer.story.querySelector('div.next');
next.addEventListener('click', e => StoriesViewer_ajaxHttpGetNext(StoriesViewer.before));
StoriesViewer.reset();
StoriesViewer.start();
},
reset: function () {
clearTimeout(StoriesViewer.timer);
StoriesViewer.consumed = 0;
},
close: function () {
StoriesViewer.reset();
StoriesViewer_ajaxClose();
Stories_ajaxHttpGet();
},
start: function () {
if (!StoriesViewer.story) return;
StoriesViewer.story.classList.remove('paused');
StoriesViewer.startDate = new Date();
StoriesViewer.timer = setTimeout(function () {
StoriesViewer_ajaxHttpGetNext(StoriesViewer.before);
}, StoriesViewer.timeout - StoriesViewer.consumed);
},
pause: function () {
if (!StoriesViewer.story) return;
StoriesViewer.story.classList.add('paused');
StoriesViewer.consumed += new Date() - StoriesViewer.startDate;
clearTimeout(StoriesViewer.timer);
},
sendComment: function (storyId) {
StoriesViewer_ajaxSendComment(storyId, document.querySelector('form[name=storycomment] input[name=comment]').value);
document.querySelector('form[name=storycomment]').reset();
}
}
MovimEvents.registerBody('click', 'storiesviewer', (e) => {
if (document.querySelector('#storiesviewer') == null
|| document.querySelector('#storiesviewer').innerHTML == '') return;
if (!document.querySelector('#storiesviewer article').contains(e.target)) {
history.back()
}
});
MovimEvents.registerBody('keydown', 'storiesviewer', (e) => {
if (document.querySelector('#storiesviewer')
&& document.querySelector('#storiesviewer').innerHTML != ''
&& e.key == 'Escape') {
history.back()
}
});
-4
View File
@@ -1,4 +0,0 @@
[feed]
title = "%s’s feed"
nope = No public feed for this contact
nope_contact = No contact specified