2020-08-20 01:24:24 +03:00
/ *
2020-10-19 20:34:47 +03:00
Copyright ( C ) 2020 Sebastian J . Wolf and other contributors
2020-08-20 01:24:24 +03:00
This file is part of Fernschreiber .
Fernschreiber is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
Fernschreiber is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with Fernschreiber . If not , see < http : //www.gnu.org/licenses/>.
* /
2020-08-21 13:53:03 +03:00
2020-11-20 23:58:26 +03:00
. pragma library
. import "debug.js" as Debug
. import Sailfish . Silica 1.0 as Silica
2020-11-23 22:15:28 +03:00
var tdLibWrapper ;
var appNotification ;
function setGlobals ( globals ) {
tdLibWrapper = globals . tdLibWrapper ;
appNotification = globals . appNotification ;
}
2023-11-19 00:24:27 +03:00
function formatUnreadCount ( value ) {
if ( value < 1000 ) {
return value ;
} else if ( value > 9000 ) {
return '9k+' ;
}
return '' + Math . floor ( value / 1000 ) + 'k' + ( ( value % 1000 ) > 0 ? '+' : '' ) ;
}
2020-11-23 22:15:28 +03:00
2020-08-19 17:47:59 +03:00
function getUserName ( userInformation ) {
2020-11-26 22:02:29 +03:00
return ( ( userInformation . first _name || "" ) + " " + ( userInformation . last _name || "" ) ) . trim ( ) ;
2020-08-19 17:47:59 +03:00
}
2020-08-20 01:24:24 +03:00
2020-12-29 18:32:39 +03:00
function getMessageText ( message , simple , currentUserId , ignoreEntities ) {
2021-12-06 00:06:05 +03:00
var myself = false ;
if ( message [ '@type' ] !== "sponsoredMessage" ) {
2022-01-07 21:18:04 +03:00
myself = ( message . sender _id [ '@type' ] === "messageSenderUser" && message . sender _id . user _id . toString ( ) === currentUserId . toString ( ) ) ;
2021-12-06 00:06:05 +03:00
}
2020-12-29 18:32:39 +03:00
2020-11-26 22:02:29 +03:00
switch ( message . content [ '@type' ] ) {
case 'messageText' :
2020-08-24 16:27:44 +03:00
if ( simple ) {
return message . content . text . text ;
} else {
2020-12-01 23:17:13 +03:00
return enhanceMessageText ( message . content . text , ignoreEntities ) ;
2020-08-24 16:27:44 +03:00
}
2020-11-26 22:02:29 +03:00
case 'messageSticker' :
2021-12-07 21:22:00 +03:00
return simple ? message . content . sticker . emoji : ""
2021-12-05 00:05:22 +03:00
case 'messageAnimatedEmoji' :
2021-12-07 21:22:00 +03:00
return simple ? message . content . animated _emoji . sticker . emoji : ""
2020-11-26 22:02:29 +03:00
case 'messagePhoto' :
2020-08-24 16:27:44 +03:00
if ( message . content . caption . text !== "" ) {
2020-12-01 23:17:13 +03:00
return simple ? qsTr ( "Picture: %1" ) . arg ( message . content . caption . text ) : enhanceMessageText ( message . content . caption , ignoreEntities )
2020-08-24 16:27:44 +03:00
} else {
2020-09-30 01:09:51 +03:00
return simple ? ( myself ? qsTr ( "sent a picture" , "myself" ) : qsTr ( "sent a picture" ) ) : "" ;
2020-08-24 16:27:44 +03:00
}
2020-11-26 22:02:29 +03:00
case 'messageVideo' :
2020-08-24 16:27:44 +03:00
if ( message . content . caption . text !== "" ) {
2020-12-01 23:17:13 +03:00
return simple ? qsTr ( "Video: %1" ) . arg ( message . content . caption . text ) : enhanceMessageText ( message . content . caption , ignoreEntities )
2020-08-24 16:27:44 +03:00
} else {
2020-09-30 01:09:51 +03:00
return simple ? ( myself ? qsTr ( "sent a video" , "myself" ) : qsTr ( "sent a video" ) ) : "" ;
2020-08-28 14:02:54 +03:00
}
2020-11-26 22:02:29 +03:00
case 'messageVideoNote' :
2020-11-14 22:02:34 +03:00
return simple ? ( myself ? qsTr ( "sent a video note" , "myself" ) : qsTr ( "sent a video note" ) ) : "" ;
2020-11-26 22:02:29 +03:00
case 'messageAnimation' :
2020-08-28 14:02:54 +03:00
if ( message . content . caption . text !== "" ) {
2020-12-01 23:17:13 +03:00
return simple ? qsTr ( "Animation: %1" ) . arg ( message . content . caption . text ) : enhanceMessageText ( message . content . caption , ignoreEntities )
2020-08-28 14:02:54 +03:00
} else {
2020-09-30 01:09:51 +03:00
return simple ? ( myself ? qsTr ( "sent an animation" , "myself" ) : qsTr ( "sent an animation" ) ) : "" ;
2020-08-24 16:27:44 +03:00
}
2020-11-26 22:02:29 +03:00
case 'messageAudio' :
2020-08-24 16:27:44 +03:00
if ( message . content . caption . text !== "" ) {
2020-12-01 23:17:13 +03:00
return simple ? qsTr ( "Audio: %1" ) . arg ( message . content . caption . text ) : enhanceMessageText ( message . content . caption , ignoreEntities )
2020-08-24 16:27:44 +03:00
} else {
2020-09-30 01:09:51 +03:00
return simple ? ( myself ? qsTr ( "sent an audio" , "myself" ) : qsTr ( "sent an audio" ) ) : "" ;
2020-08-24 16:27:44 +03:00
}
2020-11-26 22:02:29 +03:00
case 'messageVoiceNote' :
2020-08-24 16:27:44 +03:00
if ( message . content . caption . text !== "" ) {
2020-12-01 23:17:13 +03:00
return simple ? qsTr ( "Voice Note: %1" ) . arg ( message . content . caption . text ) : enhanceMessageText ( message . content . caption , ignoreEntities )
2020-08-24 16:27:44 +03:00
} else {
2020-09-30 01:09:51 +03:00
return simple ? ( myself ? qsTr ( "sent a voice note" , "myself" ) : qsTr ( "sent a voice note" ) ) : "" ;
2020-08-24 16:27:44 +03:00
}
2020-11-26 22:02:29 +03:00
case 'messageDocument' :
2020-08-28 17:18:33 +03:00
if ( message . content . document . file _name !== "" ) {
2021-01-17 23:19:29 +03:00
return simple ? qsTr ( "Document: %1" ) . arg ( message . content . document . file _name ) : ( message . content . caption . text !== "" ? enhanceMessageText ( message . content . caption , ignoreEntities ) : "" ) . trim ( ) ;
2020-08-28 17:18:33 +03:00
} else {
2020-09-30 01:09:51 +03:00
return simple ? ( myself ? qsTr ( "sent a document" , "myself" ) : qsTr ( "sent a document" ) ) : "" ;
2020-08-28 17:18:33 +03:00
}
2020-11-26 22:02:29 +03:00
case 'messageLocation' :
2020-09-30 01:09:51 +03:00
return simple ? ( myself ? qsTr ( "sent a location" , "myself" ) : qsTr ( "sent a location" ) ) : "" ;
2020-11-26 22:02:29 +03:00
case 'messageVenue' :
2020-09-30 01:09:51 +03:00
return simple ? ( myself ? qsTr ( "sent a venue" , "myself" ) : qsTr ( "sent a venue" ) ) : ( "<b>" + message . content . venue . title + "</b>, " + message . content . venue . address ) ;
2020-11-26 22:02:29 +03:00
case 'messageContactRegistered' :
2020-09-30 01:09:51 +03:00
return myself ? qsTr ( "have registered with Telegram" ) : qsTr ( "has registered with Telegram" ) ;
2020-11-26 22:02:29 +03:00
case 'messageChatJoinByLink' :
2020-09-30 01:09:51 +03:00
return myself ? qsTr ( "joined this chat" , "myself" ) : qsTr ( "joined this chat" ) ;
2020-11-26 22:02:29 +03:00
case 'messageChatAddMembers' :
2022-01-07 21:18:04 +03:00
if ( message . sender _id [ '@type' ] === "messageSenderUser" && message . sender _id . user _id === message . content . member _user _ids [ 0 ] ) {
2020-12-29 18:32:39 +03:00
return myself ? qsTr ( "were added to this chat" , "myself" ) : qsTr ( "was added to this chat" ) ;
} else {
var addedUserNames = "" ;
for ( var i = 0 ; i < message . content . member _user _ids . length ; i ++ ) {
if ( i > 0 ) {
addedUserNames += ", " ;
}
addedUserNames += getUserName ( tdLibWrapper . getUserInformation ( message . content . member _user _ids [ i ] ) ) ;
}
return myself ? qsTr ( "have added %1 to the chat" , "myself" ) . arg ( addedUserNames ) : qsTr ( "has added %1 to the chat" ) . arg ( addedUserNames ) ;
}
2020-11-26 22:02:29 +03:00
case 'messageChatDeleteMember' :
2022-01-07 21:18:04 +03:00
if ( message . sender _id [ '@type' ] === "messageSenderUser" && message . sender _id . user _id === message . content . user _id ) {
2020-12-29 18:32:39 +03:00
return myself ? qsTr ( "left this chat" , "myself" ) : qsTr ( "left this chat" ) ;
} else {
return myself ? qsTr ( "have removed %1 from the chat" , "myself" ) . arg ( getUserName ( tdLibWrapper . getUserInformation ( message . content . user _id ) ) ) : qsTr ( "has removed %1 from the chat" ) . arg ( getUserName ( tdLibWrapper . getUserInformation ( message . content . user _id ) ) ) ;
}
2020-11-26 22:02:29 +03:00
case 'messageChatChangeTitle' :
2020-10-19 13:20:02 +03:00
return myself ? qsTr ( "changed the chat title to %1" , "myself" ) . arg ( message . content . title ) : qsTr ( "changed the chat title to %1" ) . arg ( message . content . title ) ;
2020-11-26 22:02:29 +03:00
case 'messagePoll' :
2020-10-30 00:39:43 +03:00
if ( message . content . poll . type [ '@type' ] === "pollTypeQuiz" ) {
if ( message . content . poll . is _anonymous ) {
2020-10-30 21:07:06 +03:00
return simple ? ( myself ? qsTr ( "sent an anonymous quiz" , "myself" ) : qsTr ( "sent an anonymous quiz" ) ) : ( "<b>" + qsTr ( "Anonymous Quiz" ) + "</b>" ) ;
2020-10-23 11:29:50 +03:00
}
2020-10-30 21:07:06 +03:00
return simple ? ( myself ? qsTr ( "sent a quiz" , "myself" ) : qsTr ( "sent a quiz" ) ) : ( "<b>" + qsTr ( "Quiz" ) + "</b>" ) ;
2020-10-23 11:29:50 +03:00
}
2020-10-30 00:39:43 +03:00
if ( message . content . poll . is _anonymous ) {
2020-10-30 21:07:06 +03:00
return simple ? ( myself ? qsTr ( "sent an anonymous poll" , "myself" ) : qsTr ( "sent an anonymous poll" ) ) : ( "<b>" + qsTr ( "Anonymous Poll" ) + "</b>" ) ;
2020-10-23 11:29:50 +03:00
}
2020-10-30 21:07:06 +03:00
return simple ? ( myself ? qsTr ( "sent a poll" , "myself" ) : qsTr ( "sent a poll" ) ) : ( "<b>" + qsTr ( "Poll" ) + "</b>" ) ;
2020-11-26 22:02:29 +03:00
case 'messageBasicGroupChatCreate' :
case 'messageSupergroupChatCreate' :
2020-11-05 16:06:41 +03:00
return myself ? qsTr ( "created this group" , "myself" ) : qsTr ( "created this group" ) ;
2020-11-26 22:02:29 +03:00
case 'messageChatChangePhoto' :
2020-11-05 16:06:41 +03:00
return myself ? qsTr ( "changed the chat photo" , "myself" ) : qsTr ( "changed the chat photo" ) ;
2020-11-26 22:02:29 +03:00
case 'messageChatDeletePhoto' :
2020-11-05 16:06:41 +03:00
return myself ? qsTr ( "deleted the chat photo" , "myself" ) : qsTr ( "deleted the chat photo" ) ;
2020-11-26 22:02:29 +03:00
case 'messageChatSetTtl' :
2020-11-05 16:06:41 +03:00
return myself ? qsTr ( "changed the secret chat TTL setting" , "myself; TTL = Time To Live" ) : qsTr ( "changed the secret chat TTL setting" , "TTL = Time To Live" ) ;
2020-11-26 22:02:29 +03:00
case 'messageChatUpgradeFrom' :
case 'messageChatUpgradeTo' :
2020-11-05 16:06:41 +03:00
return myself ? qsTr ( "upgraded this group to a supergroup" , "myself" ) : qsTr ( "upgraded this group to a supergroup" ) ;
2020-11-26 22:02:29 +03:00
case 'messageCustomServiceAction' :
2020-11-05 16:06:41 +03:00
return message . content . text ;
2020-11-26 22:02:29 +03:00
case 'messagePinMessage' :
2020-11-05 16:06:41 +03:00
return myself ? qsTr ( "changed the pinned message" , "myself" ) : qsTr ( "changed the pinned message" ) ;
2020-11-26 22:02:29 +03:00
case 'messageExpiredPhoto' :
2020-11-05 16:06:41 +03:00
return myself ? qsTr ( "sent a self-destructing photo that is expired" , "myself" ) : qsTr ( "sent a self-destructing photo that is expired" ) ;
2020-11-26 22:02:29 +03:00
case 'messageExpiredVideo' :
2020-11-05 16:06:41 +03:00
return myself ? qsTr ( "sent a self-destructing video that is expired" , "myself" ) : qsTr ( "sent a self-destructing video that is expired" ) ;
2020-11-26 22:02:29 +03:00
case 'messageScreenshotTaken' :
2020-11-05 16:06:41 +03:00
return myself ? qsTr ( "created a screenshot in this chat" , "myself" ) : qsTr ( "created a screenshot in this chat" ) ;
2021-01-10 04:06:41 +03:00
case 'messageGame' :
return simple ? ( myself ? qsTr ( "sent a game" , "myself" ) : qsTr ( "sent a game" ) ) : "" ;
case 'messageGameScore' :
return myself ? qsTr ( "scored %Ln points" , "myself" , message . content . score ) : qsTr ( "scored %Ln points" , "myself" , message . content . score ) ;
2020-11-26 22:02:29 +03:00
case 'messageUnsupported' :
2020-11-05 16:06:41 +03:00
return myself ? qsTr ( "sent an unsupported message" , "myself" ) : qsTr ( "sent an unsupported message" ) ;
2020-11-26 22:02:29 +03:00
default :
return myself ? qsTr ( "sent an unsupported message: %1" , "myself; %1 is message type" ) . arg ( message . content [ '@type' ] . substring ( 7 ) ) : qsTr ( "sent an unsupported message: %1" , "%1 is message type" ) . arg ( message . content [ '@type' ] . substring ( 7 ) ) ;
2020-11-05 16:06:41 +03:00
}
}
2020-11-25 02:23:38 +03:00
2020-10-19 13:20:02 +03:00
function getChatPartnerStatusText ( statusType , was _online ) {
switch ( statusType ) {
case "userStatusEmpty" :
return qsTr ( "was never online" ) ;
case "userStatusLastMonth" :
2020-12-05 17:49:27 +03:00
return qsTr ( "last online: last month" ) ;
2020-10-19 13:20:02 +03:00
case "userStatusLastWeek" :
2020-12-05 17:49:27 +03:00
return qsTr ( "last online: last week" ) ;
2020-10-19 13:20:02 +03:00
case "userStatusOffline" :
2020-12-05 17:49:27 +03:00
return qsTr ( "last online: %1" ) . arg ( getDateTimeElapsed ( was _online ) ) ;
2020-10-19 13:20:02 +03:00
case "userStatusOnline" :
return qsTr ( "online" ) ;
case "userStatusRecently" :
2020-12-05 17:49:27 +03:00
return qsTr ( "was recently online" ) ;
2020-10-19 13:20:02 +03:00
}
}
2020-11-25 02:23:38 +03:00
function getSecretChatStatus ( secretChatDetails ) {
switch ( secretChatDetails . state [ "@type" ] ) {
case "secretChatStateClosed" :
return "<b>" + qsTr ( "Closed!" ) + "</b>" ;
case "secretChatStatePending" :
return qsTr ( "Pending acknowledgement" ) ;
case "secretChatStateReady" :
2020-11-26 02:25:15 +03:00
return "" ;
2020-11-25 02:23:38 +03:00
}
}
2020-10-19 13:20:02 +03:00
function getChatMemberStatusText ( statusType ) {
switch ( statusType ) {
case "chatMemberStatusAdministrator" :
return qsTr ( "Admin" , "channel user role" ) ;
case "chatMemberStatusBanned" :
return qsTr ( "Banned" , "channel user role" ) ;
case "chatMemberStatusCreator" :
return qsTr ( "Creator" , "channel user role" ) ;
case "chatMemberStatusRestricted" :
return qsTr ( "Restricted" , "channel user role" ) ;
case "chatMemberStatusLeft" :
case "chatMemberStatusMember" :
return ""
}
return statusType || "" ;
}
2020-09-24 10:55:05 +03:00
function getShortenedCount ( count ) {
if ( count >= 1000000 ) {
return qsTr ( "%1M" ) . arg ( ( count / 1000000 ) . toLocaleString ( Qt . locale ( ) , 'f' , 0 ) ) ;
} else if ( count >= 1000 ) {
return qsTr ( "%1K" ) . arg ( ( count / 1000 ) . toLocaleString ( Qt . locale ( ) , 'f' , 0 ) ) ;
} else {
return count ;
}
}
2020-08-20 01:24:24 +03:00
function getDateTimeElapsed ( timestamp ) {
2020-11-20 23:58:26 +03:00
return Silica . Format . formatDate ( new Date ( timestamp * 1000 ) , Silica . Formatter . DurationElapsed ) ;
2020-08-20 01:24:24 +03:00
}
2020-08-24 16:27:44 +03:00
2020-11-03 01:42:23 +03:00
function getDateTimeTranslated ( timestamp ) {
return new Date ( timestamp * 1000 ) . toLocaleString ( ) ;
}
2021-02-20 02:14:43 +03:00
function getDateTimeTimepoint ( timestamp ) {
return Silica . Format . formatDate ( new Date ( timestamp * 1000 ) , Silica . Formatter . TimepointRelative ) ;
}
2020-11-02 00:55:43 +03:00
function handleHtmlEntity ( messageText , messageInsertions , originalString , replacementString ) {
2020-11-26 22:02:29 +03:00
var nextIndex = - 1 ;
while ( ( nextIndex = messageText . indexOf ( originalString , nextIndex + 1 ) ) > - 1 ) {
messageInsertions . push ( { offset : nextIndex , insertionString : replacementString , removeLength : originalString . length } ) ;
2020-11-02 00:55:43 +03:00
}
2020-08-24 16:27:44 +03:00
}
2020-11-26 22:02:29 +03:00
var rawNewLineRegExp = /\r?\n/g ;
var ampRegExp = /&/g ;
var ltRegExp = /</g ;
var gtRegExp = />/g ;
2020-11-19 13:41:32 +03:00
2020-11-26 22:02:29 +03:00
function enhanceHtmlEntities ( simpleText ) {
return simpleText . replace ( ampRegExp , "&" ) . replace ( ltRegExp , "<" ) . replace ( gtRegExp , ">" ) ; //.replace(rawNewLineRegExp, "<br>");
}
2020-11-19 13:41:32 +03:00
2021-02-11 00:02:53 +03:00
function messageInsertionSorter ( a , b ) {
if ( ( b . offset + b . removeLength ) > ( a . offset + a . removeLength ) ) {
return 1 ;
}
if ( ( b . offset + b . removeLength ) < ( a . offset + a . removeLength ) ) {
return - 1 ;
}
return b . offset - a . offset ;
}
2020-11-19 13:41:32 +03:00
2020-12-01 23:17:13 +03:00
function enhanceMessageText ( formattedText , ignoreEntities ) {
2020-08-24 16:27:44 +03:00
var messageInsertions = [ ] ;
2020-11-02 00:55:43 +03:00
var messageText = formattedText . text ;
2020-11-26 22:02:29 +03:00
var entity ;
2020-12-01 23:17:13 +03:00
if ( ignoreEntities ) {
return messageText ;
}
2020-11-26 22:02:29 +03:00
if ( formattedText . entities . length === 0 ) {
return messageText . replace ( ampRegExp , "&" ) . replace ( ltRegExp , "<" ) . replace ( gtRegExp , ">" ) . replace ( rawNewLineRegExp , "<br>" ) ;
}
2020-08-24 16:27:44 +03:00
for ( var i = 0 ; i < formattedText . entities . length ; i ++ ) {
2020-11-26 22:02:29 +03:00
entity = formattedText . entities [ i ] ;
if ( entity [ '@type' ] !== "textEntity" ) {
2020-08-24 16:27:44 +03:00
continue ;
}
2020-11-26 22:02:29 +03:00
switch ( entity . type [ '@type' ] ) {
case "textEntityTypeBold" :
messageInsertions . push (
{ offset : entity . offset , insertionString : "<b>" , removeLength : 0 } ,
{ offset : ( entity . offset + entity . length ) , insertionString : "</b>" , removeLength : 0 }
) ;
break ;
case "textEntityTypeUrl" :
messageInsertions . push (
{ offset : entity . offset , insertionString : "<a href=\"" + messageText . substring ( entity . offset , ( entity . offset + entity . length ) ) + "\">" , removeLength : 0 } ,
{ offset : ( entity . offset + entity . length ) , insertionString : "</a>" , removeLength : 0 }
) ;
break ;
case "textEntityTypeCode" :
messageInsertions . push (
{ offset : entity . offset , insertionString : "<pre>" , removeLength : 0 } ,
{ offset : ( entity . offset + entity . length ) , insertionString : "</pre>" , removeLength : 0 }
) ;
break ;
case "textEntityTypeEmailAddress" :
messageInsertions . push (
{ offset : entity . offset , insertionString : "<a href=\"mailto:" + messageText . substring ( entity . offset , ( entity . offset + entity . length ) ) + "\">" , removeLength : 0 } ,
{ offset : ( entity . offset + entity . length ) , insertionString : "</a>" , removeLength : 0 }
) ;
break ;
case "textEntityTypeItalic" :
messageInsertions . push (
{ offset : entity . offset , insertionString : "<i>" , removeLength : 0 } ,
{ offset : ( entity . offset + entity . length ) , insertionString : "</i>" , removeLength : 0 }
) ;
break ;
2022-02-20 19:54:52 +03:00
case "textEntityTypeStrikethrough" :
messageInsertions . push (
{ offset : entity . offset , insertionString : "<s>" , removeLength : 0 } ,
{ offset : ( entity . offset + entity . length ) , insertionString : "</s>" , removeLength : 0 }
) ;
break ;
2020-11-26 22:02:29 +03:00
case "textEntityTypeMention" :
messageInsertions . push (
{ offset : entity . offset , insertionString : "<a href=\"user://" + messageText . substring ( entity . offset , ( entity . offset + entity . length ) ) + "\">" , removeLength : 0 } ,
{ offset : ( entity . offset + entity . length ) , insertionString : "</a>" , removeLength : 0 }
) ;
break ;
case "textEntityTypeMentionName" :
messageInsertions . push (
{ offset : entity . offset , insertionString : "<a href=\"userId://" + entity . type . user _id + "\">" , removeLength : 0 } ,
{ offset : ( entity . offset + entity . length ) , insertionString : "</a>" , removeLength : 0 }
) ;
break ;
case "textEntityTypePhoneNumber" :
messageInsertions . push (
{ offset : entity . offset , insertionString : "<a href=\"tel:" + messageText . substring ( entity . offset , ( entity . offset + entity . length ) ) + "\">" , removeLength : 0 } ,
{ offset : ( entity . offset + entity . length ) , insertionString : "</a>" , removeLength : 0 }
) ;
break ;
case "textEntityTypePre" :
messageInsertions . push (
{ offset : entity . offset , insertionString : "<pre>" , removeLength : 0 } ,
{ offset : ( entity . offset + entity . length ) , insertionString : "</pre>" , removeLength : 0 }
) ;
break ;
case "textEntityTypePreCode" :
messageInsertions . push (
{ offset : entity . offset , insertionString : "<pre>" , removeLength : 0 } ,
{ offset : ( entity . offset + entity . length ) , insertionString : "</pre>" , removeLength : 0 }
) ;
break ;
case "textEntityTypeTextUrl" :
messageInsertions . push (
{ offset : entity . offset , insertionString : "<a href=\"" + entity . type . url + "\">" , removeLength : 0 } ,
{ offset : ( entity . offset + entity . length ) , insertionString : "</a>" , removeLength : 0 }
) ;
break ;
case "textEntityTypeUnderline" :
messageInsertions . push (
{ offset : entity . offset , insertionString : "<u>" , removeLength : 0 } ,
{ offset : ( entity . offset + entity . length ) , insertionString : "</u>" , removeLength : 0 }
) ;
break ;
2020-12-27 02:01:59 +03:00
case "textEntityTypeBotCommand" :
var command = messageText . substring ( entity . offset , entity . offset + entity . length ) ;
messageInsertions . push (
{ offset : entity . offset , insertionString : "<a href=\"botCommand://" + command + "\">" , removeLength : 0 } ,
{ offset : ( entity . offset + entity . length ) , insertionString : "</a>" , removeLength : 0 }
) ;
break ;
2020-08-24 17:30:19 +03:00
}
2020-08-24 16:27:44 +03:00
}
2020-11-26 22:02:29 +03:00
if ( messageInsertions . length === 0 ) {
return messageText . replace ( ampRegExp , "&" ) . replace ( ltRegExp , "<" ) . replace ( gtRegExp , ">" ) . replace ( rawNewLineRegExp , "<br>" ) ;
}
handleHtmlEntity ( messageText , messageInsertions , "&" , "&" ) ;
handleHtmlEntity ( messageText , messageInsertions , "<" , "<" ) ;
handleHtmlEntity ( messageText , messageInsertions , ">" , ">" ) ;
messageInsertions . sort ( messageInsertionSorter ) ;
2020-08-24 16:27:44 +03:00
for ( var z = 0 ; z < messageInsertions . length ; z ++ ) {
2020-11-26 22:02:29 +03:00
messageText = messageText . substring ( 0 , messageInsertions [ z ] . offset )
+ messageInsertions [ z ] . insertionString
+ messageText . substring ( messageInsertions [ z ] . offset + messageInsertions [ z ] . removeLength ) ;
2020-08-24 16:27:44 +03:00
}
2020-11-26 22:02:29 +03:00
messageText = messageText . replace ( rawNewLineRegExp , "<br>" ) ;
2020-08-24 16:27:44 +03:00
return messageText ;
}
2020-08-24 17:30:19 +03:00
2021-11-04 01:31:00 +03:00
function handleTMeLink ( link , usedPrefix ) {
if ( link . indexOf ( "joinchat" ) !== - 1 ) {
Debug . log ( "Joining Chat: " , link ) ;
tdLibWrapper . joinChatByInviteLink ( link ) ;
// Do the necessary stuff to open the chat if successful
// Fail with nice error message if it doesn't work
2022-05-01 02:17:37 +03:00
} else if ( link . indexOf ( "/+" ) !== - 1 ) {
2022-05-01 15:04:28 +03:00
// Can't handle t.me/+... links directly, try to parse the Telegram page...
tdLibWrapper . getPageSource ( link ) ;
2021-11-04 01:31:00 +03:00
} else {
Debug . log ( "Search public chat: " , link . substring ( usedPrefix . length ) ) ;
tdLibWrapper . searchPublicChat ( link . substring ( usedPrefix . length ) , true ) ;
// Check responses for updateBasicGroup or updateSupergroup
// Fire createBasicGroupChat or createSupergroupChat
// Do the necessary stuff to open the chat
// Fail with nice error message if chat can't be found
}
}
2020-08-24 17:30:19 +03:00
function handleLink ( link ) {
2020-11-08 23:13:04 +03:00
var tMePrefix = tdLibWrapper . getOptionString ( "t_me_url" ) ;
2021-11-04 01:31:00 +03:00
var tMePrefixHttp = tMePrefix . replace ( 'https' , 'http' ) ;
2021-12-11 20:29:31 +03:00
// Checking if we have a direct message link...
Debug . log ( "URL open requested: " + link ) ;
if ( ( link . indexOf ( tMePrefix ) === 0 && link . substring ( tMePrefix . length ) . indexOf ( "/" ) > 0 ) ||
( link . indexOf ( tMePrefixHttp ) === 0 && link . substring ( tMePrefixHttp . length ) . indexOf ( "/" ) > 0 ) ||
link . indexOf ( "tg://privatepost" ) === 0 ||
2021-12-12 01:22:32 +03:00
( link . indexOf ( "tg://resolve" ) === 0 && link . indexOf ( "post" ) > 0 ) ) {
2021-12-11 20:29:31 +03:00
Debug . log ( "Using message link info for: " + link ) ;
tdLibWrapper . getMessageLinkInfo ( link , "openDirectly" ) ;
return ;
}
Debug . log ( "Trying to parse link ourselves: " + link ) ;
2020-08-24 17:30:19 +03:00
if ( link . indexOf ( "user://" ) === 0 ) {
2020-11-10 01:22:24 +03:00
var userName = link . substring ( 8 ) ;
var userInformation = tdLibWrapper . getUserInformationByName ( userName ) ;
if ( typeof userInformation . id === "undefined" ) {
appNotification . show ( qsTr ( "Unable to find user %1" ) . arg ( userName ) ) ;
} else {
2021-01-10 04:06:41 +03:00
tdLibWrapper . createPrivateChat ( userInformation . id , "openDirectly" ) ;
2020-11-10 01:22:24 +03:00
}
2020-11-04 00:21:01 +03:00
} else if ( link . indexOf ( "userId://" ) === 0 ) {
2021-01-10 04:06:41 +03:00
tdLibWrapper . createPrivateChat ( link . substring ( 9 ) , "openDirectly" ) ;
2020-11-08 23:13:04 +03:00
} else if ( link . indexOf ( "tg://" ) === 0 ) {
2020-11-20 23:58:26 +03:00
Debug . log ( "Special TG link: " , link ) ;
2020-11-08 23:13:04 +03:00
if ( link . indexOf ( "tg://join?invite=" ) === 0 ) {
tdLibWrapper . joinChatByInviteLink ( tMePrefix + "joinchat/" + link . substring ( 17 ) ) ;
} else if ( link . indexOf ( "tg://resolve?domain=" ) === 0 ) {
2021-01-10 04:06:41 +03:00
tdLibWrapper . searchPublicChat ( link . substring ( 20 ) , true ) ;
2020-11-08 23:13:04 +03:00
}
2020-12-27 02:01:59 +03:00
} else if ( link . indexOf ( "botCommand://" ) === 0 ) { // this gets returned to send on ChatPage
return link . substring ( 13 ) ;
} else {
2020-11-04 01:39:09 +03:00
if ( link . indexOf ( tMePrefix ) === 0 ) {
2021-11-04 01:31:00 +03:00
handleTMeLink ( link , tMePrefix ) ;
} else if ( link . indexOf ( tMePrefixHttp ) === 0 ) {
handleTMeLink ( link , tMePrefixHttp ) ;
2020-11-04 01:39:09 +03:00
} else {
2023-11-27 23:29:43 +03:00
Debug . log ( "Trying to open URL externally: " + link )
if ( link . indexOf ( "://" ) === - 1 ) {
Qt . openUrlExternally ( "https://" + link )
} else {
Qt . openUrlExternally ( link ) ;
}
2020-11-04 01:39:09 +03:00
}
2020-08-24 17:30:19 +03:00
}
}
2020-08-28 11:41:18 +03:00
function getVideoHeight ( videoWidth , videoData ) {
if ( typeof videoData !== "undefined" ) {
2020-09-30 00:37:56 +03:00
if ( videoData . height === 0 ) {
return videoWidth ;
} else {
var aspectRatio = videoData . height / videoData . width ;
return Math . round ( videoWidth * aspectRatio ) ;
}
2020-08-28 11:41:18 +03:00
} else {
return 1 ;
}
}
2020-12-04 23:21:53 +03:00
2020-10-19 13:20:02 +03:00
function replaceUrlsWithLinks ( string ) {
return string . replace ( /((\w+):\/\/[\w?=&.\/-;#~%-]+(?![\w\s?&.\/;#~%"=-]*>))/g , "<a href=\"$1\">$1</a>" ) ;
}
2020-11-15 01:50:12 +03:00
function sortMessagesArrayByDate ( messages ) {
messages . sort ( function ( a , b ) {
return a . date - b . date ;
} ) ;
}
function getMessagesArrayIds ( messages ) {
sortMessagesArrayByDate ( messages ) ;
return messages . map ( function ( message ) { return message . id . toString ( ) } ) ;
}
function getMessagesArrayText ( messages ) {
sortMessagesArrayByDate ( messages ) ;
var lastSenderName = "" ;
var lines = [ ] ;
for ( var i = 0 ; i < messages . length ; i += 1 ) {
2022-01-07 21:18:04 +03:00
var senderName = getUserName ( tdLibWrapper . getUserInformation ( messages [ i ] . sender _id . user _id ) ) ;
2020-11-15 01:50:12 +03:00
if ( senderName !== lastSenderName ) {
lines . push ( senderName ) ;
}
lastSenderName = senderName ;
2020-12-29 18:32:39 +03:00
lines . push ( getMessageText ( messages [ i ] , true , tdLibWrapper . getUserInformation ( ) . id , false ) ) ;
2020-11-15 01:50:12 +03:00
lines . push ( "" ) ;
}
return lines . join ( "\n" ) ;
}
2020-11-16 16:37:14 +03:00
function handleErrorMessage ( code , message ) {
2021-01-11 12:19:00 +03:00
if ( code === 404 || ( code === 400 && message === "USERNAME_INVALID" ) ) {
// Silently ignore
// - 404 Not Found messages (occur sometimes, without clear context...)
// - searchPublicChat messages for "invalid" inline queries
2020-11-16 16:37:14 +03:00
return ;
}
if ( message === "USER_ALREADY_PARTICIPANT" ) {
appNotification . show ( qsTr ( "You are already a member of this chat." ) ) ;
} else {
appNotification . show ( message ) ;
}
}
2020-11-16 12:28:16 +03:00
function getMessagesNeededForwardPermissions ( messages ) {
2020-11-18 13:13:05 +03:00
var neededPermissions = [ "can_send_messages" ]
2020-11-16 12:28:16 +03:00
2020-11-18 13:13:05 +03:00
var mediaMessageTypes = [ "messageAudio" , "messageDocument" , "messagePhoto" , "messageVideo" , "messageVideoNote" , "messageVoiceNote" ]
2020-11-16 12:28:16 +03:00
var otherMessageTypes = [ "messageAnimation" , "messageGame" , "messageSticker" ]
2020-11-16 14:25:47 +03:00
for ( var i = 0 ; i < messages . length && neededPermissions . length < 3 ; i += 1 ) {
2020-11-18 13:13:05 +03:00
var type = messages [ i ] [ "content" ] [ "@type" ]
var permission = ""
2020-11-16 12:28:16 +03:00
if ( type === "messageText" ) {
2020-11-18 13:13:05 +03:00
continue
2020-11-16 12:28:16 +03:00
} else if ( type === "messagePoll" ) {
2020-11-18 13:13:05 +03:00
permission = "can_send_polls"
2020-11-16 12:28:16 +03:00
} else if ( mediaMessageTypes . indexOf ( type ) > - 1 ) {
2020-11-18 13:13:05 +03:00
permission = "can_send_media_messages"
2020-11-16 12:28:16 +03:00
} else if ( otherMessageTypes . indexOf ( type ) > - 1 ) {
2020-11-18 13:13:05 +03:00
permission = "can_send_other_messages"
2020-11-16 12:28:16 +03:00
}
if ( permission !== "" && neededPermissions . indexOf ( permission ) === - 1 ) {
2020-11-18 13:13:05 +03:00
neededPermissions . push ( permission )
2020-11-16 12:28:16 +03:00
}
}
2020-11-18 13:13:05 +03:00
return neededPermissions
2020-11-16 12:28:16 +03:00
}
2023-12-03 01:44:14 +03:00
2023-12-03 01:50:13 +03:00
function isWidescreen ( appWindow ) {
2023-12-03 01:44:14 +03:00
return ( appWindow . deviceOrientation & Silica . Orientation . LandscapeMask ) || Silica . Screen . sizeCategory === Silica . Screen . Large || Silica . Screen . sizeCategory === Silica . Screen . ExtraLarge
}