view mod_invites_page/html/invite.html @ 4651:8231774f5bfd

mod_cloud_notify_encrypted: Ensure body substring remains valid UTF-8 The `body:sub()` call risks splitting the string in the middle of a multi-byte UTF-8 sequence. This should have been caught by util.stanza validation, but that would have caused some havoc, at the very least causing the notification to not be sent. There have been no reports of this happening. Likely because this module isn't widely deployed among users with languages that use many longer UTF-8 sequences. The util.encodings.utf8.valid() function is O(n) where only the last sequence really needs to be checked, but it's in C and expected to be fast.
author Kim Alvefur <zash@zash.se>
date Sun, 22 Aug 2021 13:22:59 +0200
parents 0f26ae2f2a74
children 09b8144051ea
line wrap: on
line source

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Invite to {site_name}</title>
	<link rel="alternate" href="{uri}">
	<link rel="stylesheet" href="/share/bootstrap4/css/bootstrap.min.css">
	<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
	<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
	<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
	<link rel="manifest" href="/site.webmanifest">
	<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
	<meta name="msapplication-TileColor" content="#fbd308">
	<meta name="theme-color" content="#fbd308">
</head>
<body>
	<div id="background" class="fixed-top overflow-hidden"></div>
	<div id="form" class="container col-md-10 col-md-offset-1 col-sm-8 col-sm-offset-2 col-lg-10 col-lg-offset-1 mt-2 mt-md-5">
		<div class="card rounded-lg shadow">
			<h1 class="card-header rounded-lg rounded-lg">
				Invite to {site_name}<br/>
			</h1>
			<div class="card-body" >
				<div id="qr-button-container" class="float-right w-25 border border-info p-3 d-none">
					<strong>Tip:</strong> You can open this invite
					on your mobile device by scanning a barcode with
					your camera.
					<button id="qr-modal-show" class="mt-2 d-block btn btn-info" title="Send this invite to your device"
						data-toggle="modal" data-target="#qr-modal">
							<img src="{static}/qr-logo.png" alt="QR code icon" class="align-middle h-50 mt-1" style="display:inline" >
							Scan with mobile device
					</button>
				</div>
			
				{inviter?<p>You have been invited to chat on {site_name} using XMPP,
				a secure and decentralized messaging network.</p>}

				{inviter&<p>You have been invited to chat with {inviter} on {site_name},
				part of the XMPP secure and decentralized messaging network.</p>}

				<h5 class="card-title" style="clear:both">Get started</h5>

				<p>To get started, you need to install an app for your platform:</p>

				<div class="container">
					<div class="row">
					{apps#
						<div class="card m-3 client-card {item.platforms#app-platform-{item|lower|classname} } flex-wrap col-sm-12 col-md-8 col-lg-5">
							<div class="row no-gutters h-100">
								<div class="col-md-4">
									<img src="{item.image|relurl}" class="p-2 img-fluid" alt="{item.imagetext?}">
								</div>
								<div class="col-md-8">
									<div class="card-body d-flex flex-column h-100">
										<h5 class="card-title text-nowrap mb-1">{item.name}</h5>
										<div>
											{item.platforms#<span class="badge badge-info client-platform-badge client-platform-badge-{item|lower|classname} mr-1 mb-3">{item}</span> }
										</div>
										<p class="card-text">{item.text}</p>
										<a href="{item.proceed_url?#}" class="btn btn-primary mt-md-auto">{item.select_text?Select}</a>
									</div>
								</div>
							</div>
						</div>
					}
					</div>
				</div>

				<div id="show-all-clients-button-container" class="d-none alert alert-info">
					Showing apps for <span class="platform-name">your current platform</span> only. You may also <a href="#" id="show-all-clients-button">view all apps.</a>
				</div>

				<div id="install-buttons-container" class="container mt-2 text-center">
				</div>

				<h5>Other software</h5>
				<p>You can connect to {site_name} using any XMPP-compatible software. If your preferred software is
				not listed above, you may still <a href="register?t={token}">register an account manually</a>.</p>
			</div>
		</div>
	</div>

	<div class="modal" tabindex="-1" role="dialog" id="qr-modal">
		<div class="modal-dialog" role="document">
			<div class="modal-content">
				<div class="modal-header">
					<h5 class="modal-title">Scan invite code</h5>
					<button type="button" class="close" data-dismiss="modal" aria-label="Close">
						<span aria-hidden="true">&times;</span>
					</button>
				</div>
				<div class="modal-body">
					<p>You can transfer this invite to your mobile device by scanning a code with your camera.</p>
					<div id="qr-info-url" class="tab-pane show active">
						<p>Use a <em>QR code</em> scanner on your mobile device to scan the code below:</p>
						<div id="qr-invite-page" class="w-50 p-1 mx-auto"></div>
					</div>
				</div>
				<div class="modal-footer">
					<button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>
				</div>
			</div>
		</div>
	</div>

	<script src="/share/jquery/jquery.min.js"></script>
	<script src="/share/bootstrap4/js/bootstrap.min.js"></script>
	<script src="{static}/qrcode.min.js"></script>
	<script src="{static}/platform.min.js"></script>
	<script>
		$(function () {
			// If QR lib loaded ok, show QR button on desktop devices
			if(window.QRCode) {
				$('#qr-modal').one('show.bs.modal', function (e) {
					new QRCode(document.getElementById("qr-invite-page"), document.location.href);
				});
				$('#qr-button-container').addClass("d-md-block");
			}

			// Detect current platform and show/hide appropriate clients
			if(window.platform) {
				var platform_friendly = null;
				var platform_classname = null;
				 
				switch(platform.os.family) {
				case "Ubuntu":
				case "Linux":
				case "Fedora":
				case "Red Hat":
				case "SuSE":
					platform_friendly = platform.os.family + " (Linux)";
					platform_classname = "linux";
					break;
				case "Windows Phone":
					platform_friendly = "Windows Phone";
					platform_classname = "windows-phone";
					break;
				default:
					if(platform.os.family.startsWith("Windows")) {
						platform_friendly = "Windows";
						platform_classname = "windows";
					} else {
						platform_friendly = platform.os.family;
						platform_classname = platform_friendly.toLowerCase();
					}
				}

				if(platform_friendly && platform_classname) {
					if($('.client-card .client-platform-badge-'+platform_classname).length == 0) {
						// No clients recognised for this platform, do nothing
						return;
					}
					// Hide clients not for this platform
					$('.client-card.app-platform-'+platform_classname).addClass("supported-platform");
					$('.client-card').not(".supported-platform, .app-platform-web").hide();
					$('.client-card .client-platform-badge')
						.not(".client-platform-badge-"+platform_classname)
							.addClass("badge-secondary")
							.removeClass("badge-info");
					$('.client-card .client-platform-badge-'+platform_classname)
						.addClass("badge-success")
						.removeClass("badge-info");
					$('#show-all-clients-button-container .platform-name').text(platform_friendly);
					$('#show-all-clients-button-container').removeClass("d-none");
					$('#show-all-clients-button').click(function () {
						$('.client-card').show();
						$('#show-all-clients-button-container').hide();
					});
				}
			}
		});
			
	</script>
</body>
</html>