Various improvements

This commit is contained in:
Isaac 2024-08-20 18:16:59 +08:00
parent ed55fbc1ab
commit bdfe639f3e
17 changed files with 138 additions and 254 deletions

View File

@ -2052,7 +2052,7 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
for attribute in item.file.attributes {
switch attribute {
case let .CustomEmoji(_, _, alt, _):
if !item.file.isPremiumEmoji || hasPremium {
if !item.file.isPremiumEmoji {
if !alt.isEmpty, let keyword = allEmoticons[alt] {
result.append((alt, item.file, keyword))
} else if alt == query {
@ -2079,7 +2079,7 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
animationData: animationData,
content: .animation(animationData),
itemFile: itemFile, subgroupId: nil,
icon: .none,
icon: (!hasPremium && itemFile.isPremiumEmoji) ? .locked : .none,
tintMode: animationData.isTemplate ? .primary : .none
)
items.append(item)
@ -2141,7 +2141,7 @@ public final class ReactionContextNode: ASDisplayNode, ASScrollViewDelegate {
content: .animation(animationData),
itemFile: item.file,
subgroupId: nil,
icon: .none,
icon: (!hasPremium && item.file.isPremiumEmoji) ? .locked : .none,
tintMode: tintMode
)

View File

@ -1743,6 +1743,15 @@ public final class SparseItemGrid: ASDisplayNode {
}
items.itemBinding.onTagTap()
}
self.scrollingArea.isDecelerating = { [weak self] in
guard let self else {
return false
}
guard let currentViewport = self.currentViewport else {
return false
}
return currentViewport.scrollView.isDecelerating
}
}
@objc private func tapGesture(_ recognizer: UITapGestureRecognizer) {

View File

@ -838,16 +838,25 @@ final class SparseItemGridScrollingIndicatorComponent: CombinedComponent {
}
public final class SparseItemGridScrollingArea: ASDisplayNode {
private struct ShouldBegin {
var shouldDelay: Bool
init(shouldDelay: Bool) {
self.shouldDelay = shouldDelay
}
}
private final class DragGesture: UIGestureRecognizer {
private let shouldBegin: (CGPoint) -> Bool
private let shouldBegin: (CGPoint) -> ShouldBegin?
private let began: () -> Void
private let ended: () -> Void
private let moved: (CGFloat) -> Void
private var initialLocation: CGPoint?
private var beginDelayTimer: SwiftSignalKit.Timer?
public init(
shouldBegin: @escaping (CGPoint) -> Bool,
shouldBegin: @escaping (CGPoint) -> ShouldBegin?,
began: @escaping () -> Void,
ended: @escaping () -> Void,
moved: @escaping (CGFloat) -> Void
@ -868,6 +877,9 @@ public final class SparseItemGridScrollingArea: ASDisplayNode {
self.initialLocation = nil
self.initialLocation = nil
self.beginDelayTimer?.invalidate()
self.beginDelayTimer = nil
}
override public func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
@ -881,10 +893,29 @@ public final class SparseItemGridScrollingArea: ASDisplayNode {
if self.state == .possible {
if let location = touches.first?.location(in: self.view) {
if self.shouldBegin(location) {
if let shouldBeginValue = self.shouldBegin(location) {
self.initialLocation = location
self.state = .began
self.began()
if shouldBeginValue.shouldDelay {
self.state = .began
if self.beginDelayTimer == nil {
self.beginDelayTimer = SwiftSignalKit.Timer(timeout: 0.2, repeat: false, completion: { [weak self] in
guard let self else {
return
}
self.beginDelayTimer = nil
if self.initialLocation != nil {
self.began()
}
}, queue: .mainQueue())
self.beginDelayTimer?.start()
}
} else {
self.state = .began
self.began()
}
} else {
self.state = .failed
}
@ -919,10 +950,20 @@ public final class SparseItemGridScrollingArea: ASDisplayNode {
override public func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
super.touchesMoved(touches, with: event)
if (self.state == .began || self.state == .changed), let initialLocation = self.initialLocation, let location = touches.first?.location(in: self.view) {
self.state = .changed
if let initialLocation = self.initialLocation, let location = touches.first?.location(in: self.view) {
let offset = location.y - initialLocation.y
self.moved(offset)
if self.beginDelayTimer != nil {
if abs(offset) > 16.0 {
self.ended()
self.state = .failed
} else {
self.initialLocation = location
}
} else if (self.state == .began || self.state == .changed) {
self.state = .changed
self.moved(offset)
}
}
}
}
@ -951,6 +992,7 @@ public final class SparseItemGridScrollingArea: ASDisplayNode {
public var finishedScrolling: (() -> Void)?
public var setContentOffset: ((CGPoint) -> Void)?
public var openCurrentDate: (() -> Void)?
public var isDecelerating: (() -> Bool)?
private var offsetBarTimer: SwiftSignalKit.Timer?
private var beganAtDateIndicator = false
@ -1002,7 +1044,7 @@ public final class SparseItemGridScrollingArea: ASDisplayNode {
let dragGesture = DragGesture(
shouldBegin: { [weak self] point in
guard let strongSelf = self else {
return false
return nil
}
if strongSelf.dateIndicator.frame.contains(point) {
@ -1011,7 +1053,7 @@ public final class SparseItemGridScrollingArea: ASDisplayNode {
strongSelf.beganAtDateIndicator = false
}
return true
return ShouldBegin(shouldDelay: strongSelf.isDecelerating?() ?? false)
},
began: { [weak self] in
guard let strongSelf = self else {
@ -1115,6 +1157,7 @@ public final class SparseItemGridScrollingArea: ASDisplayNode {
}
private var currentDate: (String, Int32)?
private var isScrolling: Bool = false
public func update(
containerSize: CGSize,
@ -1130,6 +1173,8 @@ public final class SparseItemGridScrollingArea: ASDisplayNode {
self.theme = theme
let previousDate = self.currentDate
self.currentDate = date
self.isScrolling = isScrolling
if self.dateIndicator.alpha.isZero {
let transition: ContainedViewLayoutTransition = .immediate

View File

@ -129,7 +129,8 @@ private final class CallScreenVideoView: UIView, VideoRenderingView {
return
}
self.videoLayer.video = self.videoSource.currentOutput
let videoOutput = self.videoSource.currentOutput
self.videoLayer.video = videoOutput
var notifyOrientationUpdated = false
var notifyIsMirroredUpdated = false
@ -139,7 +140,7 @@ private final class CallScreenVideoView: UIView, VideoRenderingView {
notifyIsMirroredUpdated = true
}
if let currentOutput = self.videoSource.currentOutput {
if let currentOutput = videoOutput {
let currentAspect: CGFloat
if currentOutput.resolution.height > 0.0 {
currentAspect = currentOutput.resolution.width / currentOutput.resolution.height
@ -152,16 +153,20 @@ private final class CallScreenVideoView: UIView, VideoRenderingView {
}
let currentOrientation: PresentationCallVideoView.Orientation
if abs(currentOutput.rotationAngle - 0.0) < .ulpOfOne {
if currentOutput.followsDeviceOrientation {
currentOrientation = .rotation0
} else if abs(currentOutput.rotationAngle - Float.pi * 0.5) < .ulpOfOne {
currentOrientation = .rotation90
} else if abs(currentOutput.rotationAngle - Float.pi) < .ulpOfOne {
currentOrientation = .rotation180
} else if abs(currentOutput.rotationAngle - Float.pi * 3.0 / 2.0) < .ulpOfOne {
currentOrientation = .rotation270
} else {
currentOrientation = .rotation0
if abs(currentOutput.rotationAngle - 0.0) < .ulpOfOne {
currentOrientation = .rotation0
} else if abs(currentOutput.rotationAngle - Float.pi * 0.5) < .ulpOfOne {
currentOrientation = .rotation90
} else if abs(currentOutput.rotationAngle - Float.pi) < .ulpOfOne {
currentOrientation = .rotation180
} else if abs(currentOutput.rotationAngle - Float.pi * 3.0 / 2.0) < .ulpOfOne {
currentOrientation = .rotation270
} else {
currentOrientation = .rotation0
}
}
if self.currentOrientation != currentOrientation {
self.currentOrientation = currentOrientation

View File

@ -3927,7 +3927,7 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
transition.updateAlpha(node: self.bottomGradientNode, alpha: self.isLandscape ? 0.0 : 1.0)
var isTablet = false
let videoFrame: CGRect
var videoFrame: CGRect
let videoContainerFrame: CGRect
if case .regular = layout.metrics.widthClass {
isTablet = true
@ -3941,6 +3941,11 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
videoFrame = CGRect(x: 0.0, y: videoTopEdgeY, width: isLandscape ? max(0.0, layout.size.width - layout.safeInsets.right - 92.0) : layout.size.width, height: videoBottomEdgeY - videoTopEdgeY)
videoContainerFrame = CGRect(origin: CGPoint(), size: layout.size)
}
if videoFrame.width < 0.0 || videoFrame.height < 0.0 || !videoFrame.width.isNormal || !videoFrame.height.isNormal {
videoFrame = CGRect()
}
transition.updateFrame(node: self.mainStageContainerNode, frame: videoContainerFrame)
transition.updateFrame(node: self.mainStageBackgroundNode, frame: videoFrame)
if !self.mainStageNode.animating {

View File

@ -324,10 +324,14 @@ public final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode {
}
if let selectionState = presentationInterfaceState.interfaceState.selectionState {
context.engine.messages.setMessageReactions(ids: Array(selectionState.selectedIds), reactions: mappedUpdatedReactions)
} else {
context.engine.messages.setMessageReactions(ids: Array(self.selectedMessages), reactions: mappedUpdatedReactions)
}
} else {
if let selectionState = presentationInterfaceState.interfaceState.selectionState {
context.engine.messages.addMessageReactions(ids: Array(selectionState.selectedIds), reactions: [updateReaction])
} else {
context.engine.messages.addMessageReactions(ids: Array(self.selectedMessages), reactions: [updateReaction])
}
}

View File

@ -628,7 +628,7 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
}
let dateLayoutInput: ChatMessageDateAndStatusNode.LayoutInput
dateLayoutInput = .trailingContent(contentWidth: trailingWidthToMeasure, reactionSettings: item.presentationData.isPreview ? nil : ChatMessageDateAndStatusNode.TrailingReactionSettings(displayInline: shouldDisplayInlineDateReactions(message: item.message, isPremium: item.associatedData.isPremium, forceInline: item.associatedData.forceInlineReactions), preferAdditionalInset: false))
dateLayoutInput = .trailingContent(contentWidth: trailingWidthToMeasure, reactionSettings: ChatMessageDateAndStatusNode.TrailingReactionSettings(displayInline: shouldDisplayInlineDateReactions(message: item.message, isPremium: item.associatedData.isPremium, forceInline: item.associatedData.forceInlineReactions), preferAdditionalInset: false))
statusSuggestedWidthAndContinue = statusLayout(ChatMessageDateAndStatusNode.Arguments(
context: item.context,
@ -1514,9 +1514,10 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
guard let item = self.item else {
return nil
}
guard let string = self.textNode.textNode.cachedLayout?.attributedString else {
guard let string = self.textNode.attributedString else {
return nil
}
let nsString = string.string as NSString
let substring = nsString.substring(with: range)
let offset = range.location

View File

@ -115,6 +115,8 @@ public final class InteractiveTextNodeWithEntities {
private var enableLooping: Bool = true
public private(set) var attributedString: NSAttributedString?
public var visibilityRect: CGRect? {
didSet {
if !self.inlineStickerItemLayers.isEmpty && oldValue != self.visibilityRect {
@ -217,6 +219,8 @@ public final class InteractiveTextNodeWithEntities {
let result = apply(applyArguments.applyArguments)
if let maybeNode = maybeNode {
maybeNode.attributedString = arguments.attributedString
maybeNode.updateInteractiveContents(
context: applyArguments.context,
cache: applyArguments.cache,
@ -234,6 +238,8 @@ public final class InteractiveTextNodeWithEntities {
} else {
let resultNode = InteractiveTextNodeWithEntities(textNode: result)
resultNode.attributedString = arguments.attributedString
resultNode.updateInteractiveContents(
context: applyArguments.context,
cache: applyArguments.cache,

View File

@ -292,6 +292,10 @@ final class PeerInfoSelectionPanelNode: ASDisplayNode {
let separatorNode: ASDisplayNode
let backgroundNode: NavigationBackgroundNode
var viewForOverlayContent: UIView? {
return self.selectionPanel.viewForOverlayContent
}
init(context: AccountContext, presentationData: PresentationData, peerId: PeerId, deleteMessages: @escaping () -> Void, shareMessages: @escaping () -> Void, forwardMessages: @escaping () -> Void, reportMessages: @escaping () -> Void, displayCopyProtectionTip: @escaping (ASDisplayNode, Bool) -> Void) {
self.context = context
self.peerId = peerId
@ -447,7 +451,7 @@ final class PeerInfoSelectionPanelNode: ASDisplayNode {
self.separatorNode.backgroundColor = presentationData.theme.rootController.navigationBar.separatorColor
let interfaceState = ChatPresentationInterfaceState(chatWallpaper: .color(0), theme: presentationData.theme, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, limitsConfiguration: .defaultValue, fontSize: .regular, bubbleCorners: PresentationChatBubbleCorners(mainRadius: 16.0, auxiliaryRadius: 8.0, mergeBubbleCorners: true), accountPeerId: self.context.account.peerId, mode: .standard(.default), chatLocation: .peer(id: self.peerId), subject: nil, peerNearbyData: nil, greetingData: nil, pendingUnpinnedAllMessages: false, activeGroupCallInfo: nil, hasActiveGroupCall: false, importState: nil, threadData: nil, isGeneralThreadClosed: nil, replyMessage: nil, accountPeerColor: nil, businessIntro: nil)
let panelHeight = self.selectionPanel.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: layout.intrinsicInsets.bottom, additionalSideInsets: UIEdgeInsets(), maxHeight: 0.0, isSecondary: false, transition: transition, interfaceState: interfaceState, metrics: layout.metrics, isMediaInputExpanded: false)
let panelHeight = self.selectionPanel.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: layout.intrinsicInsets.bottom, additionalSideInsets: UIEdgeInsets(), maxHeight: layout.size.height, isSecondary: false, transition: transition, interfaceState: interfaceState, metrics: layout.metrics, isMediaInputExpanded: false)
transition.updateFrame(node: self.selectionPanel, frame: CGRect(origin: CGPoint(), size: CGSize(width: layout.size.width, height: panelHeight)))
@ -11687,6 +11691,9 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
})
self.paneContainerNode.selectionPanelNode = selectionPanelNode
self.paneContainerNode.addSubnode(selectionPanelNode)
if let viewForOverlayContent = selectionPanelNode.viewForOverlayContent {
self.paneContainerNode.view.addSubview(viewForOverlayContent)
}
}
selectionPanelNode.selectionPanel.selectedMessages = selectedMessageIds
let panelHeight = selectionPanelNode.update(layout: layout, presentationData: self.presentationData, transition: wasAdded ? .immediate : transition)
@ -11694,13 +11701,23 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
if wasAdded {
selectionPanelNode.frame = panelFrame
transition.animatePositionAdditive(node: selectionPanelNode, offset: CGPoint(x: 0.0, y: panelHeight))
if let viewForOverlayContent = selectionPanelNode.viewForOverlayContent {
viewForOverlayContent.frame = panelFrame
transition.animatePositionAdditive(layer: viewForOverlayContent.layer, offset: CGPoint(x: 0.0, y: panelHeight))
}
} else {
transition.updateFrame(node: selectionPanelNode, frame: panelFrame)
if let viewForOverlayContent = selectionPanelNode.viewForOverlayContent {
transition.updateFrame(view: viewForOverlayContent, frame: panelFrame)
}
}
} else if let selectionPanelNode = self.paneContainerNode.selectionPanelNode {
self.paneContainerNode.selectionPanelNode = nil
transition.updateFrame(node: selectionPanelNode, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height), size: selectionPanelNode.bounds.size), completion: { [weak selectionPanelNode] _ in
selectionPanelNode?.removeFromSupernode()
selectionPanelNode?.viewForOverlayContent?.removeFromSuperview()
})
}

View File

@ -52,7 +52,7 @@ private final class VisualMediaItemInteraction {
let openItemContextActions: (EngineStoryItem, ASDisplayNode, CGRect, ContextGesture?) -> Void
let toggleSelection: (Int32, Bool) -> Void
var hiddenMedia = Set<Int32>()
var hiddenStories = Set<StoryId>()
var selectedIds: Set<Int32>?
init(
@ -1825,7 +1825,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
let listContext = PeerStoryListContentContextImpl(
context: self.context,
listContext: self.listSource,
initialId: item.story.id,
initialId: item.storyId,
splitIndexIntoDays: splitIndexIntoDays
)
self.pendingOpenListContext = listContext
@ -1940,8 +1940,8 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
return
}
if let itemId {
let anyAmount = self.itemInteraction.hiddenMedia.isEmpty
self.itemInteraction.hiddenMedia = Set([itemId.id])
let anyAmount = self.itemInteraction.hiddenStories.isEmpty
self.itemInteraction.hiddenStories = Set([itemId])
if let items = self.items, let item = items.items.first(where: { $0.id == AnyHashable(itemId.id) }) {
self.itemGrid.ensureItemVisible(index: item.index, anyAmount: anyAmount)
@ -1961,7 +1961,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
}
}
} else {
self.itemInteraction.hiddenMedia = Set()
self.itemInteraction.hiddenStories = Set()
}
self.updateHiddenItems()
@ -2754,6 +2754,8 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
}
} else if case .botPreview = self.scope {
title = self.presentationData.strings.BotPreviews_SubtitleCount(Int32(state.totalCount))
} else if case .search = self.scope {
title = self.presentationData.strings.StoryList_SubtitleCount(Int32(state.totalCount))
} else {
title = ""
}
@ -3018,23 +3020,6 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
}
public func updateHiddenMedia() {
//TODO:updateHiddenMedia
/*self.itemGrid.forEachVisibleItem { item in
guard let itemLayer = item.layer as? ItemLayer else {
return
}
if let item = itemLayer.item {
if self.itemInteraction.hiddenMedia[item.message.id] != nil {
itemLayer.isHidden = true
itemLayer.updateHasSpoiler(hasSpoiler: false)
self.itemGridBinding.revealedSpoilerMessageIds.insert(item.message.id)
} else {
itemLayer.isHidden = false
}
} else {
itemLayer.isHidden = false
}
}*/
}
public func transferVelocity(_ velocity: CGFloat) {
@ -3281,7 +3266,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
guard let itemLayer = itemValue.layer as? ItemLayer, let item = itemLayer.item else {
return
}
let itemHidden = self.itemInteraction.hiddenMedia.contains(item.story.id)
let itemHidden = self.itemInteraction.hiddenStories.contains(item.storyId)
itemLayer.isHidden = itemHidden
if let blurLayer = itemValue.blurLayer {

View File

@ -1472,7 +1472,7 @@ public final class PeerStoryListContentContextImpl: StoryContentContext {
private var currentPeerData: (EnginePeer.Id, Promise<PeerData>)?
public init(context: AccountContext, listContext: StoryListContext, initialId: Int32?, splitIndexIntoDays: Bool) {
public init(context: AccountContext, listContext: StoryListContext, initialId: StoryId?, splitIndexIntoDays: Bool) {
self.context = context
let preferHighQualityStories: Signal<Bool, NoError> = combineLatest(
@ -1511,9 +1511,9 @@ public final class PeerStoryListContentContextImpl: StoryContentContext {
focusedIndex = nil
}
} else if let initialId = initialId {
if let index = state.items.firstIndex(where: { $0.storyItem.id == initialId }) {
if let index = state.items.firstIndex(where: { $0.id == initialId }) {
focusedIndex = index
} else if let index = state.items.firstIndex(where: { $0.storyItem.id <= initialId }) {
} else if let index = state.items.firstIndex(where: { $0.storyItem.id <= initialId.id }) {
focusedIndex = index
} else {
focusedIndex = nil

View File

@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "verifybadge1_20.pdf",
"filename" : "g1.svg",
"idiom" : "universal"
}
],

View File

@ -0,0 +1,3 @@
<svg width="56" height="56" viewBox="0 0 56 56" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.26539 29.9771C1.74019 31.4384 3.00745 32.7056 5.54196 35.2401L6.99942 36.6976V38.7594C6.99942 42.3437 6.99942 44.1359 7.69698 45.5049C8.31057 46.7091 9.28965 47.6882 10.4939 48.3018C11.8629 48.9994 13.6551 48.9994 17.2394 48.9994H19.3012L20.7589 50.4571C23.2934 52.9916 24.5607 54.2588 26.022 54.7336C27.3074 55.1513 28.692 55.1513 29.9774 54.7336C31.4387 54.2588 32.7059 52.9916 35.2404 50.4571L36.6981 48.9994H38.7594C42.3438 48.9994 44.1359 48.9994 45.505 48.3018C46.7092 47.6882 47.6883 46.7091 48.3019 45.5049C48.9994 44.1359 48.9994 42.3437 48.9994 38.7594V36.6981L50.4574 35.2401C52.9919 32.7056 54.2591 31.4384 54.7339 29.9771C55.1516 28.6917 55.1516 27.307 54.7339 26.0217C54.2591 24.5603 52.9919 23.2931 50.4574 20.7586L48.9994 19.3006V17.2394C48.9994 13.655 48.9994 11.8629 48.3019 10.4938C47.6883 9.28959 46.7092 8.31051 45.505 7.69692C44.1359 6.99936 42.3438 6.99936 38.7594 6.99936H36.6981L35.2404 5.54165C32.7059 3.00714 31.4387 1.73989 29.9774 1.26508C28.692 0.847434 27.3074 0.847434 26.022 1.26508C24.5607 1.73989 23.2934 3.00714 20.7589 5.54165L19.3012 6.99936H17.2394C13.6551 6.99936 11.8629 6.99936 10.4939 7.69692C9.28965 8.31051 8.31057 9.28959 7.69698 10.4938C6.99942 11.8629 6.99942 13.655 6.99942 17.2394V19.3011L5.54196 20.7586C3.00745 23.2931 1.74019 24.5603 1.26539 26.0217C0.847736 27.307 0.847736 28.6917 1.26539 29.9771Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1,107 +0,0 @@
%PDF-1.7
1 0 obj
<< >>
endobj
2 0 obj
<< /Length 3 0 R >>
stream
/DeviceRGB CS
/DeviceRGB cs
q
1.000000 0.000000 -0.000000 1.000000 1.625244 1.404785 cm
0.000000 0.000000 0.000000 scn
0.020125 7.977180 m
0.168502 7.520524 0.564519 7.124507 1.356553 6.332473 c
1.812012 5.877014 l
1.812012 5.232715 l
1.812012 4.112610 1.812012 3.552557 2.029999 3.124734 c
2.221745 2.748409 2.527707 2.442449 2.904031 2.250702 c
3.331854 2.032715 3.891907 2.032715 5.012012 2.032715 c
5.656311 2.032715 l
6.111846 1.577180 l
6.903880 0.785147 7.299897 0.389130 7.756554 0.240753 c
8.158240 0.110237 8.590935 0.110237 8.992621 0.240753 c
9.449278 0.389130 9.845295 0.785147 10.637329 1.577180 c
11.092864 2.032715 l
11.737012 2.032715 l
12.857117 2.032715 13.417170 2.032715 13.844993 2.250702 c
14.221317 2.442449 14.527278 2.748409 14.719025 3.124734 c
14.937012 3.552557 14.937012 4.112610 14.937012 5.232715 c
14.937012 5.876863 l
15.392622 6.332473 l
16.184656 7.124507 16.580673 7.520524 16.729050 7.977180 c
16.859566 8.378868 16.859566 8.811562 16.729050 9.213249 c
16.580673 9.669906 16.184656 10.065923 15.392622 10.857956 c
14.937012 11.313566 l
14.937012 11.957715 l
14.937012 13.077820 14.937012 13.637873 14.719025 14.065696 c
14.527278 14.442020 14.221317 14.747981 13.844993 14.939728 c
13.417170 15.157715 12.857117 15.157715 11.737012 15.157715 c
11.092864 15.157715 l
10.637329 15.613250 l
9.845295 16.405283 9.449278 16.801300 8.992621 16.949677 c
8.590935 17.080193 8.158240 17.080193 7.756554 16.949677 c
7.299897 16.801300 6.903880 16.405283 6.111846 15.613250 c
5.656311 15.157715 l
5.012012 15.157715 l
3.891907 15.157715 3.331854 15.157715 2.904031 14.939728 c
2.527707 14.747981 2.221745 14.442020 2.029999 14.065696 c
1.812012 13.637873 1.812012 13.077820 1.812012 11.957715 c
1.812012 11.313416 l
1.356553 10.857956 l
0.564519 10.065923 0.168502 9.669906 0.020125 9.213249 c
-0.110391 8.811562 -0.110391 8.378868 0.020125 7.977180 c
h
f*
n
Q
endstream
endobj
3 0 obj
1888
endobj
4 0 obj
<< /Annots []
/Type /Page
/MediaBox [ 0.000000 0.000000 20.000000 20.000000 ]
/Resources 1 0 R
/Contents 2 0 R
/Parent 5 0 R
>>
endobj
5 0 obj
<< /Kids [ 4 0 R ]
/Count 1
/Type /Pages
>>
endobj
6 0 obj
<< /Pages 5 0 R
/Type /Catalog
>>
endobj
xref
0 7
0000000000 65535 f
0000000010 00000 n
0000000034 00000 n
0000001978 00000 n
0000002001 00000 n
0000002174 00000 n
0000002248 00000 n
trailer
<< /ID [ (some) (id) ]
/Root 6 0 R
/Size 7
>>
startxref
2307
%%EOF

View File

@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "verifybadge2_20.pdf",
"filename" : "Logo 2.svg",
"idiom" : "universal"
}
],

View File

@ -0,0 +1,3 @@
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M23.1972 31.4693C22.2599 30.5321 20.7403 30.5321 19.803 31.4693C18.8658 32.4066 18.8658 33.9262 19.803 34.8635L23.1972 31.4693ZM28.5001 40.1664L26.803 41.8635C27.7403 42.8007 29.2599 42.8007 30.1972 41.8635L28.5001 40.1664ZM44.1972 27.8635C45.1344 26.9262 45.1344 25.4066 44.1972 24.4693C43.2599 23.5321 41.7403 23.5321 40.803 24.4693L44.1972 27.8635ZM19.803 34.8635L26.803 41.8635L30.1972 38.4694L23.1972 31.4693L19.803 34.8635ZM30.1972 41.8635L44.1972 27.8635L40.803 24.4693L26.803 38.4694L30.1972 41.8635Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 637 B

View File

@ -1,92 +0,0 @@
%PDF-1.7
1 0 obj
<< >>
endobj
2 0 obj
<< /Length 3 0 R >>
stream
/DeviceRGB CS
/DeviceRGB cs
q
1.000000 0.000000 -0.000000 1.000000 6.718750 5.801514 cm
0.000000 0.000000 0.000000 scn
0.530330 4.364315 m
0.237437 4.657207 -0.237437 4.657207 -0.530330 4.364315 c
-0.823223 4.071421 -0.823223 3.596547 -0.530330 3.303654 c
0.530330 4.364315 l
h
2.187500 1.646484 m
1.657170 1.116154 l
1.950063 0.823261 2.424937 0.823261 2.717830 1.116154 c
2.187500 1.646484 l
h
7.092830 5.491154 m
7.385724 5.784048 7.385724 6.258921 7.092830 6.551815 c
6.799937 6.844707 6.325063 6.844707 6.032170 6.551815 c
7.092830 5.491154 l
h
-0.530330 3.303654 m
1.657170 1.116154 l
2.717830 2.176814 l
0.530330 4.364315 l
-0.530330 3.303654 l
h
2.717830 1.116154 m
7.092830 5.491154 l
6.032170 6.551815 l
1.657170 2.176814 l
2.717830 1.116154 l
h
f
n
Q
endstream
endobj
3 0 obj
762
endobj
4 0 obj
<< /Annots []
/Type /Page
/MediaBox [ 0.000000 0.000000 20.000000 20.000000 ]
/Resources 1 0 R
/Contents 2 0 R
/Parent 5 0 R
>>
endobj
5 0 obj
<< /Kids [ 4 0 R ]
/Count 1
/Type /Pages
>>
endobj
6 0 obj
<< /Pages 5 0 R
/Type /Catalog
>>
endobj
xref
0 7
0000000000 65535 f
0000000010 00000 n
0000000034 00000 n
0000000852 00000 n
0000000874 00000 n
0000001047 00000 n
0000001121 00000 n
trailer
<< /ID [ (some) (id) ]
/Root 6 0 R
/Size 7
>>
startxref
1180
%%EOF