This commit is contained in:
Isaac 2025-07-28 00:29:25 +02:00
parent 633b44843a
commit 6ff5012e18
44 changed files with 478 additions and 377 deletions

View File

@ -3451,6 +3451,8 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
break
case let .peer(peerData):
if let peer = peerData.peer.peer, let message = peerData.messages.first {
let _ = context.engine.peers.ensurePeerIsLocallyAvailable(peer: peer).startStandalone()
peerContextAction(peer, .search(message.id), node, gesture, location)
}
case .groupReference:

View File

@ -7,6 +7,6 @@
NSData * _Nullable prepareSvgImage(NSData * _Nonnull data, bool pattern);
UIImage * _Nullable renderPreparedImage(NSData * _Nonnull data, CGSize size, UIColor * _Nonnull backgroundColor, CGFloat scale, bool fit);
UIImage * _Nullable drawSvgImage(NSData * _Nonnull data, CGSize size, UIColor * _Nullable backgroundColor, UIColor * _Nullable foregroundColor, bool opaque);
UIImage * _Nullable drawSvgImage(NSData * _Nonnull data, CGSize size, UIColor * _Nullable backgroundColor, UIColor * _Nullable foregroundColor, CGFloat scale, bool opaque);
#endif /* Lottie_h */

View File

@ -88,8 +88,7 @@ CGSize aspectFitSize(CGSize size, CGSize bounds) {
@end
UIImage * _Nullable drawSvgImage(NSData * _Nonnull data, CGSize size, UIColor *backgroundColor, UIColor *foregroundColor, bool opaque) {
NSDate *startTime = [NSDate date];
UIImage * _Nullable drawSvgImage(NSData * _Nonnull data, CGSize size, UIColor *backgroundColor, UIColor *foregroundColor, CGFloat canvasScale, bool opaque) {
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
if (parser == nil) {
@ -120,15 +119,12 @@ UIImage * _Nullable drawSvgImage(NSData * _Nonnull data, CGSize size, UIColor *b
size = CGSizeMake(image->width, image->height);
}
double deltaTime = -1.0f * [startTime timeIntervalSinceNow];
printf("parseTime = %f\n", deltaTime);
startTime = [NSDate date];
UIGraphicsBeginImageContextWithOptions(size, opaque, 1.0);
UIGraphicsBeginImageContextWithOptions(size, opaque, canvasScale);
CGContextRef context = UIGraphicsGetCurrentContext();
if (backgroundColor != nil) {
CGContextSetFillColorWithColor(context, backgroundColor.CGColor);
CGContextFillRect(context, CGRectMake(0.0f, 0.0f, size.width, size.height));
}
CGSize svgSize = CGSizeMake(image->width, image->height);
CGSize drawingSize = aspectFillSize(svgSize, size);
@ -231,9 +227,6 @@ UIImage * _Nullable drawSvgImage(NSData * _Nonnull data, CGSize size, UIColor *b
UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
deltaTime = -1.0f * [startTime timeIntervalSinceNow];
printf("drawingTime %fx%f = %f\n", size.width, size.height, deltaTime);
nsvgDelete(image);
return resultImage;

View File

@ -2261,7 +2261,7 @@ public final class AccountViewTracker {
return -1
}
}, next: { [weak self] next, viewId in
if let strongSelf = self, let account = strongSelf.account, updateData {
if let strongSelf = self, let account = strongSelf.account {
strongSelf.updateCachedPeerData(peerId: peerId, accountPeerId: account.peerId, viewId: viewId, hasCachedData: next.cachedData != nil)
}
}, disposed: { [weak self] viewId in

View File

@ -13,11 +13,7 @@ swift_library(
"//submodules/Display",
"//submodules/ComponentFlow",
"//submodules/Components/MultilineTextComponent",
"//submodules/TelegramUI/Components/TextLoadingEffect",
"//submodules/Components/ComponentDisplayAdapters",
"//submodules/TooltipUI",
"//submodules/AccountContext",
"//submodules/UIKitRuntimeUtils",
"//submodules/Svg",
],
visibility = [
"//visibility:public",

View File

@ -3,131 +3,72 @@ import UIKit
import Display
import ComponentFlow
import MultilineTextComponent
import TextLoadingEffect
import ComponentDisplayAdapters
import TooltipUI
import AccountContext
import UIKitRuntimeUtils
import Svg
public final class PeerInfoRatingComponent: Component {
let context: AccountContext
let backgroundColor: UIColor
let borderColor: UIColor
let foregroundColor: UIColor
let tooltipBackgroundColor: UIColor
let isExpanded: Bool
let compactLabel: String
let fraction: CGFloat
let label: String
let nextLabel: String
let tooltipLabel: String
let level: Int
let action: () -> Void
public init(
context: AccountContext,
backgroundColor: UIColor,
borderColor: UIColor,
foregroundColor: UIColor,
tooltipBackgroundColor: UIColor,
isExpanded: Bool,
compactLabel: String,
fraction: CGFloat,
label: String,
nextLabel: String,
tooltipLabel: String,
level: Int,
action: @escaping () -> Void
) {
self.context = context
self.backgroundColor = backgroundColor
self.borderColor = borderColor
self.foregroundColor = foregroundColor
self.tooltipBackgroundColor = tooltipBackgroundColor
self.isExpanded = isExpanded
self.compactLabel = compactLabel
self.fraction = fraction
self.label = label
self.nextLabel = nextLabel
self.tooltipLabel = tooltipLabel
self.level = level
self.action = action
}
public static func ==(lhs: PeerInfoRatingComponent, rhs: PeerInfoRatingComponent) -> Bool {
if lhs.context !== rhs.context {
if lhs.backgroundColor != rhs.backgroundColor {
return false
}
if lhs.backgroundColor != rhs.backgroundColor {
if lhs.borderColor != rhs.borderColor {
return false
}
if lhs.foregroundColor != rhs.foregroundColor {
return false
}
if lhs.tooltipBackgroundColor != rhs.tooltipBackgroundColor {
return false
}
if lhs.isExpanded != rhs.isExpanded {
return false
}
if lhs.compactLabel != rhs.compactLabel {
return false
}
if lhs.fraction != rhs.fraction {
return false
}
if lhs.label != rhs.label {
return false
}
if lhs.nextLabel != rhs.nextLabel {
return false
}
if lhs.tooltipLabel != rhs.tooltipLabel {
if lhs.level != rhs.level {
return false
}
return true
}
public final class View: UIView {
private let backgroundView: UIImageView
private let foregroundView: UIImageView
private let foregroundMaskView: UIView
private let foregroundClippedView: UIView
private let foregroundClippedMaskView: UIView
private let foregroundClippedShapeView: UIImageView
private let compactLabel = ComponentView<Empty>()
private let expandedLabel = ComponentView<Empty>()
private let expandedClippedLabel = ComponentView<Empty>()
private let nextLabel = ComponentView<Empty>()
private struct TextLayout {
var size: CGSize
var opticalBounds: CGRect
private var shimmerEffectView: TextLoadingEffectView?
init(size: CGSize, opticalBounds: CGRect) {
self.size = size
self.opticalBounds = opticalBounds
}
}
public final class View: UIView {
private let borderLayer: SimpleLayer
private let backgroundLayer: SimpleLayer
private var tempLevel: Int = 1
private var component: PeerInfoRatingComponent?
private var tooltipController: TooltipScreen?
private weak var state: EmptyComponentState?
override public init(frame: CGRect) {
self.backgroundView = UIImageView()
self.foregroundView = UIImageView()
self.foregroundMaskView = UIView()
self.foregroundMaskView.backgroundColor = .white
self.foregroundView.mask = self.foregroundMaskView
if let filter = CALayer.luminanceToAlpha() {
self.foregroundMaskView.layer.filters = [filter]
}
self.foregroundClippedView = UIView()
self.foregroundClippedMaskView = UIView()
self.foregroundClippedMaskView.backgroundColor = .black
self.foregroundClippedView.mask = self.foregroundClippedMaskView
if let filter = CALayer.luminanceToAlpha() {
self.foregroundClippedMaskView.layer.filters = [filter]
}
self.foregroundClippedShapeView = UIImageView()
self.foregroundClippedMaskView.addSubview(self.foregroundClippedShapeView)
self.borderLayer = SimpleLayer()
self.backgroundLayer = SimpleLayer()
super.init(frame: frame)
self.addSubview(self.backgroundView)
self.addSubview(self.foregroundClippedView)
self.addSubview(self.foregroundView)
self.layer.addSublayer(self.borderLayer)
self.layer.addSublayer(self.backgroundLayer)
self.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.onTapGesture(_:))))
}
@ -139,203 +80,172 @@ public final class PeerInfoRatingComponent: Component {
@objc private func onTapGesture(_ recognizer: UITapGestureRecognizer) {
if case .ended = recognizer.state {
self.component?.action()
if self.tempLevel < 10 {
self.tempLevel += 1
} else {
self.tempLevel += 10
}
if self.tempLevel >= 110 {
self.tempLevel = 1
}
self.state?.updated(transition: .immediate)
}
}
func update(component: PeerInfoRatingComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
self.component = component
let previousBackgroundFrame = self.backgroundView.frame
let size = CGSize(width: 30.0, height: 30.0)
let alphaTransition: ComponentTransition = transition.animation.isImmediate ? .immediate : .easeInOut(duration: 0.2)
let baseHeight: CGFloat = 20.0
let innerInset: CGFloat = 2.0
let previousComponent = self.component
self.component = component
self.state = state
let compactLabelSize = self.compactLabel.update(
transition: .immediate,
component: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(string: component.compactLabel, font: Font.medium(11.0), textColor: .black))
)),
environment: {},
containerSize: CGSize(width: 100.0, height: 100.0)
)
//TODO:localize
//let level = component.level
let level = self.tempLevel
let expandedSize = CGSize(width: 174.0, height: baseHeight)
let collapsedSize = CGSize(width: max(baseHeight, compactLabelSize.width + 6.0 * 2.0), height: baseHeight)
let iconSize = CGSize(width: 26.0, height: 26.0)
if self.backgroundView.image == nil {
self.backgroundView.image = generateStretchableFilledCircleImage(diameter: baseHeight, color: .white)?.withRenderingMode(.alwaysTemplate)
}
if self.foregroundView.image == nil {
self.foregroundView.image = generateStretchableFilledCircleImage(diameter: baseHeight - innerInset * 2.0, color: .white)?.withRenderingMode(.alwaysTemplate)
}
if self.foregroundClippedShapeView.image == nil {
self.foregroundClippedShapeView.image = generateStretchableFilledCircleImage(diameter: baseHeight - innerInset * 2.0, color: .black)
//TODO:localize
if previousComponent?.level != level || previousComponent?.borderColor != component.borderColor || previousComponent?.foregroundColor != component.foregroundColor || previousComponent?.backgroundColor != component.backgroundColor || "".isEmpty {
let attributedText = NSAttributedString(string: "\(level)", attributes: [
NSAttributedString.Key.font: Font.semibold(10.0),
NSAttributedString.Key.foregroundColor: component.foregroundColor
])
var boundingRect = attributedText.boundingRect(with: CGSize(width: 100.0, height: 100.0), options: .usesLineFragmentOrigin, context: nil)
boundingRect.size.width = ceil(boundingRect.size.width)
boundingRect.size.height = ceil(boundingRect.size.height)
var textLayout: TextLayout?
if let context = DrawingContext(size: boundingRect.size, scale: 0.0, opaque: false, clear: true) {
context.withContext { c in
UIGraphicsPushContext(c)
defer {
UIGraphicsPopContext()
}
self.backgroundView.tintColor = component.backgroundColor
self.foregroundView.tintColor = component.foregroundColor
attributedText.draw(at: CGPoint())
}
var minFilledLineY = Int(context.scaledSize.height) - 1
var maxFilledLineY = 0
var minFilledLineX = Int(context.scaledSize.width) - 1
var maxFilledLineX = 0
for y in 0 ..< Int(context.scaledSize.height) {
let linePtr = context.bytes.advanced(by: max(0, y) * context.bytesPerRow).assumingMemoryBound(to: UInt32.self)
let size = component.isExpanded ? expandedSize : collapsedSize
let backgroundFrame = CGRect(origin: CGPoint(), size: size)
for x in 0 ..< Int(context.scaledSize.width) {
let pixelPtr = linePtr.advanced(by: x)
if pixelPtr.pointee != 0 {
minFilledLineY = min(y, minFilledLineY)
maxFilledLineY = max(y, maxFilledLineY)
minFilledLineX = min(x, minFilledLineX)
maxFilledLineX = max(x, maxFilledLineX)
}
}
}
transition.setFrame(view: self.backgroundView, frame: backgroundFrame)
var opticalBounds = CGRect()
if minFilledLineX <= maxFilledLineX && minFilledLineY <= maxFilledLineY {
opticalBounds.origin.x = CGFloat(minFilledLineX) / context.scale
opticalBounds.origin.y = CGFloat(minFilledLineY) / context.scale
opticalBounds.size.width = CGFloat(maxFilledLineX - minFilledLineX) / context.scale
opticalBounds.size.height = CGFloat(maxFilledLineY - minFilledLineY) / context.scale
}
let foregroundFrame: CGRect
if component.isExpanded {
let foregroundWidth = floorToScreenPixels(backgroundFrame.insetBy(dx: innerInset, dy: innerInset).width * component.fraction)
foregroundFrame = CGRect(origin: CGPoint(x: innerInset, y: innerInset), size: CGSize(width: foregroundWidth, height: backgroundFrame.height - innerInset * 2.0))
textLayout = TextLayout(size: boundingRect.size, opticalBounds: opticalBounds)
}
let levelIndex: Int
if level <= 10 {
levelIndex = max(0, component.level)
} else if level <= 90 {
levelIndex = (level / 10) * 10
} else {
foregroundFrame = backgroundFrame.insetBy(dx: innerInset, dy: innerInset)
levelIndex = 90
}
let borderImage = generateImage(iconSize, rotatedContext: { size, context in
UIGraphicsPushContext(context)
defer {
UIGraphicsPopContext()
}
transition.setFrame(view: self.foregroundView, frame: foregroundFrame)
transition.setFrame(view: self.foregroundMaskView, frame: CGRect(origin: CGPoint(), size: foregroundFrame.size))
context.clear(CGRect(origin: CGPoint(), size: size))
transition.setFrame(view: self.foregroundClippedView, frame: CGRect(origin: CGPoint(), size: size))
transition.setFrame(view: self.foregroundClippedMaskView, frame: CGRect(origin: CGPoint(), size: size))
self.foregroundClippedView.backgroundColor = component.foregroundColor
transition.setFrame(view: self.foregroundClippedShapeView, frame: foregroundFrame)
if let compactLabelView = self.compactLabel.view {
if compactLabelView.superview == nil {
self.foregroundMaskView.addSubview(compactLabelView)
if let url = Bundle.main.url(forResource: "profile_level\(levelIndex)_outer", withExtension: "svg"), let data = try? Data(contentsOf: url) {
if let image = generateTintedImage(image: drawSvgImage(data, size, nil, nil, 0.0, false), color: component.borderColor) {
image.draw(in: CGRect(origin: CGPoint(), size: size), blendMode: .normal, alpha: 1.0)
}
compactLabelView.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((collapsedSize.width - innerInset * 2.0 - compactLabelSize.width) * 0.5), y: floorToScreenPixels((baseHeight - innerInset * 2.0 - compactLabelSize.height) * 0.5) + UIScreenPixel), size: compactLabelSize)
alphaTransition.setAlpha(view: compactLabelView, alpha: component.isExpanded ? 0.0 : 1.0)
}
let expandedLabelSize = self.expandedLabel.update(
transition: .immediate,
component: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(string: component.label, font: Font.medium(11.0), textColor: .black))
)),
environment: {},
containerSize: CGSize(width: 100.0, height: 100.0)
)
if let expandedLabelView = self.expandedLabel.view {
if expandedLabelView.superview == nil {
self.foregroundMaskView.addSubview(expandedLabelView)
}
expandedLabelView.frame = CGRect(origin: CGPoint(x: 4.0, y: floorToScreenPixels((baseHeight - innerInset * 2.0 - expandedLabelSize.height) * 0.5) + UIScreenPixel), size: expandedLabelSize)
alphaTransition.setAlpha(view: expandedLabelView, alpha: component.isExpanded ? 1.0 : 0.0)
}
let expandedClippedLabelSize = self.expandedClippedLabel.update(
transition: .immediate,
component: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(string: component.label, font: Font.medium(11.0), textColor: .white))
)),
environment: {},
containerSize: CGSize(width: 100.0, height: 100.0)
)
if let expandedClippedLabelView = self.expandedClippedLabel.view {
if expandedClippedLabelView.superview == nil {
self.foregroundClippedMaskView.insertSubview(expandedClippedLabelView, belowSubview: self.foregroundClippedShapeView)
}
expandedClippedLabelView.frame = CGRect(origin: CGPoint(x: innerInset + 4.0, y: innerInset + floorToScreenPixels((baseHeight - innerInset * 2.0 - expandedClippedLabelSize.height) * 0.5) + UIScreenPixel), size: expandedClippedLabelSize)
alphaTransition.setAlpha(view: expandedClippedLabelView, alpha: component.isExpanded ? 1.0 : 0.0)
}
let nextLabelSize = self.nextLabel.update(
transition: .immediate,
component: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(string: component.nextLabel, font: Font.medium(11.0), textColor: component.foregroundColor.withMultipliedAlpha(0.5)))
)),
environment: {},
containerSize: CGSize(width: 100.0, height: 100.0)
)
if let nextLabelView = self.nextLabel.view {
if nextLabelView.superview == nil {
self.insertSubview(nextLabelView, belowSubview: self.foregroundView)
}
let nextLabelFrame = CGRect(origin: CGPoint(x: size.width - nextLabelSize.width - 4.0 - innerInset, y: floorToScreenPixels((baseHeight - nextLabelSize.height) * 0.5) + UIScreenPixel), size: nextLabelSize)
transition.setPosition(view: nextLabelView, position: nextLabelFrame.center)
nextLabelView.bounds = CGRect(origin: CGPoint(), size: nextLabelFrame.size)
alphaTransition.setAlpha(view: nextLabelView, alpha: component.isExpanded ? 1.0 : 0.0)
}
if component.isExpanded {
var shimmerEffectTransition = transition
let shimmerEffectView: TextLoadingEffectView
if let current = self.shimmerEffectView {
shimmerEffectView = current
} else {
shimmerEffectTransition = .immediate
shimmerEffectView = TextLoadingEffectView(frame: CGRect())
self.shimmerEffectView = shimmerEffectView
self.addSubview(shimmerEffectView)
shimmerEffectView.frame = previousBackgroundFrame
shimmerEffectView.alpha = 0.0
}
transition.setFrame(view: shimmerEffectView, frame: backgroundFrame)
alphaTransition.setAlpha(view: shimmerEffectView, alpha: 1.0)
shimmerEffectView.update(color: .clear, borderColor: component.foregroundColor, rect: CGRect(origin: CGPoint(), size: backgroundFrame.size), path: UIBezierPath(roundedRect: CGRect(origin: CGPoint(), size: backgroundFrame.size).insetBy(dx: 1.0, dy: 1.0), cornerRadius: backgroundFrame.height * 0.5).cgPath, transition: shimmerEffectTransition.containedViewLayoutTransition)
} else if let shimmerEffectView = self.shimmerEffectView {
self.shimmerEffectView = nil
transition.setFrame(view: shimmerEffectView, frame: backgroundFrame)
shimmerEffectView.update(color: .clear, borderColor: component.foregroundColor, rect: CGRect(origin: CGPoint(), size: backgroundFrame.size), path: UIBezierPath(roundedRect: CGRect(origin: CGPoint(), size: backgroundFrame.size), cornerRadius: backgroundFrame.height * 0.5).cgPath, transition: transition.containedViewLayoutTransition)
alphaTransition.setAlpha(view: shimmerEffectView, alpha: 0.0, completion: { [weak shimmerEffectView] _ in
shimmerEffectView?.removeFromSuperview()
})
}
if !component.tooltipLabel.isEmpty {
let tooltipController: TooltipScreen
if let current = self.tooltipController {
tooltipController = current
if let previousContents = self.borderLayer.contents, CFGetTypeID(previousContents as CFTypeRef) == CGImage.typeID {
self.borderLayer.contents = borderImage!.cgImage
alphaTransition.animateContentsImage(layer: self.borderLayer, from: previousContents as! CGImage, to: borderImage!.cgImage!, duration: 0.2, curve: .easeInOut)
} else {
tooltipController = TooltipScreen(
context: component.context,
account: component.context.account,
sharedContext: component.context.sharedContext,
text: .attributedString(text: NSAttributedString(string: component.tooltipLabel, font: Font.semibold(11.0), textColor: .white)),
style: .customBlur(component.tooltipBackgroundColor, -4.0),
arrowStyle: .small,
location: .point(CGRect(origin: CGPoint(x: 100.0, y: 100.0), size: CGSize()), .bottom),
displayDuration: .infinite,
isShimmering: true,
cornerRadius: 10.0,
shouldDismissOnTouch: { _, _ in
return .ignore
}
)
self.tooltipController = tooltipController
tooltipController.containerLayoutUpdated(ContainerViewLayout(
size: CGSize(width: 200.0, height: 200.0),
metrics: LayoutMetrics(),
deviceMetrics: DeviceMetrics.iPhoneXSMax,
intrinsicInsets: UIEdgeInsets(),
safeInsets: UIEdgeInsets(),
additionalInsets: UIEdgeInsets(),
statusBarHeight: nil,
inputHeight: nil,
inputHeightIsInteractivellyChanging: false,
inVoiceOver: false
), transition: .immediate)
self.layer.addSublayer(tooltipController.view.layer)
tooltipController.viewWillAppear(false)
tooltipController.viewDidAppear(false)
tooltipController.setIgnoreAppearanceMethodInvocations(true)
tooltipController.view.isUserInteractionEnabled = false
self.borderLayer.contents = borderImage!.cgImage
}
transition.setFrame(view: tooltipController.view, frame: CGRect(origin: CGPoint(), size: CGSize(width: 200.0, height: 200.0)).offsetBy(dx: -200.0 * 0.5 + foregroundFrame.width + 2.0, dy: -200.0 * 0.5))
alphaTransition.setAlpha(view: tooltipController.view, alpha: component.isExpanded ? 1.0 : 0.0)
let backgroundImage = generateImage(iconSize, rotatedContext: { size, context in
UIGraphicsPushContext(context)
defer {
UIGraphicsPopContext()
}
context.clear(CGRect(origin: CGPoint(), size: size))
if let url = Bundle.main.url(forResource: "profile_level\(levelIndex)_inner", withExtension: "svg"), let data = try? Data(contentsOf: url) {
if let image = generateTintedImage(image: drawSvgImage(data, size, nil, nil, 0.0, false), color: component.backgroundColor) {
image.draw(in: CGRect(origin: CGPoint(), size: size), blendMode: .normal, alpha: 1.0)
}
}
if component.foregroundColor.alpha < 1.0 {
context.setBlendMode(.copy)
} else {
if let tooltipController = self.tooltipController {
self.tooltipController = nil
tooltipController.view.layer.removeFromSuperlayer()
context.setBlendMode(.normal)
}
if let textLayout {
let titleScale: CGFloat
if level < 10 {
titleScale = 1.0
} else if level < 100 {
titleScale = 0.8
} else {
titleScale = 0.6
}
var textFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - textLayout.size.width) * 0.5), y: floorToScreenPixels((size.height - textLayout.size.height) * 0.5)), size: textLayout.size)
if level == 1 {
} else {
textFrame.origin.x += UIScreenPixel
}
context.saveGState()
context.translateBy(x: textFrame.midX, y: textFrame.midY)
context.scaleBy(x: titleScale, y: titleScale)
context.translateBy(x: -textFrame.midX, y: -textFrame.midY)
attributedText.draw(at: textFrame.origin)
context.restoreGState()
}
})
if let previousContents = self.backgroundLayer.contents, CFGetTypeID(previousContents as CFTypeRef) == CGImage.typeID {
self.backgroundLayer.contents = backgroundImage!.cgImage
alphaTransition.animateContentsImage(layer: self.backgroundLayer, from: previousContents as! CGImage, to: backgroundImage!.cgImage!, duration: 0.2, curve: .easeInOut)
} else {
self.backgroundLayer.contents = backgroundImage!.cgImage
}
}
let backgroundFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - iconSize.width) * 0.5), y: floorToScreenPixels((size.height - iconSize.height) * 0.5)), size: iconSize)
transition.setFrame(layer: self.backgroundLayer, frame: backgroundFrame)
transition.setFrame(layer: self.borderLayer, frame: backgroundFrame)
return size
}
}

View File

@ -132,8 +132,6 @@ final class PeerInfoHeaderNode: ASDisplayNode {
let titleExpandedStatusIconView: ComponentHostView<Empty>
var titleExpandedStatusIconSize: CGSize?
var subtitleRatingIsExpanded: Bool = false
var didDisplayRatingTooltip: Bool = false
var subtitleRating: ComponentView<Empty>?
let subtitleNodeContainer: ASDisplayNode
@ -779,6 +777,10 @@ final class PeerInfoHeaderNode: ASDisplayNode {
self.avatarClippingNode.clipsToBounds = true
}
let ratingBackgroundColor: UIColor
let ratingBorderColor: UIColor
let ratingForegroundColor: UIColor
if state.isEditing {
navigationContentsAccentColor = collapsedHeaderNavigationContentsAccentColor
navigationContentsPrimaryColor = collapsedHeaderNavigationContentsPrimaryColor
@ -789,6 +791,10 @@ final class PeerInfoHeaderNode: ASDisplayNode {
contentButtonForegroundColor = collapsedHeaderContentButtonForegroundColor
headerButtonBackgroundColor = collapsedHeaderButtonBackgroundColor
ratingBackgroundColor = presentationData.theme.list.itemCheckColors.fillColor
ratingBorderColor = .clear
ratingForegroundColor = presentationData.theme.list.itemCheckColors.foregroundColor
} else if self.isAvatarExpanded {
navigationContentsAccentColor = expandedAvatarNavigationContentsAccentColor
navigationContentsPrimaryColor = expandedAvatarNavigationContentsPrimaryColor
@ -799,6 +805,10 @@ final class PeerInfoHeaderNode: ASDisplayNode {
navigationContentsCanBeExpanded = false
headerButtonBackgroundColor = expandedAvatarHeaderButtonBackgroundColor
ratingBackgroundColor = .white
ratingBorderColor = .clear
ratingForegroundColor = .clear
} else {
let effectiveTransitionFraction: CGFloat = innerBackgroundTransitionFraction < 0.5 ? 0.0 : 1.0
@ -812,10 +822,22 @@ final class PeerInfoHeaderNode: ASDisplayNode {
navigationContentsCanBeExpanded = true
}
contentButtonBackgroundColor = regularContentButtonBackgroundColor//.mixedWith(collapsedHeaderContentButtonBackgroundColor, alpha: effectiveTransitionFraction)
contentButtonForegroundColor = regularContentButtonForegroundColor//.mixedWith(collapsedHeaderContentButtonForegroundColor, alpha: effectiveTransitionFraction)
contentButtonBackgroundColor = regularContentButtonBackgroundColor
contentButtonForegroundColor = regularContentButtonForegroundColor
headerButtonBackgroundColor = regularHeaderButtonBackgroundColor.mixedWith(collapsedHeaderButtonBackgroundColor, alpha: effectiveTransitionFraction)
if let profileColor = peer?.profileColor {
let backgroundColors = self.context.peerNameColors.getProfile(profileColor, dark: presentationData.theme.overallDarkAppearance)
ratingBackgroundColor = UIColor(white: 1.0, alpha: 1.0).mixedWith(presentationData.theme.list.itemCheckColors.fillColor, alpha: effectiveTransitionFraction)
ratingForegroundColor = backgroundColors.main.withMultiplied(hue: 1.0, saturation: 1.1, brightness: 0.9).mixedWith(UIColor.clear, alpha: effectiveTransitionFraction)
ratingBorderColor = ratingForegroundColor.mixedWith(presentationData.theme.list.itemCheckColors.foregroundColor, alpha: effectiveTransitionFraction)
} else {
ratingBackgroundColor = presentationData.theme.list.itemCheckColors.fillColor
ratingBorderColor = UIColor.clear
ratingForegroundColor = presentationData.theme.list.itemCheckColors.foregroundColor
}
}
do {
@ -1552,6 +1574,9 @@ final class PeerInfoHeaderNode: ASDisplayNode {
titleCollapseFraction = max(0.0, min(1.0, contentOffset / titleCollapseOffset))
subtitleFrame = CGRect(origin: CGPoint(x: 16.0, y: minTitleFrame.maxY + 2.0), size: subtitleSize)
if self.subtitleRating != nil {
subtitleFrame.origin.x += 22.0
}
usernameFrame = CGRect(origin: CGPoint(x: width - usernameSize.width - 16.0, y: minTitleFrame.midY - usernameSize.height / 2.0), size: usernameSize)
} else {
titleFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((width - titleSize.width) / 2.0), y: avatarFrame.maxY + 9.0 + (subtitleSize.height.isZero ? 11.0 : 0.0)), size: titleSize)
@ -1917,7 +1942,9 @@ final class PeerInfoHeaderNode: ASDisplayNode {
let apparentBackgroundHeight = (1.0 - transitionFraction) * backgroundHeight + transitionFraction * transitionSourceHeight
var subtitleRatingSize: CGSize?
if let cachedData = cachedData as? CachedUserData, let starRating = cachedData.starRating {
//TODO:localize
//if let cachedData = cachedData as? CachedUserData, let starRating = cachedData.starRating {
if "".isEmpty {
let subtitleRating: ComponentView<Empty>
var subtitleRatingTransition = ComponentTransition(transition)
if let current = self.subtitleRating {
@ -1927,82 +1954,21 @@ final class PeerInfoHeaderNode: ASDisplayNode {
subtitleRating = ComponentView()
self.subtitleRating = subtitleRating
}
let fraction: CGFloat
let tooltipLabel: String
if let nextLevelStars = starRating.nextLevelStars {
fraction = CGFloat(starRating.currentLevelStars) / CGFloat(nextLevelStars)
tooltipLabel = "\(starRating.currentLevelStars) / \(nextLevelStars)"
} else {
fraction = 1.0
tooltipLabel = ""
}
let tooltipBackgroundColor: UIColor
let ratingBackgroundColor: UIColor
let ratingForegroundColor: UIColor
if peer?.profileColor != nil {
ratingBackgroundColor = UIColor(white: 1.0, alpha: 0.1)
ratingForegroundColor = UIColor(white: 1.0, alpha: 1.0)
if !self.isAvatarExpanded {
tooltipBackgroundColor = contentButtonBackgroundColor
} else {
tooltipBackgroundColor = UIColor(rgb: 0x000000, alpha: 0.65)
}
} else {
ratingBackgroundColor = presentationData.theme.list.freeTextColor.withMultipliedAlpha(0.1)
ratingForegroundColor = presentationData.theme.list.freeTextColor.withMultipliedAlpha(1.0)
tooltipBackgroundColor = UIColor(rgb: 0x000000, alpha: 0.65)
}
//TODO:localize
subtitleRatingSize = subtitleRating.update(
transition: subtitleRatingTransition,
component: AnyComponent(PeerInfoRatingComponent(
context: self.context,
backgroundColor: ratingBackgroundColor,
borderColor: ratingBorderColor,
foregroundColor: ratingForegroundColor,
tooltipBackgroundColor: tooltipBackgroundColor,
isExpanded: self.subtitleRatingIsExpanded,
compactLabel: "\(starRating.level)",
fraction: fraction,
label: "Level \(starRating.level)",
nextLabel: starRating.nextLevelStars != nil ? "\(starRating.level + 1)" : "",
tooltipLabel: tooltipLabel,
//TODO:localize
level: 1,//Int(starRating.level),
action: { [weak self] in
guard let self else {
return
}
self.subtitleRatingIsExpanded = !self.subtitleRatingIsExpanded
self.requestUpdateLayout?(true)
if self.subtitleRatingIsExpanded, let controller = self.controller, let presentationData = self.presentationData, !self.didDisplayRatingTooltip {
self.didDisplayRatingTooltip = true
controller.present(UndoOverlayController(
presentationData: presentationData,
content: .info(
title: nil,
text: "Profile level reflects the user's payment reliability",
timeout: 4.0,
customUndoText: "Learn More"
),
position: .top,
action: { [weak self] action in
guard let self else {
return true
}
if case .undo = action {
var infoUrl = "https://telegram.org/blog/telegram-stars"
if let data = self.context.currentAppConfiguration.with({ $0 }).data, let value = data["stars_rating_learnmore_url"] as? String {
infoUrl = value
}
self.context.sharedContext.applicationBindings.openUrl(infoUrl)
}
return true
}
), in: .current)
}
let _ = self
}
)),
environment: {},
@ -2064,11 +2030,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
if let subtitleRatingView = self.subtitleRating?.view, let subtitleRatingSize {
let subtitleBadgeFrame: CGRect
if self.subtitleRatingIsExpanded {
subtitleBadgeFrame = CGRect(origin: CGPoint(x: -subtitleRatingSize.width * 0.5, y: floor((-subtitleRatingSize.height) * 0.5)), size: subtitleRatingSize)
} else {
subtitleBadgeFrame = CGRect(origin: CGPoint(x: (-subtitleSize.width) * 0.5 - 4.0 - subtitleRatingSize.width, y: floor((-subtitleRatingSize.height) * 0.5)), size: subtitleRatingSize)
}
subtitleBadgeFrame = CGRect(origin: CGPoint(x: (-subtitleSize.width) * 0.5 - subtitleRatingSize.width + 1.0, y: floor((-subtitleRatingSize.height) * 0.5)), size: subtitleRatingSize)
transition.updateFrameAdditive(view: subtitleRatingView, frame: subtitleBadgeFrame)
transition.updateAlpha(layer: subtitleRatingView.layer, alpha: (1.0 - transitionFraction))
}
@ -2077,18 +2039,15 @@ final class PeerInfoHeaderNode: ASDisplayNode {
let subtitleScale: CGFloat
var subtitleOffset: CGFloat = 0.0
let subtitleBadgeFraction: CGFloat
let subtitleRatingFraction: CGFloat
if self.isAvatarExpanded {
titleScale = expandedTitleScale
subtitleScale = 1.0
subtitleBadgeFraction = 1.0
subtitleRatingFraction = 0.0
} else {
titleScale = (1.0 - titleCollapseFraction) * 1.0 + titleCollapseFraction * titleMinScale
subtitleScale = (1.0 - titleCollapseFraction) * 1.0 + titleCollapseFraction * subtitleMinScale
subtitleOffset = titleCollapseFraction * -1.0
subtitleBadgeFraction = (1.0 - titleCollapseFraction)
subtitleRatingFraction = (1.0 - titleCollapseFraction)
}
let rawTitleFrame = titleFrame.offsetBy(dx: self.isAvatarExpanded ? titleExpandedHorizontalOffset : titleHorizontalOffset * titleScale, dy: 0.0)
@ -2128,20 +2087,9 @@ final class PeerInfoHeaderNode: ASDisplayNode {
}
if let subtitleRatingView = self.subtitleRating?.view, let subtitleRatingSize {
let subtitleBadgeFrame: CGRect
if self.subtitleRatingIsExpanded {
subtitleBadgeFrame = CGRect(origin: CGPoint(x: -subtitleRatingSize.width * 0.5, y: floor((-subtitleRatingSize.height) * 0.5)), size: subtitleRatingSize)
} else {
subtitleBadgeFrame = CGRect(origin: CGPoint(x: (-subtitleSize.width) * 0.5 - 4.0 - subtitleRatingSize.width, y: floor((-subtitleRatingSize.height) * 0.5)), size: subtitleRatingSize)
}
let subtitleBadgeFrame = CGRect(origin: CGPoint(x: (-subtitleSize.width) * 0.5 - subtitleRatingSize.width + 1.0, y: floor((-subtitleRatingSize.height) * 0.5)), size: subtitleRatingSize)
transition.updateFrameAdditive(view: subtitleRatingView, frame: subtitleBadgeFrame)
transition.updateAlpha(layer: subtitleRatingView.layer, alpha: (1.0 - transitionFraction) * subtitleRatingFraction)
}
let subtitleAlpha: CGFloat = subtitleRatingFraction * (self.subtitleRatingIsExpanded ? 0.0 : 1.0) + (1.0 - subtitleRatingFraction) * 1.0
let subtitleInnerScale: CGFloat = subtitleRatingFraction * (self.subtitleRatingIsExpanded ? 0.001 : 1.0) + (1.0 - subtitleRatingFraction) * 1.0
transition.updateAlpha(node: self.subtitleNode, alpha: subtitleAlpha)
transition.updateTransformScale(node: self.subtitleNode, scale: subtitleInnerScale)
}
}
@ -2669,7 +2617,6 @@ final class PeerInfoHeaderNode: ASDisplayNode {
self.isAvatarExpanded = isAvatarExpanded
if isAvatarExpanded {
self.avatarListNode.listContainerNode.selectFirstItem()
self.subtitleRatingIsExpanded = false
}
if case .animated = transition, !isAvatarExpanded {
self.avatarListNode.animateAvatarCollapse(transition: transition)

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level10_inner</title>
<g id="Badge-/-level10_inner" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M23,15 L49,15 C53.418278,15 57,18.581722 57,23 L57,46.8429984 C57,48.7715399 55.8908719,50.5281562 54.1496679,51.357301 L37.2898007,59.3858092 C36.4738291,59.7743671 35.5261709,59.7743671 34.7101993,59.3858092 L17.8503321,51.357301 C16.1091281,50.5281562 15,48.7715399 15,46.8429984 L15,23 C15,18.581722 18.581722,15 23,15 Z" id="Path" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 714 B

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level10_outer</title>
<g id="Badge-/-level10_outer" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M49,11 C55.627417,11 61,16.372583 61,23 L61,46.8429984 C61,50.3143731 59.0035694,53.4762825 55.8694022,54.9687431 L39.0095351,62.9972512 C37.1056012,63.9038864 34.8943988,63.9038864 32.9904649,62.9972512 L16.1305978,54.9687431 C12.9964306,53.4762825 11,50.3143731 11,46.8429984 L11,23 C11,16.372583 16.372583,11 23,11 L49,11 Z" id="Path" fill="#FFFFFF"></path>
<path d="M23,15 L49,15 C53.418278,15 57,18.581722 57,23 L57,46.8429984 C57,48.7715399 55.8908719,50.5281562 54.1496679,51.357301 L37.2898007,59.3858092 C36.4738291,59.7743671 35.5261709,59.7743671 34.7101993,59.3858092 L17.8503321,51.357301 C16.1091281,50.5281562 15,48.7715399 15,46.8429984 L15,23 C15,18.581722 18.581722,15 23,15 Z" id="Path" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level1_inner</title>
<g id="Badge-/-level1_inner" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M53,45 C54.6943359,39.9169922 55.1925159,32.4416725 54.49454,22.5740409 C54.2708931,19.4342396 51.6589867,17.0009114 48.5112305,17 L23.4887695,17 C20.3410133,17.0009114 17.7291069,19.4342396 17.50546,22.5740409 C16.8074841,32.4416725 17.3056641,39.9169922 19,45 C20.9999787,50.9999361 32.8055802,57.9438271 36.0181519,58.0000467 C39.2307237,58.0555136 50.70353,51.8894101 53,45 Z" id="Path" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 767 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level1_outer</title>
<g id="Badge-/-level1_outer" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M48.5123886,13 C53.7585594,13.0015192 58.1116928,17.0569317 58.4845708,22.2918105 C59.216306,32.6367133 58.6862484,40.5903656 56.7947332,46.2649111 C54.2690969,53.8418199 42.0021357,62.1042926 35.9486315,61.9990662 C30.1753042,61.89871 17.4910652,53.1223062 15.2052668,46.2649111 C13.3137516,40.5903656 12.783694,32.6367133 13.5155689,22.2898424 C13.8883072,17.0569317 18.2414406,13.0015192 23.4887695,13 L48.5123886,13 Z" id="Path" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 809 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level20_inner</title>
<g id="Badge-/-level20_inner" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M17.5067188,13.1565216 L35.4932812,17.8672879 C35.8254913,17.9542953 36.1745087,17.9542953 36.5067188,17.8672879 L54.4932812,13.1565216 C55.5618111,12.8766685 56.6548914,13.5160174 56.9347444,14.5845472 C56.9780693,14.7499693 57,14.9202646 57,15.091266 L57,50 C57,53.8659932 53.8659932,57 50,57 L22,57 C18.1340068,57 15,53.8659932 15,50 L15,15.091266 C15,13.9866965 15.8954305,13.091266 17,13.091266 C17.1710014,13.091266 17.3412968,13.1131968 17.5067188,13.1565216 Z" id="Path" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 857 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level20_outer</title>
<g id="Badge-/-level20_outer" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M60.8042333,13.5711097 C60.9342078,14.0673757 61,14.5782618 61,15.091266 L61,50 C61,56.0751322 56.0751322,61 50,61 L22,61 C15.9248678,61 11,56.0751322 11,50 L11,15.091266 C11,11.7775575 13.6862915,9.09126603 17,9.09126603 C17.5130042,9.09126603 18.0238903,9.15705826 18.5201564,9.28703269 L36,13.864 L53.4798436,9.28703269 C56.6854332,8.44747352 59.9646742,10.3655201 60.8042333,13.5711097 Z" id="Path" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 781 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level2_inner</title>
<g id="Badge-/-level2_inner" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M28,15 L44,15 C51.1797017,15 57,20.8202983 57,28 L57,44 C57,51.1797017 51.1797017,57 44,57 L28,57 C20.8202983,57 15,51.1797017 15,44 L15,28 C15,20.8202983 20.8202983,15 28,15 Z" id="Rectangle" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 569 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level2_outer</title>
<g id="Badge-/-level2_outer" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M44,11 C53.3888407,11 61,18.6111593 61,28 L61,44 C61,53.3888407 53.3888407,61 44,61 L28,61 C18.6111593,61 11,53.3888407 11,44 L11,28 C11,18.6111593 18.6111593,11 28,11 L44,11 Z" id="Path" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 564 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level30_inner</title>
<g id="Badge-/-level30_inner" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M17.5067188,13.1565216 L35.4932812,17.8672879 C35.8254913,17.9542953 36.1745087,17.9542953 36.5067188,17.8672879 L54.4932812,13.1565216 C55.5618111,12.8766685 56.6548914,13.5160174 56.9347444,14.5845472 C56.9780693,14.7499693 57,14.9202646 57,15.091266 L57,47.2740807 C57,49.2380496 55.850227,51.0201354 54.0608393,51.8296203 L37.2365036,59.4406293 C36.4505105,59.7961976 35.5494895,59.7961976 34.7634964,59.4406293 L17.9391607,51.8296203 C16.149773,51.0201354 15,49.2380496 15,47.2740807 L15,15.091266 C15,13.9866965 15.8954305,13.091266 17,13.091266 C17.1710014,13.091266 17.3412968,13.1131968 17.5067188,13.1565216 Z" id="Path" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1009 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level30_outer</title>
<g id="Badge-/-level30_outer" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M60.8042333,13.5711097 C60.9342078,14.0673757 61,14.5782618 61,15.091266 L61,47.2740807 C61,50.8092247 58.9304086,54.0169792 55.7095108,55.474052 L38.8851751,63.085061 C37.0511912,63.9147204 34.9488088,63.9147204 33.1148249,63.085061 L16.2904892,55.474052 C13.0695914,54.0169792 11,50.8092247 11,47.2740807 L11,15.091266 C11,11.7775575 13.6862915,9.09126603 17,9.09126603 C17.5130042,9.09126603 18.0238903,9.15705826 18.5201564,9.28703269 L36,13.864777 L53.4798436,9.28703269 C56.6854332,8.44747352 59.9646742,10.3655201 60.8042333,13.5711097 Z" id="Path" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 934 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level3_inner</title>
<g id="Badge-/-level3_inner" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M35.8544323,16.5 C42.5603579,16.5 48.9772339,17.3142695 55.1127909,18.9403855 C57.8720367,19.6721748 59.5984053,22.4098874 59.0695564,25.2151096 L58.9161688,25.9952446 C57.6492744,32.2345248 55.3583898,38.2325914 52.0339947,44.0033008 C48.4623738,50.2031617 44.2319724,54.8983246 39.3449322,58.1412366 L38.808,58.49 L38.6366496,58.5935691 C37.0148548,59.5241021 35.0268922,59.5572143 33.3750071,58.6812087 L33.244,58.609 L33.1538672,58.5548802 C27.4610226,55.1837021 22.8566119,50.5438551 19.3062949,44.5841668 L18.9660053,44.0033008 C15.6094458,38.1767582 13.4677002,31.8512809 12.5350759,24.997545 C12.1766452,22.3675806 13.7646861,19.874921 16.2717218,19.0736995 L16.531,18.998 L17.3695077,18.774139 C22.9281007,17.3348182 28.7645985,16.5777965 34.8855941,16.5056926 L35.8544323,16.5 Z" id="Path" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level3_outer</title>
<g id="Badge-/-level3_outer" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M41.0056106,61.8327419 C46.6699888,58.2185305 51.5014519,52.9409499 55.5,46 C59.0431255,39.8496034 61.4907225,33.435796 62.842791,26.7585779 L63.0003148,25.956148 C63.9174844,21.0911212 60.9234863,16.3431744 56.1381952,15.0740506 C49.6626738,13.3578332 42.9013708,12.5 35.8544323,12.5 C29.0304059,12.5 22.5198632,13.3044208 16.3228042,14.9132624 L15.4398147,15.1491982 C10.8691231,16.399576 7.93181443,20.8424697 8.57171471,25.5377007 C9.57366173,32.9008811 11.8831564,39.7216385 15.5,46 C19.4342778,52.8293852 24.6395156,58.1616091 31.1157135,61.9966718 C34.0865037,63.757244 37.7725344,63.750645 40.7310338,62.0026676 L41.0056106,61.8327419 Z" id="Polygon" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level40_inner</title>
<g id="Badge-/-level40_inner" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M13.8209245,17.0037365 L23.6412021,18.7573575 C24.5036156,18.9113599 25.3902576,18.6806984 26.0682874,18.1259467 L34.7335244,11.0362073 C35.4702562,10.4334268 36.5297438,10.4334268 37.2664756,11.0362073 L45.9317126,18.1259467 C46.6097424,18.6806984 47.4963844,18.9113599 48.3587979,18.7573575 L58.1790755,17.0037365 C59.2664441,16.8095635 60.3053389,17.5336417 60.4995119,18.6210104 C60.5408831,18.8526891 60.541039,19.0898514 60.4999724,19.3215843 L55.1703343,49.3959706 C54.4933325,53.2161951 51.17282,56 47.2930717,56 L24.7069283,56 C20.82718,56 17.5066675,53.2161951 16.8296657,49.3959706 L11.5000276,19.3215843 C11.3072843,18.2339613 12.0327276,17.1960193 13.1203506,17.003276 C13.3520835,16.9622094 13.5892458,16.9623653 13.8209245,17.0037365 Z" id="Path" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level40_outer</title>
<g id="Badge-/-level40_outer" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M39.7994267,7.9403781 L48.107,14.738 L57.4759129,13.0660262 C60.6638802,12.4967464 63.7129607,14.5584268 64.3936061,17.6971399 L64.4372222,17.9178478 C64.5613358,18.6128839 64.5618035,19.324371 64.4386037,20.0195696 L59.1089656,50.0939559 C58.0934629,55.8242927 53.1126942,60 47.2930717,60 L24.7069283,60 C18.8873058,60 13.9065371,55.8242927 12.8910344,50.0939559 L7.5613963,20.0195696 C6.98316635,16.7567006 9.15949631,13.6428747 12.4223653,13.0646447 C13.1175639,12.941445 13.829051,12.9419126 14.5240871,13.0660262 L23.892,14.738 L32.2005733,7.9403781 C34.4107686,6.13203649 37.5892314,6.13203649 39.7994267,7.9403781 Z" id="Path" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1012 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level4_inner</title>
<g id="Badge-/-level4_inner" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M44.3705856,16.4672101 L55.5327899,27.6294144 C60.1557367,32.2523612 60.1557367,39.7476388 55.5327899,44.3705856 L44.3705856,55.5327899 C39.7476388,60.1557367 32.2523612,60.1557367 27.6294144,55.5327899 L16.4672101,44.3705856 C11.8442633,39.7476388 11.8442633,32.2523612 16.4672101,27.6294144 L27.6294144,16.4672101 C32.2523612,11.8442633 39.7476388,11.8442633 44.3705856,16.4672101 Z" id="Polygon" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 775 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level4_outer</title>
<g id="Badge-/-level4_outer" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M47.1990127,13.638783 L58.361217,24.8009873 C64.546261,30.9860312 64.546261,41.0139688 58.361217,47.1990127 L47.1990127,58.361217 C41.0139688,64.546261 30.9860312,64.546261 24.8009873,58.361217 L13.638783,47.1990127 C7.45373902,41.0139688 7.45373902,30.9860312 13.638783,24.8009873 L24.8009873,13.638783 C30.9860312,7.45373902 41.0139688,7.45373902 47.1990127,13.638783 Z" id="Path" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 759 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level50_inner</title>
<g id="Badge-/-level50_inner" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M13.8457992,17.0081784 L23.6412021,18.7573575 C24.5036156,18.9113599 25.3902576,18.6806984 26.0682874,18.1259467 L34.7335244,11.0362073 C35.4702562,10.4334268 36.5297438,10.4334268 37.2664756,11.0362073 L45.9317126,18.1259467 C46.6097424,18.6806984 47.4963844,18.9113599 48.3587979,18.7573575 L58.1542008,17.0081784 C59.2415694,16.8140055 60.2804642,17.5380836 60.4746372,18.6254523 C60.5169804,18.862574 60.516141,19.1053947 60.4721595,19.342218 L55.2572125,47.4227021 C54.7824054,49.9793556 53.0945991,52.1457247 50.731704,53.2313793 L37.6700007,59.2327024 C36.6099358,59.7197592 35.3900642,59.7197592 34.3299993,59.2327024 L21.268296,53.2313793 C18.9054009,52.1457247 17.2175946,49.9793556 16.7427875,47.4227021 L11.5278405,19.342218 C11.3261547,18.2562177 12.0430333,17.2123419 13.1290336,17.0106561 C13.3658569,16.9666746 13.6086775,16.9658353 13.8457992,17.0081784 Z" id="Path" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level50_outer</title>
<g id="Badge-/-level50_outer" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M39.7994267,7.9403781 L48.107,14.738 L57.4510382,13.0704681 C60.6390055,12.5011883 63.688086,14.5628687 64.3687314,17.7015818 L64.4123475,17.9222898 C64.539377,18.6336549 64.5368589,19.3621168 64.4049145,20.0725867 L59.1899674,48.1530708 C58.4777568,51.9880512 55.9460473,55.2376049 52.4017046,56.8660866 L39.3400014,62.8674098 C37.2198716,63.8415234 34.7801284,63.8415234 32.6599986,62.8674098 L19.5982954,56.8660866 C16.0539527,55.2376049 13.5222432,51.9880512 12.8100326,48.1530708 L7.59508554,20.0725867 C6.99002823,16.8145859 9.14066392,13.6829585 12.3986648,13.0779012 C13.1091347,12.9459567 13.8375966,12.9434386 14.5489618,13.0704681 L23.892,14.738 L32.2005733,7.9403781 C34.4107686,6.13203649 37.5892314,6.13203649 39.7994267,7.9403781 Z" id="Path" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level5_inner</title>
<g id="Badge-/-level5_inner" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M24.6347159,52.197233 L15.086894,45.3306104 C13.3626301,44.0905507 12.6070688,41.9044024 13.1995002,39.8696074 L16.4885503,28.5785206 L20.056184,18.2789734 C20.736028,16.3172234 22.5589494,14.9756983 24.6408724,14.9050076 L35.519949,14.536208 L46.4041369,14.5 C48.4875477,14.4932153 50.3596774,15.7663386 51.1123731,17.7018167 L55.0199245,27.7496763 C55.0516847,27.8313442 55.081291,27.9138273 55.1087132,27.9970407 L58.7486546,39.0425771 C59.4120036,41.0555339 58.7334828,43.2666211 57.0537084,44.5658775 L47.7086588,51.7944553 L39.3643082,58.4096688 C37.5845851,59.8205932 35.0761178,59.866608 33.245468,58.5219115 L24.6347159,52.197233 Z" id="Star-Flat" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level5_outer</title>
<g id="Badge-/-level5_outer" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M46.3911108,10.4999249 C50.1271554,10.4878546 53.4874078,12.772975 54.8403854,16.2520154 L58.7479369,26.299875 C58.8050998,26.4468635 58.8583886,26.5953257 58.907748,26.7451084 L62.5476894,37.7906448 C63.7418498,41.4143683 62.5205017,45.3943604 59.5010675,47.7298044 L50.1936104,54.9289433 L41.8492599,61.5441568 C38.6567698,64.0750912 34.1609892,64.1575608 30.8775485,61.7457225 L22.2992466,55.4446293 L12.7514246,48.5780067 C9.65235483,46.3492112 8.29246598,42.4144958 9.35911798,38.7509188 L12.6481681,27.459832 L12.708879,27.2692899 L16.2767025,16.969195 C17.4989159,13.4423901 20.7714195,11.0340879 24.5053507,10.907304 L35.3844273,10.5385044 L35.5066425,10.5362301 L46.3911108,10.4999249 Z" id="Path" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level60_inner</title>
<g id="Badge-/-level60_inner" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M25.1630277,52.850407 L17.8273486,50.8900353 C15.0747,50.1544232 13.4412291,47.3453418 14.1759196,44.6106697 L16.1338353,37.322897 C16.3667018,36.4561188 16.3667018,35.5438812 16.1338353,34.677103 L14.1759196,27.3893303 C13.4412291,24.6546582 15.0747,21.8455768 17.8273486,21.1099647 L25.1630277,19.149593 C26.0355037,18.9164343 26.8311982,18.4603155 27.4708076,17.826696 L32.848571,12.499295 C34.8665291,10.500235 38.1334709,10.500235 40.151429,12.499295 L45.5291924,17.826696 C46.1688018,18.4603155 46.9644963,18.9164343 47.8369723,19.149593 L55.1726514,21.1099647 C57.9253,21.8455768 59.5587709,24.6546582 58.8240804,27.3893303 L56.8661647,34.677103 C56.6332982,35.5438812 56.6332982,36.4561188 56.8661647,37.322897 L58.8240804,44.6106697 C59.5587709,47.3453418 57.9253,50.1544232 55.1726514,50.8900353 L47.8369723,52.850407 C46.9644963,53.0835657 46.1688018,53.5396845 45.5291924,54.173304 L40.151429,59.500705 C38.1334709,61.499765 34.8665291,61.499765 32.848571,59.500705 L27.4708076,54.173304 C26.8311982,53.5396845 26.0355037,53.0835657 25.1630277,52.850407 Z" id="Star-Flat" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level60_outer</title>
<g id="Badge-/-level60_outer" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M42.9665187,9.65759303 L48.3442821,14.984994 C48.4885608,15.1279215 48.6697115,15.2317632 48.8696837,15.2852034 L56.2053628,17.2455751 C61.0889021,18.550642 63.9969507,23.5516158 62.6870987,28.4271596 L60.729183,35.7149323 C60.6789587,35.9018776 60.6789587,36.0981224 60.729183,36.2850677 L62.6870987,43.5728404 C63.9969507,48.4483842 61.0889021,53.449358 56.2053628,54.7544249 L48.8696837,56.7147966 C48.6697115,56.7682368 48.4885608,56.8720785 48.3442821,57.015006 L42.9665187,62.342407 C39.3895633,65.8858643 33.6104367,65.8858643 30.0334813,62.342407 L24.6557179,57.015006 C24.5114392,56.8720785 24.3302885,56.7682368 24.1303163,56.7147966 L16.7946372,54.7544249 C11.9110979,53.449358 9.00304929,48.4483842 10.3129013,43.5728404 L12.270817,36.2850677 C12.3210413,36.0981224 12.3210413,35.9018776 12.270817,35.7149323 L10.3129013,28.4271596 C9.00304929,23.5516158 11.9110979,18.550642 16.7946372,17.2455751 L24.1303163,15.2852034 C24.3302885,15.2317632 24.5114392,15.1279215 24.6557179,14.984994 L30.0334813,9.65759303 C33.6104367,6.11413566 39.3895633,6.11413566 42.9665187,9.65759303 Z" id="Path" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level6_inner</title>
<g id="Badge-/-level6_inner" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M56.5,27.2077494 L56.5,44.7922506 C56.5,46.727022 55.4750178,48.5148244 53.8111544,49.4822101 L38.6888456,58.2744607 C37.0249822,59.2418464 34.9750178,59.2418464 33.3111544,58.2744607 L18.1888456,49.4822101 C16.5249822,48.5148244 15.5,46.727022 15.5,44.7922506 L15.5,27.2077494 C15.5,25.272978 16.5249822,23.4851756 18.1888456,22.5177899 L33.3111544,13.7255393 C34.9750178,12.7581536 37.0249822,12.7581536 38.6888456,13.7255393 L53.8111544,22.5177899 C55.4750178,23.4851756 56.5,25.272978 56.5,27.2077494 Z" id="Polygon-Flat" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 902 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level6_outer</title>
<g id="Badge-/-level6_outer" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M40.6993635,10.2675314 L55.8216722,19.0597821 C58.719202,20.7444328 60.5,23.8505503 60.5,27.2077494 L60.5,44.7922506 C60.5,48.1494497 58.719202,51.2555672 55.8216722,52.9402179 L40.6993635,61.7324686 C37.792561,63.4225105 34.207439,63.4225105 31.3006365,61.7324686 L16.1783278,52.9402179 C13.280798,51.2555672 11.5,48.1494497 11.5,44.7922506 L11.5,27.2077494 C11.5,23.8505503 13.280798,20.7444328 16.1783278,19.0597821 L31.3006365,10.2675314 C34.207439,8.57748952 37.792561,8.57748952 40.6993635,10.2675314 Z" id="Path" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 896 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level70_inner</title>
<g id="Badge-/-level70_inner" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M25.6231529,53.6849537 L20.2456512,53.1119864 C17.3639984,52.8049492 15.263688,50.1918606 15.5389909,47.256223 L16.0527382,41.7779796 C16.1648264,40.5827489 15.8804506,39.3837383 15.2449668,38.3721824 L12.332278,33.7357975 C10.7714495,31.2512883 11.4691887,27.9507327 13.8958667,26.3394648 L18.424332,23.3326503 C19.4123422,22.6766303 20.1560647,21.7027674 20.5368804,20.5663865 L22.2823186,15.3578763 C23.2176501,12.5667813 26.188027,11.0641444 28.9387422,11.9905637 L34.0718987,13.7193707 C35.1918391,14.0965579 36.4036217,14.0811813 37.5139749,13.6756934 L42.6031895,11.8171724 C45.3303573,10.821243 48.3366176,12.248041 49.3400252,15.0145349 L51.2125014,20.1771366 C51.621034,21.3035012 52.3883797,22.2581898 53.3921518,22.8889356 L57.9928604,25.779908 C60.4582516,27.3290994 61.2366199,30.6109243 59.7371336,33.1342664 L56.9389167,37.8431184 C56.3284081,38.870485 56.07349,40.0763388 56.2148201,41.2683538 L56.8625953,46.7318584 C57.20972,49.6595979 55.1740691,52.3251686 52.3008327,52.7052309 L46.9390371,53.4144716 C45.7692127,53.5692121 44.6839892,54.1181986 43.8564529,54.9738712 L40.0635069,58.8957776 C38.030973,60.9974176 34.7141896,61.0395051 32.6308086,58.9900928 L28.7429758,55.1656495 C27.8947373,54.3312412 26.7964039,53.8099624 25.6231529,53.6849537 Z" id="Star-Flat" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level70_outer</title>
<g id="Badge-/-level70_outer" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M53.1003284,13.6506726 L54.9728045,18.8132742 C55.0785512,19.1048284 55.2728431,19.3465554 55.5203623,19.5020904 L60.1210709,22.3930628 C64.4301129,25.1007591 65.7805182,30.794457 63.1758035,35.1776826 L60.3775866,39.8865345 C60.217228,40.1563866 60.1491686,40.4783318 60.1869982,40.7973962 L60.8347735,46.2609009 C61.4377683,51.3467159 57.8828327,56.0017047 52.8253705,56.6706892 L47.4635749,57.3799299 C47.1906985,57.4160251 46.9332988,57.5462369 46.7317579,57.7546303 L42.9388119,61.6765367 C39.3615507,65.3754249 33.4937411,65.4498829 29.825724,61.8416713 L25.9378912,58.017228 C25.7320697,57.8147624 25.4724313,57.6915357 25.1993558,57.6624398 L19.8218541,57.0894725 C14.7478294,56.5488403 11.078144,51.9832233 11.5564649,46.8827434 L12.0702123,41.4045 C12.1002037,41.084692 12.0243967,40.7650677 11.8578906,40.5000253 L8.94520186,35.8636403 C6.23343256,31.5470767 7.44368777,25.8221377 11.6832658,23.0071388 L16.211731,20.0003242 C16.4562897,19.8379419 16.6453088,19.5904319 16.7441767,19.2954032 L18.4896149,14.086893 C20.1236614,9.21078304 25.3568542,6.56344611 30.2154477,8.19978242 L35.3486042,9.92858941 C35.6073633,10.0157375 35.8849477,10.0122151 36.1418543,9.91839588 L41.2310688,8.05987489 C46.0480475,6.30077121 51.346618,8.81552015 53.1003284,13.6506726 Z" id="Path" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level7_inner</title>
<g id="Badge-/-level7_inner" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M47.5119469,15.9725146 L56.9485165,28.1544765 C57.8703305,29.3444749 58.2101938,30.8974518 57.8718989,32.3737956 L54.4087892,47.487062 C54.0704943,48.9634057 53.0908608,50.2024337 51.7472,50.8534058 L37.9922031,57.5173789 C36.6485423,58.1683511 35.087096,58.1604167 33.7498732,57.4958219 L20.0607825,50.6923941 C18.7235597,50.0277993 17.7561016,48.7788774 17.4322729,47.2991691 L14.1172527,32.1514602 C13.793424,30.6717519 14.1484698,29.1223062 15.0818847,27.9417349 L24.637213,15.8562787 C25.570628,14.6757075 26.9808209,13.9925021 28.468599,14 L43.6989186,14.0774536 C45.1866968,14.0850136 46.5901329,14.7825162 47.5119469,15.9725146 Z" id="Polygon-Flat" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level7_outer</title>
<g id="Badge-/-level7_outer" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M28.4889407,9.99982941 L43.719244,10.0775052 C46.4412057,10.0913366 49.0016774,11.3638817 50.6741664,13.5229499 L60.110736,25.7049117 C61.7679495,27.8442602 62.3764018,30.6245323 61.7708477,33.2672151 L58.307738,48.3804815 C57.6996801,51.0340909 55.9309079,53.2712112 53.4912098,54.4531877 L39.736213,61.1171608 C37.2783069,62.3079587 34.4154997,62.2934116 31.9696314,61.077824 L18.2805406,54.2743962 C15.8530752,53.0679548 14.106707,50.8135137 13.5247514,48.1543157 L10.2097312,33.0066069 C9.63007446,30.3579135 10.2657744,27.5836719 11.9441448,25.4608906 L21.4994731,13.3754344 C23.1933538,11.2330359 25.7665919,9.98633195 28.4889407,9.99982941 Z" id="Path" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level80_inner</title>
<g id="Badge-/-level80_inner" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M25.4075318,55.0983015 L20.6181753,54.4891523 C18.1878179,54.1800396 16.3367069,52.1599065 16.2405902,49.7118564 L16.0511788,44.887634 C16.0102196,43.84442 15.6446438,42.8400089 15.0054554,42.0145324 L12.0496025,38.1972124 C10.5496559,36.2601145 10.6691726,33.5227316 12.3322407,31.723734 L15.609547,28.1785595 C16.3182481,27.4119333 16.769973,26.4432062 16.9016985,25.4075318 L17.5108477,20.6181753 C17.8199604,18.1878179 19.8400935,16.3367069 22.2881436,16.2405902 L27.112366,16.0511788 C28.15558,16.0102196 29.1599911,15.6446438 29.9854676,15.0054554 L33.8027876,12.0496025 C35.7398855,10.5496559 38.4772684,10.6691726 40.276266,12.3322407 L43.8214405,15.609547 C44.5880667,16.3182481 45.5567938,16.769973 46.5924682,16.9016985 L51.3818247,17.5108477 C53.8121821,17.8199604 55.6632931,19.8400935 55.7594098,22.2881436 L55.9488212,27.112366 C55.9897804,28.15558 56.3553562,29.1599911 56.9945446,29.9854676 L59.9503975,33.8027876 C61.4503441,35.7398855 61.3308274,38.4772684 59.6677593,40.276266 L56.390453,43.8214405 C55.6817519,44.5880667 55.230027,45.5567938 55.0983015,46.5924682 L54.4891523,51.3818247 C54.1800396,53.8121821 52.1599065,55.6632931 49.7118564,55.7594098 L44.887634,55.9488212 C43.84442,55.9897804 42.8400089,56.3553562 42.0145324,56.9945446 L38.1972124,59.9503975 C36.2601145,61.4503441 33.5227316,61.3308274 31.723734,59.6677593 L28.1785595,56.390453 C27.4119333,55.6817519 26.4432062,55.230027 25.4075318,55.0983015 Z" id="Star" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level80_outer</title>
<g id="Badge-/-level80_outer" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M42.9915498,9.39502532 L46.5367242,12.6723316 C46.6917717,12.815664 46.8876934,12.9070237 47.097155,12.9336648 L51.8865114,13.5428141 C56.255695,14.0985223 59.5835361,17.7302236 59.7563303,22.1312143 L59.9457416,26.9554366 C59.9540255,27.1664231 60.0279619,27.3695617 60.1572356,27.5365115 L63.1130884,31.3538315 C65.8096226,34.8362559 65.5947611,39.7573955 62.6049747,42.9915498 L59.3276684,46.5367242 C59.184336,46.6917717 59.0929763,46.8876934 59.0663352,47.097155 L58.4571859,51.8865114 C57.9014777,56.255695 54.2697764,59.5835361 49.8687857,59.7563303 L45.0445634,59.9457416 C44.8335769,59.9540255 44.6304383,60.0279619 44.4634885,60.1572356 L40.6461685,63.1130884 C37.1637441,65.8096226 32.2426045,65.5947611 29.0084502,62.6049747 L25.4632758,59.3276684 C25.3082283,59.184336 25.1123066,59.0929763 24.902845,59.0663352 L20.1134886,58.4571859 C15.744305,57.9014777 12.4164639,54.2697764 12.2436697,49.8687857 L12.0542584,45.0445634 C12.0459745,44.8335769 11.9720381,44.6304383 11.8427644,44.4634885 L8.88691157,40.6461685 C6.19037735,37.1637441 6.40523895,32.2426045 9.39502532,29.0084502 L12.6723316,25.4632758 C12.815664,25.3082283 12.9070237,25.1123066 12.9336648,24.902845 L13.5428141,20.1134886 C14.0985223,15.744305 17.7302236,12.4164639 22.1312143,12.2436697 L26.9554366,12.0542584 C27.1664231,12.0459745 27.3695617,11.9720381 27.5365115,11.8427644 L31.3538315,8.88691157 C34.8362559,6.19037735 39.7573955,6.40523895 42.9915498,9.39502532 Z" id="Path" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level8_inner</title>
<g id="Badge-/-level8_inner" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M27.9852814,15 L44.0147186,15 C45.6060176,15 47.132141,15.632141 48.2573593,16.7573593 L55.2426407,23.7426407 C56.367859,24.867859 57,26.3939824 57,27.9852814 L57,44.0147186 C57,45.6060176 56.367859,47.132141 55.2426407,48.2573593 L48.2573593,55.2426407 C47.132141,56.367859 45.6060176,57 44.0147186,57 L27.9852814,57 C26.3939824,57 24.867859,56.367859 23.7426407,55.2426407 L16.7573593,48.2573593 C15.632141,47.132141 15,45.6060176 15,44.0147186 L15,27.9852814 C15,26.3939824 15.632141,24.867859 16.7573593,23.7426407 L23.7426407,16.7573593 C24.867859,15.632141 26.3939824,15 27.9852814,15 Z" id="Rectangle" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 985 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level8_outer</title>
<g id="Badge-/-level8_outer" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M44.0147186,11 C46.6668835,11 49.2104227,12.0535684 51.0857864,13.9289322 L58.0710678,20.9142136 C59.9464316,22.7895773 61,25.3331165 61,27.9852814 L61,44.0147186 C61,46.6668835 59.9464316,49.2104227 58.0710678,51.0857864 L51.0857864,58.0710678 C49.2104227,59.9464316 46.6668835,61 44.0147186,61 L27.9852814,61 C25.3331165,61 22.7895773,59.9464316 20.9142136,58.0710678 L13.9289322,51.0857864 C12.0535684,49.2104227 11,46.6668835 11,44.0147186 L11,27.9852814 C11,25.3331165 12.0535684,22.7895773 13.9289322,20.9142136 L20.9142136,13.9289322 C22.7895773,12.0535684 25.3331165,11 27.9852814,11 L44.0147186,11 Z" id="Path" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 996 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level90_inner</title>
<g id="Badge-/-level90_inner" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M15.8733536,45.5876663 L13.5374788,26.4767308 C13.2739231,24.3204523 14.4193524,22.2383675 16.3756386,21.3177141 L34.3082495,12.8783965 C35.3803169,12.3738678 36.6196831,12.3738678 37.6917505,12.8783965 L55.6243614,21.3177141 C57.5806476,22.2383675 58.7260769,24.3204523 58.4625212,26.4767308 L56.1266464,45.5876663 C55.9615284,46.9385772 55.2580965,48.1641245 54.1775745,48.9834175 L39.003776,60.4887707 C37.2255672,61.8370764 34.7744328,61.8370764 32.996224,60.4887707 L17.8224255,48.9834175 C16.7419035,48.1641245 16.0384716,46.9385772 15.8733536,45.5876663 Z" id="Diamond-Flat" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 960 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level90_outer</title>
<g id="Badge-/-level90_outer" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M39.3950116,9.25915606 L57.3276226,17.6984736 C60.8489171,19.3556401 62.9057094,23.0943394 62.4329729,26.9620277 L60.0970981,46.0729632 C59.8008781,48.4964839 58.5376987,50.6972457 56.5943464,52.1707696 L41.4205479,63.6761227 C38.2133283,66.1079591 33.7866717,66.1079591 30.5794521,63.6761227 L15.4056536,52.1707696 C13.4623013,50.6972457 12.1991219,48.4964839 11.9029019,46.0729632 L9.56702707,26.9620277 C9.09429062,23.0943394 11.1510829,19.3556401 14.6723774,17.6984736 L32.6049884,9.25915606 C34.755818,8.24694798 37.244182,8.24694798 39.3950116,9.25915606 Z" id="Path" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 952 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level9_inner</title>
<g id="Badge-/-level9_inner" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<circle id="Oval" fill="#FFFFFF" cx="36" cy="36" r="21"></circle>
</g>
</svg>

After

Width:  |  Height:  |  Size: 410 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Badge / level9_outer</title>
<g id="Badge-/-level9_outer" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M36,11 C49.8071187,11 61,22.1928813 61,36 C61,49.8071187 49.8071187,61 36,61 C22.1928813,61 11,49.8071187 11,36 C11,22.1928813 22.1928813,11 36,11 Z" id="Path" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 536 B

View File

@ -1333,7 +1333,7 @@ public func themeImage(account: Account, accountManager: AccountManager<Telegram
case let .pattern(data, colors, intensity):
let wallpaperImage = generateImage(arguments.drawingSize, rotatedContext: { size, context in
drawWallpaperGradientImage(colors.map(UIColor.init(rgb:)), context: context, size: size)
if let unpackedData = TGGUnzipData(data, 2 * 1024 * 1024), let image = drawSvgImage(unpackedData, arguments.drawingSize, .clear, .black, true) {
if let unpackedData = TGGUnzipData(data, 2 * 1024 * 1024), let image = drawSvgImage(unpackedData, arguments.drawingSize, .clear, .black, 1.0, true) {
context.setBlendMode(.softLight)
context.setAlpha(abs(CGFloat(intensity)) / 100.0)
context.draw(image.cgImage!, in: CGRect(origin: CGPoint(), size: arguments.drawingSize))