Skip to content

Commit

Permalink
fix: Corrigido e melhorado a função de onLiveLocation (fix #258)
Browse files Browse the repository at this point in the history
  • Loading branch information
edgardmessias committed Jun 21, 2021
1 parent 04af780 commit 6bc6d7e
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 55 deletions.
1 change: 1 addition & 0 deletions src/api/helpers/exposed.enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ export enum ExposedFn {
onIncomingCall = 'onIncomingCall',
onInterfaceChange = 'onInterfaceChange',
onPresenceChanged = 'onPresenceChanged',
onLiveLocation = 'onLiveLocation',
}
76 changes: 50 additions & 26 deletions src/api/layers/listener.layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ export class ListenerLayer extends ProfileLayer {
window.WAPI.onPresenceChanged(window['onPresenceChanged']);
window['onPresenceChanged'].exposed = true;
}
if (!window['onLiveLocation'].exposed) {
window.WAPI.onLiveLocation(window['onLiveLocation']);
window['onLiveLocation'].exposed = true;
}
})
.catch(() => {});
}
Expand Down Expand Up @@ -213,30 +217,49 @@ export class ListenerLayer extends ProfileLayer {
}

/**
* @event Listens to live locations from a chat that already has valid live locations
* @param chatId the chat from which you want to subscribes to live location updates
* @param fn callback that takes in a LiveLocation
* @returns boolean, if returns false then there were no valid live locations in the chat of chatId
* @emits <LiveLocation> LiveLocation
* Escuta os eventos de Localização em tempo real de todos os chats
* @event Eventos de Localização em tempo real
* @param callback Função para ser executada quando houver alterações
* @returns Objeto descartável para parar de ouvir
*/
public onLiveLocation(callback: (liveLocationEvent: LiveLocation) => void): {
dispose: () => void;
};
/**
* Escuta os eventos de Localização em tempo real
* @event Eventos de Localização em tempo real
* @param id Único ID ou lista de IDs de contatos para acompanhar a localização
* @param callback Função para ser executada quando houver alterações
* @returns Objeto descartável para parar de ouvir
*/
public async onLiveLocation(
chatId: string,
fn: (liveLocationChangedEvent: LiveLocation) => void
public onLiveLocation(
id: string | string[],
callback: (liveLocationEvent: LiveLocation) => void
): { dispose: () => void };
public onLiveLocation(
id: any,
callback?: (liveLocationEvent: LiveLocation) => void
) {
const method = 'onLiveLocation_' + chatId.replace('_', '').replace('_', '');
return this.page
.exposeFunction(method, (liveLocationChangedEvent: LiveLocation) =>
fn(liveLocationChangedEvent)
)
.then((_) =>
this.page.evaluate(
({ chatId, method }) => {
//@ts-ignore
return WAPI.onLiveLocation(chatId, window[method]);
},
{ chatId, method }
)
);
const ids: string[] = [];

if (typeof id === 'function') {
callback = id;
} else if (Array.isArray(id)) {
ids.push(...id);
} else {
ids.push(id);
}

return this.registerEvent(
ExposedFn.onLiveLocation,
(event: LiveLocation) => {
// Only group events
if (ids.length && !ids.includes(event.id)) {
return;
}
callback(event);
}
);
}

/**
Expand Down Expand Up @@ -332,13 +355,14 @@ export class ListenerLayer extends ProfileLayer {
id: any,
callback?: (presenceChangedEvent: PresenceEvent) => void
): { dispose: () => void } {
let ids = [];
const ids = [];

if (typeof id === 'function') {
callback = id;
ids = [];
} else if (!Array.isArray(id)) {
ids = [id];
} else if (Array.isArray(id)) {
ids.push(...id);
} else {
ids.push(id);
}

if (ids.length) {
Expand Down
50 changes: 47 additions & 3 deletions src/api/model/live-location.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,56 @@
* along with WPPConnect. If not, see <https://www.gnu.org/licenses/>.
*/

/**
* Interface de dados para os eventos de Localização em tempo real
*/
export interface LiveLocation {
/**
* Tipo de evento de Localização em tempo real
* * enable - Quando inicia o compartilhamento
* * update - Atualzação de localização
* * disable - Fim do compartilhamento
*/
type: 'enable' | 'update' | 'disable';

/**
* ID de contato que realizou o compartilhamento
*/
id: string;

/**
* Latitude em graus
*/
lat: number;

/**
* Longitude em graus
*/
lng: number;

/**
* Velocidade atual em milhar por hora (mp/h)
*/
speed: number;
lastUpdated: number;
accuracy: number;
degrees: any;

/**
* Precisão da localização em metros
*/
accuracy?: number;

/**
* Tempo em segundos após o último compartilhamento
*/
elapsed?: number;

/**
* Graus de direção
*/
degrees?: number;

/**
* Tempo em segundos para o compartilhamento
* Somente no type:enable
*/
shareDuration?: number;
}
101 changes: 76 additions & 25 deletions src/lib/wapi/listeners/add-on-live-location.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,83 @@
*/

export function addOnLiveLocation() {
window.WAPI.onLiveLocation = async function (chatId, callback) {
return await window.WAPI.waitForStore(['LiveLocation'], () => {
var lLChat = Store.LiveLocation.get(chatId);
if (lLChat) {
var validLocs = lLChat.participants.validLocations();
validLocs.map((x) =>
x.on('change:lastUpdated', (x, y, z) => {
console.log(x, y, z);
const { id, lat, lng, accuracy, degrees, speed, lastUpdated } = x;
const l = {
id: id.toString(),
lat,
lng,
accuracy,
degrees,
speed,
lastUpdated,
};
// console.log('newloc',l)
callback(l);
})
);
return true;
} else {
return false;
const callbacks = [];

/**
* Dispara o evento com dados formatados
*/
function fireCallback(data) {
const location = Object.assign({}, data);
if (location.jid) {
location.id = location.jid.toString();
}
delete location.jid;
delete location.body;
delete location.isLive;
delete location.sequence;

for (const callback of callbacks) {
try {
callback(location);
} catch (error) {}
}
}

window.WAPI.waitForStore(['LiveLocation'], async () => {
/**
* Substitui o manipulador original para capturar todos eventos,
* pois o Store.LiveLocation só inicializa a partir de uma mensagem,
* caso a mensagem fique muito para atrás (após troca de 50 mensagens),
* ele não é inicializado até carregar a mensage.
*/
const originalHandle = Store.LiveLocation.handle;
Store.LiveLocation.handle = function (list) {
originalHandle.apply(this, arguments);

for (const p of list) {
fireCallback(p);
}
};

// Para cada novo LiveLocation inicializado, força a vizualização de mapa de todos
Store.LiveLocation.on('add', () => {
setTimeout(() => {
Store.LiveLocation.forEach((l) => {
l.startViewingMap();
setTimeout(() => {
try {
l._startKeepAlive();
} catch (error) {}
}, 1000);
});
}, 100);
});

// Força a inicialização de localização para todos chats ativos
Store.Chat.map((c) => Store.LiveLocation.find(c.id));
});

// Caso receba nova mensagem de localização, inicializa o LiveLocation e dispara o primeiro evento
WAPI.waitNewMessages(false, (messages) => {
for (const message of messages) {
if (message.isLive) {
fireCallback({
type: 'enable',
isLive: message.isLive,
id: message.sender.id,
lat: message.lat,
lng: message.lng,
accuracy: message.accuracy,
speed: message.speed,
degrees: message.degrees,
sequence: message.sequence,
shareDuration: message.shareDuration,
});
}
}
});

window.WAPI.onLiveLocation = async function (callback) {
callbacks.push(callback);
};
}
19 changes: 19 additions & 0 deletions src/lib/wapi/wapi.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,25 @@ if (typeof window.Store === 'undefined') {
};
}

// setTimeout(() => {
// window.WAPI.waitForStore(['LiveLocation'], async () => {
// console.log('handle');
// // Store.LiveLocation.handle = (e) => console.log(e[0]);
// Store.LiveLocation.handle = (e) =>
// console.log(e[0].jid.user, (e[0].speed * 3.6).toFixed(2) + ' km/h');

// const livePromises = Store.Chat.map((c) => Store.LiveLocation.find(c.id));

// await Promise.all(livePromises);
// console.log('find');

// setTimeout(() => {
// Store.LiveLocation.forEach((l) => l.startViewingMap());
// console.log('start');
// }, 1000);
// });
// }, 100);

if (typeof window.WAPI === 'undefined') {
window.WAPI = {
lastRead: {},
Expand Down
2 changes: 1 addition & 1 deletion src/types/WAPI.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ interface WAPI {
onAddedToGroup: (callback: Function) => any;
onIncomingCall: (callback: Function) => any;
onInterfaceChange: (callback: Function) => void;
onLiveLocation: (chatId: string, callback: Function) => any;
onLiveLocation: (callback: Function) => any;
onNotificationMessage: (callback: (message: Message) => void) => any;
onParticipantsChanged: (groupId: string, callback: Function) => any;
onStateChange: (callback: Function) => void;
Expand Down

0 comments on commit 6bc6d7e

Please sign in to comment.