-
-
Save KlavierCat/0b1e3214f8d9ca1b0f4e523b38a3df88 to your computer and use it in GitHub Desktop.
sample jscpd JSON report
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"statistics": { | |
"detectionDate": "2021-03-07T12:36:50.737Z", | |
"formats": { | |
"swift": { | |
"sources": { | |
"ViewControllers/ConversationView/CV/CVComponents/CVComponentViewOnce.swift": { | |
"lines": 364, | |
"tokens": 2530, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVComponents/CVComponentUnreadIndicator.swift": { | |
"lines": 201, | |
"tokens": 1480, | |
"sources": 1, | |
"clones": 4, | |
"duplicatedLines": 82, | |
"duplicatedTokens": 599, | |
"percentage": 40.8, | |
"percentageTokens": 40.47, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVComponents/CVComponentTypingIndicator.swift": { | |
"lines": 197, | |
"tokens": 1518, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 25, | |
"duplicatedTokens": 180, | |
"percentage": 12.69, | |
"percentageTokens": 11.86, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVComponents/CVComponentThreadDetails.swift": { | |
"lines": 432, | |
"tokens": 3628, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVComponents/CVComponentSystemMessage.swift": { | |
"lines": 919, | |
"tokens": 7386, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 20, | |
"duplicatedTokens": 146, | |
"percentage": 2.18, | |
"percentageTokens": 1.98, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVComponents/CVComponentSticker.swift": { | |
"lines": 196, | |
"tokens": 1490, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVComponents/CVComponentSenderName.swift": { | |
"lines": 115, | |
"tokens": 868, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 13, | |
"duplicatedTokens": 110, | |
"percentage": 11.3, | |
"percentageTokens": 12.67, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVComponents/CVComponentReactions.swift": { | |
"lines": 77, | |
"tokens": 515, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVComponents/CVComponentQuotedReply.swift": { | |
"lines": 88, | |
"tokens": 585, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVComponents/CVComponentLinkPreview.swift": { | |
"lines": 76, | |
"tokens": 490, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVComponents/CVComponentGenericAttachment.swift": { | |
"lines": 330, | |
"tokens": 2786, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVComponents/CVComponentFooter.swift": { | |
"lines": 371, | |
"tokens": 2994, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVComponents/CVComponentDateHeader.swift": { | |
"lines": 209, | |
"tokens": 1526, | |
"sources": 1, | |
"clones": 2, | |
"duplicatedLines": 37, | |
"duplicatedTokens": 273, | |
"percentage": 17.7, | |
"percentageTokens": 17.89, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVComponents/CVComponentContactShare.swift": { | |
"lines": 92, | |
"tokens": 629, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVComponents/CVComponentBottomButtons.swift": { | |
"lines": 144, | |
"tokens": 1073, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVComponents/CVComponentBodyText.swift": { | |
"lines": 648, | |
"tokens": 4993, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVComponents/CVComponentBodyMedia.swift": { | |
"lines": 434, | |
"tokens": 3435, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 13, | |
"duplicatedTokens": 110, | |
"percentage": 3, | |
"percentageTokens": 3.2, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVComponents/CVComponentAudioAttachment.swift": { | |
"lines": 203, | |
"tokens": 1485, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/UserInterface/Individual/CallKit/CallKitCallUIAdaptee.swift": { | |
"lines": 470, | |
"tokens": 3200, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/UserInterface/Individual/CallKit/CallKitCallManager.swift": { | |
"lines": 147, | |
"tokens": 1130, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Registration/SecondaryLinking/SecondaryLinkingSetDeviceNameViewController.swift": { | |
"lines": 162, | |
"tokens": 1240, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Registration/SecondaryLinking/SecondaryLinkingQRCodeViewController.swift": { | |
"lines": 130, | |
"tokens": 1009, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 7, | |
"duplicatedTokens": 81, | |
"percentage": 5.38, | |
"percentageTokens": 8.03, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Registration/SecondaryLinking/SecondaryLinkingPrepViewController.swift": { | |
"lines": 115, | |
"tokens": 890, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Registration/SecondaryLinking/ProvisioningController.swift": { | |
"lines": 247, | |
"tokens": 2062, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Registration/Device Transfer/OnboardingTransferQRCodeViewController.swift": { | |
"lines": 184, | |
"tokens": 1204, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Registration/Device Transfer/OnboardingTransferProgressViewController.swift": { | |
"lines": 145, | |
"tokens": 971, | |
"sources": 1, | |
"clones": 2, | |
"duplicatedLines": 35, | |
"duplicatedTokens": 239, | |
"percentage": 24.14, | |
"percentageTokens": 24.61, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Registration/Device Transfer/OnboardingTransferChoiceViewController.swift": { | |
"lines": 239, | |
"tokens": 1936, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/MediaGallery/Transitions/MediaZoomAnimationController.swift": { | |
"lines": 159, | |
"tokens": 1262, | |
"sources": 1, | |
"clones": 3, | |
"duplicatedLines": 48, | |
"duplicatedTokens": 391, | |
"percentage": 30.19, | |
"percentageTokens": 30.98, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/MediaGallery/Transitions/MediaPresentationContext.swift": { | |
"lines": 68, | |
"tokens": 449, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/MediaGallery/Transitions/MediaInteractiveDismiss.swift": { | |
"lines": 125, | |
"tokens": 857, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/MediaGallery/Transitions/MediaDismissAnimationController.swift": { | |
"lines": 255, | |
"tokens": 2086, | |
"sources": 1, | |
"clones": 3, | |
"duplicatedLines": 48, | |
"duplicatedTokens": 391, | |
"percentage": 18.82, | |
"percentageTokens": 18.74, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/Reactions Details/ReactionsDetailSheet.swift": { | |
"lines": 648, | |
"tokens": 5183, | |
"sources": 1, | |
"clones": 19, | |
"duplicatedLines": 410, | |
"duplicatedTokens": 3534, | |
"percentage": 63.27, | |
"percentageTokens": 68.18, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/Reactions Details/EmojiReactorsTableView.swift": { | |
"lines": 124, | |
"tokens": 1034, | |
"sources": 1, | |
"clones": 2, | |
"duplicatedLines": 23, | |
"duplicatedTokens": 223, | |
"percentage": 18.55, | |
"percentageTokens": 21.57, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/Reactions Details/EmojiCountsCollectionView.swift": { | |
"lines": 150, | |
"tokens": 1176, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/Emoji Picker/EmojiSkinTonePicker.swift": { | |
"lines": 304, | |
"tokens": 3141, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/Emoji Picker/EmojiPickerSheet.swift": { | |
"lines": 355, | |
"tokens": 2947, | |
"sources": 1, | |
"clones": 13, | |
"duplicatedLines": 239, | |
"duplicatedTokens": 2139, | |
"percentage": 67.32, | |
"percentageTokens": 72.58, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/Emoji Picker/EmojiPickerSectionToolbar.swift": { | |
"lines": 125, | |
"tokens": 1035, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/Emoji Picker/EmojiPickerCollectionView.swift": { | |
"lines": 343, | |
"tokens": 2956, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/Cells/ReusableMediaView.swift": { | |
"lines": 511, | |
"tokens": 3271, | |
"sources": 1, | |
"clones": 8, | |
"duplicatedLines": 204, | |
"duplicatedTokens": 1260, | |
"percentage": 39.92, | |
"percentageTokens": 38.52, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/Cells/QuotedMessageView.swift": { | |
"lines": 608, | |
"tokens": 4911, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/Cells/LoadMoreMessagesView.swift": { | |
"lines": 38, | |
"tokens": 240, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/Cells/CVReactionCountsView.swift": { | |
"lines": 260, | |
"tokens": 2313, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/Cells/CVMediaView.swift": { | |
"lines": 278, | |
"tokens": 2099, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/Cells/CVMediaCache.swift": { | |
"lines": 124, | |
"tokens": 914, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/Cells/CVMediaAlbumView.swift": { | |
"lines": 437, | |
"tokens": 3650, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/Cells/CVContactShareView.swift": { | |
"lines": 110, | |
"tokens": 1051, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/Cells/CVAttachmentProgressView.swift": { | |
"lines": 526, | |
"tokens": 3940, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/Cells/AudioWaveformProgressView.swift": { | |
"lines": 199, | |
"tokens": 1531, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/Cells/AudioMessageView.swift": { | |
"lines": 331, | |
"tokens": 2869, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/OWSStackView.swift": { | |
"lines": 75, | |
"tokens": 511, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVViewStateSnapshot.swift": { | |
"lines": 63, | |
"tokens": 402, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVUpdate.swift": { | |
"lines": 315, | |
"tokens": 2549, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVStackView.swift": { | |
"lines": 63, | |
"tokens": 481, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVRenderState.swift": { | |
"lines": 107, | |
"tokens": 744, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVRenderItem.swift": { | |
"lines": 162, | |
"tokens": 1233, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVNode.swift": { | |
"lines": 95, | |
"tokens": 629, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVMessageMapping.swift": { | |
"lines": 579, | |
"tokens": 4727, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVLoader.swift": { | |
"lines": 365, | |
"tokens": 2934, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVLoadRequest.swift": { | |
"lines": 244, | |
"tokens": 1561, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVLoadCoordinator.swift": { | |
"lines": 859, | |
"tokens": 5507, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVLoadContext.swift": { | |
"lines": 88, | |
"tokens": 582, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVItemViewState.swift": { | |
"lines": 647, | |
"tokens": 5027, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVItemViewModelImpl.swift": { | |
"lines": 233, | |
"tokens": 1446, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVItemModel.swift": { | |
"lines": 44, | |
"tokens": 263, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVComponentState+GroupLink.swift": { | |
"lines": 169, | |
"tokens": 1455, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVComponentDelegate.swift": { | |
"lines": 239, | |
"tokens": 1530, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVComponent.swift": { | |
"lines": 378, | |
"tokens": 2436, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVCell.swift": { | |
"lines": 379, | |
"tokens": 2621, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVAvatarBuilder.swift": { | |
"lines": 71, | |
"tokens": 560, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVAudioPlayback.swift": { | |
"lines": 277, | |
"tokens": 1609, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CV/CVAttachments.swift": { | |
"lines": 66, | |
"tokens": 470, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/Profile/UsernameViewController.swift": { | |
"lines": 295, | |
"tokens": 2037, | |
"sources": 1, | |
"clones": 3, | |
"duplicatedLines": 64, | |
"duplicatedTokens": 397, | |
"percentage": 21.69, | |
"percentageTokens": 19.49, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/Profile/ProfileSettingsViewController.swift": { | |
"lines": 354, | |
"tokens": 2869, | |
"sources": 1, | |
"clones": 4, | |
"duplicatedLines": 68, | |
"duplicatedTokens": 589, | |
"percentage": 19.21, | |
"percentageTokens": 20.53, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/Profile/ProfileNameViewController.swift": { | |
"lines": 254, | |
"tokens": 1687, | |
"sources": 1, | |
"clones": 3, | |
"duplicatedLines": 63, | |
"duplicatedTokens": 387, | |
"percentage": 24.8, | |
"percentageTokens": 22.94, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/Profile/ProfileBioViewController.swift": { | |
"lines": 366, | |
"tokens": 2783, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/Privacy/PrivacySettingsViewController.swift": { | |
"lines": 242, | |
"tokens": 1759, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/Privacy/AdvancedPrivacySettingsViewController.swift": { | |
"lines": 258, | |
"tokens": 1757, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/Notifications/NotificationSettingsViewController.swift": { | |
"lines": 150, | |
"tokens": 1190, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/Notifications/NotificationSettingsSoundViewController.swift": { | |
"lines": 162, | |
"tokens": 1130, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 19, | |
"duplicatedTokens": 121, | |
"percentage": 11.73, | |
"percentageTokens": 10.71, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/Notifications/NotificationSettingsContentViewController.swift": { | |
"lines": 39, | |
"tokens": 289, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/UserInterface/Individual/NonCallKitCallUIAdaptee.swift": { | |
"lines": 188, | |
"tokens": 1210, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/UserInterface/Individual/CallUIAdapter.swift": { | |
"lines": 327, | |
"tokens": 2469, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/UserInterface/Group/GroupCallViewController.swift": { | |
"lines": 797, | |
"tokens": 6510, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/UserInterface/Group/GroupCallVideoOverflow.swift": { | |
"lines": 189, | |
"tokens": 1490, | |
"sources": 1, | |
"clones": 2, | |
"duplicatedLines": 54, | |
"duplicatedTokens": 336, | |
"percentage": 28.57, | |
"percentageTokens": 22.55, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/UserInterface/Group/GroupCallVideoGridLayout.swift": { | |
"lines": 153, | |
"tokens": 1426, | |
"sources": 1, | |
"clones": 2, | |
"duplicatedLines": 48, | |
"duplicatedTokens": 313, | |
"percentage": 31.37, | |
"percentageTokens": 21.95, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/UserInterface/Group/GroupCallVideoGrid.swift": { | |
"lines": 192, | |
"tokens": 1496, | |
"sources": 1, | |
"clones": 2, | |
"duplicatedLines": 54, | |
"duplicatedTokens": 336, | |
"percentage": 28.13, | |
"percentageTokens": 22.46, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/UserInterface/Group/GroupCallTooltip.swift": { | |
"lines": 27, | |
"tokens": 239, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/UserInterface/Group/GroupCallSpeakerToastView.swift": { | |
"lines": 45, | |
"tokens": 351, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/UserInterface/Group/GroupCallNotificationView.swift": { | |
"lines": 269, | |
"tokens": 2216, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/UserInterface/Group/GroupCallMemberView.swift": { | |
"lines": 460, | |
"tokens": 3785, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/UserInterface/Group/GroupCallMemberSheet.swift": { | |
"lines": 628, | |
"tokens": 5351, | |
"sources": 1, | |
"clones": 12, | |
"duplicatedLines": 270, | |
"duplicatedTokens": 2361, | |
"percentage": 42.99, | |
"percentageTokens": 44.12, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/UserInterface/Group/GroupCallErrorView.swift": { | |
"lines": 141, | |
"tokens": 1144, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"util/Emoji/EmojiWithSkinTones.swift": { | |
"lines": 55, | |
"tokens": 614, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"util/Emoji/Emoji+Available.swift": { | |
"lines": 118, | |
"tokens": 1030, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"util/Device Transfer/SelfSignedIdentity.swift": { | |
"lines": 241, | |
"tokens": 1986, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"util/Device Transfer/DeviceTransferService.swift": { | |
"lines": 456, | |
"tokens": 3362, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"util/Device Transfer/DeviceTransferService+URL.swift": { | |
"lines": 77, | |
"tokens": 757, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"util/Device Transfer/DeviceTransferService+State.swift": { | |
"lines": 84, | |
"tokens": 626, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"util/Device Transfer/DeviceTransferService+Restore.swift": { | |
"lines": 251, | |
"tokens": 1871, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"util/Device Transfer/DeviceTransferService+MultipeerDelegates.swift": { | |
"lines": 343, | |
"tokens": 2832, | |
"sources": 1, | |
"clones": 2, | |
"duplicatedLines": 50, | |
"duplicatedTokens": 424, | |
"percentage": 14.58, | |
"percentageTokens": 14.97, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"util/Device Transfer/DeviceTransferService+Manifest.swift": { | |
"lines": 265, | |
"tokens": 2229, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"util/Device Transfer/DeviceTransferOperation.swift": { | |
"lines": 139, | |
"tokens": 1305, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"util/Backup/OWSBackupLazyRestore.swift": { | |
"lines": 171, | |
"tokens": 1255, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"util/Backup/OWSBackupAPI.swift": { | |
"lines": 734, | |
"tokens": 6173, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Wallpapers/WallpaperSettingsViewController.swift": { | |
"lines": 380, | |
"tokens": 3163, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 16, | |
"duplicatedTokens": 116, | |
"percentage": 4.21, | |
"percentageTokens": 3.67, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Wallpapers/SetWallpaperViewController.swift": { | |
"lines": 238, | |
"tokens": 2018, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 16, | |
"duplicatedTokens": 116, | |
"percentage": 6.72, | |
"percentageTokens": 5.75, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Wallpapers/PreviewWallpaperViewController.swift": { | |
"lines": 507, | |
"tokens": 4397, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Utils/MessageRecipientStatusUtils.swift": { | |
"lines": 162, | |
"tokens": 1398, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ThreadSettings/ReplaceAdminViewController.swift": { | |
"lines": 76, | |
"tokens": 475, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ThreadSettings/OWSAddToContactViewController.swift": { | |
"lines": 133, | |
"tokens": 1035, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 8, | |
"duplicatedTokens": 75, | |
"percentage": 6.02, | |
"percentageTokens": 7.25, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ThreadSettings/NameCollisionResolutionViewController.swift": { | |
"lines": 320, | |
"tokens": 2987, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ThreadSettings/MemberActionSheet.swift": { | |
"lines": 364, | |
"tokens": 3018, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ThreadSettings/GroupViewHelper.swift": { | |
"lines": 173, | |
"tokens": 1090, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ThreadSettings/GroupViewHelper+MemberActionSheet.swift": { | |
"lines": 181, | |
"tokens": 1652, | |
"sources": 1, | |
"clones": 6, | |
"duplicatedLines": 72, | |
"duplicatedTokens": 816, | |
"percentage": 39.78, | |
"percentageTokens": 49.39, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ThreadSettings/GroupMemberRequestsAndInvitesViewController.swift": { | |
"lines": 594, | |
"tokens": 5055, | |
"sources": 1, | |
"clones": 2, | |
"duplicatedLines": 26, | |
"duplicatedTokens": 328, | |
"percentage": 4.38, | |
"percentageTokens": 6.49, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ThreadSettings/GroupLinkViewController.swift": { | |
"lines": 412, | |
"tokens": 3287, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ThreadSettings/GroupLinkQRCodeViewController.swift": { | |
"lines": 92, | |
"tokens": 704, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ThreadSettings/GroupAttributesViewController.swift": { | |
"lines": 316, | |
"tokens": 2380, | |
"sources": 1, | |
"clones": 3, | |
"duplicatedLines": 68, | |
"duplicatedTokens": 523, | |
"percentage": 21.52, | |
"percentageTokens": 21.97, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ThreadSettings/GroupAttributesEditorHelper.swift": { | |
"lines": 257, | |
"tokens": 1898, | |
"sources": 1, | |
"clones": 2, | |
"duplicatedLines": 28, | |
"duplicatedTokens": 295, | |
"percentage": 10.89, | |
"percentageTokens": 15.54, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ThreadSettings/ConversationSettingsViewController+LegacyGroups.swift": { | |
"lines": 251, | |
"tokens": 1925, | |
"sources": 1, | |
"clones": 2, | |
"duplicatedLines": 30, | |
"duplicatedTokens": 223, | |
"percentage": 11.95, | |
"percentageTokens": 11.58, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ThreadSettings/ConversationSettingsViewController+Header.swift": { | |
"lines": 300, | |
"tokens": 2612, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ThreadSettings/ConversationSettingsViewController+Contents.swift": { | |
"lines": 825, | |
"tokens": 7127, | |
"sources": 1, | |
"clones": 8, | |
"duplicatedLines": 88, | |
"duplicatedTokens": 828, | |
"percentage": 10.67, | |
"percentageTokens": 11.62, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ThreadSettings/AddToGroupViewController.swift": { | |
"lines": 279, | |
"tokens": 2380, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 18, | |
"duplicatedTokens": 138, | |
"percentage": 6.45, | |
"percentageTokens": 5.8, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ThreadSettings/AddGroupMembersViewController.swift": { | |
"lines": 274, | |
"tokens": 1969, | |
"sources": 1, | |
"clones": 2, | |
"duplicatedLines": 50, | |
"duplicatedTokens": 385, | |
"percentage": 18.25, | |
"percentageTokens": 19.55, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Stickers/StickerPackViewController.swift": { | |
"lines": 539, | |
"tokens": 4227, | |
"sources": 1, | |
"clones": 2, | |
"duplicatedLines": 24, | |
"duplicatedTokens": 213, | |
"percentage": 4.45, | |
"percentageTokens": 5.04, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Stickers/ManageStickersViewController.swift": { | |
"lines": 596, | |
"tokens": 4927, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 9, | |
"duplicatedTokens": 97, | |
"percentage": 1.51, | |
"percentageTokens": 1.97, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Registration/RegistrationController.swift": { | |
"lines": 76, | |
"tokens": 276, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Registration/OnboardingVerificationViewController.swift": { | |
"lines": 706, | |
"tokens": 5762, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Registration/OnboardingSplashViewController.swift": { | |
"lines": 108, | |
"tokens": 889, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 7, | |
"duplicatedTokens": 81, | |
"percentage": 6.48, | |
"percentageTokens": 9.11, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Registration/OnboardingProfileCreationViewController.swift": { | |
"lines": 470, | |
"tokens": 3920, | |
"sources": 1, | |
"clones": 2, | |
"duplicatedLines": 49, | |
"duplicatedTokens": 311, | |
"percentage": 10.43, | |
"percentageTokens": 7.93, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Registration/OnboardingPinAttemptsExhaustedViewController.swift": { | |
"lines": 105, | |
"tokens": 768, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Registration/OnboardingPhoneNumberViewController.swift": { | |
"lines": 672, | |
"tokens": 5494, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Registration/OnboardingPhoneNumberDiscoverabilityViewController.swift": { | |
"lines": 213, | |
"tokens": 1673, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Registration/OnboardingPermissionsViewController.swift": { | |
"lines": 113, | |
"tokens": 841, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Registration/OnboardingModeSwitchConfirmationViewController.swift": { | |
"lines": 93, | |
"tokens": 702, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Registration/OnboardingCaptchaViewController.swift": { | |
"lines": 206, | |
"tokens": 1672, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Registration/OnboardingBaseViewController.swift": { | |
"lines": 162, | |
"tokens": 1308, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Registration/Onboarding2FAViewController.swift": { | |
"lines": 487, | |
"tokens": 3650, | |
"sources": 1, | |
"clones": 4, | |
"duplicatedLines": 39, | |
"duplicatedTokens": 355, | |
"percentage": 8.01, | |
"percentageTokens": 9.73, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Registration/BackupRestoreViewController.swift": { | |
"lines": 164, | |
"tokens": 1147, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/RecipientPicker/RecipientPickerDelegate.swift": { | |
"lines": 225, | |
"tokens": 1760, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/RecipientPicker/ComposeViewController.swift": { | |
"lines": 144, | |
"tokens": 1132, | |
"sources": 1, | |
"clones": 4, | |
"duplicatedLines": 59, | |
"duplicatedTokens": 456, | |
"percentage": 40.97, | |
"percentageTokens": 40.28, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/RecipientPicker/AddToBlockListViewController.swift": { | |
"lines": 133, | |
"tokens": 985, | |
"sources": 1, | |
"clones": 4, | |
"duplicatedLines": 59, | |
"duplicatedTokens": 456, | |
"percentage": 44.36, | |
"percentageTokens": 46.29, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Photos/SendMediaNavigationController.swift": { | |
"lines": 888, | |
"tokens": 7319, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Photos/SendMediaBottomButton.swift": { | |
"lines": 84, | |
"tokens": 625, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Photos/PhotoLibrary.swift": { | |
"lines": 382, | |
"tokens": 3294, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Photos/PhotoCollectionPickerController.swift": { | |
"lines": 132, | |
"tokens": 1032, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Photos/PhotoCaptureDismiss.swift": { | |
"lines": 109, | |
"tokens": 818, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Photos/ImagePickerController.swift": { | |
"lines": 656, | |
"tokens": 5007, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Photos/AvatarViewController.swift": { | |
"lines": 133, | |
"tokens": 1162, | |
"sources": 1, | |
"clones": 2, | |
"duplicatedLines": 22, | |
"duplicatedTokens": 170, | |
"percentage": 16.54, | |
"percentageTokens": 14.63, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/NewGroupView/NewGroupState.swift": { | |
"lines": 19, | |
"tokens": 118, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/NewGroupView/NewGroupMembersViewController.swift": { | |
"lines": 124, | |
"tokens": 785, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/NewGroupView/NewGroupMembersBar.swift": { | |
"lines": 428, | |
"tokens": 3394, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/NewGroupView/NewGroupConfirmViewController.swift": { | |
"lines": 557, | |
"tokens": 4346, | |
"sources": 1, | |
"clones": 3, | |
"duplicatedLines": 46, | |
"duplicatedTokens": 349, | |
"percentage": 8.26, | |
"percentageTokens": 8.03, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/NewGroupView/BaseGroupMemberViewController.swift": { | |
"lines": 626, | |
"tokens": 4782, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/MediaGallery/MediaTileViewController.swift": { | |
"lines": 848, | |
"tokens": 6884, | |
"sources": 1, | |
"clones": 4, | |
"duplicatedLines": 48, | |
"duplicatedTokens": 374, | |
"percentage": 5.66, | |
"percentageTokens": 5.43, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/MediaGallery/MediaPageViewController.swift": { | |
"lines": 930, | |
"tokens": 7323, | |
"sources": 1, | |
"clones": 2, | |
"duplicatedLines": 25, | |
"duplicatedTokens": 222, | |
"percentage": 2.69, | |
"percentageTokens": 3.03, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/HomeView/ConversationSplitViewController.swift": { | |
"lines": 632, | |
"tokens": 4585, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/HomeView/ConversationSearchViewController.swift": { | |
"lines": 497, | |
"tokens": 3605, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/GifPicker/GifPickerViewController.swift": { | |
"lines": 663, | |
"tokens": 5245, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/GifPicker/GifPickerLayout.swift": { | |
"lines": 138, | |
"tokens": 1179, | |
"sources": 1, | |
"clones": 2, | |
"duplicatedLines": 48, | |
"duplicatedTokens": 313, | |
"percentage": 34.78, | |
"percentageTokens": 26.55, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/GifPicker/GifPickerCell.swift": { | |
"lines": 280, | |
"tokens": 1990, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Device Transfer/DeviceTransferQRScanningViewController.swift": { | |
"lines": 236, | |
"tokens": 1864, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Device Transfer/DeviceTransferProgressViewController.swift": { | |
"lines": 107, | |
"tokens": 718, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 22, | |
"duplicatedTokens": 137, | |
"percentage": 20.56, | |
"percentageTokens": 19.08, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Device Transfer/DeviceTransferNavigationController.swift": { | |
"lines": 130, | |
"tokens": 1042, | |
"sources": 1, | |
"clones": 4, | |
"duplicatedLines": 50, | |
"duplicatedTokens": 432, | |
"percentage": 38.46, | |
"percentageTokens": 41.46, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Device Transfer/DeviceTransferInitialViewController.swift": { | |
"lines": 58, | |
"tokens": 448, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/DebugUI/LogViewController.swift": { | |
"lines": 145, | |
"tokens": 1154, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/DebugUI/DebugUIStress.swift": { | |
"lines": 355, | |
"tokens": 3221, | |
"sources": 1, | |
"clones": 2, | |
"duplicatedLines": 30, | |
"duplicatedTokens": 266, | |
"percentage": 8.45, | |
"percentageTokens": 8.26, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/DebugUI/DebugUIProfile.swift": { | |
"lines": 74, | |
"tokens": 578, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/DebugUI/DebugUINotifications.swift": { | |
"lines": 233, | |
"tokens": 1914, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/DebugUI/DebugUIMessages+OWS.swift": { | |
"lines": 76, | |
"tokens": 648, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/DebugUI/DebugUIFileBrowser.swift": { | |
"lines": 371, | |
"tokens": 3438, | |
"sources": 1, | |
"clones": 4, | |
"duplicatedLines": 38, | |
"duplicatedTokens": 460, | |
"percentage": 10.24, | |
"percentageTokens": 13.38, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/DebugUI/DebugUIDataStoreViewController.swift": { | |
"lines": 100, | |
"tokens": 849, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/DebugUI/DebugUICalling.swift": { | |
"lines": 74, | |
"tokens": 611, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/DebugUI/DebugContactsUtils.swift": { | |
"lines": 38, | |
"tokens": 303, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/UnreadIndicatorInteraction.swift": { | |
"lines": 45, | |
"tokens": 308, | |
"sources": 1, | |
"clones": 3, | |
"duplicatedLines": 48, | |
"duplicatedTokens": 357, | |
"percentage": 106.67, | |
"percentageTokens": 115.91, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/TypingIndicatorInteraction.swift": { | |
"lines": 48, | |
"tokens": 332, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 15, | |
"duplicatedTokens": 105, | |
"percentage": 31.25, | |
"percentageTokens": 31.63, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/ThreadDetailsInteraction.swift": { | |
"lines": 44, | |
"tokens": 295, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 15, | |
"duplicatedTokens": 117, | |
"percentage": 34.09, | |
"percentageTokens": 39.66, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/MessageSelectionView.swift": { | |
"lines": 58, | |
"tokens": 428, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/MessageRequestView.swift": { | |
"lines": 378, | |
"tokens": 2859, | |
"sources": 1, | |
"clones": 4, | |
"duplicatedLines": 56, | |
"duplicatedTokens": 594, | |
"percentage": 14.81, | |
"percentageTokens": 20.78, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/MemberRequestView.swift": { | |
"lines": 131, | |
"tokens": 974, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 33, | |
"duplicatedTokens": 236, | |
"percentage": 25.19, | |
"percentageTokens": 24.23, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/InteractionReactionState.swift": { | |
"lines": 57, | |
"tokens": 518, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/DateHeaderInteraction.swift": { | |
"lines": 44, | |
"tokens": 295, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 18, | |
"duplicatedTokens": 135, | |
"percentage": 40.91, | |
"percentageTokens": 45.76, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/ConversationViewLayout.swift": { | |
"lines": 461, | |
"tokens": 3350, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/ConversationViewController+Wallpaper.swift": { | |
"lines": 46, | |
"tokens": 319, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/ConversationViewController+Selection.swift": { | |
"lines": 391, | |
"tokens": 3166, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/ConversationViewController+Scroll.swift": { | |
"lines": 802, | |
"tokens": 5822, | |
"sources": 1, | |
"clones": 2, | |
"duplicatedLines": 22, | |
"duplicatedTokens": 196, | |
"percentage": 2.74, | |
"percentageTokens": 3.37, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/ConversationViewController+OWS.swift": { | |
"lines": 500, | |
"tokens": 3430, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 48, | |
"duplicatedTokens": 318, | |
"percentage": 9.6, | |
"percentageTokens": 9.27, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/ConversationViewController+MessageRequest.swift": { | |
"lines": 320, | |
"tokens": 2552, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/ConversationViewController+MessageActionsDelegate.swift": { | |
"lines": 110, | |
"tokens": 797, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/ConversationViewController+Mentions.swift": { | |
"lines": 32, | |
"tokens": 292, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/ConversationViewController+LastVisibleSortId.swift": { | |
"lines": 178, | |
"tokens": 1375, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/ConversationViewController+GestureRecognizers.swift": { | |
"lines": 345, | |
"tokens": 2483, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/ConversationViewController+CVC.swift": { | |
"lines": 742, | |
"tokens": 4674, | |
"sources": 1, | |
"clones": 2, | |
"duplicatedLines": 36, | |
"duplicatedTokens": 194, | |
"percentage": 4.85, | |
"percentageTokens": 4.15, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/ConversationViewController+BottomBar.swift": { | |
"lines": 349, | |
"tokens": 2040, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/ConversationViewController+Banners.swift": { | |
"lines": 534, | |
"tokens": 4813, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/ConversationInputTextView.swift": { | |
"lines": 235, | |
"tokens": 1739, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/ConversationHeaderView.swift": { | |
"lines": 158, | |
"tokens": 1162, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/CVViewState.swift": { | |
"lines": 571, | |
"tokens": 3821, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ConversationView/BlockingGroupMigrationView.swift": { | |
"lines": 122, | |
"tokens": 921, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 33, | |
"duplicatedTokens": 236, | |
"percentage": 27.05, | |
"percentageTokens": 25.62, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Attachment Keyboard/RecentPhotoCollectionView.swift": { | |
"lines": 352, | |
"tokens": 2906, | |
"sources": 1, | |
"clones": 2, | |
"duplicatedLines": 27, | |
"duplicatedTokens": 211, | |
"percentage": 7.67, | |
"percentageTokens": 7.26, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Attachment Keyboard/AttachmentKeyboard.swift": { | |
"lines": 317, | |
"tokens": 2278, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/Attachment Keyboard/AttachmentFormatPickerView.swift": { | |
"lines": 204, | |
"tokens": 1572, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 15, | |
"duplicatedTokens": 109, | |
"percentage": 7.35, | |
"percentageTokens": 6.93, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/ThemeSettingsTableViewController.swift": { | |
"lines": 70, | |
"tokens": 516, | |
"sources": 1, | |
"clones": 2, | |
"duplicatedLines": 23, | |
"duplicatedTokens": 192, | |
"percentage": 32.86, | |
"percentageTokens": 37.21, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/TestingViewController.swift": { | |
"lines": 200, | |
"tokens": 1593, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/PhoneNumberSharingSettingsTableViewController.swift": { | |
"lines": 86, | |
"tokens": 599, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/PhoneNumberDiscoverabilitySettingsTableViewController.swift": { | |
"lines": 82, | |
"tokens": 576, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/NetworkInterfacePreferenceViewController.swift": { | |
"lines": 57, | |
"tokens": 474, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/MediaDownloadSettingsViewController.swift": { | |
"lines": 82, | |
"tokens": 618, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/LinkedDevicesTableViewController.swift": { | |
"lines": 374, | |
"tokens": 2584, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/InternalSettingsViewController.swift": { | |
"lines": 155, | |
"tokens": 1455, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/HelpViewController.swift": { | |
"lines": 110, | |
"tokens": 979, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/FlagsViewController.swift": { | |
"lines": 36, | |
"tokens": 317, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/DataSettingsTableViewController.swift": { | |
"lines": 136, | |
"tokens": 1031, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/ContactSupportViewController.swift": { | |
"lines": 319, | |
"tokens": 2609, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/ComposeSupportEmailOperation.swift": { | |
"lines": 243, | |
"tokens": 1871, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/ChatsSettingsViewController.swift": { | |
"lines": 140, | |
"tokens": 1019, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/AppearanceSettingsTableViewController.swift": { | |
"lines": 82, | |
"tokens": 649, | |
"sources": 1, | |
"clones": 2, | |
"duplicatedLines": 23, | |
"duplicatedTokens": 192, | |
"percentage": 28.05, | |
"percentageTokens": 29.58, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/AppSettingsViewController.swift": { | |
"lines": 268, | |
"tokens": 2507, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 9, | |
"duplicatedTokens": 94, | |
"percentage": 3.36, | |
"percentageTokens": 3.75, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/AdvancedPinSettingsTableViewController.swift": { | |
"lines": 49, | |
"tokens": 431, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AppSettings/AccountSettingsViewController.swift": { | |
"lines": 329, | |
"tokens": 2564, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Experience Upgrades/Upgrade Views/SharingSuggestionsMegaphone.swift": { | |
"lines": 37, | |
"tokens": 294, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Experience Upgrades/Upgrade Views/ResearchMegaphone.swift": { | |
"lines": 153, | |
"tokens": 1233, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Experience Upgrades/Upgrade Views/PinReminderMegaphone.swift": { | |
"lines": 49, | |
"tokens": 407, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Experience Upgrades/Upgrade Views/NotificationPermissionReminderMegaphone.swift": { | |
"lines": 210, | |
"tokens": 1730, | |
"sources": 1, | |
"clones": 4, | |
"duplicatedLines": 51, | |
"duplicatedTokens": 454, | |
"percentage": 24.29, | |
"percentageTokens": 26.24, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Experience Upgrades/Upgrade Views/LinkPreviewsMegaphone.swift": { | |
"lines": 37, | |
"tokens": 300, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Experience Upgrades/Upgrade Views/IntroducingPINs.swift": { | |
"lines": 241, | |
"tokens": 2109, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 14, | |
"duplicatedTokens": 107, | |
"percentage": 5.81, | |
"percentageTokens": 5.07, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Experience Upgrades/Upgrade Views/GroupsV2AndMentionsSplash.swift": { | |
"lines": 170, | |
"tokens": 1456, | |
"sources": 1, | |
"clones": 2, | |
"duplicatedLines": 30, | |
"duplicatedTokens": 233, | |
"percentage": 17.65, | |
"percentageTokens": 16, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Experience Upgrades/Upgrade Views/GroupCallsMegaphone.swift": { | |
"lines": 20, | |
"tokens": 138, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Experience Upgrades/Upgrade Views/ContactPermissionReminderMegaphone.swift": { | |
"lines": 71, | |
"tokens": 508, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 14, | |
"duplicatedTokens": 124, | |
"percentage": 19.72, | |
"percentageTokens": 24.41, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/UserInterface/LocalVideoView.swift": { | |
"lines": 112, | |
"tokens": 727, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/UserInterface/CallHeader.swift": { | |
"lines": 320, | |
"tokens": 2670, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/UserInterface/CallControls.swift": { | |
"lines": 286, | |
"tokens": 2441, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/UserInterface/CallButton.swift": { | |
"lines": 145, | |
"tokens": 1361, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/Signaling/WebRTCCallMessageHandler.swift": { | |
"lines": 171, | |
"tokens": 1215, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/Signaling/TurnServerInfo.swift": { | |
"lines": 27, | |
"tokens": 194, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/Individual/OutboundIndividualCallInitiator.swift": { | |
"lines": 96, | |
"tokens": 596, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/Individual/IndividualCall.swift": { | |
"lines": 221, | |
"tokens": 1438, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/Group/GroupCallUpdateMessageHandler.swift": { | |
"lines": 80, | |
"tokens": 763, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/Group/GroupCallRemoteVideoManager.swift": { | |
"lines": 172, | |
"tokens": 1572, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"views/VoiceNoteLock.swift": { | |
"lines": 75, | |
"tokens": 657, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"views/TypingIndicatorView.swift": { | |
"lines": 209, | |
"tokens": 1689, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 10, | |
"duplicatedTokens": 79, | |
"percentage": 4.78, | |
"percentageTokens": 4.68, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"views/TransferProgressView.swift": { | |
"lines": 108, | |
"tokens": 873, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"views/SupportRequestTextView.swift": { | |
"lines": 145, | |
"tokens": 979, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"views/ReminderView.swift": { | |
"lines": 115, | |
"tokens": 891, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 10, | |
"duplicatedTokens": 79, | |
"percentage": 8.7, | |
"percentageTokens": 8.87, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"views/QuotedReplyPreview.swift": { | |
"lines": 95, | |
"tokens": 669, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"views/QRCodeView.swift": { | |
"lines": 137, | |
"tokens": 1047, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"views/PhotoGridViewCell.swift": { | |
"lines": 191, | |
"tokens": 1496, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 12, | |
"duplicatedTokens": 102, | |
"percentage": 6.28, | |
"percentageTokens": 6.82, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"views/NeverClearView.swift": { | |
"lines": 8, | |
"tokens": 61, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"views/NameCollisionReviewCell.swift": { | |
"lines": 299, | |
"tokens": 2646, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"views/MockConversationView.swift": { | |
"lines": 390, | |
"tokens": 2834, | |
"sources": 1, | |
"clones": 4, | |
"duplicatedLines": 154, | |
"duplicatedTokens": 976, | |
"percentage": 39.49, | |
"percentageTokens": 34.44, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"views/LottieToggleButton.swift": { | |
"lines": 67, | |
"tokens": 481, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"views/JoinGroupCallPill.swift": { | |
"lines": 100, | |
"tokens": 786, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"views/GroupTableViewCell.swift": { | |
"lines": 73, | |
"tokens": 608, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"views/GetStartedBannerCell.swift": { | |
"lines": 143, | |
"tokens": 1163, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"views/ExpirationNagView.swift": { | |
"lines": 22, | |
"tokens": 228, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"views/EmojiMoodPickerView.swift": { | |
"lines": 126, | |
"tokens": 1038, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"views/DismissableTextField.swift": { | |
"lines": 61, | |
"tokens": 449, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"views/ContactCell.swift": { | |
"lines": 170, | |
"tokens": 1530, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"views/CircularProgressView.swift": { | |
"lines": 104, | |
"tokens": 918, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"views/CaptionView.swift": { | |
"lines": 171, | |
"tokens": 1191, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"views/AvatarTableViewCell.swift": { | |
"lines": 67, | |
"tokens": 513, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"views/AnimatedProgressView.swift": { | |
"lines": 178, | |
"tokens": 1325, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"util/VolumeButtons.swift": { | |
"lines": 242, | |
"tokens": 1787, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"util/TextFieldHelper.swift": { | |
"lines": 102, | |
"tokens": 662, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"util/OWSCellAccessibilityCustomAction.swift": { | |
"lines": 21, | |
"tokens": 158, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"util/OWSAnalytics.swift": { | |
"lines": 17, | |
"tokens": 242, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"util/Dependencies+MainApp.swift": { | |
"lines": 109, | |
"tokens": 603, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"util/ContactSupportAlert.swift": { | |
"lines": 113, | |
"tokens": 1247, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"util/AppUpdateNag.swift": { | |
"lines": 258, | |
"tokens": 1899, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"network/GiphyDownloader.swift": { | |
"lines": 10, | |
"tokens": 49, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"network/GiphyAPI.swift": { | |
"lines": 493, | |
"tokens": 3942, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"environment/SignalApp.swift": { | |
"lines": 31, | |
"tokens": 229, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"environment/PushRegistrationManager.swift": { | |
"lines": 277, | |
"tokens": 1930, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"environment/AppEnvironment.swift": { | |
"lines": 88, | |
"tokens": 526, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ViewOnceMessageViewController.swift": { | |
"lines": 445, | |
"tokens": 3136, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/SendMessageFlow.swift": { | |
"lines": 649, | |
"tokens": 4998, | |
"sources": 1, | |
"clones": 4, | |
"duplicatedLines": 80, | |
"duplicatedTokens": 612, | |
"percentage": 12.33, | |
"percentageTokens": 12.24, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/SafetyNumberConfirmationSheet.swift": { | |
"lines": 587, | |
"tokens": 5093, | |
"sources": 1, | |
"clones": 3, | |
"duplicatedLines": 82, | |
"duplicatedTokens": 749, | |
"percentage": 13.97, | |
"percentageTokens": 14.71, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/OWSPinSetupViewController.swift": { | |
"lines": 760, | |
"tokens": 6217, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 11, | |
"duplicatedTokens": 113, | |
"percentage": 1.45, | |
"percentageTokens": 1.82, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/OWSPinReminderViewController.swift": { | |
"lines": 370, | |
"tokens": 3120, | |
"sources": 1, | |
"clones": 12, | |
"duplicatedLines": 260, | |
"duplicatedTokens": 2205, | |
"percentage": 70.27, | |
"percentageTokens": 70.67, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/OWSPinConfirmationViewController.swift": { | |
"lines": 338, | |
"tokens": 2789, | |
"sources": 1, | |
"clones": 9, | |
"duplicatedLines": 225, | |
"duplicatedTokens": 1893, | |
"percentage": 66.57, | |
"percentageTokens": 67.87, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/OWSImagePickerController.swift": { | |
"lines": 9, | |
"tokens": 47, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/MessageReactionPicker.swift": { | |
"lines": 198, | |
"tokens": 1970, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/MessageDetailViewController.swift": { | |
"lines": 958, | |
"tokens": 7134, | |
"sources": 1, | |
"clones": 4, | |
"duplicatedLines": 182, | |
"duplicatedTokens": 1201, | |
"percentage": 19, | |
"percentageTokens": 16.83, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/MessageActionsViewController.swift": { | |
"lines": 497, | |
"tokens": 4025, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/LongTextViewController.swift": { | |
"lines": 216, | |
"tokens": 1524, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 13, | |
"duplicatedTokens": 109, | |
"percentage": 6.02, | |
"percentageTokens": 7.15, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/LocationPicker.swift": { | |
"lines": 532, | |
"tokens": 4630, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/LoadingViewController.swift": { | |
"lines": 163, | |
"tokens": 1182, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/InviteFlow.swift": { | |
"lines": 328, | |
"tokens": 2918, | |
"sources": 1, | |
"clones": 2, | |
"duplicatedLines": 16, | |
"duplicatedTokens": 214, | |
"percentage": 4.88, | |
"percentageTokens": 7.33, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/GroupMigrationActionSheet.swift": { | |
"lines": 692, | |
"tokens": 5533, | |
"sources": 1, | |
"clones": 2, | |
"duplicatedLines": 30, | |
"duplicatedTokens": 260, | |
"percentage": 4.34, | |
"percentageTokens": 4.7, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/GroupLinkPromotionActionSheet.swift": { | |
"lines": 224, | |
"tokens": 1656, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 14, | |
"duplicatedTokens": 115, | |
"percentage": 6.25, | |
"percentageTokens": 6.94, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/GroupInviteLinksUI.swift": { | |
"lines": 389, | |
"tokens": 3172, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/GetStartedBannerViewController.swift": { | |
"lines": 339, | |
"tokens": 2814, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ForwardMessageNavigationController.swift": { | |
"lines": 509, | |
"tokens": 3960, | |
"sources": 1, | |
"clones": 4, | |
"duplicatedLines": 80, | |
"duplicatedTokens": 612, | |
"percentage": 15.72, | |
"percentageTokens": 15.45, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/CropScaleImageViewController.swift": { | |
"lines": 509, | |
"tokens": 4321, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ContactsPicker.swift": { | |
"lines": 383, | |
"tokens": 3269, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 8, | |
"duplicatedTokens": 75, | |
"percentage": 2.09, | |
"percentageTokens": 2.29, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ContactViewController.swift": { | |
"lines": 658, | |
"tokens": 5712, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ContactShareViewHelper.swift": { | |
"lines": 214, | |
"tokens": 1629, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ColorPickerViewController.swift": { | |
"lines": 239, | |
"tokens": 1824, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/CameraFirstNavigationController.swift": { | |
"lines": 116, | |
"tokens": 894, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/AddContactShareToExistingContactViewController.swift": { | |
"lines": 141, | |
"tokens": 980, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ViewControllers/ActionSheetContentBuilder.swift": { | |
"lines": 51, | |
"tokens": 434, | |
"sources": 1, | |
"clones": 1, | |
"duplicatedLines": 16, | |
"duplicatedTokens": 145, | |
"percentage": 31.37, | |
"percentageTokens": 33.41, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"UserInterface/OWSLayerView.swift": { | |
"lines": 45, | |
"tokens": 274, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Models/ThreadMapping.swift": { | |
"lines": 696, | |
"tokens": 5822, | |
"sources": 1, | |
"clones": 6, | |
"duplicatedLines": 74, | |
"duplicatedTokens": 802, | |
"percentage": 10.63, | |
"percentageTokens": 13.78, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Models/PhoneNumberValidator.swift": { | |
"lines": 42, | |
"tokens": 342, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Models/MessageActions.swift": { | |
"lines": 173, | |
"tokens": 1729, | |
"sources": 1, | |
"clones": 8, | |
"duplicatedLines": 106, | |
"duplicatedTokens": 962, | |
"percentage": 61.27, | |
"percentageTokens": 55.64, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Models/CompareSafetyNumbersActivity.swift": { | |
"lines": 104, | |
"tokens": 880, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Models/AccountManager.swift": { | |
"lines": 499, | |
"tokens": 3975, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Jobs/SyncPushTokensJob.swift": { | |
"lines": 114, | |
"tokens": 969, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Jobs/SessionResetJob.swift": { | |
"lines": 175, | |
"tokens": 1304, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Jobs/ConversationConfigurationSyncOperation.swift": { | |
"lines": 101, | |
"tokens": 736, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Experience Upgrades/SplashViewController.swift": { | |
"lines": 95, | |
"tokens": 668, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Experience Upgrades/MegaphoneView.swift": { | |
"lines": 354, | |
"tokens": 3017, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Experience Upgrades/ExperienceUpgradeManager.swift": { | |
"lines": 242, | |
"tokens": 1929, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/SignalCall.swift": { | |
"lines": 317, | |
"tokens": 2677, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/CallAudioService.swift": { | |
"lines": 603, | |
"tokens": 4419, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"Calls/AudioSource.swift": { | |
"lines": 79, | |
"tokens": 550, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"UserNotificationActionHandler.swift": { | |
"lines": 72, | |
"tokens": 614, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"UIStoryboard+OWS.swift": { | |
"lines": 11, | |
"tokens": 77, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"UIResponder+OWS.swift": { | |
"lines": 14, | |
"tokens": 115, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"UIApplication+OWS.swift": { | |
"lines": 30, | |
"tokens": 251, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"NotificationActionHandler.swift": { | |
"lines": 216, | |
"tokens": 2176, | |
"sources": 1, | |
"clones": 6, | |
"duplicatedLines": 54, | |
"duplicatedTokens": 652, | |
"percentage": 25, | |
"percentageTokens": 29.96, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
}, | |
"ConversationSearch.swift": { | |
"lines": 340, | |
"tokens": 2668, | |
"sources": 1, | |
"clones": 0, | |
"duplicatedLines": 0, | |
"duplicatedTokens": 0, | |
"percentage": 0, | |
"percentageTokens": 0, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
} | |
}, | |
"total": { | |
"lines": 81131, | |
"tokens": 637041, | |
"sources": 322, | |
"clones": 134, | |
"duplicatedLines": 2428, | |
"duplicatedTokens": 19817, | |
"percentage": 2.99, | |
"percentageTokens": 3.11, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
} | |
} | |
}, | |
"total": { | |
"lines": 81131, | |
"tokens": 637041, | |
"sources": 322, | |
"clones": 134, | |
"duplicatedLines": 2428, | |
"duplicatedTokens": 19817, | |
"percentage": 2.99, | |
"percentageTokens": 3.11, | |
"newDuplicatedLines": 0, | |
"newClones": 0 | |
} | |
}, | |
"duplicates": [ | |
{ | |
"format": "swift", | |
"lines": 26, | |
"fragment": "super.init(itemModel: itemModel)\n }\n\n public func configure(cellView: UIView,\n cellMeasurement: CVCellMeasurement,\n componentDelegate: CVComponentDelegate,\n cellSelection: CVCellSelection,\n swipeToReplyState: CVSwipeToReplyState,\n componentView: CVComponentView) {\n\n configureForRendering(componentView: componentView,\n cellMeasurement: cellMeasurement,\n componentDelegate: componentDelegate)\n\n let rootView = componentView.rootView\n if rootView.superview == nil {\n owsAssertDebug(cellView.layoutMargins == .zero)\n owsAssertDebug(cellView.subviews.isEmpty)\n\n cellView.addSubview(rootView)\n rootView.autoPinEdgesToSuperviewMargins()\n }\n }\n\n public func buildComponentView(componentDelegate: CVComponentDelegate) -> CVComponentView {\n CVComponentViewTypingIndicator", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/CV/CVComponents/CVComponentTypingIndicator.swift", | |
"start": 22, | |
"end": 47, | |
"startLoc": { | |
"line": 22, | |
"column": 9, | |
"position": 108 | |
}, | |
"endLoc": { | |
"line": 47, | |
"column": 31, | |
"position": 288 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/CV/CVComponents/CVComponentUnreadIndicator.swift", | |
"start": 17, | |
"end": 42, | |
"startLoc": { | |
"line": 17, | |
"column": 9, | |
"position": 76 | |
}, | |
"endLoc": { | |
"line": 42, | |
"column": 31, | |
"position": 256 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 21, | |
"fragment": "super.init(itemModel: itemModel)\n }\n\n public func configure(cellView: UIView,\n cellMeasurement: CVCellMeasurement,\n componentDelegate: CVComponentDelegate,\n cellSelection: CVCellSelection,\n swipeToReplyState: CVSwipeToReplyState,\n componentView: CVComponentView) {\n\n configureForRendering(componentView: componentView,\n cellMeasurement: cellMeasurement,\n componentDelegate: componentDelegate)\n\n let rootView = componentView.rootView\n if rootView.superview == nil {\n owsAssertDebug(cellView.layoutMargins == .zero)\n owsAssertDebug(cellView.subviews.isEmpty)\n\n cellView.addSubview(rootView)\n cellView", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/CV/CVComponents/CVComponentSystemMessage.swift", | |
"start": 24, | |
"end": 44, | |
"startLoc": { | |
"line": 24, | |
"column": 9, | |
"position": 136 | |
}, | |
"endLoc": { | |
"line": 44, | |
"column": 9, | |
"position": 282 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/CV/CVComponents/CVComponentUnreadIndicator.swift", | |
"start": 17, | |
"end": 37, | |
"startLoc": { | |
"line": 17, | |
"column": 9, | |
"position": 76 | |
}, | |
"endLoc": { | |
"line": 37, | |
"column": 9, | |
"position": 222 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 28, | |
"fragment": "super.init(itemModel: itemModel)\n }\n\n public func configure(cellView: UIView,\n cellMeasurement: CVCellMeasurement,\n componentDelegate: CVComponentDelegate,\n cellSelection: CVCellSelection,\n swipeToReplyState: CVSwipeToReplyState,\n componentView: CVComponentView) {\n\n configureForRendering(componentView: componentView,\n cellMeasurement: cellMeasurement,\n componentDelegate: componentDelegate)\n\n let rootView = componentView.rootView\n if rootView.superview == nil {\n owsAssertDebug(cellView.layoutMargins == .zero)\n owsAssertDebug(cellView.subviews.isEmpty)\n\n cellView.addSubview(rootView)\n cellView.layoutMargins = cellLayoutMargins\n rootView.autoPinEdgesToSuperviewMargins()\n }\n }\n\n private var cellLayoutMargins: UIEdgeInsets {\n UIEdgeInsets(top: 0,\n leading: conversationStyle.headerGutterLeading", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/CV/CVComponents/CVComponentDateHeader.swift", | |
"start": 24, | |
"end": 51, | |
"startLoc": { | |
"line": 24, | |
"column": 9, | |
"position": 124 | |
}, | |
"endLoc": { | |
"line": 51, | |
"column": 20, | |
"position": 319 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/CV/CVComponents/CVComponentUnreadIndicator.swift", | |
"start": 17, | |
"end": 51, | |
"startLoc": { | |
"line": 17, | |
"column": 9, | |
"position": 76 | |
}, | |
"endLoc": { | |
"line": 51, | |
"column": 23, | |
"position": 331 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 11, | |
"fragment": ")\n\n let leadingSpacer = UIView.hStretchingSpacer()\n let trailingSpacer = UIView.hStretchingSpacer()\n\n hStackView.addArrangedSubview(leadingSpacer)\n hStackView.addArrangedSubview(contentView)\n hStackView.addArrangedSubview(trailingSpacer)\n\n leadingSpacer.autoMatch(.width, to: .width, of: trailingSpacer)\n }", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/CV/CVComponents/CVComponentDateHeader.swift", | |
"start": 84, | |
"end": 94, | |
"startLoc": { | |
"line": 84, | |
"column": 13, | |
"position": 581 | |
}, | |
"endLoc": { | |
"line": 94, | |
"column": 2, | |
"position": 659 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/CV/CVComponents/CVComponentUnreadIndicator.swift", | |
"start": 66, | |
"end": 77, | |
"startLoc": { | |
"line": 66, | |
"column": 11, | |
"position": 455 | |
}, | |
"endLoc": { | |
"line": 77, | |
"column": 12, | |
"position": 534 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 14, | |
"fragment": "()\n }\n\n private var bodyTextColor: UIColor {\n guard let message = interaction as? TSMessage else {\n return .black\n }\n return conversationStyle.bubbleTextColor(message: message)\n }\n\n public func configureForRendering(componentView componentViewParam: CVComponentView,\n cellMeasurement: CVCellMeasurement,\n componentDelegate: CVComponentDelegate) {\n guard let componentView = componentViewParam as? CVComponentViewBodyMedia", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/CV/CVComponents/CVComponentBodyMedia.swift", | |
"start": 47, | |
"end": 60, | |
"startLoc": { | |
"line": 47, | |
"column": 25, | |
"position": 289 | |
}, | |
"endLoc": { | |
"line": 60, | |
"column": 25, | |
"position": 399 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/CV/CVComponents/CVComponentSenderName.swift", | |
"start": 19, | |
"end": 32, | |
"startLoc": { | |
"line": 19, | |
"column": 26, | |
"position": 104 | |
}, | |
"endLoc": { | |
"line": 32, | |
"column": 26, | |
"position": 214 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 21, | |
"fragment": ": UIViewControllerAnimatedTransitioning {\n func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {\n return kIsDebuggingMediaPresentationAnimations ? 1.5 : 0.15\n }\n\n func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {\n let containerView = transitionContext.containerView\n\n guard let fromVC = transitionContext.viewController(forKey: .from) else {\n owsFailDebug(\"fromVC was unexpectedly nil\")\n transitionContext.completeTransition(false)\n return\n }\n\n let fromContextProvider: MediaPresentationContextProvider\n switch fromVC {\n case let contextProvider as MediaPresentationContextProvider:\n fromContextProvider = contextProvider\n case let navController as UINavigationController:\n guard let contextProvider = navController.topViewController as? MediaPresentationContextProvider else {\n owsFailDebug(\"unexpected context: ", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/MediaGallery/Transitions/MediaDismissAnimationController.swift", | |
"start": 27, | |
"end": 47, | |
"startLoc": { | |
"line": 27, | |
"column": 32, | |
"position": 187 | |
}, | |
"endLoc": { | |
"line": 47, | |
"column": 22, | |
"position": 374 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/MediaGallery/Transitions/MediaZoomAnimationController.swift", | |
"start": 19, | |
"end": 39, | |
"startLoc": { | |
"line": 19, | |
"column": 29, | |
"position": 89 | |
}, | |
"endLoc": { | |
"line": 39, | |
"column": 30, | |
"position": 276 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 17, | |
"fragment": ".topViewController))\")\n transitionContext.completeTransition(false)\n return\n }\n fromContextProvider = contextProvider\n default:\n owsFailDebug(\"unexpected fromVC: \\(fromVC)\")\n transitionContext.completeTransition(false)\n return\n }\n\n guard let fromMediaContext = fromContextProvider.mediaPresentationContext(item: item, in: containerView) else {\n owsFailDebug(\"fromPresentationContext was unexpectedly nil\")\n transitionContext.completeTransition(false)\n return\n }\n self", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/MediaGallery/Transitions/MediaDismissAnimationController.swift", | |
"start": 47, | |
"end": 63, | |
"startLoc": { | |
"line": 47, | |
"column": 15, | |
"position": 381 | |
}, | |
"endLoc": { | |
"line": 63, | |
"column": 5, | |
"position": 488 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/MediaGallery/Transitions/MediaZoomAnimationController.swift", | |
"start": 46, | |
"end": 63, | |
"startLoc": { | |
"line": 46, | |
"column": 21, | |
"position": 355 | |
}, | |
"endLoc": { | |
"line": 63, | |
"column": 6, | |
"position": 463 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 13, | |
"fragment": "containerView.addSubview(transitionView)\n transitionView.frame = fromMediaContext.presentationFrame\n\n let fromTransitionalOverlayView: UIView?\n if let (overlayView, overlayViewFrame) = fromContextProvider.snapshotOverlayView(in: containerView) {\n fromTransitionalOverlayView = overlayView\n containerView.addSubview(overlayView)\n overlayView.frame = overlayViewFrame\n } else {\n fromTransitionalOverlayView = nil\n }\n\n assert", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/MediaGallery/Transitions/MediaDismissAnimationController.swift", | |
"start": 132, | |
"end": 144, | |
"startLoc": { | |
"line": 132, | |
"column": 9, | |
"position": 1055 | |
}, | |
"endLoc": { | |
"line": 144, | |
"column": 7, | |
"position": 1152 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/MediaGallery/Transitions/MediaZoomAnimationController.swift", | |
"start": 108, | |
"end": 120, | |
"startLoc": { | |
"line": 108, | |
"column": 9, | |
"position": 813 | |
}, | |
"endLoc": { | |
"line": 120, | |
"column": 4, | |
"position": 910 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 20, | |
"fragment": "super.init(nibName: nil, bundle: nil)\n modalPresentationStyle = .custom\n transitioningDelegate = self\n }\n\n required init?(coder aDecoder: NSCoder) {\n fatalError(\"init(coder:) has not been implemented\")\n }\n\n // MARK: -\n\n override public func loadView() {\n view = UIView()\n view.backgroundColor = .clear\n\n view.addSubview(contentView)\n contentView.autoPinEdge(toSuperviewEdge: .bottom)\n contentView.autoHCenterInSuperview()\n contentView.autoMatch(.height, to: .height, of: view, withOffset: 0, relation: .lessThanOrEqual)\n contentView.backgroundColor = Theme.isDarkThemeEnabled", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/Emoji Picker/EmojiPickerSheet.swift", | |
"start": 20, | |
"end": 39, | |
"startLoc": { | |
"line": 20, | |
"column": 9, | |
"position": 135 | |
}, | |
"endLoc": { | |
"line": 39, | |
"column": 19, | |
"position": 304 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Reactions Details/ReactionsDetailSheet.swift", | |
"start": 34, | |
"end": 53, | |
"startLoc": { | |
"line": 34, | |
"column": 9, | |
"position": 243 | |
}, | |
"endLoc": { | |
"line": 53, | |
"column": 27, | |
"position": 412 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 14, | |
"fragment": ")\n\n let cornerRadius: CGFloat = 16\n let path = UIBezierPath(\n roundedRect: contentView.bounds,\n byRoundingCorners: [.topLeft, .topRight],\n cornerRadii: CGSize(square: cornerRadius)\n )\n let shapeLayer = CAShapeLayer()\n shapeLayer.path = path.cgPath\n contentView.layer.mask = shapeLayer\n }\n\n @objc func didTapBackdrop", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/Emoji Picker/EmojiPickerSheet.swift", | |
"start": 81, | |
"end": 94, | |
"startLoc": { | |
"line": 81, | |
"column": 2, | |
"position": 635 | |
}, | |
"endLoc": { | |
"line": 94, | |
"column": 15, | |
"position": 740 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Reactions Details/ReactionsDetailSheet.swift", | |
"start": 104, | |
"end": 120, | |
"startLoc": { | |
"line": 104, | |
"column": 2, | |
"position": 713 | |
}, | |
"endLoc": { | |
"line": 120, | |
"column": 17, | |
"position": 823 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 24, | |
"fragment": "var minimizedHeight: CGFloat {\n return min(maximizedHeight, 346)\n }\n var maximizedHeight: CGFloat {\n return CurrentAppContext().frame.height - topLayoutGuide.length - 32\n }\n\n let maxAnimationDuration: TimeInterval = 0.2\n var startingHeight: CGFloat?\n var startingTranslation: CGFloat?\n\n func setupInteractiveSizing() {\n heightConstraint = contentView.autoSetDimension(.height, toSize: minimizedHeight)\n\n // Create a pan gesture to handle when the user interacts with the\n // view outside of the collection view.\n let panGestureRecognizer = DirectionalPanGestureRecognizer(direction: .vertical, target: self, action: #selector(handlePan))\n view.addGestureRecognizer(panGestureRecognizer)\n panGestureRecognizer.delegate = self\n\n // We also want to handle the pan gesture for the collection view,\n // so we can do a nice scroll to dismiss gesture, and so we can\n // transfer any initial scrolling into maximizing the view.\n collectionView", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/Emoji Picker/EmojiPickerSheet.swift", | |
"start": 103, | |
"end": 126, | |
"startLoc": { | |
"line": 103, | |
"column": 5, | |
"position": 797 | |
}, | |
"endLoc": { | |
"line": 126, | |
"column": 15, | |
"position": 981 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Reactions Details/ReactionsDetailSheet.swift", | |
"start": 171, | |
"end": 195, | |
"startLoc": { | |
"line": 171, | |
"column": 5, | |
"position": 1257 | |
}, | |
"endLoc": { | |
"line": 195, | |
"column": 19, | |
"position": 1444 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 10, | |
"fragment": "handle.backgroundColor = .ows_whiteAlpha80\n handle.autoSetDimensions(to: CGSize(width: 56, height: 5))\n handle.layer.cornerRadius = 5 / 2\n view.addSubview(handle)\n handle.autoHCenterInSuperview()\n handle.autoPinEdge(.bottom, to: .top, of: contentView, withOffset: -8)\n }\n\n @objc func handlePan(_ sender: UIPanGestureRecognizer) {\n let isCollectionViewPanGesture", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/Emoji Picker/EmojiPickerSheet.swift", | |
"start": 128, | |
"end": 137, | |
"startLoc": { | |
"line": 128, | |
"column": 9, | |
"position": 1002 | |
}, | |
"endLoc": { | |
"line": 137, | |
"column": 27, | |
"position": 1117 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Reactions Details/ReactionsDetailSheet.swift", | |
"start": 197, | |
"end": 206, | |
"startLoc": { | |
"line": 197, | |
"column": 9, | |
"position": 1474 | |
}, | |
"endLoc": { | |
"line": 206, | |
"column": 22, | |
"position": 1589 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 39, | |
"fragment": ".alpha = 1 - (startingHeight - newHeight) / startingHeight\n }\n\n // Update our height to reflect the new position\n heightConstraint?.constant = newHeight\n view.layoutIfNeeded()\n case .ended, .cancelled, .failed:\n guard let startingHeight = startingHeight else { break }\n\n let dismissThreshold = startingHeight * 0.5\n let growThreshold = startingHeight * 1.5\n let velocityThreshold: CGFloat = 500\n\n let currentHeight = contentView.height\n let currentVelocity = sender.velocity(in: view).y\n\n enum CompletionState { case growing, dismissing, cancelling }\n let completionState: CompletionState\n\n if abs(currentVelocity) >= velocityThreshold {\n completionState = currentVelocity < 0 ? .growing : .dismissing\n } else if currentHeight >= growThreshold {\n completionState = .growing\n } else if currentHeight <= dismissThreshold {\n completionState = .dismissing\n } else {\n completionState = .cancelling\n }\n\n let finalHeight: CGFloat\n switch completionState {\n case .dismissing:\n finalHeight = 0\n case .growing:\n finalHeight = maximizedHeight\n case .cancelling:\n finalHeight = startingHeight\n\n if", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/Emoji Picker/EmojiPickerSheet.swift", | |
"start": 166, | |
"end": 204, | |
"startLoc": { | |
"line": 166, | |
"column": 2, | |
"position": 1315 | |
}, | |
"endLoc": { | |
"line": 204, | |
"column": 3, | |
"position": 1652 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Reactions Details/ReactionsDetailSheet.swift", | |
"start": 235, | |
"end": 272, | |
"startLoc": { | |
"line": 235, | |
"column": 13, | |
"position": 1786 | |
}, | |
"endLoc": { | |
"line": 272, | |
"column": 2, | |
"position": 2122 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 19, | |
"fragment": "}\n\n let remainingDistance = finalHeight - currentHeight\n\n // Calculate the time to complete the animation if we want to preserve\n // the user's velocity. If this time is too slow (e.g. the user was scrolling\n // very slowly) we'll default to `maxAnimationDuration`\n let remainingTime = TimeInterval(abs(remainingDistance / currentVelocity))\n\n UIView.animate(withDuration: min(remainingTime, maxAnimationDuration), delay: 0, options: .curveEaseOut, animations: {\n if remainingDistance < 0 {\n self.contentView.frame.origin.y -= remainingDistance\n self.handle.frame.origin.y -= remainingDistance\n } else {\n self.heightConstraint?.constant = finalHeight\n self.view.layoutIfNeeded()\n }\n\n self.backdropView?", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/Emoji Picker/EmojiPickerSheet.swift", | |
"start": 207, | |
"end": 225, | |
"startLoc": { | |
"line": 207, | |
"column": 13, | |
"position": 1678 | |
}, | |
"endLoc": { | |
"line": 225, | |
"column": 2, | |
"position": 1838 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Reactions Details/ReactionsDetailSheet.swift", | |
"start": 272, | |
"end": 290, | |
"startLoc": { | |
"line": 272, | |
"column": 13, | |
"position": 2122 | |
}, | |
"endLoc": { | |
"line": 290, | |
"column": 2, | |
"position": 2282 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 17, | |
"fragment": ".panGestureRecognizer else { return false }\n\n if startingTranslation == nil {\n startingTranslation = sender.translation(in: view).y\n }\n\n if startingHeight == nil {\n startingHeight = contentView.height\n }\n\n return true\n }\n\n func resetInteractiveTransition() {\n startingTranslation = nil\n startingHeight = nil\n collectionView", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/Emoji Picker/EmojiPickerSheet.swift", | |
"start": 253, | |
"end": 269, | |
"startLoc": { | |
"line": 253, | |
"column": 15, | |
"position": 2052 | |
}, | |
"endLoc": { | |
"line": 269, | |
"column": 15, | |
"position": 2155 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Reactions Details/ReactionsDetailSheet.swift", | |
"start": 315, | |
"end": 331, | |
"startLoc": { | |
"line": 315, | |
"column": 24, | |
"position": 2490 | |
}, | |
"endLoc": { | |
"line": 331, | |
"column": 24, | |
"position": 2593 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 16, | |
"fragment": ": UIGestureRecognizerDelegate {\n func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {\n switch gestureRecognizer {\n case is UITapGestureRecognizer:\n let point = gestureRecognizer.location(in: view)\n guard !contentView.frame.contains(point) else { return false }\n return true\n default:\n return true\n }\n }\n\n func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {\n switch gestureRecognizer {\n case is UIPanGestureRecognizer:\n return collectionView", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/Emoji Picker/EmojiPickerSheet.swift", | |
"start": 303, | |
"end": 318, | |
"startLoc": { | |
"line": 303, | |
"column": 17, | |
"position": 2435 | |
}, | |
"endLoc": { | |
"line": 318, | |
"column": 15, | |
"position": 2583 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Reactions Details/ReactionsDetailSheet.swift", | |
"start": 583, | |
"end": 598, | |
"startLoc": { | |
"line": 583, | |
"column": 21, | |
"position": 4539 | |
}, | |
"endLoc": { | |
"line": 598, | |
"column": 24, | |
"position": 4687 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 9, | |
"fragment": "presentedViewController.transitionCoordinator?.animate(alongsideTransition: { _ in\n self.backdropView?.alpha = 1\n }, completion: nil)\n }\n\n override func dismissalTransitionWillBegin() {\n presentedViewController.transitionCoordinator?.animate(alongsideTransition: { _ in\n self.backdropView?.alpha = 0\n }, completion: nil", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/Emoji Picker/EmojiPickerSheet.swift", | |
"start": 335, | |
"end": 343, | |
"startLoc": { | |
"line": 335, | |
"column": 9, | |
"position": 2684 | |
}, | |
"endLoc": { | |
"line": 343, | |
"column": 4, | |
"position": 2773 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Reactions Details/ReactionsDetailSheet.swift", | |
"start": 626, | |
"end": 634, | |
"startLoc": { | |
"line": 626, | |
"column": 9, | |
"position": 4903 | |
}, | |
"endLoc": { | |
"line": 634, | |
"column": 2, | |
"position": 4992 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 14, | |
"fragment": ")\n }\n\n override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {\n super.viewWillTransition(to: size, with: coordinator)\n guard let presentedView = presentedView else { return }\n coordinator.animate(alongsideTransition: { _ in\n presentedView.frame = self.frameOfPresentedViewInContainerView\n presentedView.layoutIfNeeded()\n }, completion: nil)\n }\n}\n\nextension EmojiPickerSheet", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/Emoji Picker/EmojiPickerSheet.swift", | |
"start": 343, | |
"end": 356, | |
"startLoc": { | |
"line": 343, | |
"column": 4, | |
"position": 2774 | |
}, | |
"endLoc": { | |
"line": 356, | |
"column": 17, | |
"position": 2891 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Reactions Details/ReactionsDetailSheet.swift", | |
"start": 636, | |
"end": 649, | |
"startLoc": { | |
"line": 636, | |
"column": 2, | |
"position": 5010 | |
}, | |
"endLoc": { | |
"line": 649, | |
"column": 21, | |
"position": 5127 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 23, | |
"fragment": "()\n\n init(attachmentStream: TSAttachmentStream) {\n self.attachmentStream = attachmentStream\n }\n\n var mediaView: UIView {\n imageView\n }\n\n var isLoaded: Bool {\n imageView.image != nil\n }\n\n var cacheKey: String {\n attachmentStream.uniqueId\n }\n\n func loadMedia() -> Promise<AnyObject> {\n guard attachmentStream.isValidImage else {\n return Promise(error: ReusableMediaError.invalidMedia)\n }\n let", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/Cells/ReusableMediaView.swift", | |
"start": 323, | |
"end": 345, | |
"startLoc": { | |
"line": 323, | |
"column": 12, | |
"position": 1922 | |
}, | |
"endLoc": { | |
"line": 345, | |
"column": 4, | |
"position": 2054 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Cells/ReusableMediaView.swift", | |
"start": 269, | |
"end": 291, | |
"startLoc": { | |
"line": 269, | |
"column": 20, | |
"position": 1560 | |
}, | |
"endLoc": { | |
"line": 291, | |
"column": 6, | |
"position": 1692 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 22, | |
"fragment": "}\n\n func applyMedia(_ media: AnyObject) {\n AssertIsOnMainThread()\n\n guard let image = media as? UIImage else {\n owsFailDebug(\"Media has unexpected type: \\(type(of: media))\")\n return\n }\n imageView.image = image\n }\n\n func unloadMedia() {\n AssertIsOnMainThread()\n\n imageView.image = nil\n }\n}\n\n// MARK: -\n\nclass MediaViewAdapterVideo", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/Cells/ReusableMediaView.swift", | |
"start": 357, | |
"end": 378, | |
"startLoc": { | |
"line": 357, | |
"column": 5, | |
"position": 2164 | |
}, | |
"endLoc": { | |
"line": 378, | |
"column": 22, | |
"position": 2277 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Cells/ReusableMediaView.swift", | |
"start": 244, | |
"end": 265, | |
"startLoc": { | |
"line": 244, | |
"column": 5, | |
"position": 1412 | |
}, | |
"endLoc": { | |
"line": 265, | |
"column": 25, | |
"position": 1525 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 24, | |
"fragment": ": MediaViewAdapterSwift {\n\n public let shouldBeRenderedByYY = false\n let attachmentStream: TSAttachmentStream\n let imageView = UIImageView()\n\n init(attachmentStream: TSAttachmentStream) {\n self.attachmentStream = attachmentStream\n }\n\n var mediaView: UIView {\n imageView\n }\n\n var isLoaded: Bool {\n imageView.image != nil\n }\n\n var cacheKey: String {\n attachmentStream.uniqueId\n }\n\n func loadMedia() -> Promise<AnyObject> {\n guard attachmentStream.isValidVideo", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/Cells/ReusableMediaView.swift", | |
"start": 378, | |
"end": 401, | |
"startLoc": { | |
"line": 378, | |
"column": 22, | |
"position": 2278 | |
}, | |
"endLoc": { | |
"line": 401, | |
"column": 13, | |
"position": 2421 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Cells/ReusableMediaView.swift", | |
"start": 319, | |
"end": 288, | |
"startLoc": { | |
"line": 319, | |
"column": 22, | |
"position": 1888 | |
}, | |
"endLoc": { | |
"line": 288, | |
"column": 13, | |
"position": 1669 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 37, | |
"fragment": "else {\n return Promise(error: ReusableMediaError.invalidMedia)\n }\n let (promise, resolver) = Promise<AnyObject>.pending()\n let possibleThumbnail = attachmentStream.thumbnailImageLarge(success: { (image) in\n resolver.fulfill(image)\n }, failure: {\n resolver.reject(OWSAssertionError(\"Could not load thumbnail\"))\n })\n // TSAttachmentStream's thumbnail methods return a UIImage sync\n // if the thumbnail already exists. Otherwise, the callbacks are invoked async.\n if let thumbnail = possibleThumbnail {\n resolver.fulfill(thumbnail)\n }\n return promise\n }\n\n func applyMedia(_ media: AnyObject) {\n AssertIsOnMainThread()\n\n guard let image = media as? UIImage else {\n owsFailDebug(\"Media has unexpected type: \\(type(of: media))\")\n return\n }\n imageView.image = image\n }\n\n func unloadMedia() {\n AssertIsOnMainThread()\n\n imageView.image = nil\n }\n}\n\n// MARK: -\n\n@objc", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/Cells/ReusableMediaView.swift", | |
"start": 401, | |
"end": 437, | |
"startLoc": { | |
"line": 401, | |
"column": 2, | |
"position": 2423 | |
}, | |
"endLoc": { | |
"line": 437, | |
"column": 6, | |
"position": 2665 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Cells/ReusableMediaView.swift", | |
"start": 342, | |
"end": 265, | |
"startLoc": { | |
"line": 342, | |
"column": 2, | |
"position": 2033 | |
}, | |
"endLoc": { | |
"line": 265, | |
"column": 6, | |
"position": 1523 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 27, | |
"fragment": ")\n\n navigationItem.leftBarButtonItem = UIBarButtonItem(\n barButtonSystemItem: .cancel,\n target: self,\n action: #selector(didTapCancel),\n accessibilityIdentifier: \"cancel_button\"\n )\n\n if hasUnsavedChanges {\n navigationItem.rightBarButtonItem = UIBarButtonItem(\n barButtonSystemItem: .done,\n target: self,\n action: #selector(didTapDone),\n accessibilityIdentifier: \"done_button\"\n )\n } else {\n navigationItem.rightBarButtonItem = nil\n }\n }\n\n public override func viewWillAppear(_ animated: Bool) {\n super.viewWillAppear(animated)\n\n updateNavigation()\n\n firstTextField", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/AppSettings/Profile/ProfileNameViewController.swift", | |
"start": 71, | |
"end": 97, | |
"startLoc": { | |
"line": 71, | |
"column": 35, | |
"position": 470 | |
}, | |
"endLoc": { | |
"line": 97, | |
"column": 15, | |
"position": 629 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/AppSettings/Profile/UsernameViewController.swift", | |
"start": 62, | |
"end": 87, | |
"startLoc": { | |
"line": 62, | |
"column": 35, | |
"position": 384 | |
}, | |
"endLoc": { | |
"line": 87, | |
"column": 2, | |
"position": 542 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 20, | |
"fragment": "}\n\n private func nameCell(textField: UITextField) -> UITableViewCell {\n let cell = OWSTableItem.newCell()\n\n cell.selectionStyle = .none\n\n textField.font = .ows_dynamicTypeBodyClamped\n textField.textColor = Theme.primaryTextColor\n\n cell.addSubview(textField)\n textField.autoPinEdgesToSuperviewMargins()\n\n return cell\n }\n\n @objc\n func didTapCancel() {\n guard hasUnsavedChanges else {\n dismiss", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/AppSettings/Profile/ProfileNameViewController.swift", | |
"start": 164, | |
"end": 183, | |
"startLoc": { | |
"line": 164, | |
"column": 5, | |
"position": 1099 | |
}, | |
"endLoc": { | |
"line": 183, | |
"column": 8, | |
"position": 1216 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/AppSettings/Profile/UsernameViewController.swift", | |
"start": 177, | |
"end": 195, | |
"startLoc": { | |
"line": 177, | |
"column": 5, | |
"position": 1151 | |
}, | |
"endLoc": { | |
"line": 195, | |
"column": 7, | |
"position": 1267 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 20, | |
"fragment": "navigationItem.leftBarButtonItem = UIBarButtonItem(\n barButtonSystemItem: .cancel,\n target: self,\n action: #selector(didTapCancel),\n accessibilityIdentifier: \"cancel_button\"\n )\n\n if hasUnsavedChanges {\n navigationItem.rightBarButtonItem = UIBarButtonItem(\n barButtonSystemItem: .done,\n target: self,\n action: #selector(didTapDone),\n accessibilityIdentifier: \"done_button\"\n )\n } else {\n navigationItem.rightBarButtonItem = nil\n }\n }\n\n func", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/AppSettings/Notifications/NotificationSettingsSoundViewController.swift", | |
"start": 45, | |
"end": 64, | |
"startLoc": { | |
"line": 45, | |
"column": 9, | |
"position": 290 | |
}, | |
"endLoc": { | |
"line": 64, | |
"column": 5, | |
"position": 411 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/AppSettings/Profile/UsernameViewController.swift", | |
"start": 64, | |
"end": 83, | |
"startLoc": { | |
"line": 64, | |
"column": 9, | |
"position": 388 | |
}, | |
"endLoc": { | |
"line": 83, | |
"column": 7, | |
"position": 509 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 24, | |
"fragment": ": CallObserver {\n func groupCallRemoteDeviceStatesChanged(_ call: SignalCall) {\n AssertIsOnMainThread()\n owsAssertDebug(call.isGroupCall)\n\n reloadData()\n }\n\n func groupCallPeekChanged(_ call: SignalCall) {\n AssertIsOnMainThread()\n owsAssertDebug(call.isGroupCall)\n\n reloadData()\n }\n\n func groupCallEnded(_ call: SignalCall, reason: GroupCallEndReason) {\n AssertIsOnMainThread()\n owsAssertDebug(call.isGroupCall)\n\n reloadData()\n }\n}\n\nextension", | |
"tokens": 0, | |
"firstFile": { | |
"name": "Calls/UserInterface/Group/GroupCallVideoGrid.swift", | |
"start": 75, | |
"end": 98, | |
"startLoc": { | |
"line": 75, | |
"column": 19, | |
"position": 629 | |
}, | |
"endLoc": { | |
"line": 98, | |
"column": 10, | |
"position": 757 | |
} | |
}, | |
"secondFile": { | |
"name": "Calls/UserInterface/Group/GroupCallVideoOverflow.swift", | |
"start": 138, | |
"end": 161, | |
"startLoc": { | |
"line": 138, | |
"column": 23, | |
"position": 1125 | |
}, | |
"endLoc": { | |
"line": 161, | |
"column": 6, | |
"position": 1253 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 32, | |
"fragment": ")\n\n override init(frame: CGRect) {\n super.init(frame: frame)\n\n contentView.addSubview(memberView)\n memberView.autoPinEdgesToSuperviewEdges()\n\n contentView.layer.cornerRadius = 10\n contentView.clipsToBounds = true\n }\n\n func configure(call: SignalCall, device: RemoteDeviceState) {\n memberView.configure(call: call, device: device)\n }\n\n required init?(coder: NSCoder) {\n fatalError(\"init(coder:) has not been implemented\")\n }\n\n func cleanupVideoViews() {\n memberView.cleanupVideoViews()\n }\n\n func configureRemoteVideo(device: RemoteDeviceState) {\n memberView.configureRemoteVideo(device: device)\n }\n\n func setMemberViewDelegate(_ delegate: GroupCallMemberViewDelegate?) {\n memberView.delegate = delegate\n }\n}", | |
"tokens": 0, | |
"firstFile": { | |
"name": "Calls/UserInterface/Group/GroupCallVideoGrid.swift", | |
"start": 126, | |
"end": 157, | |
"startLoc": { | |
"line": 126, | |
"column": 10, | |
"position": 987 | |
}, | |
"endLoc": { | |
"line": 157, | |
"column": 2, | |
"position": 1195 | |
} | |
}, | |
"secondFile": { | |
"name": "Calls/UserInterface/Group/GroupCallVideoOverflow.swift", | |
"start": 163, | |
"end": 194, | |
"startLoc": { | |
"line": 163, | |
"column": 14, | |
"position": 1289 | |
}, | |
"endLoc": { | |
"line": 194, | |
"column": 2, | |
"position": 1497 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 14, | |
"fragment": ") }\n\n // MARK: -\n\n override public func loadView() {\n view = UIView()\n view.backgroundColor = .clear\n\n view.addSubview(contentView)\n contentView.autoPinEdge(toSuperviewEdge: .bottom)\n contentView.autoHCenterInSuperview()\n contentView.autoMatch(.height, to: .height, of: view, withOffset: 0, relation: .lessThanOrEqual)\n\n if", | |
"tokens": 0, | |
"firstFile": { | |
"name": "Calls/UserInterface/Group/GroupCallMemberSheet.swift", | |
"start": 30, | |
"end": 43, | |
"startLoc": { | |
"line": 30, | |
"column": 5, | |
"position": 197 | |
}, | |
"endLoc": { | |
"line": 43, | |
"column": 3, | |
"position": 303 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Reactions Details/ReactionsDetailSheet.swift", | |
"start": 40, | |
"end": 53, | |
"startLoc": { | |
"line": 40, | |
"column": 40, | |
"position": 298 | |
}, | |
"endLoc": { | |
"line": 53, | |
"column": 12, | |
"position": 404 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 24, | |
"fragment": ")\n }\n\n public override func viewDidLayoutSubviews() {\n super.viewDidLayoutSubviews()\n\n // Ensure the scrollView's layout has completed\n // as we're about to use its bounds to calculate\n // the masking view and contentOffset.\n contentView.layoutIfNeeded()\n\n let cornerRadius: CGFloat = 16\n let path = UIBezierPath(\n roundedRect: contentView.bounds,\n byRoundingCorners: [.topLeft, .topRight],\n cornerRadii: CGSize(square: cornerRadius)\n )\n let shapeLayer = CAShapeLayer()\n shapeLayer.path = path.cgPath\n contentView.layer.mask = shapeLayer\n }\n\n @objc func didTapBackdrop(_ sender: UITapGestureRecognizer) {\n dismiss", | |
"tokens": 0, | |
"firstFile": { | |
"name": "Calls/UserInterface/Group/GroupCallMemberSheet.swift", | |
"start": 77, | |
"end": 100, | |
"startLoc": { | |
"line": 77, | |
"column": 2, | |
"position": 621 | |
}, | |
"endLoc": { | |
"line": 100, | |
"column": 8, | |
"position": 780 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Reactions Details/ReactionsDetailSheet.swift", | |
"start": 95, | |
"end": 95, | |
"startLoc": { | |
"line": 95, | |
"column": 5, | |
"position": 672 | |
}, | |
"endLoc": { | |
"line": 95, | |
"column": 18, | |
"position": 753 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 31, | |
"fragment": "dismiss(animated: true)\n }\n\n // MARK: - Resize / Interactive Dismiss\n\n var heightConstraint: NSLayoutConstraint?\n let maxWidth: CGFloat = 512\n var minimizedHeight: CGFloat {\n return min(maximizedHeight, 346)\n }\n var maximizedHeight: CGFloat {\n return CurrentAppContext().frame.height - topLayoutGuide.length - 32\n }\n\n let maxAnimationDuration: TimeInterval = 0.2\n var startingHeight: CGFloat?\n var startingTranslation: CGFloat?\n\n func setupInteractiveSizing() {\n heightConstraint = contentView.autoSetDimension(.height, toSize: minimizedHeight)\n\n // Create a pan gesture to handle when the user interacts with the\n // view outside of the collection view.\n let panGestureRecognizer = DirectionalPanGestureRecognizer(direction: .vertical, target: self, action: #selector(handlePan))\n view.addGestureRecognizer(panGestureRecognizer)\n panGestureRecognizer.delegate = self\n\n // We also want to handle the pan gesture for the collection view,\n // so we can do a nice scroll to dismiss gesture, and so we can\n // transfer any initial scrolling into maximizing the view.\n tableView", | |
"tokens": 0, | |
"firstFile": { | |
"name": "Calls/UserInterface/Group/GroupCallMemberSheet.swift", | |
"start": 100, | |
"end": 130, | |
"startLoc": { | |
"line": 100, | |
"column": 9, | |
"position": 780 | |
}, | |
"endLoc": { | |
"line": 130, | |
"column": 10, | |
"position": 1002 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Emoji Picker/EmojiPickerSheet.swift", | |
"start": 96, | |
"end": 195, | |
"startLoc": { | |
"line": 96, | |
"column": 9, | |
"position": 759 | |
}, | |
"endLoc": { | |
"line": 195, | |
"column": 19, | |
"position": 1444 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 12, | |
"fragment": ".panGestureRecognizer.addTarget(self, action: #selector(handlePan))\n\n handle.backgroundColor = .ows_whiteAlpha80\n handle.autoSetDimensions(to: CGSize(width: 56, height: 5))\n handle.layer.cornerRadius = 5 / 2\n view.addSubview(handle)\n handle.autoHCenterInSuperview()\n handle.autoPinEdge(.bottom, to: .top, of: contentView, withOffset: -8)\n }\n\n @objc func handlePan(_ sender: UIPanGestureRecognizer) {\n let isCollectionViewPanGesture = sender == tableView", | |
"tokens": 0, | |
"firstFile": { | |
"name": "Calls/UserInterface/Group/GroupCallMemberSheet.swift", | |
"start": 130, | |
"end": 141, | |
"startLoc": { | |
"line": 130, | |
"column": 10, | |
"position": 1003 | |
}, | |
"endLoc": { | |
"line": 141, | |
"column": 10, | |
"position": 1146 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Emoji Picker/EmojiPickerSheet.swift", | |
"start": 126, | |
"end": 137, | |
"startLoc": { | |
"line": 126, | |
"column": 15, | |
"position": 982 | |
}, | |
"endLoc": { | |
"line": 137, | |
"column": 15, | |
"position": 1125 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 56, | |
"fragment": ".showsVerticalScrollIndicator = false\n }\n\n // We may have panned some distance if we were scrolling before we started\n // this interactive transition. Offset the translation we use to move the\n // view by whatever the translation was when we started the interactive\n // portion of the gesture.\n let translation = sender.translation(in: view).y - startingTranslation\n\n var newHeight = startingHeight - translation\n if newHeight > maximizedHeight {\n newHeight = maximizedHeight\n }\n\n // If the height is decreasing, adjust the relevant view's proporitionally\n if newHeight < startingHeight {\n backdropView.alpha = 1 - (startingHeight - newHeight) / startingHeight\n }\n\n // Update our height to reflect the new position\n heightConstraint?.constant = newHeight\n view.layoutIfNeeded()\n case .ended, .cancelled, .failed:\n guard let startingHeight = startingHeight else { break }\n\n let dismissThreshold = startingHeight * 0.5\n let growThreshold = startingHeight * 1.5\n let velocityThreshold: CGFloat = 500\n\n let currentHeight = contentView.height\n let currentVelocity = sender.velocity(in: view).y\n\n enum CompletionState { case growing, dismissing, cancelling }\n let completionState: CompletionState\n\n if abs(currentVelocity) >= velocityThreshold {\n completionState = currentVelocity < 0 ? .growing : .dismissing\n } else if currentHeight >= growThreshold {\n completionState = .growing\n } else if currentHeight <= dismissThreshold {\n completionState = .dismissing\n } else {\n completionState = .cancelling\n }\n\n let finalHeight: CGFloat\n switch completionState {\n case .dismissing:\n finalHeight = 0\n case .growing:\n finalHeight = maximizedHeight\n case .cancelling:\n finalHeight = startingHeight\n\n if isCollectionViewPanGesture {\n tableView", | |
"tokens": 0, | |
"firstFile": { | |
"name": "Calls/UserInterface/Group/GroupCallMemberSheet.swift", | |
"start": 154, | |
"end": 209, | |
"startLoc": { | |
"line": 154, | |
"column": 10, | |
"position": 1237 | |
}, | |
"endLoc": { | |
"line": 209, | |
"column": 10, | |
"position": 1679 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Reactions Details/ReactionsDetailSheet.swift", | |
"start": 219, | |
"end": 205, | |
"startLoc": { | |
"line": 219, | |
"column": 24, | |
"position": 1688 | |
}, | |
"endLoc": { | |
"line": 205, | |
"column": 15, | |
"position": 1659 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 27, | |
"fragment": ".contentOffset, animated: false)\n }\n }\n\n let remainingDistance = finalHeight - currentHeight\n\n // Calculate the time to complete the animation if we want to preserve\n // the user's velocity. If this time is too slow (e.g. the user was scrolling\n // very slowly) we'll default to `maxAnimationDuration`\n let remainingTime = TimeInterval(abs(remainingDistance / currentVelocity))\n\n UIView.animate(withDuration: min(remainingTime, maxAnimationDuration), delay: 0, options: .curveEaseOut, animations: {\n if remainingDistance < 0 {\n self.contentView.frame.origin.y -= remainingDistance\n self.handle.frame.origin.y -= remainingDistance\n } else {\n self.heightConstraint?.constant = finalHeight\n self.view.layoutIfNeeded()\n }\n\n self.backdropView.alpha = completionState == .dismissing ? 0 : 1\n }) { _ in\n self.heightConstraint?.constant = finalHeight\n self.view.layoutIfNeeded()\n\n if completionState == .dismissing {\n self.dismiss(animated: true)", | |
"tokens": 0, | |
"firstFile": { | |
"name": "Calls/UserInterface/Group/GroupCallMemberSheet.swift", | |
"start": 209, | |
"end": 235, | |
"startLoc": { | |
"line": 209, | |
"column": 10, | |
"position": 1684 | |
}, | |
"endLoc": { | |
"line": 235, | |
"column": 2, | |
"position": 1931 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Emoji Picker/EmojiPickerSheet.swift", | |
"start": 205, | |
"end": 295, | |
"startLoc": { | |
"line": 205, | |
"column": 15, | |
"position": 1664 | |
}, | |
"endLoc": { | |
"line": 295, | |
"column": 2, | |
"position": 2354 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 17, | |
"fragment": ".panGestureRecognizer else { return false }\n\n if startingTranslation == nil {\n startingTranslation = sender.translation(in: view).y\n }\n\n if startingHeight == nil {\n startingHeight = contentView.height\n }\n\n return true\n }\n\n func resetInteractiveTransition() {\n startingTranslation = nil\n startingHeight = nil\n tableView", | |
"tokens": 0, | |
"firstFile": { | |
"name": "Calls/UserInterface/Group/GroupCallMemberSheet.swift", | |
"start": 256, | |
"end": 272, | |
"startLoc": { | |
"line": 256, | |
"column": 10, | |
"position": 2062 | |
}, | |
"endLoc": { | |
"line": 272, | |
"column": 10, | |
"position": 2165 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Reactions Details/ReactionsDetailSheet.swift", | |
"start": 315, | |
"end": 331, | |
"startLoc": { | |
"line": 315, | |
"column": 24, | |
"position": 2490 | |
}, | |
"endLoc": { | |
"line": 331, | |
"column": 24, | |
"position": 2593 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 16, | |
"fragment": ": UIGestureRecognizerDelegate {\n func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {\n switch gestureRecognizer {\n case is UITapGestureRecognizer:\n let point = gestureRecognizer.location(in: view)\n guard !contentView.frame.contains(point) else { return false }\n return true\n default:\n return true\n }\n }\n\n func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {\n switch gestureRecognizer {\n case is UIPanGestureRecognizer:\n return tableView", | |
"tokens": 0, | |
"firstFile": { | |
"name": "Calls/UserInterface/Group/GroupCallMemberSheet.swift", | |
"start": 425, | |
"end": 440, | |
"startLoc": { | |
"line": 425, | |
"column": 21, | |
"position": 3535 | |
}, | |
"endLoc": { | |
"line": 440, | |
"column": 10, | |
"position": 3683 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Reactions Details/ReactionsDetailSheet.swift", | |
"start": 583, | |
"end": 598, | |
"startLoc": { | |
"line": 583, | |
"column": 21, | |
"position": 4539 | |
}, | |
"endLoc": { | |
"line": 598, | |
"column": 24, | |
"position": 4687 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 40, | |
"fragment": "else { return nil }\n return vc.backdropView\n }\n\n override init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?) {\n super.init(presentedViewController: presentedViewController, presenting: presentingViewController)\n backdropView?.backgroundColor = Theme.backdropColor\n }\n\n override func presentationTransitionWillBegin() {\n guard let containerView = containerView, let backdropView = backdropView else { return }\n backdropView.alpha = 0\n containerView.addSubview(backdropView)\n backdropView.autoPinEdgesToSuperviewEdges()\n containerView.layoutIfNeeded()\n\n presentedViewController.transitionCoordinator?.animate(alongsideTransition: { _ in\n self.backdropView?.alpha = 1\n }, completion: nil)\n }\n\n override func dismissalTransitionWillBegin() {\n presentedViewController.transitionCoordinator?.animate(alongsideTransition: { _ in\n self.backdropView?.alpha = 0\n }, completion: { _ in\n self.backdropView?.removeFromSuperview()\n })\n }\n\n override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {\n super.viewWillTransition(to: size, with: coordinator)\n guard let presentedView = presentedView else { return }\n coordinator.animate(alongsideTransition: { _ in\n presentedView.frame = self.frameOfPresentedViewInContainerView\n presentedView.layoutIfNeeded()\n }, completion: nil)\n }\n}\n\nextension GroupCallMemberSheet", | |
"tokens": 0, | |
"firstFile": { | |
"name": "Calls/UserInterface/Group/GroupCallMemberSheet.swift", | |
"start": 452, | |
"end": 491, | |
"startLoc": { | |
"line": 452, | |
"column": 2, | |
"position": 3751 | |
}, | |
"endLoc": { | |
"line": 491, | |
"column": 21, | |
"position": 4123 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Reactions Details/ReactionsDetailSheet.swift", | |
"start": 610, | |
"end": 649, | |
"startLoc": { | |
"line": 610, | |
"column": 2, | |
"position": 4755 | |
}, | |
"endLoc": { | |
"line": 649, | |
"column": 21, | |
"position": 5127 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 16, | |
"fragment": "()\n\n override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {\n super.init(style: style, reuseIdentifier: reuseIdentifier)\n\n backgroundColor = .clear\n selectionStyle = .none\n\n layoutMargins = UIEdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16)\n\n contentView.addSubview(avatarView)\n avatarView.autoPinLeadingToSuperviewMargin()\n avatarView.autoPinHeightToSuperviewMargins()\n avatarView.autoSetDimensions(to: CGSize(square: avatarDiameter))\n\n nameLabel", | |
"tokens": 0, | |
"firstFile": { | |
"name": "Calls/UserInterface/Group/GroupCallMemberSheet.swift", | |
"start": 534, | |
"end": 549, | |
"startLoc": { | |
"line": 534, | |
"column": 12, | |
"position": 4434 | |
}, | |
"endLoc": { | |
"line": 549, | |
"column": 10, | |
"position": 4568 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Reactions Details/EmojiReactorsTableView.swift", | |
"start": 78, | |
"end": 93, | |
"startLoc": { | |
"line": 78, | |
"column": 8, | |
"position": 610 | |
}, | |
"endLoc": { | |
"line": 93, | |
"column": 12, | |
"position": 744 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 9, | |
"fragment": "override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {\n super.init(style: style, reuseIdentifier: reuseIdentifier)\n\n backgroundColor = .clear\n selectionStyle = .none\n\n layoutMargins = UIEdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16)\n\n let", | |
"tokens": 0, | |
"firstFile": { | |
"name": "Calls/UserInterface/Group/GroupCallMemberSheet.swift", | |
"start": 601, | |
"end": 609, | |
"startLoc": { | |
"line": 601, | |
"column": 5, | |
"position": 5035 | |
}, | |
"endLoc": { | |
"line": 609, | |
"column": 4, | |
"position": 5124 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Reactions Details/EmojiReactorsTableView.swift", | |
"start": 80, | |
"end": 88, | |
"startLoc": { | |
"line": 80, | |
"column": 5, | |
"position": 615 | |
}, | |
"endLoc": { | |
"line": 88, | |
"column": 12, | |
"position": 704 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 26, | |
"fragment": ", nameComponents.count == 2 else {\n return owsFailDebug(\"Received incorrectly formatted resourceName: \\(resourceName)\")\n }\n\n guard !receivedFileIds.contains(fileIdentifier) else {\n return Logger.info(\"Ignoring duplicate file: \\(fileIdentifier)\")\n }\n\n guard !skippedFileIds.contains(fileIdentifier) else {\n return Logger.info(\"Ignoring previously skipped file: \\(fileIdentifier)\")\n }\n\n guard let file: DeviceTransferProtoFile = {\n switch fileIdentifier {\n case DeviceTransferService.databaseIdentifier:\n return manifest.database?.database\n case DeviceTransferService.databaseWALIdentifier:\n return manifest.database?.wal\n default:\n return manifest.files.first(where: { $0.identifier == fileIdentifier })\n }\n }() else {\n return owsFailDebug(\"Received unexpected file on new device: \\(fileIdentifier)\")\n }\n\n if", | |
"tokens": 0, | |
"firstFile": { | |
"name": "util/Device Transfer/DeviceTransferService+MultipeerDelegates.swift", | |
"start": 240, | |
"end": 265, | |
"startLoc": { | |
"line": 240, | |
"column": 5, | |
"position": 1977 | |
}, | |
"endLoc": { | |
"line": 265, | |
"column": 3, | |
"position": 2189 | |
} | |
}, | |
"secondFile": { | |
"name": "util/Device Transfer/DeviceTransferService+MultipeerDelegates.swift", | |
"start": 181, | |
"end": 206, | |
"startLoc": { | |
"line": 181, | |
"column": 6, | |
"position": 1426 | |
}, | |
"endLoc": { | |
"line": 206, | |
"column": 7, | |
"position": 1638 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 17, | |
"fragment": "let thread: TSThread?\n public init(thread: TSThread? = nil) {\n self.thread = thread\n super.init()\n\n NotificationCenter.default.addObserver(\n self,\n selector: #selector(updateTableContents),\n name: Wallpaper.wallpaperDidChangeNotification,\n object: nil\n )\n }\n\n public override func viewDidLoad() {\n super.viewDidLoad()\n\n title = NSLocalizedString(\"SET_WALLPAPER_TITLE\"", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/Wallpapers/SetWallpaperViewController.swift", | |
"start": 18, | |
"end": 34, | |
"startLoc": { | |
"line": 18, | |
"column": 5, | |
"position": 130 | |
}, | |
"endLoc": { | |
"line": 34, | |
"column": 22, | |
"position": 246 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/Wallpapers/WallpaperSettingsViewController.swift", | |
"start": 8, | |
"end": 24, | |
"startLoc": { | |
"line": 8, | |
"column": 5, | |
"position": 24 | |
}, | |
"endLoc": { | |
"line": 24, | |
"column": 27, | |
"position": 140 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 13, | |
"fragment": "(address: SignalServiceAddress) -> Promise<Void> {\n guard let oldGroupModel = delegate?.currentGroupModel as? TSGroupModelV2 else {\n return Promise(error: OWSAssertionError(\"Missing group model.\"))\n }\n guard oldGroupModel.groupMembership.isMemberOfAnyKind(address) else {\n return Promise(error: OWSAssertionError(\"Not a group member.\"))\n }\n guard let uuid = address.uuid else {\n return Promise(error: OWSAssertionError(\"Invalid member address.\"))\n }\n return firstly {\n return GroupManager.messageProcessingPromise(for: oldGroupModel,\n description: \"Revoke group admin\"", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ThreadSettings/GroupViewHelper+MemberActionSheet.swift", | |
"start": 119, | |
"end": 131, | |
"startLoc": { | |
"line": 119, | |
"column": 24, | |
"position": 994 | |
}, | |
"endLoc": { | |
"line": 131, | |
"column": 21, | |
"position": 1142 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ThreadSettings/GroupViewHelper+MemberActionSheet.swift", | |
"start": 72, | |
"end": 84, | |
"startLoc": { | |
"line": 72, | |
"column": 22, | |
"position": 545 | |
}, | |
"endLoc": { | |
"line": 84, | |
"column": 19, | |
"position": 693 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 13, | |
"fragment": "(address: SignalServiceAddress) -> Bool {\n guard let groupThread = thread as? TSGroupThread,\n groupThread.isGroupV2Thread else {\n return false\n }\n guard let localAddress = tsAccountManager.localAddress else {\n owsFailDebug(\"Missing localAddress.\")\n return false\n }\n // Only admins can kick out other members.\n let groupMembership = groupThread.groupModel.groupMembership\n let isLocalUserAdmin = groupMembership.isFullMemberAndAdministrator(localAddress)\n let isAddressInGroup", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ThreadSettings/GroupViewHelper+MemberActionSheet.swift", | |
"start": 140, | |
"end": 152, | |
"startLoc": { | |
"line": 140, | |
"column": 19, | |
"position": 1207 | |
}, | |
"endLoc": { | |
"line": 152, | |
"column": 17, | |
"position": 1319 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ThreadSettings/GroupViewHelper+MemberActionSheet.swift", | |
"start": 92, | |
"end": 103, | |
"startLoc": { | |
"line": 92, | |
"column": 37, | |
"position": 755 | |
}, | |
"endLoc": { | |
"line": 103, | |
"column": 15, | |
"position": 864 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 13, | |
"fragment": "(address: SignalServiceAddress) -> Promise<Void> {\n guard let oldGroupModel = delegate?.currentGroupModel as? TSGroupModelV2 else {\n return Promise(error: OWSAssertionError(\"Missing group model.\"))\n }\n guard oldGroupModel.groupMembership.isMemberOfAnyKind(address) else {\n return Promise(error: OWSAssertionError(\"Not a group member.\"))\n }\n guard let uuid = address.uuid else {\n return Promise(error: OWSAssertionError(\"Invalid member address.\"))\n }\n return firstly {\n return GroupManager.messageProcessingPromise(for: oldGroupModel,\n description: \"Remove user from group\"", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ThreadSettings/GroupViewHelper+MemberActionSheet.swift", | |
"start": 169, | |
"end": 181, | |
"startLoc": { | |
"line": 169, | |
"column": 23, | |
"position": 1463 | |
}, | |
"endLoc": { | |
"line": 181, | |
"column": 25, | |
"position": 1611 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ThreadSettings/GroupViewHelper+MemberActionSheet.swift", | |
"start": 72, | |
"end": 84, | |
"startLoc": { | |
"line": 72, | |
"column": 22, | |
"position": 545 | |
}, | |
"endLoc": { | |
"line": 84, | |
"column": 19, | |
"position": 693 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 14, | |
"fragment": ") -> Promise<TSGroupThread> {\n guard let groupModelV2 = groupModel as? TSGroupModelV2 else {\n return Promise(error: OWSAssertionError(\"Invalid group model.\"))\n }\n let uuids = addresses.compactMap { $0.uuid }\n guard !uuids.isEmpty else {\n return Promise(error: OWSAssertionError(\"Invalid addresses.\"))\n }\n\n return firstly { () -> Promise<Void> in\n return GroupManager.messageProcessingPromise(for: groupModel,\n description: self.logTag)\n }.then(on: .global()) { _ in\n GroupManager.acceptOrDenyMemberRequestsV2", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ThreadSettings/GroupMemberRequestsAndInvitesViewController.swift", | |
"start": 583, | |
"end": 596, | |
"startLoc": { | |
"line": 583, | |
"column": 5, | |
"position": 4872 | |
}, | |
"endLoc": { | |
"line": 596, | |
"column": 29, | |
"position": 5036 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ThreadSettings/GroupMemberRequestsAndInvitesViewController.swift", | |
"start": 483, | |
"end": 496, | |
"startLoc": { | |
"line": 483, | |
"column": 2, | |
"position": 3951 | |
}, | |
"endLoc": { | |
"line": 496, | |
"column": 32, | |
"position": 4115 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 11, | |
"fragment": "let cameraImageContainer = UIView()\n cameraImageContainer.autoSetDimensions(to: CGSize.square(32))\n cameraImageContainer.backgroundColor = Theme.isDarkThemeEnabled ? .ows_gray15 : UIColor(rgbHex: 0xf8f9f9)\n cameraImageContainer.layer.cornerRadius = 16\n\n cameraImageContainer.layer.shadowColor = UIColor.black.cgColor\n cameraImageContainer.layer.shadowOpacity = 0.2\n cameraImageContainer.layer.shadowRadius = 4\n cameraImageContainer.layer.shadowOffset = CGSize(width: 0, height: 2)\n\n let", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ThreadSettings/GroupAttributesEditorHelper.swift", | |
"start": 127, | |
"end": 137, | |
"startLoc": { | |
"line": 127, | |
"column": 9, | |
"position": 807 | |
}, | |
"endLoc": { | |
"line": 137, | |
"column": 4, | |
"position": 933 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/AppSettings/Profile/ProfileSettingsViewController.swift", | |
"start": 244, | |
"end": 254, | |
"startLoc": { | |
"line": 244, | |
"column": 9, | |
"position": 1949 | |
}, | |
"endLoc": { | |
"line": 254, | |
"column": 5, | |
"position": 2075 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 19, | |
"fragment": ")\n\n let secondaryShadowView = UIView()\n secondaryShadowView.layer.shadowColor = UIColor.black.cgColor\n secondaryShadowView.layer.shadowOpacity = 0.12\n secondaryShadowView.layer.shadowRadius = 16\n secondaryShadowView.layer.shadowOffset = CGSize(width: 0, height: 4)\n\n cameraImageContainer.addSubview(secondaryShadowView)\n secondaryShadowView.autoPinEdgesToSuperviewEdges()\n\n let cameraImageView = UIImageView.withTemplateImageName(\"camera-outline-32\", tintColor: Theme.isDarkThemeEnabled ? .ows_gray80 : .ows_black)\n cameraImageView.autoSetDimensions(to: CGSize.square(20))\n cameraImageView.contentMode = .scaleAspectFit\n\n cameraImageContainer.addSubview(cameraImageView)\n cameraImageView.autoCenterInSuperview()\n\n return cameraImageContainer", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ThreadSettings/GroupAttributesEditorHelper.swift", | |
"start": 135, | |
"end": 153, | |
"startLoc": { | |
"line": 135, | |
"column": 2, | |
"position": 929 | |
}, | |
"endLoc": { | |
"line": 153, | |
"column": 21, | |
"position": 1098 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/AppSettings/Profile/ProfileSettingsViewController.swift", | |
"start": 256, | |
"end": 274, | |
"startLoc": { | |
"line": 256, | |
"column": 16, | |
"position": 2115 | |
}, | |
"endLoc": { | |
"line": 274, | |
"column": 5, | |
"position": 2284 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 12, | |
"fragment": ")\n section.add(OWSTableItem(customCellBlock: { [weak self] in\n guard let self = self else {\n owsFailDebug(\"Missing self\")\n return OWSTableItem.newCell()\n }\n let cell = OWSTableItem.newCell()\n cell.preservesSuperviewLayoutMargins = true\n cell.contentView.preservesSuperviewLayoutMargins = true\n cell.selectionStyle = .none\n\n let iconView", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ThreadSettings/ConversationSettingsViewController+Contents.swift", | |
"start": 300, | |
"end": 311, | |
"startLoc": { | |
"line": 300, | |
"column": 24, | |
"position": 2455 | |
}, | |
"endLoc": { | |
"line": 311, | |
"column": 9, | |
"position": 2557 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ThreadSettings/ConversationSettingsViewController+Contents.swift", | |
"start": 258, | |
"end": 269, | |
"startLoc": { | |
"line": 258, | |
"column": 41, | |
"position": 2044 | |
}, | |
"endLoc": { | |
"line": 269, | |
"column": 5, | |
"position": 2146 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 10, | |
"fragment": "section.add(OWSTableItem(customCellBlock: { [weak self] in\n guard let self = self else {\n owsFailDebug(\"Missing self\")\n return OWSTableItem.newCell()\n }\n let cell = OWSTableItem.newCell()\n cell.preservesSuperviewLayoutMargins = true\n cell.contentView.preservesSuperviewLayoutMargins = true\n\n let", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ThreadSettings/ConversationSettingsViewController+Contents.swift", | |
"start": 620, | |
"end": 629, | |
"startLoc": { | |
"line": 620, | |
"column": 13, | |
"position": 5316 | |
}, | |
"endLoc": { | |
"line": 629, | |
"column": 4, | |
"position": 5403 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ThreadSettings/ConversationSettingsViewController+Contents.swift", | |
"start": 259, | |
"end": 267, | |
"startLoc": { | |
"line": 259, | |
"column": 9, | |
"position": 2047 | |
}, | |
"endLoc": { | |
"line": 267, | |
"column": 5, | |
"position": 2133 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 11, | |
"fragment": "{\n section.add(OWSTableItem(customCellBlock: { [weak self] in\n guard let self = self else {\n owsFailDebug(\"Missing self\")\n return OWSTableItem.newCell()\n }\n let cell = OWSTableItem.newCell()\n cell.preservesSuperviewLayoutMargins = true\n cell.contentView.preservesSuperviewLayoutMargins = true\n\n let iconView = OWSTableItem.buildIconInCircleView(icon: .settingsShowAllMembers", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ThreadSettings/ConversationSettingsViewController+Contents.swift", | |
"start": 759, | |
"end": 769, | |
"startLoc": { | |
"line": 759, | |
"column": 2, | |
"position": 6572 | |
}, | |
"endLoc": { | |
"line": 769, | |
"column": 23, | |
"position": 6676 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ThreadSettings/ConversationSettingsViewController+Contents.swift", | |
"start": 619, | |
"end": 629, | |
"startLoc": { | |
"line": 619, | |
"column": 2, | |
"position": 5313 | |
}, | |
"endLoc": { | |
"line": 629, | |
"column": 19, | |
"position": 5417 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 15, | |
"fragment": ")\n rowLabel.textColor = Theme.primaryTextColor\n rowLabel.font = OWSTableItem.primaryLabelFont\n rowLabel.lineBreakMode = .byTruncatingTail\n\n let contentRow = UIStackView(arrangedSubviews: [ iconView, rowLabel ])\n contentRow.spacing = self.iconSpacingSmall\n\n cell.contentView.addSubview(contentRow)\n contentRow.autoPinWidthToSuperviewMargins()\n contentRow.autoPinHeightToSuperview(withMargin: 7)\n\n return cell\n }) { [weak self] in\n self?.showAllGroupMembers", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ThreadSettings/ConversationSettingsViewController+Contents.swift", | |
"start": 776, | |
"end": 790, | |
"startLoc": { | |
"line": 776, | |
"column": 69, | |
"position": 6731 | |
}, | |
"endLoc": { | |
"line": 790, | |
"column": 20, | |
"position": 6852 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ThreadSettings/ConversationSettingsViewController+Contents.swift", | |
"start": 636, | |
"end": 650, | |
"startLoc": { | |
"line": 636, | |
"column": 64, | |
"position": 5472 | |
}, | |
"endLoc": { | |
"line": 650, | |
"column": 19, | |
"position": 5593 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 19, | |
"fragment": ".localAddress else {\n return Promise(error: OWSAssertionError(\"Missing localAddress.\"))\n }\n\n return firstly { () -> Promise<Void> in\n return GroupManager.messageProcessingPromise(for: oldGroupModel,\n description: self.logTag)\n }.then(on: .global()) { _ in\n // dmConfiguration: nil means don't change disappearing messages configuration.\n GroupManager.localUpdateExistingGroup(oldGroupModel: oldGroupModel,\n newGroupModel: newGroupModel,\n dmConfiguration: nil,\n groupUpdateSourceAddress: localAddress)\n }.asVoid()\n }\n\n // MARK: -\n\n private", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ThreadSettings/AddToGroupViewController.swift", | |
"start": 246, | |
"end": 264, | |
"startLoc": { | |
"line": 246, | |
"column": 17, | |
"position": 2119 | |
}, | |
"endLoc": { | |
"line": 264, | |
"column": 8, | |
"position": 2257 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ThreadSettings/GroupAttributesViewController.swift", | |
"start": 298, | |
"end": 313, | |
"startLoc": { | |
"line": 298, | |
"column": 17, | |
"position": 2223 | |
}, | |
"endLoc": { | |
"line": 313, | |
"column": 2, | |
"position": 2355 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 14, | |
"fragment": "hasUnsavedChanges {\n navigationItem.rightBarButtonItem = UIBarButtonItem(title: NSLocalizedString(\"EDIT_GROUP_UPDATE_BUTTON\",\n comment: \"The title for the 'update group' button.\"),\n style: .plain,\n target: self,\n action: #selector(updateGroupPressed),\n accessibilityIdentifier: UIView.accessibilityIdentifier(in: self, name: \"update\"))\n } else {\n navigationItem.rightBarButtonItem = nil\n }\n }\n\n @objc func updateGroupPressed() {\n showConfirmationAlert", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ThreadSettings/AddGroupMembersViewController.swift", | |
"start": 46, | |
"end": 59, | |
"startLoc": { | |
"line": 46, | |
"column": 2, | |
"position": 224 | |
}, | |
"endLoc": { | |
"line": 59, | |
"column": 22, | |
"position": 335 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ThreadSettings/GroupAttributesViewController.swift", | |
"start": 142, | |
"end": 155, | |
"startLoc": { | |
"line": 142, | |
"column": 2, | |
"position": 1060 | |
}, | |
"endLoc": { | |
"line": 155, | |
"column": 28, | |
"position": 1171 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 38, | |
"fragment": ") else {\n let error = OWSAssertionError(\"Couldn't build group model.\")\n GroupViewUtils.showUpdateErrorUI(error: error)\n return\n }\n GroupViewUtils.updateGroupWithActivityIndicator(fromViewController: self,\n updatePromiseBlock: {\n self.updateGroupThreadPromise(newGroupModel: newGroupModel)\n },\n completion: { _ in\n dismissAndUpdateDelegate()\n })\n }\n\n func updateGroupThreadPromise(newGroupModel: TSGroupModel) -> Promise<Void> {\n\n let oldGroupModel = self.oldGroupModel\n\n guard let localAddress = tsAccountManager.localAddress else {\n return Promise(error: OWSAssertionError(\"Missing localAddress.\"))\n }\n\n return firstly { () -> Promise<Void> in\n return GroupManager.messageProcessingPromise(for: oldGroupModel,\n description: self.logTag)\n }.then(on: .global()) { _ in\n // dmConfiguration: nil means don't change disappearing messages configuration.\n GroupManager.localUpdateExistingGroup(oldGroupModel: oldGroupModel,\n newGroupModel: newGroupModel,\n dmConfiguration: nil,\n groupUpdateSourceAddress: localAddress)\n }.asVoid()\n }\n}\n\n// MARK: -\n\nextension AddGroupMembersViewController", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ThreadSettings/AddGroupMembersViewController.swift", | |
"start": 152, | |
"end": 189, | |
"startLoc": { | |
"line": 152, | |
"column": 2, | |
"position": 1073 | |
}, | |
"endLoc": { | |
"line": 189, | |
"column": 30, | |
"position": 1347 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ThreadSettings/GroupAttributesViewController.swift", | |
"start": 280, | |
"end": 317, | |
"startLoc": { | |
"line": 280, | |
"column": 14, | |
"position": 2089 | |
}, | |
"endLoc": { | |
"line": 317, | |
"column": 30, | |
"position": 2363 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 10, | |
"fragment": "let messageBody = MessageBody(text: packUrl, ranges: .empty)\n let unapprovedContent = SendMessageUnapprovedContent.text(messageBody: messageBody)\n let sendMessageFlow = SendMessageFlow(flowType: .`default`,\n unapprovedContent: unapprovedContent,\n useConversationComposeForSingleRecipient: true,\n navigationController: navigationController,\n delegate: self)\n // Retain the flow until it is complete.\n self.sendMessageFlow = sendMessageFlow\n }", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/Stickers/ManageStickersViewController.swift", | |
"start": 506, | |
"end": 515, | |
"startLoc": { | |
"line": 506, | |
"column": 9, | |
"position": 4329 | |
}, | |
"endLoc": { | |
"line": 515, | |
"column": 2, | |
"position": 4426 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/Stickers/StickerPackViewController.swift", | |
"start": 398, | |
"end": 408, | |
"startLoc": { | |
"line": 398, | |
"column": 9, | |
"position": 3165 | |
}, | |
"endLoc": { | |
"line": 408, | |
"column": 8, | |
"position": 3263 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 8, | |
"fragment": ")\n explanationLabel.textColor = Theme.accentBlueColor\n explanationLabel.font = UIFont.ows_dynamicTypeSubheadlineClamped\n explanationLabel.numberOfLines = 0\n explanationLabel.textAlignment = .center\n explanationLabel.lineBreakMode = .byWordWrapping\n explanationLabel.isUserInteractionEnabled = true\n explanationLabel.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(explanationLabelTapped", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/Registration/OnboardingSplashViewController.swift", | |
"start": 57, | |
"end": 64, | |
"startLoc": { | |
"line": 57, | |
"column": 74, | |
"position": 452 | |
}, | |
"endLoc": { | |
"line": 64, | |
"column": 23, | |
"position": 533 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/Registration/SecondaryLinking/SecondaryLinkingQRCodeViewController.swift", | |
"start": 43, | |
"end": 50, | |
"startLoc": { | |
"line": 43, | |
"column": 79, | |
"position": 298 | |
}, | |
"endLoc": { | |
"line": 50, | |
"column": 23, | |
"position": 379 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 19, | |
"fragment": "{\n OWSActionSheets.showErrorAlert(message: NSLocalizedString(\"PROFILE_VIEW_ERROR_GIVEN_NAME_REQUIRED\",\n comment: \"Error message shown when user tries to update profile without a given name\"))\n return\n }\n\n if profileManager.isProfileNameTooLong(normalizedGivenName) {\n OWSActionSheets.showErrorAlert(message: NSLocalizedString(\"PROFILE_VIEW_ERROR_GIVEN_NAME_TOO_LONG\",\n comment: \"Error message shown when user tries to update profile with a given name that is too long.\"))\n return\n }\n\n if profileManager.isProfileNameTooLong(normalizedFamilyName) {\n OWSActionSheets.showErrorAlert(message: NSLocalizedString(\"PROFILE_VIEW_ERROR_FAMILY_NAME_TOO_LONG\",\n comment: \"Error message shown when user tries to update profile with a family name that is too long.\"))\n return\n }\n\n if", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/Registration/OnboardingProfileCreationViewController.swift", | |
"start": 312, | |
"end": 330, | |
"startLoc": { | |
"line": 312, | |
"column": 2, | |
"position": 2781 | |
}, | |
"endLoc": { | |
"line": 330, | |
"column": 3, | |
"position": 2892 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/AppSettings/Profile/ProfileNameViewController.swift", | |
"start": 194, | |
"end": 218, | |
"startLoc": { | |
"line": 194, | |
"column": 2, | |
"position": 1293 | |
}, | |
"endLoc": { | |
"line": 218, | |
"column": 16, | |
"position": 1416 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 32, | |
"fragment": ": AvatarViewHelperDelegate {\n\n public func avatarActionSheetTitle() -> String? {\n NSLocalizedString(\"PROFILE_VIEW_AVATAR_ACTIONSHEET_TITLE\", comment: \"Action Sheet title prompting the user for a profile avatar\")\n }\n\n public func avatarDidChange(_ image: UIImage) {\n AssertIsOnMainThread()\n\n setAvatarImage(image.resizedImage(toFillPixelSize: .square(CGFloat(kOWSProfileManager_MaxAvatarDiameter))))\n }\n\n public func fromViewController() -> UIViewController {\n self\n }\n\n public func hasClearAvatarAction() -> Bool {\n avatarData != nil\n }\n\n public func clearAvatar() {\n setAvatarImage(nil)\n }\n\n public func clearAvatarActionLabel() -> String {\n return NSLocalizedString(\"PROFILE_VIEW_CLEAR_AVATAR\", comment: \"Label for action that clear's the user's profile avatar\")\n }\n}\n\n// MARK: - <UITextFieldDelegate>\n\nextension OnboardingProfileCreationViewController", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/Registration/OnboardingProfileCreationViewController.swift", | |
"start": 398, | |
"end": 429, | |
"startLoc": { | |
"line": 398, | |
"column": 40, | |
"position": 3376 | |
}, | |
"endLoc": { | |
"line": 429, | |
"column": 40, | |
"position": 3576 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/AppSettings/Profile/ProfileSettingsViewController.swift", | |
"start": 291, | |
"end": 321, | |
"startLoc": { | |
"line": 291, | |
"column": 30, | |
"position": 2395 | |
}, | |
"endLoc": { | |
"line": 321, | |
"column": 30, | |
"position": 2593 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 12, | |
"fragment": "progressView.stopAnimatingImmediately()\n progressView.removeFromSuperview()\n\n self.nextButton.alpha = 1\n self.pinTypeToggle.alpha = 1\n self.pinTextField.alpha = 1\n self.validationWarningLabel.alpha = 1\n self.needHelpLink.alpha = 1\n self.view.isUserInteractionEnabled = true\n\n // If we have success while pending restoration, show the next onboarding milestone.\n if", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/Registration/Onboarding2FAViewController.swift", | |
"start": 320, | |
"end": 331, | |
"startLoc": { | |
"line": 320, | |
"column": 17, | |
"position": 2476 | |
}, | |
"endLoc": { | |
"line": 331, | |
"column": 3, | |
"position": 2561 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/Registration/Onboarding2FAViewController.swift", | |
"start": 305, | |
"end": 314, | |
"startLoc": { | |
"line": 305, | |
"column": 17, | |
"position": 2366 | |
}, | |
"endLoc": { | |
"line": 314, | |
"column": 5, | |
"position": 2447 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 9, | |
"fragment": "recipientPicker.delegate = self\n addChild(recipientPicker)\n view.addSubview(recipientPicker.view)\n recipientPicker.view.autoPin(toTopLayoutGuideOf: self, withInset: 0)\n recipientPicker.view.autoPinEdge(toSuperviewEdge: .leading)\n recipientPicker.view.autoPinEdge(toSuperviewEdge: .trailing)\n recipientPicker.view.autoPinEdge(toSuperviewEdge: .bottom)\n\n recipientPicker", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/RecipientPicker/AddToBlockListViewController.swift", | |
"start": 24, | |
"end": 32, | |
"startLoc": { | |
"line": 24, | |
"column": 9, | |
"position": 111 | |
}, | |
"endLoc": { | |
"line": 32, | |
"column": 16, | |
"position": 198 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/RecipientPicker/ComposeViewController.swift", | |
"start": 23, | |
"end": 31, | |
"startLoc": { | |
"line": 23, | |
"column": 9, | |
"position": 124 | |
}, | |
"endLoc": { | |
"line": 31, | |
"column": 15, | |
"position": 211 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 14, | |
"fragment": ")\n }\n\n override func viewWillAppear(_ animated: Bool) {\n super.viewWillAppear(animated)\n recipientPicker.applyTheme(to: self)\n }\n\n override func viewWillDisappear(_ animated: Bool) {\n super.viewWillDisappear(animated)\n recipientPicker.removeTheme(from: self)\n }\n\n func", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/RecipientPicker/AddToBlockListViewController.swift", | |
"start": 35, | |
"end": 48, | |
"startLoc": { | |
"line": 35, | |
"column": 9, | |
"position": 218 | |
}, | |
"endLoc": { | |
"line": 48, | |
"column": 5, | |
"position": 305 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/RecipientPicker/ComposeViewController.swift", | |
"start": 31, | |
"end": 44, | |
"startLoc": { | |
"line": 31, | |
"column": 2, | |
"position": 240 | |
}, | |
"endLoc": { | |
"line": 44, | |
"column": 6, | |
"position": 327 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 23, | |
"fragment": "(thread: groupThread)\n }\n }\n\n func recipientPicker(_ recipientPickerViewController: RecipientPickerViewController,\n willRenderRecipient recipient: PickedRecipient) {\n // Do nothing.\n }\n\n func recipientPicker(_ recipientPickerViewController: RecipientPickerViewController,\n prepareToSelectRecipient recipient: PickedRecipient) -> AnyPromise {\n owsFailDebug(\"This method should not called.\")\n return AnyPromise(Promise.value(()))\n }\n\n func recipientPicker(_ recipientPickerViewController: RecipientPickerViewController,\n showInvalidRecipientAlert recipient: PickedRecipient) {\n owsFailDebug(\"Unexpected error.\")\n }\n\n func recipientPicker(\n _ recipientPickerViewController: RecipientPickerViewController,\n accessoryMessageForRecipient", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/RecipientPicker/AddToBlockListViewController.swift", | |
"start": 99, | |
"end": 121, | |
"startLoc": { | |
"line": 99, | |
"column": 6, | |
"position": 681 | |
}, | |
"endLoc": { | |
"line": 121, | |
"column": 29, | |
"position": 829 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/RecipientPicker/ComposeViewController.swift", | |
"start": 85, | |
"end": 107, | |
"startLoc": { | |
"line": 85, | |
"column": 16, | |
"position": 635 | |
}, | |
"endLoc": { | |
"line": 107, | |
"column": 21, | |
"position": 783 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 17, | |
"fragment": "}\n\n func recipientPicker(\n _ recipientPickerViewController: RecipientPickerViewController,\n accessoryMessageForRecipient recipient: PickedRecipient\n ) -> String? {\n switch recipient.identifier {\n case .address(let address):\n guard contactsViewHelper.isSignalServiceAddressBlocked(address) else { return nil }\n return MessageStrings.conversationIsBlocked\n case .group(let thread):\n guard contactsViewHelper.isThreadBlocked(thread) else { return nil }\n return MessageStrings.conversationIsBlocked\n }\n }\n\n func recipientPickerTableViewWillBeginDragging", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/RecipientPicker/AddToBlockListViewController.swift", | |
"start": 117, | |
"end": 133, | |
"startLoc": { | |
"line": 117, | |
"column": 5, | |
"position": 810 | |
}, | |
"endLoc": { | |
"line": 133, | |
"column": 42, | |
"position": 944 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/RecipientPicker/ComposeViewController.swift", | |
"start": 108, | |
"end": 124, | |
"startLoc": { | |
"line": 108, | |
"column": 2, | |
"position": 794 | |
}, | |
"endLoc": { | |
"line": 124, | |
"column": 16, | |
"position": 928 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 12, | |
"fragment": ",\n diameter: UInt(UIScreen.main.bounds.size.smallerAxis),\n transaction: readTx) else { return nil }\n\n self.avatarImage = avatarImage\n super.init(nibName: nil, bundle: nil)\n\n modalPresentationStyle = .custom\n transitioningDelegate = self\n }\n\n override", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/Photos/AvatarViewController.swift", | |
"start": 48, | |
"end": 59, | |
"startLoc": { | |
"line": 48, | |
"column": 8, | |
"position": 375 | |
}, | |
"endLoc": { | |
"line": 59, | |
"column": 9, | |
"position": 460 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/Photos/AvatarViewController.swift", | |
"start": 34, | |
"end": 45, | |
"startLoc": { | |
"line": 34, | |
"column": 7, | |
"position": 251 | |
}, | |
"endLoc": { | |
"line": 45, | |
"column": 6, | |
"position": 336 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 14, | |
"fragment": ")\n\n let buttonFont = UIFont.ows_dynamicTypeBodyClamped.ows_semibold\n let buttonHeight = OWSFlatButton.heightForFont(buttonFont)\n let okayButton = OWSFlatButton.button(title: CommonStrings.okayButton,\n font: buttonFont,\n titleColor: .white,\n backgroundColor: .ows_accentBlue,\n target: self,\n selector: #selector(dismissAlert))\n okayButton.autoSetDimension(.height, toSize: buttonHeight)\n\n let stackView = UIStackView(arrangedSubviews: [\n wrapViewWithHMargins", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/NewGroupView/NewGroupConfirmViewController.swift", | |
"start": 522, | |
"end": 535, | |
"startLoc": { | |
"line": 522, | |
"column": 4, | |
"position": 4011 | |
}, | |
"endLoc": { | |
"line": 535, | |
"column": 21, | |
"position": 4132 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ThreadSettings/ConversationSettingsViewController+LegacyGroups.swift", | |
"start": 206, | |
"end": 219, | |
"startLoc": { | |
"line": 206, | |
"column": 68, | |
"position": 1530 | |
}, | |
"endLoc": { | |
"line": 219, | |
"column": 11, | |
"position": 1651 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 18, | |
"fragment": ")\n\n layoutMargins = .zero\n addSubview(stackView)\n stackView.autoPinEdgesToSuperviewMargins()\n\n let actionSheetController = ActionSheetController()\n actionSheetController.customHeader = self\n actionSheetController.isCancelable = true\n fromViewController.presentActionSheet(actionSheetController)\n self.actionSheetController = actionSheetController\n }\n\n @objc\n func dismissAlert() {\n actionSheetController?.dismiss(animated: true)\n }\n}", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/NewGroupView/NewGroupConfirmViewController.swift", | |
"start": 545, | |
"end": 562, | |
"startLoc": { | |
"line": 545, | |
"column": 21, | |
"position": 4251 | |
}, | |
"endLoc": { | |
"line": 562, | |
"column": 2, | |
"position": 4353 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ThreadSettings/ConversationSettingsViewController+LegacyGroups.swift", | |
"start": 237, | |
"end": 256, | |
"startLoc": { | |
"line": 237, | |
"column": 16, | |
"position": 1826 | |
}, | |
"endLoc": { | |
"line": 256, | |
"column": 2, | |
"position": 1932 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 17, | |
"fragment": "indexPath: IndexPath) -> Bool {\n\n Logger.debug(\"\")\n\n guard galleryDates.count > 0 else {\n return false\n }\n\n switch indexPath.section {\n case kLoadOlderSectionIdx, loadNewerSectionIdx:\n return false\n default:\n return true\n }\n }\n\n override public func collectionView(_ collectionView: UICollectionView, didSelectItemAt", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/MediaGallery/MediaTileViewController.swift", | |
"start": 203, | |
"end": 219, | |
"startLoc": { | |
"line": 203, | |
"column": 2, | |
"position": 1649 | |
}, | |
"endLoc": { | |
"line": 219, | |
"column": 16, | |
"position": 1752 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/MediaGallery/MediaTileViewController.swift", | |
"start": 171, | |
"end": 187, | |
"startLoc": { | |
"line": 171, | |
"column": 2, | |
"position": 1439 | |
}, | |
"endLoc": { | |
"line": 187, | |
"column": 21, | |
"position": 1542 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 9, | |
"fragment": "guard let collectionView = self.collectionView else {\n owsFailDebug(\"collectionView was unexpectedly nil\")\n return\n }\n\n // hide toolbar\n UIView.animate(withDuration: 0.1, delay: 0, options: .curveEaseInOut, animations: {\n NSLayoutConstraint.deactivate([self.footerBarBottomConstraint])\n self.footerBarBottomConstraint = self.footerBar.autoPinEdge", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/MediaGallery/MediaTileViewController.swift", | |
"start": 561, | |
"end": 569, | |
"startLoc": { | |
"line": 561, | |
"column": 9, | |
"position": 4570 | |
}, | |
"endLoc": { | |
"line": 569, | |
"column": 12, | |
"position": 4654 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/MediaGallery/MediaTileViewController.swift", | |
"start": 529, | |
"end": 537, | |
"startLoc": { | |
"line": 529, | |
"column": 9, | |
"position": 4349 | |
}, | |
"endLoc": { | |
"line": 537, | |
"column": 8, | |
"position": 4433 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 40, | |
"fragment": ": UICollectionViewLayoutAttributes]()\n\n private var contentSize = CGSize.zero\n\n // MARK: Initializers and Factory Methods\n\n @available(*, unavailable, message:\"use other constructor instead.\")\n required init?(coder aDecoder: NSCoder) {\n notImplemented()\n }\n\n override init() {\n super.init()\n }\n\n // MARK: Methods\n\n override func invalidateLayout() {\n super.invalidateLayout()\n\n itemAttributesMap.removeAll()\n }\n\n override func invalidateLayout(with context: UICollectionViewLayoutInvalidationContext) {\n super.invalidateLayout(with: context)\n\n itemAttributesMap.removeAll()\n }\n\n override func prepare() {\n super.prepare()\n\n guard let collectionView = collectionView else {\n return\n }\n guard let delegate = delegate else {\n return\n }\n\n let vInset =", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/GifPicker/GifPickerLayout.swift", | |
"start": 16, | |
"end": 55, | |
"startLoc": { | |
"line": 16, | |
"column": 5, | |
"position": 75 | |
}, | |
"endLoc": { | |
"line": 55, | |
"column": 2, | |
"position": 302 | |
} | |
}, | |
"secondFile": { | |
"name": "Calls/UserInterface/Group/GroupCallVideoGridLayout.swift", | |
"start": 20, | |
"end": 55, | |
"startLoc": { | |
"line": 20, | |
"column": 4, | |
"position": 125 | |
}, | |
"endLoc": { | |
"line": 55, | |
"column": 2, | |
"position": 347 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 10, | |
"fragment": "}\n\n override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {\n return itemAttributesMap.values.filter { itemAttributes in\n return itemAttributes.frame.intersects(rect)\n }\n }\n\n override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {\n let", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/GifPicker/GifPickerLayout.swift", | |
"start": 120, | |
"end": 129, | |
"startLoc": { | |
"line": 120, | |
"column": 5, | |
"position": 991 | |
}, | |
"endLoc": { | |
"line": 129, | |
"column": 4, | |
"position": 1077 | |
} | |
}, | |
"secondFile": { | |
"name": "Calls/UserInterface/Group/GroupCallVideoGridLayout.swift", | |
"start": 139, | |
"end": 148, | |
"startLoc": { | |
"line": 139, | |
"column": 5, | |
"position": 1283 | |
}, | |
"endLoc": { | |
"line": 148, | |
"column": 7, | |
"position": 1369 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 23, | |
"fragment": ")\n topSpacer.autoMatch(.height, to: .height, of: bottomSpacer)\n }\n\n override public func viewWillAppear(_ animated: Bool) {\n super.viewWillAppear(animated)\n\n progressView.startUpdatingProgress()\n\n deviceTransferService.addObserver(self)\n }\n\n public override func viewWillDisappear(_ animated: Bool) {\n super.viewWillDisappear(animated)\n\n progressView.stopUpdatingProgress()\n\n deviceTransferService.removeObserver(self)\n deviceTransferService.cancelTransferFromOldDevice()\n }\n\n @objc\n func didTapNext", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/Device Transfer/DeviceTransferProgressViewController.swift", | |
"start": 45, | |
"end": 67, | |
"startLoc": { | |
"line": 45, | |
"column": 13, | |
"position": 293 | |
}, | |
"endLoc": { | |
"line": 67, | |
"column": 11, | |
"position": 430 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/Registration/Device Transfer/OnboardingTransferProgressViewController.swift", | |
"start": 57, | |
"end": 82, | |
"startLoc": { | |
"line": 57, | |
"column": 2, | |
"position": 382 | |
}, | |
"endLoc": { | |
"line": 82, | |
"column": 13, | |
"position": 524 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 14, | |
"fragment": "let actionSheet = ActionSheetController(\n title: NSLocalizedString(\"DEVICE_TRANSFER_CANCEL_CONFIRMATION_TITLE\",\n comment: \"The title of the dialog asking the user if they want to cancel a device transfer\"),\n message: NSLocalizedString(\"DEVICE_TRANSFER_CANCEL_CONFIRMATION_MESSAGE\",\n comment: \"The message of the dialog asking the user if they want to cancel a device transfer\")\n )\n actionSheet.addAction(OWSActionSheets.cancelAction)\n\n let okAction = ActionSheetAction(\n title: NSLocalizedString(\"DEVICE_TRANSFER_CANCEL_CONFIRMATION_ACTION\",\n comment: \"The stop action of the dialog asking the user if they want to cancel a device transfer\"),\n style: .destructive\n ) { _ in\n self.dismissActionSheet", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/Device Transfer/DeviceTransferNavigationController.swift", | |
"start": 39, | |
"end": 52, | |
"startLoc": { | |
"line": 39, | |
"column": 13, | |
"position": 285 | |
}, | |
"endLoc": { | |
"line": 52, | |
"column": 19, | |
"position": 387 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/Registration/Device Transfer/OnboardingTransferProgressViewController.swift", | |
"start": 89, | |
"end": 102, | |
"startLoc": { | |
"line": 89, | |
"column": 9, | |
"position": 567 | |
}, | |
"endLoc": { | |
"line": 102, | |
"column": 21, | |
"position": 669 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 16, | |
"fragment": "self.databaseStorage.write { transaction in\n let oldDMConfig = oldGroupThread.disappearingMessagesConfiguration(with: transaction)\n _ = OWSDisappearingMessagesConfiguration.applyToken(oldDMConfig.asToken,\n toThread: newGroupThread,\n transaction: transaction)\n }\n\n Logger.info(\"Complete.\")\n\n SignalApp.shared().presentConversation(for: newGroupThread, animated: true)\n }.catch(on: .global()) { error in\n owsFailDebug(\"Error: \\(error)\")\n }\n }\n\n class func copyToAnotherGroup", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/DebugUI/DebugUIStress.swift", | |
"start": 123, | |
"end": 138, | |
"startLoc": { | |
"line": 123, | |
"column": 13, | |
"position": 1075 | |
}, | |
"endLoc": { | |
"line": 138, | |
"column": 19, | |
"position": 1208 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/DebugUI/DebugUIStress.swift", | |
"start": 45, | |
"end": 62, | |
"startLoc": { | |
"line": 45, | |
"column": 13, | |
"position": 280 | |
}, | |
"endLoc": { | |
"line": 62, | |
"column": 15, | |
"position": 419 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 8, | |
"fragment": ")\", style: .default) { _ in\n guard let textField = alert.textFields?.first else {\n owsFailDebug(\"missing text field\")\n return\n }\n\n guard let inputString = textField.text, inputString.count >= 4 else {\n OWSActionSheets.showActionSheet(title: \"new file dir missing or less than 4 chars\"", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/DebugUI/DebugUIFileBrowser.swift", | |
"start": 171, | |
"end": 178, | |
"startLoc": { | |
"line": 171, | |
"column": 9, | |
"position": 1538 | |
}, | |
"endLoc": { | |
"line": 178, | |
"column": 44, | |
"position": 1622 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/DebugUI/DebugUIFileBrowser.swift", | |
"start": 126, | |
"end": 133, | |
"startLoc": { | |
"line": 126, | |
"column": 18, | |
"position": 1090 | |
}, | |
"endLoc": { | |
"line": 133, | |
"column": 45, | |
"position": 1174 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 13, | |
"fragment": ",\n message: \"Will be created in \\(strongSelf.fileURL.lastPathComponent)\",\n preferredStyle: .alert)\n\n alert.addAction(UIAlertAction(title: \"Cancel\", style: .cancel, handler: nil))\n alert.addAction(UIAlertAction(title: \"Create\", style: .default) { _ in\n guard let textField = alert.textFields?.first else {\n owsFailDebug(\"missing text field\")\n return\n }\n\n guard let inputString = textField.text, inputString.count >= 4 else {\n OWSActionSheets.showActionSheet(title: \"dir name missing or less than 4 chars\"", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/DebugUI/DebugUIFileBrowser.swift", | |
"start": 320, | |
"end": 332, | |
"startLoc": { | |
"line": 320, | |
"column": 14, | |
"position": 2962 | |
}, | |
"endLoc": { | |
"line": 332, | |
"column": 40, | |
"position": 3108 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/DebugUI/DebugUIFileBrowser.swift", | |
"start": 282, | |
"end": 294, | |
"startLoc": { | |
"line": 282, | |
"column": 15, | |
"position": 2624 | |
}, | |
"endLoc": { | |
"line": 294, | |
"column": 41, | |
"position": 2770 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 16, | |
"fragment": "}\n\n @available(*, unavailable, message:\"use other constructor instead.\")\n @objc\n public required init(coder aDecoder: NSCoder) {\n notImplemented()\n }\n\n @available(*, unavailable, message:\"use other constructor instead.\")\n @objc\n public required init(dictionary dictionaryValue: [String: Any]!) throws {\n notImplemented()\n }\n\n @objc\n public let", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/TypingIndicatorInteraction.swift", | |
"start": 20, | |
"end": 35, | |
"startLoc": { | |
"line": 20, | |
"column": 5, | |
"position": 104 | |
}, | |
"endLoc": { | |
"line": 35, | |
"column": 4, | |
"position": 209 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/UnreadIndicatorInteraction.swift", | |
"start": 18, | |
"end": 33, | |
"startLoc": { | |
"line": 18, | |
"column": 5, | |
"position": 88 | |
}, | |
"endLoc": { | |
"line": 33, | |
"column": 5, | |
"position": 193 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 16, | |
"fragment": "}\n\n @available(*, unavailable, message:\"use other constructor instead.\")\n @objc\n public required init(coder aDecoder: NSCoder) {\n notImplemented()\n }\n\n @available(*, unavailable, message:\"use other constructor instead.\")\n @objc\n public required init(dictionary dictionaryValue: [String: Any]!) throws {\n notImplemented()\n }\n\n @objc\n public init(thread: TSThread, timestamp: UInt64)", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/ThreadDetailsInteraction.swift", | |
"start": 18, | |
"end": 33, | |
"startLoc": { | |
"line": 18, | |
"column": 5, | |
"position": 88 | |
}, | |
"endLoc": { | |
"line": 33, | |
"column": 2, | |
"position": 205 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/UnreadIndicatorInteraction.swift", | |
"start": 18, | |
"end": 33, | |
"startLoc": { | |
"line": 18, | |
"column": 5, | |
"position": 88 | |
}, | |
"endLoc": { | |
"line": 33, | |
"column": 2, | |
"position": 205 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 13, | |
"fragment": "{\n buttons = [\n prepareButton(title: NSLocalizedString(\"MESSAGE_REQUEST_VIEW_BLOCK_BUTTON\",\n comment: \"A button used to block a user on an incoming message request.\"),\n titleColor: .ows_accentRed) { [weak self] in\n self?.delegate?.messageRequestViewDidTapBlock(mode: mode)\n },\n prepareButton(title: NSLocalizedString(\"MESSAGE_REQUEST_VIEW_DELETE_BUTTON\",\n comment: \"incoming message request button text which deletes a conversation\"),\n titleColor: .ows_accentRed) { [weak self] in\n self?.delegate?.messageRequestViewDidTapDelete()\n },\n prepareButton(title: NSLocalizedString(\"MESSAGE_REQUEST_VIEW_ACCEPT_BUTTON\"", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/MessageRequestView.swift", | |
"start": 257, | |
"end": 269, | |
"startLoc": { | |
"line": 257, | |
"column": 2, | |
"position": 1743 | |
}, | |
"endLoc": { | |
"line": 269, | |
"column": 37, | |
"position": 1868 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/MessageRequestView.swift", | |
"start": 237, | |
"end": 249, | |
"startLoc": { | |
"line": 237, | |
"column": 2, | |
"position": 1555 | |
}, | |
"endLoc": { | |
"line": 249, | |
"column": 39, | |
"position": 1680 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 17, | |
"fragment": "buttons = [\n prepareButton(title: NSLocalizedString(\"MESSAGE_REQUEST_VIEW_BLOCK_BUTTON\",\n comment: \"A button used to block a user on an incoming message request.\"),\n titleColor: .ows_accentRed) { [weak self] in\n self?.delegate?.messageRequestViewDidTapBlock(mode: mode)\n },\n prepareButton(title: NSLocalizedString(\"MESSAGE_REQUEST_VIEW_DELETE_BUTTON\",\n comment: \"incoming message request button text which deletes a conversation\"),\n titleColor: .ows_accentRed) { [weak self] in\n self?.delegate?.messageRequestViewDidTapDelete()\n },\n prepareButton(title: NSLocalizedString(\"MESSAGE_REQUEST_VIEW_ACCEPT_BUTTON\",\n comment: \"A button used to accept a user on an incoming message request.\"),\n titleColor: Theme.accentBlueColor) { [weak self] in\n self?.delegate?.messageRequestViewDidTapAccept(mode: mode)\n }]\n return", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/MessageRequestView.swift", | |
"start": 298, | |
"end": 314, | |
"startLoc": { | |
"line": 298, | |
"column": 2, | |
"position": 2063 | |
}, | |
"endLoc": { | |
"line": 314, | |
"column": 7, | |
"position": 2235 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/MessageRequestView.swift", | |
"start": 238, | |
"end": 274, | |
"startLoc": { | |
"line": 238, | |
"column": 13, | |
"position": 1558 | |
}, | |
"endLoc": { | |
"line": 274, | |
"column": 2, | |
"position": 1918 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 19, | |
"fragment": "}\n\n @available(*, unavailable, message:\"use other constructor instead.\")\n @objc\n public required init(coder aDecoder: NSCoder) {\n notImplemented()\n }\n\n @available(*, unavailable, message:\"use other constructor instead.\")\n @objc\n public required init(dictionary dictionaryValue: [String: Any]!) throws {\n notImplemented()\n }\n\n @objc\n public init(thread: TSThread, timestamp: UInt64) {\n // Include timestamp in uniqueId to ensure invariant that\n // interactions don't move in the chat history ordering.\n super.init(uniqueId: \"DateHeader_", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/DateHeaderInteraction.swift", | |
"start": 18, | |
"end": 36, | |
"startLoc": { | |
"line": 18, | |
"column": 5, | |
"position": 88 | |
}, | |
"endLoc": { | |
"line": 36, | |
"column": 13, | |
"position": 223 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/UnreadIndicatorInteraction.swift", | |
"start": 18, | |
"end": 36, | |
"startLoc": { | |
"line": 18, | |
"column": 5, | |
"position": 88 | |
}, | |
"endLoc": { | |
"line": 36, | |
"column": 16, | |
"position": 223 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 12, | |
"fragment": "var sortIdToIndexPathMap = [UInt64: IndexPath]()\n for (index, renderItem) in renderItems.enumerated() {\n let indexPath = IndexPath(row: index, section: Self.messageSection)\n let sortId = renderItem.interaction.sortId\n sortIdToIndexPathMap[sortId] = indexPath\n }\n\n // Honor the scroll continuity bias.\n //\n // If we prefer continuity with regard to the bottom\n // of the conversation, start with the last items.\n let", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/ConversationViewController+Scroll.swift", | |
"start": 646, | |
"end": 657, | |
"startLoc": { | |
"line": 646, | |
"column": 9, | |
"position": 4495 | |
}, | |
"endLoc": { | |
"line": 657, | |
"column": 4, | |
"position": 4593 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/ConversationViewController+Scroll.swift", | |
"start": 588, | |
"end": 595, | |
"startLoc": { | |
"line": 588, | |
"column": 9, | |
"position": 3982 | |
}, | |
"endLoc": { | |
"line": 595, | |
"column": 4, | |
"position": 4068 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 19, | |
"fragment": "guard let self = self else {\n return\n }\n\n // If the scroll action is not animated, perform it _before_\n // updateViewToReflectLoad().\n if !scrollAction.isAnimated {\n self.perform(scrollAction: scrollAction)\n }\n\n self.updateViewToReflectLoad(loadedRenderState: renderState)\n\n self.loadDidLand()\n\n if scrollAction.isAnimated {\n self.perform(scrollAction: scrollAction)\n }\n\n viewState", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/ConversationViewController+CVC.swift", | |
"start": 567, | |
"end": 585, | |
"startLoc": { | |
"line": 567, | |
"column": 13, | |
"position": 3397 | |
}, | |
"endLoc": { | |
"line": 585, | |
"column": 10, | |
"position": 3494 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/ConversationViewController+CVC.swift", | |
"start": 424, | |
"end": 436, | |
"startLoc": { | |
"line": 424, | |
"column": 13, | |
"position": 2368 | |
}, | |
"endLoc": { | |
"line": 436, | |
"column": 2, | |
"position": 2459 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 34, | |
"fragment": "?\n\n @objc\n init(threadViewModel: ThreadViewModel, fromViewController: UIViewController) {\n let thread = threadViewModel.threadRecord\n self.thread = thread\n owsAssertDebug(thread as? TSGroupThread != nil)\n self.fromViewController = fromViewController\n\n super.init(frame: .zero)\n\n createContents()\n }\n\n private func createContents() {\n // We want the background to extend to the bottom of the screen\n // behind the safe area, so we add that inset to our bottom inset\n // instead of pinning this view to the safe area\n let safeAreaInset = safeAreaInsets.bottom\n\n autoresizingMask = .flexibleHeight\n\n axis = .vertical\n spacing = 11\n layoutMargins = UIEdgeInsets(top: 16, leading: 16, bottom: 20 + safeAreaInset, trailing: 16)\n isLayoutMarginsRelativeArrangement = true\n alignment = .fill\n\n let backgroundView = UIView()\n backgroundView.backgroundColor = Theme.backgroundColor\n addSubview(backgroundView)\n backgroundView.autoPinEdgesToSuperviewEdges()\n\n let format", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ConversationView/BlockingGroupMigrationView.swift", | |
"start": 13, | |
"end": 46, | |
"startLoc": { | |
"line": 13, | |
"column": 17, | |
"position": 50 | |
}, | |
"endLoc": { | |
"line": 46, | |
"column": 7, | |
"position": 286 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/MemberRequestView.swift", | |
"start": 16, | |
"end": 49, | |
"startLoc": { | |
"line": 16, | |
"column": 23, | |
"position": 65 | |
}, | |
"endLoc": { | |
"line": 49, | |
"column": 6, | |
"position": 301 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 16, | |
"fragment": "}\n\n private let collectionViewFlowLayout = UICollectionViewFlowLayout()\n\n init() {\n super.init(frame: .zero, collectionViewLayout: collectionViewFlowLayout)\n\n dataSource = self\n delegate = self\n showsHorizontalScrollIndicator = false\n\n contentInset = UIEdgeInsets(top: 0, leading: 6, bottom: 0, trailing: 6)\n\n backgroundColor = .clear\n\n register(AttachmentFormatCell", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/Attachment Keyboard/AttachmentFormatPickerView.swift", | |
"start": 24, | |
"end": 39, | |
"startLoc": { | |
"line": 24, | |
"column": 5, | |
"position": 130 | |
}, | |
"endLoc": { | |
"line": 39, | |
"column": 21, | |
"position": 239 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/Attachment Keyboard/RecentPhotoCollectionView.swift", | |
"start": 64, | |
"end": 79, | |
"startLoc": { | |
"line": 64, | |
"column": 5, | |
"position": 466 | |
}, | |
"endLoc": { | |
"line": 79, | |
"column": 16, | |
"position": 575 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 14, | |
"fragment": "nameForTheme(mode),\n actionBlock: { [weak self] in\n self?.changeTheme(mode)\n },\n accessoryType: Theme.getOrFetchCurrentTheme() == mode ? .checkmark : .none\n )\n }\n\n func changeTheme(_ mode: ThemeMode) {\n Theme.setCurrent(mode)\n updateTableContents()\n }\n\n var", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/AppSettings/AppearanceSettingsTableViewController.swift", | |
"start": 60, | |
"end": 73, | |
"startLoc": { | |
"line": 60, | |
"column": 2, | |
"position": 438 | |
}, | |
"endLoc": { | |
"line": 73, | |
"column": 4, | |
"position": 535 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/AppSettings/ThemeSettingsTableViewController.swift", | |
"start": 38, | |
"end": 51, | |
"startLoc": { | |
"line": 38, | |
"column": 2, | |
"position": 231 | |
}, | |
"endLoc": { | |
"line": 51, | |
"column": 7, | |
"position": 328 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 11, | |
"fragment": "func nameForTheme(_ mode: ThemeMode) -> String {\n switch mode {\n case .dark:\n return NSLocalizedString(\"APPEARANCE_SETTINGS_DARK_THEME_NAME\", comment: \"Name indicating that the dark theme is enabled.\")\n case .light:\n return NSLocalizedString(\"APPEARANCE_SETTINGS_LIGHT_THEME_NAME\", comment: \"Name indicating that the light theme is enabled.\")\n case .system:\n return NSLocalizedString(\"APPEARANCE_SETTINGS_SYSTEM_THEME_NAME\", comment: \"Name indicating that the system theme is enabled.\")\n }\n }\n}", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/AppSettings/AppearanceSettingsTableViewController.swift", | |
"start": 77, | |
"end": 87, | |
"startLoc": { | |
"line": 77, | |
"column": 5, | |
"position": 561 | |
}, | |
"endLoc": { | |
"line": 87, | |
"column": 2, | |
"position": 656 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/AppSettings/ThemeSettingsTableViewController.swift", | |
"start": 55, | |
"end": 69, | |
"startLoc": { | |
"line": 55, | |
"column": 2, | |
"position": 358 | |
}, | |
"endLoc": { | |
"line": 69, | |
"column": 6, | |
"position": 458 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 10, | |
"fragment": "avatarData {\n avatarImageView.image = UIImage(data: avatarData)\n } else {\n avatarImageView.image = OWSContactAvatarBuilder(forLocalUserWithDiameter: UInt(avatarDiameter)).buildDefaultImage()\n }\n avatarImageView.clipsToBounds = true\n avatarImageView.layer.cornerRadius = avatarDiameter / 2\n avatarImageView.autoSetDimensions(to: CGSize(square: avatarDiameter))\n\n let", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/AppSettings/AppSettingsViewController.swift", | |
"start": 202, | |
"end": 211, | |
"startLoc": { | |
"line": 202, | |
"column": 2, | |
"position": 1860 | |
}, | |
"endLoc": { | |
"line": 211, | |
"column": 4, | |
"position": 1954 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/AppSettings/Profile/ProfileSettingsViewController.swift", | |
"start": 231, | |
"end": 240, | |
"startLoc": { | |
"line": 231, | |
"column": 2, | |
"position": 1830 | |
}, | |
"endLoc": { | |
"line": 240, | |
"column": 5, | |
"position": 1924 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 11, | |
"fragment": "}\n\n func titleLabel(text: String) -> UILabel {\n let titleLabel = UILabel()\n titleLabel.text = text\n titleLabel.textColor = Theme.primaryTextColor\n titleLabel.font = UIFont.ows_dynamicTypeTitle2.ows_semibold\n titleLabel.numberOfLines = 0\n titleLabel.lineBreakMode = .byWordWrapping\n titleLabel.textAlignment = .center\n titleLabel", | |
"tokens": 0, | |
"firstFile": { | |
"name": "Experience Upgrades/Upgrade Views/NotificationPermissionReminderMegaphone.swift", | |
"start": 119, | |
"end": 129, | |
"startLoc": { | |
"line": 119, | |
"column": 5, | |
"position": 870 | |
}, | |
"endLoc": { | |
"line": 129, | |
"column": 11, | |
"position": 965 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/Device Transfer/DeviceTransferNavigationController.swift", | |
"start": 99, | |
"end": 109, | |
"startLoc": { | |
"line": 99, | |
"column": 5, | |
"position": 721 | |
}, | |
"endLoc": { | |
"line": 109, | |
"column": 7, | |
"position": 816 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 12, | |
"fragment": "return titleLabel\n }\n\n func explanationLabel(explanationText: String) -> UILabel {\n let explanationLabel = UILabel()\n explanationLabel.textColor = Theme.secondaryTextAndIconColor\n explanationLabel.font = .ows_dynamicTypeBody2\n explanationLabel.text = explanationText\n explanationLabel.numberOfLines = 0\n explanationLabel.textAlignment = .center\n explanationLabel.lineBreakMode = .byWordWrapping\n explanationLabel", | |
"tokens": 0, | |
"firstFile": { | |
"name": "Experience Upgrades/Upgrade Views/NotificationPermissionReminderMegaphone.swift", | |
"start": 131, | |
"end": 142, | |
"startLoc": { | |
"line": 131, | |
"column": 9, | |
"position": 979 | |
}, | |
"endLoc": { | |
"line": 142, | |
"column": 17, | |
"position": 1076 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/Device Transfer/DeviceTransferNavigationController.swift", | |
"start": 109, | |
"end": 120, | |
"startLoc": { | |
"line": 109, | |
"column": 9, | |
"position": 816 | |
}, | |
"endLoc": { | |
"line": 120, | |
"column": 7, | |
"position": 913 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 17, | |
"fragment": "return explanationLabel\n }\n\n func button(title: String, selector: Selector) -> OWSFlatButton {\n let font = UIFont.ows_dynamicTypeBodyClamped.ows_semibold\n let buttonHeight = OWSFlatButton.heightForFont(font)\n let button = OWSFlatButton.button(title: title,\n font: font,\n titleColor: .white,\n backgroundColor: .ows_accentBlue,\n target: self,\n selector: selector)\n button.autoSetDimension(.height, toSize: buttonHeight)\n return button\n }\n\n private", | |
"tokens": 0, | |
"firstFile": { | |
"name": "Experience Upgrades/Upgrade Views/NotificationPermissionReminderMegaphone.swift", | |
"start": 144, | |
"end": 160, | |
"startLoc": { | |
"line": 144, | |
"column": 9, | |
"position": 1090 | |
}, | |
"endLoc": { | |
"line": 160, | |
"column": 8, | |
"position": 1228 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/Device Transfer/DeviceTransferNavigationController.swift", | |
"start": 120, | |
"end": 135, | |
"startLoc": { | |
"line": 120, | |
"column": 9, | |
"position": 913 | |
}, | |
"endLoc": { | |
"line": 135, | |
"column": 2, | |
"position": 1049 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 15, | |
"fragment": ")\n navigationController?.setNavigationBarHidden(true, animated: false)\n }\n\n override func viewWillDisappear(_ animated: Bool) {\n super.viewWillDisappear(animated)\n navigationController?.setNavigationBarHidden(false, animated: false)\n }\n\n override func loadView() {\n\n self.view = UIView.container()\n self.view.backgroundColor = Theme.backgroundColor\n\n let title", | |
"tokens": 0, | |
"firstFile": { | |
"name": "Experience Upgrades/Upgrade Views/GroupsV2AndMentionsSplash.swift", | |
"start": 22, | |
"end": 36, | |
"startLoc": { | |
"line": 22, | |
"column": 2, | |
"position": 133 | |
}, | |
"endLoc": { | |
"line": 36, | |
"column": 6, | |
"position": 240 | |
} | |
}, | |
"secondFile": { | |
"name": "Experience Upgrades/Upgrade Views/IntroducingPINs.swift", | |
"start": 65, | |
"end": 79, | |
"startLoc": { | |
"line": 65, | |
"column": 9, | |
"position": 515 | |
}, | |
"endLoc": { | |
"line": 79, | |
"column": 14, | |
"position": 622 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 17, | |
"fragment": ")\n }\n }\n\n private class func showLearnMoreView() {\n guard let url = URL(string: \"https://support.signal.org/hc/articles/360007319331\") else {\n owsFailDebug(\"Invalid url.\")\n return\n }\n guard let fromViewController = CurrentAppContext().frontmostViewController() else {\n owsFailDebug(\"Missing fromViewController.\")\n return\n }\n let vc = SFSafariViewController(url: url)\n fromViewController.present(vc, animated: true, completion: nil)\n }\n}", | |
"tokens": 0, | |
"firstFile": { | |
"name": "Experience Upgrades/Upgrade Views/GroupsV2AndMentionsSplash.swift", | |
"start": 159, | |
"end": 175, | |
"startLoc": { | |
"line": 159, | |
"column": 2, | |
"position": 1337 | |
}, | |
"endLoc": { | |
"line": 175, | |
"column": 2, | |
"position": 1463 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/NewGroupView/NewGroupConfirmViewController.swift", | |
"start": 391, | |
"end": 407, | |
"startLoc": { | |
"line": 391, | |
"column": 12, | |
"position": 2975 | |
}, | |
"endLoc": { | |
"line": 407, | |
"column": 2, | |
"position": 3101 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 15, | |
"fragment": ",\n comment: \"Snooze action text for contact permission reminder megaphone\")\n )\n setButtons(primary: primaryButton, secondary: secondaryButton)\n }\n\n required init(coder: NSCoder) {\n fatalError(\"init(coder:) has not been implemented\")\n }\n\n override func dismiss(animated: Bool = true, completion: (() -> Void)? = nil) {\n super.dismiss(animated: animated, completion: completion)\n actionSheetController?.dismiss(animated: animated)\n }\n}", | |
"tokens": 0, | |
"firstFile": { | |
"name": "Experience Upgrades/Upgrade Views/ContactPermissionReminderMegaphone.swift", | |
"start": 62, | |
"end": 76, | |
"startLoc": { | |
"line": 62, | |
"column": 36, | |
"position": 391 | |
}, | |
"endLoc": { | |
"line": 76, | |
"column": 2, | |
"position": 515 | |
} | |
}, | |
"secondFile": { | |
"name": "Experience Upgrades/Upgrade Views/NotificationPermissionReminderMegaphone.swift", | |
"start": 68, | |
"end": 82, | |
"startLoc": { | |
"line": 68, | |
"column": 41, | |
"position": 431 | |
}, | |
"endLoc": { | |
"line": 82, | |
"column": 2, | |
"position": 555 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 11, | |
"fragment": "@available(*, unavailable, message:\"use other constructor instead.\")\n required init?(coder aDecoder: NSCoder) {\n notImplemented()\n }\n\n @available(*, unavailable, message:\"use other constructor instead.\")\n override init(frame: CGRect) {\n notImplemented()\n }\n\n init(mode", | |
"tokens": 0, | |
"firstFile": { | |
"name": "views/ReminderView.swift", | |
"start": 33, | |
"end": 43, | |
"startLoc": { | |
"line": 33, | |
"column": 5, | |
"position": 147 | |
}, | |
"endLoc": { | |
"line": 43, | |
"column": 5, | |
"position": 226 | |
} | |
}, | |
"secondFile": { | |
"name": "views/TypingIndicatorView.swift", | |
"start": 111, | |
"end": 121, | |
"startLoc": { | |
"line": 111, | |
"column": 9, | |
"position": 704 | |
}, | |
"endLoc": { | |
"line": 121, | |
"column": 8, | |
"position": 783 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 13, | |
"fragment": ")\n }\n\n @available(*, unavailable, message: \"Unimplemented\")\n required public init?(coder aDecoder: NSCoder) {\n notImplemented()\n }\n\n var image: UIImage? {\n get { return imageView.image }\n set {\n imageView.image = newValue\n imageView.backgroundColor = newValue == nil ? loadingColor", | |
"tokens": 0, | |
"firstFile": { | |
"name": "views/PhotoGridViewCell.swift", | |
"start": 126, | |
"end": 138, | |
"startLoc": { | |
"line": 126, | |
"column": 20, | |
"position": 1016 | |
}, | |
"endLoc": { | |
"line": 138, | |
"column": 13, | |
"position": 1118 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/Attachment Keyboard/RecentPhotoCollectionView.swift", | |
"start": 298, | |
"end": 310, | |
"startLoc": { | |
"line": 298, | |
"column": 2, | |
"position": 2458 | |
}, | |
"endLoc": { | |
"line": 310, | |
"column": 6, | |
"position": 2560 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 17, | |
"fragment": "(coder: NSCoder) {\n fatalError(\"init(coder:) has not been implemented\")\n }\n\n required init(dictionary dictionaryValue: [String: Any]!) throws {\n fatalError(\"init(dictionary:) has not been implemented\")\n }\n\n public override var shouldBeSaved: Bool {\n return false\n }\n\n override func anyWillInsert(with transaction: SDSAnyWriteTransaction) {\n owsFailDebug(\"shouldn't save mock message\")\n }\n\n class", | |
"tokens": 0, | |
"firstFile": { | |
"name": "views/MockConversationView.swift", | |
"start": 233, | |
"end": 249, | |
"startLoc": { | |
"line": 233, | |
"column": 2, | |
"position": 1630 | |
}, | |
"endLoc": { | |
"line": 249, | |
"column": 6, | |
"position": 1733 | |
} | |
}, | |
"secondFile": { | |
"name": "views/MockConversationView.swift", | |
"start": 208, | |
"end": 223, | |
"startLoc": { | |
"line": 208, | |
"column": 5, | |
"position": 1454 | |
}, | |
"endLoc": { | |
"line": 223, | |
"column": 2, | |
"position": 1555 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 20, | |
"fragment": "let panGestureRecognizer = DirectionalPanGestureRecognizer(direction: .vertical, target: self, action: #selector(handlePan))\n view.addGestureRecognizer(panGestureRecognizer)\n panGestureRecognizer.delegate = self\n\n // We also want to handle the pan gesture for the table\n // view, so we can do a nice scroll to dismiss gesture, and\n // so we can transfer any initial scrolling into maximizing\n // the view.\n tableView.panGestureRecognizer.addTarget(self, action: #selector(handlePan))\n\n handle.backgroundColor = .ows_whiteAlpha80\n handle.autoSetDimensions(to: CGSize(width: 56, height: 5))\n handle.layer.cornerRadius = 5 / 2\n view.addSubview(handle)\n handle.autoHCenterInSuperview()\n handle.autoPinEdge(.bottom, to: .top, of: contentView, withOffset: -8)\n }\n\n @objc func handlePan(_ sender: UIPanGestureRecognizer) {\n switch", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/SafetyNumberConfirmationSheet.swift", | |
"start": 284, | |
"end": 303, | |
"startLoc": { | |
"line": 284, | |
"column": 9, | |
"position": 2416 | |
}, | |
"endLoc": { | |
"line": 303, | |
"column": 7, | |
"position": 2612 | |
} | |
}, | |
"secondFile": { | |
"name": "Calls/UserInterface/Group/GroupCallMemberSheet.swift", | |
"start": 123, | |
"end": 206, | |
"startLoc": { | |
"line": 123, | |
"column": 9, | |
"position": 943 | |
}, | |
"endLoc": { | |
"line": 206, | |
"column": 4, | |
"position": 1587 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 25, | |
"fragment": ": UIGestureRecognizerDelegate {\n func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {\n switch gestureRecognizer {\n case is UITapGestureRecognizer:\n let point = gestureRecognizer.location(in: view)\n guard !contentView.frame.contains(point) else { return false }\n return true\n default:\n return true\n }\n }\n\n func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {\n switch gestureRecognizer {\n case is UIPanGestureRecognizer:\n return tableView.panGestureRecognizer == otherGestureRecognizer\n default:\n return false\n }\n }\n}\n\n// MARK: -\n\nprivate class SafetyNumberConfirmationAnimationController", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/SafetyNumberConfirmationSheet.swift", | |
"start": 522, | |
"end": 546, | |
"startLoc": { | |
"line": 522, | |
"column": 30, | |
"position": 4449 | |
}, | |
"endLoc": { | |
"line": 546, | |
"column": 44, | |
"position": 4630 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Reactions Details/ReactionsDetailSheet.swift", | |
"start": 583, | |
"end": 449, | |
"startLoc": { | |
"line": 583, | |
"column": 21, | |
"position": 4539 | |
}, | |
"endLoc": { | |
"line": 449, | |
"column": 40, | |
"position": 3716 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 40, | |
"fragment": "else { return nil }\n return vc.backdropView\n }\n\n override init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?) {\n super.init(presentedViewController: presentedViewController, presenting: presentingViewController)\n backdropView?.backgroundColor = Theme.backdropColor\n }\n\n override func presentationTransitionWillBegin() {\n guard let containerView = containerView, let backdropView = backdropView else { return }\n backdropView.alpha = 0\n containerView.addSubview(backdropView)\n backdropView.autoPinEdgesToSuperviewEdges()\n containerView.layoutIfNeeded()\n\n presentedViewController.transitionCoordinator?.animate(alongsideTransition: { _ in\n self.backdropView?.alpha = 1\n }, completion: nil)\n }\n\n override func dismissalTransitionWillBegin() {\n presentedViewController.transitionCoordinator?.animate(alongsideTransition: { _ in\n self.backdropView?.alpha = 0\n }, completion: { _ in\n self.backdropView?.removeFromSuperview()\n })\n }\n\n override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {\n super.viewWillTransition(to: size, with: coordinator)\n guard let presentedView = presentedView else { return }\n coordinator.animate(alongsideTransition: { _ in\n presentedView.frame = self.frameOfPresentedViewInContainerView\n presentedView.layoutIfNeeded()\n }, completion: nil)\n }\n}\n\nextension SafetyNumberConfirmationSheet", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/SafetyNumberConfirmationSheet.swift", | |
"start": 549, | |
"end": 588, | |
"startLoc": { | |
"line": 549, | |
"column": 2, | |
"position": 4665 | |
}, | |
"endLoc": { | |
"line": 588, | |
"column": 30, | |
"position": 5037 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Reactions Details/ReactionsDetailSheet.swift", | |
"start": 610, | |
"end": 649, | |
"startLoc": { | |
"line": 610, | |
"column": 2, | |
"position": 4755 | |
}, | |
"endLoc": { | |
"line": 649, | |
"column": 21, | |
"position": 5127 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 12, | |
"fragment": ": UITextFieldDelegate {\n public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {\n let hasPendingChanges: Bool\n if pinType == .numeric {\n ViewControllerUtils.ows2FAPINTextField(textField, shouldChangeCharactersIn: range, replacementString: string)\n hasPendingChanges = false\n } else {\n hasPendingChanges = true\n }\n\n // Reset the validation state to clear errors, since the user is trying again\n validationState", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/OWSPinSetupViewController.swift", | |
"start": 659, | |
"end": 670, | |
"startLoc": { | |
"line": 659, | |
"column": 23, | |
"position": 5381 | |
}, | |
"endLoc": { | |
"line": 670, | |
"column": 16, | |
"position": 5494 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/Registration/Onboarding2FAViewController.swift", | |
"start": 472, | |
"end": 483, | |
"startLoc": { | |
"line": 472, | |
"column": 28, | |
"position": 3492 | |
}, | |
"endLoc": { | |
"line": 483, | |
"column": 13, | |
"position": 3605 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 7, | |
"fragment": "pinTextField.isSecureTextEntry = true\n pinTextField.defaultTextAttributes.updateValue(5, forKey: .kern)\n pinTextField.keyboardAppearance = Theme.keyboardAppearance\n pinTextField.setContentHuggingHorizontalLow()\n pinTextField.setCompressionResistanceHorizontalLow()\n pinTextField.autoSetDimension(.height, toSize: 40)\n pinTextField.accessibilityIdentifier = \"pinReminder.pinTextField\"", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/OWSPinReminderViewController.swift", | |
"start": 123, | |
"end": 129, | |
"startLoc": { | |
"line": 123, | |
"column": 9, | |
"position": 948 | |
}, | |
"endLoc": { | |
"line": 129, | |
"column": 27, | |
"position": 1020 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/Registration/Onboarding2FAViewController.swift", | |
"start": 84, | |
"end": 90, | |
"startLoc": { | |
"line": 84, | |
"column": 9, | |
"position": 633 | |
}, | |
"endLoc": { | |
"line": 90, | |
"column": 30, | |
"position": 705 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 16, | |
"fragment": "()\n\n presentedViewController.transitionCoordinator?.animate(alongsideTransition: { _ in\n self.backdropView.alpha = 1\n }, completion: nil)\n }\n\n override func dismissalTransitionWillBegin() {\n presentedViewController.transitionCoordinator?.animate(alongsideTransition: { _ in\n self.backdropView.alpha = 0\n }, completion: { _ in\n self.backdropView.removeFromSuperview()\n })\n }\n\n override", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/OWSPinReminderViewController.swift", | |
"start": 324, | |
"end": 339, | |
"startLoc": { | |
"line": 324, | |
"column": 15, | |
"position": 2689 | |
}, | |
"endLoc": { | |
"line": 339, | |
"column": 9, | |
"position": 2805 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/Stickers/StickerPackViewController.swift", | |
"start": 442, | |
"end": 457, | |
"startLoc": { | |
"line": 442, | |
"column": 29, | |
"position": 3482 | |
}, | |
"endLoc": { | |
"line": 457, | |
"column": 4, | |
"position": 3598 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 15, | |
"fragment": ".removeFromSuperview()\n })\n }\n\n override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {\n super.viewWillTransition(to: size, with: coordinator)\n guard let presentedView = presentedView else { return }\n coordinator.animate(alongsideTransition: { _ in\n presentedView.frame = self.frameOfPresentedViewInContainerView\n presentedView.layoutIfNeeded()\n }, completion: nil)\n }\n}\n\nextension PinReminderViewController", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/OWSPinReminderViewController.swift", | |
"start": 335, | |
"end": 349, | |
"startLoc": { | |
"line": 335, | |
"column": 13, | |
"position": 2791 | |
}, | |
"endLoc": { | |
"line": 349, | |
"column": 26, | |
"position": 2915 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/Reactions Details/ReactionsDetailSheet.swift", | |
"start": 635, | |
"end": 649, | |
"startLoc": { | |
"line": 635, | |
"column": 2, | |
"position": 5003 | |
}, | |
"endLoc": { | |
"line": 649, | |
"column": 21, | |
"position": 5127 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 29, | |
"fragment": "private let containerView = UIView()\n private let pinTextField = UITextField()\n\n private lazy var pinStrokeNormal = pinTextField.addBottomStroke()\n private lazy var pinStrokeError = pinTextField.addBottomStroke(color: .ows_accentRed, strokeWidth: 2)\n private let validationWarningLabel = UILabel()\n\n enum ValidationState {\n case valid\n case tooShort\n case mismatch\n\n var isInvalid: Bool {\n return self != .valid\n }\n }\n private var validationState: ValidationState = .valid {\n didSet {\n updateValidationWarnings()\n\n if validationState.isInvalid {\n hasGuessedWrong = true\n }\n }\n }\n private var hasGuessedWrong = false\n\n @objc\n init(title", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/OWSPinConfirmationViewController.swift", | |
"start": 15, | |
"end": 43, | |
"startLoc": { | |
"line": 15, | |
"column": 5, | |
"position": 81 | |
}, | |
"endLoc": { | |
"line": 43, | |
"column": 6, | |
"position": 286 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/OWSPinReminderViewController.swift", | |
"start": 12, | |
"end": 40, | |
"startLoc": { | |
"line": 12, | |
"column": 5, | |
"position": 51 | |
}, | |
"endLoc": { | |
"line": 40, | |
"column": 18, | |
"position": 256 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 63, | |
"fragment": "self.completionHandler = completionHandler\n super.init()\n modalPresentationStyle = .custom\n transitioningDelegate = self\n }\n\n public override func viewWillAppear(_ animated: Bool) {\n super.viewWillAppear(animated)\n pinTextField.becomeFirstResponder()\n }\n\n public override func viewDidAppear(_ animated: Bool) {\n super.viewDidAppear(animated)\n\n // For now, the design only allows for portrait layout on non-iPads\n if !UIDevice.current.isIPad && CurrentAppContext().interfaceOrientation != .portrait {\n UIDevice.current.ows_setOrientation(.portrait)\n }\n }\n\n public override func viewWillDisappear(_ animated: Bool) {\n super.viewWillDisappear(animated)\n pinTextField.resignFirstResponder()\n }\n\n override public var preferredStatusBarStyle: UIStatusBarStyle {\n return Theme.isDarkThemeEnabled ? .lightContent : .default\n }\n\n public override var supportedInterfaceOrientations: UIInterfaceOrientationMask {\n return UIDevice.current.isIPad ? .all : .portrait\n }\n\n override public func loadView() {\n view = UIView()\n view.backgroundColor = .clear\n\n containerView.backgroundColor = Theme.backgroundColor\n\n view.addSubview(containerView)\n containerView.autoPinWidthToSuperview()\n autoPinView(toBottomOfViewControllerOrKeyboard: containerView, avoidNotch: true)\n\n // We want the background to extend to the bottom of the screen\n // behind the safe area, so we add that inset to our bottom inset\n // instead of pinning this view to the safe area\n let safeAreaBackdrop = UIView()\n safeAreaBackdrop.backgroundColor = Theme.backgroundColor\n view.addSubview(safeAreaBackdrop)\n safeAreaBackdrop.autoPinEdge(.top, to: .bottom, of: containerView)\n safeAreaBackdrop.autoPinWidthToSuperview()\n // We don't know the safe area insets, so just guess a big number that will extend off screen\n safeAreaBackdrop.autoSetDimension(.height, toSize: 150)\n\n // Title\n\n let titleLabel = UILabel()\n titleLabel.textColor = Theme.primaryTextColor\n titleLabel.font = UIFont.ows_dynamicTypeTitle3Clamped.ows_semibold\n titleLabel.numberOfLines = 0\n titleLabel.lineBreakMode = .byWordWrapping\n titleLabel.textAlignment = .center\n titleLabel.text = titleText", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/OWSPinConfirmationViewController.swift", | |
"start": 47, | |
"end": 109, | |
"startLoc": { | |
"line": 47, | |
"column": 9, | |
"position": 350 | |
}, | |
"endLoc": { | |
"line": 109, | |
"column": 10, | |
"position": 844 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/OWSPinReminderViewController.swift", | |
"start": 41, | |
"end": 103, | |
"startLoc": { | |
"line": 41, | |
"column": 9, | |
"position": 278 | |
}, | |
"endLoc": { | |
"line": 103, | |
"column": 18, | |
"position": 772 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 12, | |
"fragment": "pinTextField.delegate = self\n pinTextField.keyboardType = KeyBackupService.currentPinType == .alphanumeric ? .default : .asciiCapableNumberPad\n pinTextField.textColor = Theme.primaryTextColor\n pinTextField.font = .ows_dynamicTypeBodyClamped\n pinTextField.textAlignment = .center\n pinTextField.isSecureTextEntry = true\n pinTextField.defaultTextAttributes.updateValue(5, forKey: .kern)\n pinTextField.keyboardAppearance = Theme.keyboardAppearance\n pinTextField.setContentHuggingHorizontalLow()\n pinTextField.setCompressionResistanceHorizontalLow()\n pinTextField.autoSetDimension(.height, toSize: 40)\n pinTextField.accessibilityIdentifier = \"pinConfirmation.pinTextField\"", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/OWSPinConfirmationViewController.swift", | |
"start": 124, | |
"end": 135, | |
"startLoc": { | |
"line": 124, | |
"column": 9, | |
"position": 936 | |
}, | |
"endLoc": { | |
"line": 135, | |
"column": 31, | |
"position": 1074 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/OWSPinReminderViewController.swift", | |
"start": 118, | |
"end": 90, | |
"startLoc": { | |
"line": 118, | |
"column": 9, | |
"position": 882 | |
}, | |
"endLoc": { | |
"line": 90, | |
"column": 30, | |
"position": 705 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 19, | |
"fragment": "let pinStack = UIStackView(arrangedSubviews: [\n pinTextField,\n UIView.spacer(withHeight: 10),\n validationWarningLabel\n ])\n pinStack.axis = .vertical\n pinStack.alignment = .fill\n\n let pinStackRow = UIView()\n pinStackRow.addSubview(pinStack)\n pinStack.autoHCenterInSuperview()\n pinStack.autoPinHeightToSuperview()\n pinStack.autoSetDimension(.width, toSize: 227)\n pinStackRow.setContentHuggingVerticalHigh()\n\n let font = UIFont.ows_dynamicTypeBodyClamped.ows_semibold\n let buttonHeight = OWSFlatButton.heightForFont(font)\n let submitButton = OWSFlatButton.button(\n title: actionText", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/OWSPinConfirmationViewController.swift", | |
"start": 142, | |
"end": 160, | |
"startLoc": { | |
"line": 142, | |
"column": 9, | |
"position": 1119 | |
}, | |
"endLoc": { | |
"line": 160, | |
"column": 11, | |
"position": 1275 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/OWSPinReminderViewController.swift", | |
"start": 138, | |
"end": 156, | |
"startLoc": { | |
"line": 138, | |
"column": 9, | |
"position": 1084 | |
}, | |
"endLoc": { | |
"line": 156, | |
"column": 18, | |
"position": 1240 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 13, | |
"fragment": "])\n stackView.axis = .vertical\n stackView.alignment = .fill\n stackView.layoutMargins = UIEdgeInsets(top: 32, left: 32, bottom: 16, right: 32)\n stackView.isLayoutMarginsRelativeArrangement = true\n containerView.addSubview(stackView)\n stackView.autoPinEdgesToSuperviewEdges()\n\n // Ensure whitespace is balanced, so inputs are vertically centered.\n topSpacer.autoMatch(.height, to: .height, of: bottomSpacer)\n topSpacer.autoSetDimension(.height, toSize: 20, relation: .greaterThanOrEqual)\n\n updateValidationWarnings", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/OWSPinConfirmationViewController.swift", | |
"start": 191, | |
"end": 203, | |
"startLoc": { | |
"line": 191, | |
"column": 9, | |
"position": 1535 | |
}, | |
"endLoc": { | |
"line": 203, | |
"column": 25, | |
"position": 1665 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/OWSPinReminderViewController.swift", | |
"start": 188, | |
"end": 200, | |
"startLoc": { | |
"line": 188, | |
"column": 9, | |
"position": 1517 | |
}, | |
"endLoc": { | |
"line": 200, | |
"column": 4, | |
"position": 1647 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 22, | |
"fragment": ")\n\n updateValidationWarnings()\n }\n\n public override func viewDidLayoutSubviews() {\n super.viewDidLayoutSubviews()\n\n let cornerRadius: CGFloat = 16\n let path = UIBezierPath(\n roundedRect: containerView.bounds,\n byRoundingCorners: [.topLeft, .topRight],\n cornerRadii: CGSize(square: cornerRadius)\n )\n let shapeLayer = CAShapeLayer()\n shapeLayer.path = path.cgPath\n containerView.layer.mask = shapeLayer\n }\n\n // MARK: - Events\n\n @objc func cancelPressed", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/OWSPinConfirmationViewController.swift", | |
"start": 201, | |
"end": 222, | |
"startLoc": { | |
"line": 201, | |
"column": 19, | |
"position": 1661 | |
}, | |
"endLoc": { | |
"line": 222, | |
"column": 14, | |
"position": 1800 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/OWSPinReminderViewController.swift", | |
"start": 206, | |
"end": 227, | |
"startLoc": { | |
"line": 206, | |
"column": 2, | |
"position": 1757 | |
}, | |
"endLoc": { | |
"line": 227, | |
"column": 14, | |
"position": 1896 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 25, | |
"fragment": "}\n\n private func updateValidationWarnings() {\n AssertIsOnMainThread()\n\n pinStrokeNormal.isHidden = validationState.isInvalid\n pinStrokeError.isHidden = !validationState.isInvalid\n validationWarningLabel.isHidden = !validationState.isInvalid\n\n switch validationState {\n case .tooShort:\n validationWarningLabel.text = NSLocalizedString(\"PIN_REMINDER_TOO_SHORT_ERROR\",\n comment: \"Label indicating that the attempted PIN is too short\")\n case .mismatch:\n validationWarningLabel.text = NSLocalizedString(\"PIN_REMINDER_MISMATCH_ERROR\",\n comment: \"Label indicating that the attempted PIN does not match the user's PIN\")\n default:\n break\n }\n }\n}\n\n// MARK: -\n\nprivate class PinConfirmationPresentationController", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/OWSPinConfirmationViewController.swift", | |
"start": 255, | |
"end": 279, | |
"startLoc": { | |
"line": 255, | |
"column": 5, | |
"position": 2069 | |
}, | |
"endLoc": { | |
"line": 279, | |
"column": 38, | |
"position": 2207 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/OWSPinReminderViewController.swift", | |
"start": 284, | |
"end": 308, | |
"startLoc": { | |
"line": 284, | |
"column": 5, | |
"position": 2391 | |
}, | |
"endLoc": { | |
"line": 308, | |
"column": 34, | |
"position": 2529 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 42, | |
"fragment": ": UIPresentationController {\n let backdropView = UIView()\n\n override init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?) {\n super.init(presentedViewController: presentedViewController, presenting: presentingViewController)\n\n let alpha: CGFloat = Theme.isDarkThemeEnabled ? 0.7 : 0.6\n backdropView.backgroundColor = UIColor.black.withAlphaComponent(alpha)\n }\n\n override func presentationTransitionWillBegin() {\n guard let containerView = containerView else { return }\n\n backdropView.alpha = 0\n containerView.addSubview(backdropView)\n backdropView.autoPinEdgesToSuperviewEdges()\n containerView.layoutIfNeeded()\n\n presentedViewController.transitionCoordinator?.animate(alongsideTransition: { _ in\n self.backdropView.alpha = 1\n }, completion: nil)\n }\n\n override func dismissalTransitionWillBegin() {\n presentedViewController.transitionCoordinator?.animate(alongsideTransition: { _ in\n self.backdropView.alpha = 0\n }, completion: { _ in\n self.backdropView.removeFromSuperview()\n })\n }\n\n override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {\n super.viewWillTransition(to: size, with: coordinator)\n guard let presentedView = presentedView else { return }\n coordinator.animate(alongsideTransition: { _ in\n presentedView.frame = self.frameOfPresentedViewInContainerView\n presentedView.layoutIfNeeded()\n }, completion: nil)\n }\n}\n\nextension PinConfirmationViewController", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/OWSPinConfirmationViewController.swift", | |
"start": 279, | |
"end": 320, | |
"startLoc": { | |
"line": 279, | |
"column": 38, | |
"position": 2208 | |
}, | |
"endLoc": { | |
"line": 320, | |
"column": 30, | |
"position": 2593 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/OWSPinReminderViewController.swift", | |
"start": 308, | |
"end": 649, | |
"startLoc": { | |
"line": 308, | |
"column": 34, | |
"position": 2530 | |
}, | |
"endLoc": { | |
"line": 649, | |
"column": 21, | |
"position": 5127 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 9, | |
"fragment": ": UITextFieldDelegate {\n public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {\n let hasPendingChanges: Bool\n if KeyBackupService.currentPinType == .alphanumeric {\n hasPendingChanges = true\n } else {\n ViewControllerUtils.ows2FAPINTextField(textField, shouldChangeCharactersIn: range, replacementString: string)\n hasPendingChanges = false\n }", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/OWSPinConfirmationViewController.swift", | |
"start": 328, | |
"end": 336, | |
"startLoc": { | |
"line": 328, | |
"column": 30, | |
"position": 2665 | |
}, | |
"endLoc": { | |
"line": 336, | |
"column": 2, | |
"position": 2773 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/OWSPinReminderViewController.swift", | |
"start": 357, | |
"end": 367, | |
"startLoc": { | |
"line": 357, | |
"column": 26, | |
"position": 2987 | |
}, | |
"endLoc": { | |
"line": 367, | |
"column": 15, | |
"position": 3099 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 13, | |
"fragment": "guard let interaction = TSInteraction.anyFetch(uniqueId: interactionId,\n transaction: transaction) else {\n owsFailDebug(\"Missing interaction.\")\n return nil\n }\n guard let thread = TSThread.anyFetch(uniqueId: interaction.uniqueThreadId,\n transaction: transaction) else {\n owsFailDebug(\"Missing thread.\")\n return nil\n }\n return CVLoader.buildStandaloneRenderItem(interaction: interaction,\n thread: thread,\n containerView: containerView", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/MessageDetailViewController.swift", | |
"start": 335, | |
"end": 347, | |
"startLoc": { | |
"line": 335, | |
"column": 13, | |
"position": 2546 | |
}, | |
"endLoc": { | |
"line": 347, | |
"column": 14, | |
"position": 2659 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/MediaGallery/MediaPageViewController.swift", | |
"start": 627, | |
"end": 639, | |
"startLoc": { | |
"line": 627, | |
"column": 13, | |
"position": 4911 | |
}, | |
"endLoc": { | |
"line": 639, | |
"column": 5, | |
"position": 5024 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 49, | |
"fragment": ".albumItemView(forAttachment: galleryItem.attachmentStream) else {\n owsFailDebug(\"itemView was unexpectedly nil\")\n return nil\n }\n\n guard let mediaSuperview = mediaView.superview else {\n owsFailDebug(\"mediaSuperview was unexpectedly nil\")\n return nil\n }\n\n let presentationFrame = coordinateSpace.convert(mediaView.frame, from: mediaSuperview)\n\n // TODO better corner rounding.\n return MediaPresentationContext(mediaView: mediaView,\n presentationFrame: presentationFrame,\n cornerRadius: kOWSMessageCellCornerRadius_Small * 2)\n }\n\n func snapshotOverlayView(in coordinateSpace: UICoordinateSpace) -> (UIView, CGRect)? {\n return nil\n }\n\n func mediaWillDismiss(toContext: MediaPresentationContext) {\n // To avoid flicker when transition view is animated over the message bubble,\n // we initially hide the overlaying elements and fade them in.\n let mediaOverlayViews = toContext.mediaOverlayViews\n for mediaOverlayView in mediaOverlayViews {\n mediaOverlayView.alpha = 0\n }\n }\n\n func mediaDidDismiss(toContext: MediaPresentationContext) {\n // To avoid flicker when transition view is animated over the message bubble,\n // we initially hide the overlaying elements and fade them in.\n let mediaOverlayViews = toContext.mediaOverlayViews\n let duration: TimeInterval = kIsDebuggingMediaPresentationAnimations ? 1.5 : 0.2\n UIView.animate(\n withDuration: duration,\n animations: {\n for mediaOverlayView in mediaOverlayViews {\n mediaOverlayView.alpha = 1\n }\n })\n }\n}\n\n// MARK: -\n\nextension", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/MessageDetailViewController.swift", | |
"start": 602, | |
"end": 650, | |
"startLoc": { | |
"line": 602, | |
"column": 9, | |
"position": 4655 | |
}, | |
"endLoc": { | |
"line": 650, | |
"column": 10, | |
"position": 4973 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ConversationView/ConversationViewController+OWS.swift", | |
"start": 392, | |
"end": 438, | |
"startLoc": { | |
"line": 392, | |
"column": 12, | |
"position": 2643 | |
}, | |
"endLoc": { | |
"line": 438, | |
"column": 6, | |
"position": 2959 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 54, | |
"fragment": ": CVComponentDelegate {\n\n // MARK: - Long Press\n\n // TODO:\n func cvc_didLongPressTextViewItem(_ cell: CVCell,\n itemViewModel: CVItemViewModelImpl,\n shouldAllowReply: Bool) {}\n\n // TODO:\n func cvc_didLongPressMediaViewItem(_ cell: CVCell,\n itemViewModel: CVItemViewModelImpl,\n shouldAllowReply: Bool) {}\n\n // TODO:\n func cvc_didLongPressQuote(_ cell: CVCell,\n itemViewModel: CVItemViewModelImpl,\n shouldAllowReply: Bool) {}\n\n // TODO:\n func cvc_didLongPressSystemMessage(_ cell: CVCell,\n itemViewModel: CVItemViewModelImpl) {}\n\n // TODO:\n func cvc_didLongPressSticker(_ cell: CVCell,\n itemViewModel: CVItemViewModelImpl,\n shouldAllowReply: Bool) {}\n\n // TODO:\n func cvc_didChangeLongpress(_ itemViewModel: CVItemViewModelImpl) {}\n\n // TODO:\n func cvc_didEndLongpress(_ itemViewModel: CVItemViewModelImpl) {}\n\n // TODO:\n func cvc_didCancelLongpress(_ itemViewModel: CVItemViewModelImpl) {}\n\n // MARK: -\n\n // TODO:\n func cvc_didTapReplyToItem(_ itemViewModel: CVItemViewModelImpl) {}\n\n // TODO:\n func cvc_didTapSenderAvatar(_ interaction: TSInteraction) {}\n\n // TODO:\n func cvc_shouldAllowReplyForItem(_ itemViewModel: CVItemViewModelImpl) -> Bool { false }\n\n // TODO:\n func cvc_didTapReactions(reactionState: InteractionReactionState,\n message: TSMessage) {}\n\n func cvc_didTapTruncatedTextMessage(_ itemViewModel: CVItemViewModelImpl) {\n AssertIsOnMainThread", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/MessageDetailViewController.swift", | |
"start": 751, | |
"end": 804, | |
"startLoc": { | |
"line": 751, | |
"column": 28, | |
"position": 5644 | |
}, | |
"endLoc": { | |
"line": 804, | |
"column": 21, | |
"position": 5991 | |
} | |
}, | |
"secondFile": { | |
"name": "views/MockConversationView.swift", | |
"start": 277, | |
"end": 315, | |
"startLoc": { | |
"line": 277, | |
"column": 21, | |
"position": 1930 | |
}, | |
"endLoc": { | |
"line": 315, | |
"column": 2, | |
"position": 2235 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 70, | |
"fragment": "}\n\n func cvc_didTapMention(_ mention: Mention) {}\n\n // MARK: - Selection\n\n // TODO:\n var isShowingSelectionUI: Bool { false }\n\n // TODO:\n func cvc_isMessageSelected(_ interaction: TSInteraction) -> Bool { false }\n\n // TODO:\n func cvc_didSelectViewItem(_ itemViewModel: CVItemViewModelImpl) {}\n\n // TODO:\n func cvc_didDeselectViewItem(_ itemViewModel: CVItemViewModelImpl) {}\n\n // MARK: - System Cell\n\n // TODO:\n func cvc_didTapNonBlockingIdentityChange(_ address: SignalServiceAddress) {}\n\n // TODO:\n func cvc_didTapInvalidIdentityKeyErrorMessage(_ message: TSInvalidIdentityKeyErrorMessage) {}\n\n // TODO:\n func cvc_didTapCorruptedMessage(_ message: TSErrorMessage) {}\n\n // TODO:\n func cvc_didTapSessionRefreshMessage(_ message: TSErrorMessage) {}\n\n // See: resendGroupUpdate\n // TODO:\n func cvc_didTapResendGroupUpdateForErrorMessage(_ errorMessage: TSErrorMessage) {}\n\n // TODO:\n func cvc_didTapShowFingerprint(_ address: SignalServiceAddress) {}\n\n // TODO:\n func cvc_didTapIndividualCall(_ call: TSCall) {}\n\n // TODO:\n func cvc_didTapGroupCall() {}\n\n // TODO:\n func cvc_didTapFailedOutgoingMessage(_ message: TSOutgoingMessage) {}\n\n // TODO:\n func cvc_didTapShowGroupMigrationLearnMoreActionSheet(infoMessage: TSInfoMessage,\n oldGroupModel: TSGroupModel,\n newGroupModel: TSGroupModel) {}\n\n func cvc_didTapGroupInviteLinkPromotion(groupModel: TSGroupModel) {}\n\n // TODO:\n func cvc_didTapShowConversationSettings() {}\n\n // TODO:\n func cvc_didTapShowConversationSettingsAndShowMemberRequests() {}\n\n // TODO:\n func cvc_didTapShowUpgradeAppUI() {}\n\n // TODO:\n func cvc_didTapUpdateSystemContact(_ address: SignalServiceAddress,\n newNameComponents: PersonNameComponents) {}\n\n func cvc_didTapViewOnceAttachment(_ interaction: TSInteraction) {\n guard", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/MessageDetailViewController.swift", | |
"start": 883, | |
"end": 952, | |
"startLoc": { | |
"line": 883, | |
"column": 5, | |
"position": 6634 | |
}, | |
"endLoc": { | |
"line": 952, | |
"column": 6, | |
"position": 7057 | |
} | |
}, | |
"secondFile": { | |
"name": "views/MockConversationView.swift", | |
"start": 343, | |
"end": 392, | |
"startLoc": { | |
"line": 343, | |
"column": 2, | |
"position": 2458 | |
}, | |
"endLoc": { | |
"line": 392, | |
"column": 2, | |
"position": 2822 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 14, | |
"fragment": "threads: [TSThread]) {\n guard threads.count == 1 else {\n return\n }\n guard let thread = threads.first else {\n owsFailDebug(\"Missing thread.\")\n return\n }\n guard thread.uniqueId != itemViewModel.interaction.uniqueThreadId else {\n return\n }\n SignalApp.shared().presentConversation(for: thread, animated: true)\n }\n}", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/LongTextViewController.swift", | |
"start": 208, | |
"end": 221, | |
"startLoc": { | |
"line": 208, | |
"column": 2, | |
"position": 1422 | |
}, | |
"endLoc": { | |
"line": 221, | |
"column": 2, | |
"position": 1531 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/MediaGallery/MediaPageViewController.swift", | |
"start": 922, | |
"end": 935, | |
"startLoc": { | |
"line": 922, | |
"column": 28, | |
"position": 7221 | |
}, | |
"endLoc": { | |
"line": 935, | |
"column": 2, | |
"position": 7330 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 9, | |
"fragment": ") {\n presentingViewController?.dismiss(animated: true) {\n switch result {\n case .failed:\n let warning = ActionSheetController(title: nil, message: NSLocalizedString(\"SEND_INVITE_FAILURE\", comment: \"Alert body after invite failed\"))\n warning.addAction(OWSActionSheets.dismissAction)\n self.presentingViewController?.present(warning, animated: true, completion: nil)\n case .sent:\n Logger.debug(\"user successfully invited their friends via mail.\"", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/InviteFlow.swift", | |
"start": 314, | |
"end": 322, | |
"startLoc": { | |
"line": 314, | |
"column": 2, | |
"position": 2759 | |
}, | |
"endLoc": { | |
"line": 322, | |
"column": 52, | |
"position": 2866 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/InviteFlow.swift", | |
"start": 254, | |
"end": 262, | |
"startLoc": { | |
"line": 254, | |
"column": 21, | |
"position": 2203 | |
}, | |
"endLoc": { | |
"line": 262, | |
"column": 51, | |
"position": 2310 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 15, | |
"fragment": "()\n actionSheetController.customHeader = self\n actionSheetController.isCancelable = true\n fromViewController.presentActionSheet(actionSheetController)\n self.actionSheetController = actionSheetController\n }\n\n @objc\n public func configure() {\n let subviews = buildContents()\n\n let stackView = UIStackView(arrangedSubviews: subviews)\n stackView.axis = .vertical\n stackView.alignment = .fill\n stackView.layoutMargins = UIEdgeInsets(top: 24", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/GroupLinkPromotionActionSheet.swift", | |
"start": 42, | |
"end": 56, | |
"startLoc": { | |
"line": 42, | |
"column": 18, | |
"position": 237 | |
}, | |
"endLoc": { | |
"line": 56, | |
"column": 3, | |
"position": 352 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/GroupMigrationActionSheet.swift", | |
"start": 67, | |
"end": 81, | |
"startLoc": { | |
"line": 67, | |
"column": 22, | |
"position": 476 | |
}, | |
"endLoc": { | |
"line": 81, | |
"column": 3, | |
"position": 591 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 12, | |
"fragment": "{ thread in\n let contactShareCopy = contactShare.copyForResending()\n\n if let avatarImage = contactShareCopy.avatarImage {\n self.databaseStorage.write { transaction in\n contactShareCopy.dbRecord.saveAvatarImage(avatarImage, transaction: transaction)\n }\n }\n\n self.send(contactShare: contactShareCopy, thread: thread)\n }\n case .stickerMessage", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ForwardMessageNavigationController.swift", | |
"start": 182, | |
"end": 193, | |
"startLoc": { | |
"line": 182, | |
"column": 2, | |
"position": 1263 | |
}, | |
"endLoc": { | |
"line": 193, | |
"column": 15, | |
"position": 1358 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/SendMessageFlow.swift", | |
"start": 349, | |
"end": 359, | |
"startLoc": { | |
"line": 349, | |
"column": 2, | |
"position": 2569 | |
}, | |
"endLoc": { | |
"line": 359, | |
"column": 17, | |
"position": 2663 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 28, | |
"fragment": "}\n }\n\n func threads(for conversationItems: [ConversationItem]) -> Promise<[TSThread]> {\n return DispatchQueue.global().async(.promise) {\n guard conversationItems.count > 0 else {\n throw OWSAssertionError(\"No recipients.\")\n }\n\n var threads: [TSThread] = []\n\n self.databaseStorage.write { transaction in\n for conversation in conversationItems {\n guard let thread = conversation.thread(transaction: transaction) else {\n owsFailDebug(\"Missing thread for conversation\")\n continue\n }\n threads.append(thread)\n }\n }\n return threads\n }\n }\n}\n\n// MARK: -\n\nextension ForwardMessageNavigationController", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ForwardMessageNavigationController.swift", | |
"start": 311, | |
"end": 338, | |
"startLoc": { | |
"line": 311, | |
"column": 9, | |
"position": 2382 | |
}, | |
"endLoc": { | |
"line": 338, | |
"column": 35, | |
"position": 2567 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/SendMessageFlow.swift", | |
"start": 426, | |
"end": 453, | |
"startLoc": { | |
"line": 426, | |
"column": 9, | |
"position": 3313 | |
}, | |
"endLoc": { | |
"line": 453, | |
"column": 16, | |
"position": 3498 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 27, | |
"fragment": ": ConversationPickerDelegate {\n var selectedConversationsForConversationPicker: [ConversationItem] {\n return selectedConversations\n }\n\n func conversationPicker(_ conversationPickerViewController: ConversationPickerViewController,\n didSelectConversation conversation: ConversationItem) {\n self.selectedConversations.append(conversation)\n }\n\n func conversationPicker(_ conversationPickerViewController: ConversationPickerViewController,\n didDeselectConversation conversation: ConversationItem) {\n self.selectedConversations = self.selectedConversations.filter {\n $0.messageRecipient != conversation.messageRecipient\n }\n }\n\n func conversationPickerDidCompleteSelection(_ conversationPickerViewController: ConversationPickerViewController) {\n approve()\n }\n\n func conversationPickerCanCancel(_ conversationPickerViewController: ConversationPickerViewController) -> Bool {\n return true\n }\n\n func conversationPickerDidCancel(_ conversationPickerViewController: ConversationPickerViewController) {\n forwardMessageDelegate", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ForwardMessageNavigationController.swift", | |
"start": 338, | |
"end": 364, | |
"startLoc": { | |
"line": 338, | |
"column": 35, | |
"position": 2568 | |
}, | |
"endLoc": { | |
"line": 364, | |
"column": 23, | |
"position": 2760 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/SendMessageFlow.swift", | |
"start": 453, | |
"end": 479, | |
"startLoc": { | |
"line": 453, | |
"column": 16, | |
"position": 3499 | |
}, | |
"endLoc": { | |
"line": 479, | |
"column": 14, | |
"position": 3691 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 17, | |
"fragment": ".map { $0.title }\n }\n\n var attachmentApprovalMentionableAddresses: [SignalServiceAddress] {\n guard selectedConversations.count == 1,\n case .group(let groupThreadId) = selectedConversations.first?.messageRecipient,\n let groupThread = databaseStorage.uiRead(block: { transaction in\n return TSGroupThread.anyFetchGroupThread(uniqueId: groupThreadId, transaction: transaction)\n }),\n Mention.threadAllowsMentionSend(groupThread) else { return [] }\n return groupThread.recipientAddresses\n }\n}\n\n// MARK: -\n\nextension", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ForwardMessageNavigationController.swift", | |
"start": 473, | |
"end": 489, | |
"startLoc": { | |
"line": 473, | |
"column": 43, | |
"position": 3568 | |
}, | |
"endLoc": { | |
"line": 489, | |
"column": 10, | |
"position": 3708 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/SendMessageFlow.swift", | |
"start": 600, | |
"end": 616, | |
"startLoc": { | |
"line": 600, | |
"column": 22, | |
"position": 4596 | |
}, | |
"endLoc": { | |
"line": 616, | |
"column": 7, | |
"position": 4736 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 9, | |
"fragment": "view.addSubview(tableView)\n tableView.autoPinEdge(toSuperviewEdge: .top)\n tableView.autoPinEdge(toSuperviewEdge: .bottom)\n tableView.autoPinEdge(toSuperviewSafeArea: .leading)\n tableView.autoPinEdge(toSuperviewSafeArea: .trailing)\n tableView.delegate = self\n tableView.dataSource = self\n\n let", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ContactsPicker.swift", | |
"start": 74, | |
"end": 82, | |
"startLoc": { | |
"line": 74, | |
"column": 9, | |
"position": 505 | |
}, | |
"endLoc": { | |
"line": 82, | |
"column": 4, | |
"position": 580 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/ThreadSettings/OWSAddToContactViewController.swift", | |
"start": 33, | |
"end": 40, | |
"startLoc": { | |
"line": 33, | |
"column": 9, | |
"position": 175 | |
}, | |
"endLoc": { | |
"line": 40, | |
"column": 2, | |
"position": 249 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 17, | |
"fragment": "func addBottomButton(title: String,\n titleColor: UIColor,\n backgroundColor: UIColor,\n target: Any,\n selector: Selector) {\n let buttonFont = UIFont.ows_dynamicTypeBodyClamped.ows_semibold\n let buttonHeight = OWSFlatButton.heightForFont(buttonFont)\n let upgradeButton = OWSFlatButton.button(title: title,\n font: buttonFont,\n titleColor: titleColor,\n backgroundColor: backgroundColor,\n target: target,\n selector: selector)\n upgradeButton.autoSetDimension(.height, toSize: buttonHeight)\n subviews.append(upgradeButton)\n }\n}", | |
"tokens": 0, | |
"firstFile": { | |
"name": "ViewControllers/ActionSheetContentBuilder.swift", | |
"start": 40, | |
"end": 56, | |
"startLoc": { | |
"line": 40, | |
"column": 5, | |
"position": 296 | |
}, | |
"endLoc": { | |
"line": 56, | |
"column": 2, | |
"position": 441 | |
} | |
}, | |
"secondFile": { | |
"name": "ViewControllers/GroupMigrationActionSheet.swift", | |
"start": 202, | |
"end": 219, | |
"startLoc": { | |
"line": 202, | |
"column": 2, | |
"position": 1624 | |
}, | |
"endLoc": { | |
"line": 219, | |
"column": 9, | |
"position": 1771 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 14, | |
"fragment": "thread: TSThread?) -> IndexPath? {\n let isPinnedThread: Bool\n if let thread = thread, pinnedThreads.orderedKeys.contains(thread.uniqueId) {\n isPinnedThread = true\n } else {\n isPinnedThread = false\n }\n\n let section = isPinnedThread ? pinnedSection : unpinnedSection\n let threadsInSection = isPinnedThread ? pinnedThreads.orderedValues : unpinnedThreads\n\n guard !threadsInSection.isEmpty else { return nil }\n\n let lastIndexPath", | |
"tokens": 0, | |
"firstFile": { | |
"name": "Models/ThreadMapping.swift", | |
"start": 181, | |
"end": 194, | |
"startLoc": { | |
"line": 181, | |
"column": 2, | |
"position": 1351 | |
}, | |
"endLoc": { | |
"line": 194, | |
"column": 14, | |
"position": 1483 | |
} | |
}, | |
"secondFile": { | |
"name": "Models/ThreadMapping.swift", | |
"start": 155, | |
"end": 168, | |
"startLoc": { | |
"line": 155, | |
"column": 2, | |
"position": 1063 | |
}, | |
"endLoc": { | |
"line": 168, | |
"column": 15, | |
"position": 1195 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 11, | |
"fragment": "let oldThreadIds = wasPinned ? oldPinnedThreadIds : oldUnpinnedThreadIds\n let newThreadIds = isPinned ? newPinnedThreadIds : newUnpinnedThreadIds\n\n guard let oldIndex = oldThreadIds.firstIndexAsInt(of: threadId) else {\n continue\n }\n guard let newIndex = newThreadIds.firstIndexAsInt(of: threadId) else {\n throw OWSAssertionError(\"newIndex was unexpectedly nil.\")\n }\n\n let naiveThreadIdOrdering", | |
"tokens": 0, | |
"firstFile": { | |
"name": "Models/ThreadMapping.swift", | |
"start": 538, | |
"end": 548, | |
"startLoc": { | |
"line": 538, | |
"column": 13, | |
"position": 4377 | |
}, | |
"endLoc": { | |
"line": 548, | |
"column": 22, | |
"position": 4478 | |
} | |
}, | |
"secondFile": { | |
"name": "Models/ThreadMapping.swift", | |
"start": 471, | |
"end": 481, | |
"startLoc": { | |
"line": 471, | |
"column": 13, | |
"position": 3812 | |
}, | |
"endLoc": { | |
"line": 481, | |
"column": 11, | |
"position": 3913 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 15, | |
"fragment": "else {\n logThreadIds(newPinnedThreadIds, name: \"newPinnedThreadIds\")\n logThreadIds(oldPinnedThreadIds, name: \"oldPinnedThreadIds\")\n logThreadIds(newUnpinnedThreadIds, name: \"newUnpinnedThreadIds\")\n logThreadIds(oldUnpinnedThreadIds, name: \"oldUnpinnedThreadIds\")\n logThreadIds(newlyPinnedThreadIds, name: \"newlyPinnedThreadIds\")\n logThreadIds(newlyUnpinnedThreadIds, name: \"newlyUnpinnedThreadIds\")\n logThreadIds(naivePinnedThreadIdOrdering, name: \"naivePinnedThreadIdOrdering\")\n logThreadIds(naiveUnpinnedThreadIdOrdering, name: \"naiveUnpinnedThreadIdOrdering\")\n logThreadIds(insertedThreadIds, name: \"insertedThreadIds\")\n logThreadIds(deletedThreadIds, name: \"deletedThreadIds\")\n logThreadIds(movedToNewSectionThreadIds, name: \"movedToNewSectionThreadIds\")\n logThreadIds(Array(possiblyMovedWithinSectionThreadIds), name: \"possiblyMovedWithinSectionThreadIds\")\n logThreadIds(movedThreadIds, name: \"movedThreadIds\")\n throw OWSAssertionError(\"Could not reorder unpinned contents.\"", | |
"tokens": 0, | |
"firstFile": { | |
"name": "Models/ThreadMapping.swift", | |
"start": 603, | |
"end": 617, | |
"startLoc": { | |
"line": 603, | |
"column": 2, | |
"position": 5009 | |
}, | |
"endLoc": { | |
"line": 617, | |
"column": 39, | |
"position": 5177 | |
} | |
}, | |
"secondFile": { | |
"name": "Models/ThreadMapping.swift", | |
"start": 586, | |
"end": 600, | |
"startLoc": { | |
"line": 586, | |
"column": 2, | |
"position": 4825 | |
}, | |
"endLoc": { | |
"line": 600, | |
"column": 37, | |
"position": 4993 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 10, | |
"fragment": "(itemViewModel: CVItemViewModelImpl, shouldAllowReply: Bool, delegate: MessageActionsDelegate) -> [MessageAction] {\n var actions: [MessageAction] = []\n\n let showDetailsAction = MessageActionBuilder.showDetails(itemViewModel: itemViewModel, delegate: delegate)\n actions.append(showDetailsAction)\n\n let deleteAction = MessageActionBuilder.deleteMessage(itemViewModel: itemViewModel, delegate: delegate)\n actions.append(deleteAction)\n\n if itemViewModel.canShareMedia", | |
"tokens": 0, | |
"firstFile": { | |
"name": "Models/MessageActions.swift", | |
"start": 118, | |
"end": 127, | |
"startLoc": { | |
"line": 118, | |
"column": 13, | |
"position": 1141 | |
}, | |
"endLoc": { | |
"line": 127, | |
"column": 14, | |
"position": 1254 | |
} | |
}, | |
"secondFile": { | |
"name": "Models/MessageActions.swift", | |
"start": 88, | |
"end": 97, | |
"startLoc": { | |
"line": 88, | |
"column": 12, | |
"position": 862 | |
}, | |
"endLoc": { | |
"line": 97, | |
"column": 19, | |
"position": 975 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 20, | |
"fragment": ")\n }\n\n if shouldAllowReply {\n let replyAction = MessageActionBuilder.reply(itemViewModel: itemViewModel, delegate: delegate)\n actions.append(replyAction)\n }\n\n if itemViewModel.canForwardMessage {\n actions.append(MessageActionBuilder.forwardMessage(itemViewModel: itemViewModel, delegate: delegate))\n }\n\n let selectAction = MessageActionBuilder.selectMessage(itemViewModel: itemViewModel, delegate: delegate)\n actions.append(selectAction)\n\n return actions\n }\n\n @objc\n class func quotedMessageActions", | |
"tokens": 0, | |
"firstFile": { | |
"name": "Models/MessageActions.swift", | |
"start": 129, | |
"end": 148, | |
"startLoc": { | |
"line": 129, | |
"column": 17, | |
"position": 1287 | |
}, | |
"endLoc": { | |
"line": 148, | |
"column": 21, | |
"position": 1419 | |
} | |
}, | |
"secondFile": { | |
"name": "Models/MessageActions.swift", | |
"start": 99, | |
"end": 118, | |
"startLoc": { | |
"line": 99, | |
"column": 15, | |
"position": 1008 | |
}, | |
"endLoc": { | |
"line": 118, | |
"column": 13, | |
"position": 1140 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 10, | |
"fragment": "(itemViewModel: CVItemViewModelImpl, shouldAllowReply: Bool, delegate: MessageActionsDelegate) -> [MessageAction] {\n var actions: [MessageAction] = []\n\n let showDetailsAction = MessageActionBuilder.showDetails(itemViewModel: itemViewModel, delegate: delegate)\n actions.append(showDetailsAction)\n\n let deleteAction = MessageActionBuilder.deleteMessage(itemViewModel: itemViewModel, delegate: delegate)\n actions.append(deleteAction)\n\n if shouldAllowReply", | |
"tokens": 0, | |
"firstFile": { | |
"name": "Models/MessageActions.swift", | |
"start": 148, | |
"end": 157, | |
"startLoc": { | |
"line": 148, | |
"column": 21, | |
"position": 1420 | |
}, | |
"endLoc": { | |
"line": 157, | |
"column": 17, | |
"position": 1531 | |
} | |
}, | |
"secondFile": { | |
"name": "Models/MessageActions.swift", | |
"start": 88, | |
"end": 97, | |
"startLoc": { | |
"line": 88, | |
"column": 12, | |
"position": 862 | |
}, | |
"endLoc": { | |
"line": 97, | |
"column": 14, | |
"position": 973 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 17, | |
"fragment": "if shouldAllowReply {\n let replyAction = MessageActionBuilder.reply(itemViewModel: itemViewModel, delegate: delegate)\n actions.append(replyAction)\n }\n\n if itemViewModel.canForwardMessage {\n actions.append(MessageActionBuilder.forwardMessage(itemViewModel: itemViewModel, delegate: delegate))\n }\n\n let selectAction = MessageActionBuilder.selectMessage(itemViewModel: itemViewModel, delegate: delegate)\n actions.append(selectAction)\n\n return actions\n }\n\n @objc\n class func infoMessageActions", | |
"tokens": 0, | |
"firstFile": { | |
"name": "Models/MessageActions.swift", | |
"start": 157, | |
"end": 173, | |
"startLoc": { | |
"line": 157, | |
"column": 9, | |
"position": 1529 | |
}, | |
"endLoc": { | |
"line": 173, | |
"column": 19, | |
"position": 1654 | |
} | |
}, | |
"secondFile": { | |
"name": "Models/MessageActions.swift", | |
"start": 102, | |
"end": 118, | |
"startLoc": { | |
"line": 102, | |
"column": 9, | |
"position": 1015 | |
}, | |
"endLoc": { | |
"line": 118, | |
"column": 13, | |
"position": 1140 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 10, | |
"fragment": "(userInfo: [AnyHashable: Any]) throws -> Promise<Void> {\n guard let localCallIdString = userInfo[AppNotificationUserInfoKey.localCallId] as? String else {\n throw OWSAssertionError(\"localCallIdString was unexpectedly nil\")\n }\n\n guard let localCallId = UUID(uuidString: localCallIdString) else {\n throw OWSAssertionError(\"unable to build localCallId. localCallIdString: \\(localCallIdString)\")\n }\n\n callUIAdapter.localHangupCall", | |
"tokens": 0, | |
"firstFile": { | |
"name": "NotificationActionHandler.swift", | |
"start": 65, | |
"end": 74, | |
"startLoc": { | |
"line": 65, | |
"column": 12, | |
"position": 462 | |
}, | |
"endLoc": { | |
"line": 74, | |
"column": 16, | |
"position": 563 | |
} | |
}, | |
"secondFile": { | |
"name": "NotificationActionHandler.swift", | |
"start": 40, | |
"end": 49, | |
"startLoc": { | |
"line": 40, | |
"column": 11, | |
"position": 192 | |
}, | |
"endLoc": { | |
"line": 49, | |
"column": 11, | |
"position": 293 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 7, | |
"fragment": ") throws -> Promise<Void> {\n return firstly { () -> Promise<NotificationMessage> in\n self.notificationMessage(forUserInfo: userInfo)\n }.then(on: .global()) { (notificationMessage: NotificationMessage) -> Promise<Void> in\n let thread = notificationMessage.thread\n let interaction = notificationMessage.interaction\n guard let", | |
"tokens": 0, | |
"firstFile": { | |
"name": "NotificationActionHandler.swift", | |
"start": 130, | |
"end": 136, | |
"startLoc": { | |
"line": 130, | |
"column": 2, | |
"position": 1188 | |
}, | |
"endLoc": { | |
"line": 136, | |
"column": 4, | |
"position": 1291 | |
} | |
}, | |
"secondFile": { | |
"name": "NotificationActionHandler.swift", | |
"start": 86, | |
"end": 92, | |
"startLoc": { | |
"line": 86, | |
"column": 7, | |
"position": 695 | |
}, | |
"endLoc": { | |
"line": 92, | |
"column": 4, | |
"position": 798 | |
} | |
} | |
}, | |
{ | |
"format": "swift", | |
"lines": 13, | |
"fragment": ", transaction: transaction)\n }\n }.recover(on: .global()) { error -> Promise<Void> in\n Logger.warn(\"Failed to send reply message from notification with error: \\(error)\")\n self.notificationPresenter.notifyForFailedSend(inThread: thread)\n throw error\n }.then(on: .global()) { () -> Promise<Void> in\n self.markMessageAsRead(notificationMessage: notificationMessage)\n }\n }\n }\n\n func showCallLobby", | |
"tokens": 0, | |
"firstFile": { | |
"name": "NotificationActionHandler.swift", | |
"start": 142, | |
"end": 154, | |
"startLoc": { | |
"line": 142, | |
"column": 6, | |
"position": 1383 | |
}, | |
"endLoc": { | |
"line": 154, | |
"column": 14, | |
"position": 1505 | |
} | |
}, | |
"secondFile": { | |
"name": "NotificationActionHandler.swift", | |
"start": 99, | |
"end": 112, | |
"startLoc": { | |
"line": 99, | |
"column": 7, | |
"position": 896 | |
}, | |
"endLoc": { | |
"line": 112, | |
"column": 11, | |
"position": 1019 | |
} | |
} | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment