Eduard Kuzmenko 38ed314695 some changes
2022-01-16 06:45:41 +04:00

300 lines
10 KiB
TypeScript

/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import { SliderSuperTab } from "../../slider";
import ButtonCorner from "../../buttonCorner";
import appUsersManager from "../../../lib/appManagers/appUsersManager";
import AppNewGroupTab from "./newGroup";
import { toast } from "../../toast";
import { ButtonMenuItemOptions } from "../../buttonMenu";
import type { LazyLoadQueueIntersector } from "../../lazyLoadQueue";
import { i18n, join, _i18n } from "../../../lib/langPack";
import rootScope from '../../../lib/rootScope';
import { wrapSticker } from "../../wrappers";
import appStickersManager from "../../../lib/appManagers/appStickersManager";
import SortedUserList from "../../sortedUserList";
import { PeerLocated, Update, Updates } from "../../../layer";
import appPeersManager from "../../../lib/appManagers/appPeersManager";
import { SettingChatListSection } from "..";
import appProfileManager from "../../../lib/appManagers/appProfileManager";
import appDialogsManager from "../../../lib/appManagers/appDialogsManager";
import { attachClickEvent } from "../../../helpers/dom/clickEvent";
import confirmationPopup from "../../confirmationPopup";
export default class AppPeopleNearbyTab extends SliderSuperTab {
private latestLocationSaved: {latitude: number, longitude: number, accuracy: number};
private isLocationWatched: boolean = false;
private errorCategory: HTMLElement;
private retryBtn: HTMLButtonElement;
private btnOptions: HTMLButtonElement;
private menuButtons: (ButtonMenuItemOptions & {verify?: () => boolean})[];
protected lazyLoadQueue: LazyLoadQueueIntersector;
protected peopleSection: SettingChatListSection;
protected chatsSection: SettingChatListSection;
protected locatedPeers: Map<PeerId, PeerLocated.peerLocated>;
protected init() {
this.container.classList.add('people-nearby-container');
this.setTitle('PeopleNearby');
this.errorCategory = document.createElement('div');
this.errorCategory.classList.add('text', 'hide', 'nearby-error');
this.retryBtn = ButtonCorner({icon: 'check'});
const emoji = '🧭';
const doc = appStickersManager.getAnimatedEmojiSticker(emoji);
const stickerContainer = document.createElement('div');
stickerContainer.classList.add('sticker-container');
if(doc) {
wrapSticker({
doc,
div: stickerContainer,
loop: false,
play: true,
width: 86,
height: 86,
emoji,
needUpscale: true
}).then(() => {
// this.animation = player;
});
} else {
stickerContainer.classList.add('media-sticker-wrapper');
}
const caption = document.createElement('div');
caption.classList.add('caption');
_i18n(caption, 'PeopleNearbyInfo2');
this.locatedPeers = new Map();
const m = () => {
const sortedUserList = new SortedUserList({
avatarSize: 42,
createChatListOptions: {
dialogSize: 48,
new: true
},
autonomous: false,
onUpdate: (element) => {
const peer = this.locatedPeers.get(element.id);
const elements: HTMLElement[] = [
this.parseDistance(peer.distance)
];
if(!element.id.isUser()) {
elements.push(appProfileManager.getChatMembersString(element.id.toChatId()));
}
element.dom.lastMessageSpan.textContent = '';
element.dom.lastMessageSpan.append(...join(elements, false));
},
getIndex: (element) => {
const peer = this.locatedPeers.get(element.id);
return 0x7FFFFFFF - peer.distance;
}
});
appDialogsManager.setListClickListener(sortedUserList.list, undefined, undefined, false);
return sortedUserList;
};
const peopleSection = this.peopleSection = new SettingChatListSection({
name: 'PeopleNearbyHeader',
sortedList: m()
});
const chatsSection = this.chatsSection = new SettingChatListSection({
name: 'ChatsNearbyHeader',
sortedList: m()
});
const btnMakeVisible = peopleSection.makeButton({
text: 'MakeMyselfVisible',
icon: 'location'
});
const btnMakeInvisible = peopleSection.makeButton({
text: 'StopShowingMe',
icon: 'location'
});
const btnCreateGroup = chatsSection.makeButton({
text: 'NearbyCreateGroup',
icon: 'newgroup'
});
attachClickEvent(btnMakeVisible, () => {
confirmationPopup({
titleLangKey: 'MakeMyselfVisibleTitle',
descriptionLangKey: 'MakeMyselfVisibleInfo',
button: {
langKey: 'OK'
}
}).then(() => {
this.startWatching();
});
}, {listenerSetter: this.listenerSetter});
attachClickEvent(btnMakeInvisible, () => {
this.stopWatching();
}, {listenerSetter: this.listenerSetter});
attachClickEvent(btnCreateGroup, () => {
new AppNewGroupTab(this.slider).open([], true);
}, {listenerSetter: this.listenerSetter});
btnMakeVisible.classList.add('primary');
btnMakeInvisible.classList.add('danger');
btnCreateGroup.classList.add('primary');
this.content.append(this.retryBtn);
this.scrollable.append(
stickerContainer,
caption,
peopleSection.container,
chatsSection.container,
this.errorCategory
);
}
private parseDistance(distance: number) {
if(rootScope.settings.distanceUnit === 'miles') {
if(distance > 1609.34) {
return i18n('MilesAway', [Math.round(distance / 1609)]);
} else {
return i18n('FootsAway', [Math.round(distance * 3.281)]);
}
} else {
if(distance >= 1000) {
return i18n('KMetersAway2', [distance / 1000]);
} else {
return i18n('MetersAway2', [distance]);
}
}
}
public open() {
const result = super.open();
result.then(() => {
this.retryBtn.classList.remove('is-visible');
navigator.geolocation.getCurrentPosition((location) => {
this.latestLocationSaved = {
latitude: location.coords.latitude,
longitude: location.coords.longitude,
accuracy: location.coords.accuracy
};
console.log(this.latestLocationSaved);
appUsersManager.getLocated(
location.coords.latitude,
location.coords.longitude,
location.coords.accuracy
).then((response) => {
const update = (response as Updates.updates).updates[0] as Update.updatePeerLocated;
const peers = update.peers as PeerLocated.peerLocated[];
const orderedPeers = peers.sort((a, b) => a.distance - b.distance);
const groupsCounter = peers.filter((e) => e.peer._ == 'peerChannel').length;
const usersCounter = peers.filter((e) => e.peer._ != 'peerChannel').length;
orderedPeers?.forEach(peer => {
const peerId = appPeersManager.getPeerId(peer.peer);
const section = peerId.isUser() ? this.peopleSection : this.chatsSection;
this.locatedPeers.set(peerId, peer);
section.sortedList.add(peerId);
});
this.errorCategory.classList.toggle('hide', !!(usersCounter || groupsCounter));
this.errorCategory.innerHTML = "No groups or channels found around you.";
});
}, (error) => {
this.errorCategory.classList.remove('hide');
this.retryBtn.classList.add('is-visible');
this.retryBtn.addEventListener('click', this.open);
if(error instanceof GeolocationPositionError) {
this.errorCategory.innerHTML = "Location permission denied. Click below to retry.";
} else {
this.errorCategory.innerHTML = "An error has occurred. Please retry later clicking the button below.";
}
});
});
return result;
}
private startWatching() {
if(!this.latestLocationSaved || this.isLocationWatched) return;
this.isLocationWatched = true;
toast('Your position is now being shared. Do not close the page or it will be suspended.');
appUsersManager.getLocated(
this.latestLocationSaved.latitude,
this.latestLocationSaved.longitude,
this.latestLocationSaved.accuracy,
true, // background parameter
0x7fffffff // self_expires parameter
);
navigator.geolocation.watchPosition((result) => {
const isLongitudeDifferent = result.coords.longitude !== this.latestLocationSaved.longitude;
const isLatitudeDifferent = result.coords.latitude !== this.latestLocationSaved.latitude;
const distanceCheck = this.calculateDistance(
result.coords.latitude, result.coords.longitude,
this.latestLocationSaved.latitude, this.latestLocationSaved.longitude
) > 100;
if((isLatitudeDifferent || isLongitudeDifferent) && distanceCheck) {
appUsersManager.getLocated(
result.coords.latitude,
result.coords.longitude,
result.coords.accuracy,
true, // background parameter
0x7fffffff // self_expires parameter
);
this.latestLocationSaved = {
latitude: result.coords.latitude,
longitude: result.coords.longitude,
accuracy: result.coords.accuracy
}
}
});
}
private stopWatching() {
if(!this.isLocationWatched) return;
this.isLocationWatched = false;
toast('The sharing of your position has been stopped. You will no longer be visible to other users.');
appUsersManager.getLocated(
0, // latitude parameter
0, // longitude parameter
0, // accuracy parameter
false, // background parameter
0 // self_expires parameter
);
}
private calculateDistance(lat1: number, long1: number, lat2: number, long2: number) {
const p = 0.017453292519943295; // Math.PI/180
return (
12742 * Math.asin(
Math.sqrt(
(0.5 - Math.cos((lat2 - lat1) * p)) +
(
Math.cos(lat1 * p) * Math.cos(lat2 * p)
* (1 - Math.cos((long2 - long1) * p)/2)
)
)
)
);
}
}