Merge commit '6ece02e998ee2812e81c9166cae8f17d71ee643d'

This commit is contained in:
Ali 2022-12-24 20:25:59 +04:00
commit 1ea4088098
9 changed files with 132 additions and 50 deletions

View File

@ -338,15 +338,17 @@ final class DrawingSettings: Codable, Equatable {
private final class ReferenceContentSource: ContextReferenceContentSource {
private let sourceView: UIView
private let contentArea: CGRect
private let customPosition: CGPoint
init(sourceView: UIView, customPosition: CGPoint) {
init(sourceView: UIView, contentArea: CGRect, customPosition: CGPoint) {
self.sourceView = sourceView
self.contentArea = contentArea
self.customPosition = customPosition
}
func transitionInfo() -> ContextControllerReferenceViewInfo? {
return ContextControllerReferenceViewInfo(referenceView: self.sourceView, contentAreaInScreenSpace: UIScreen.main.bounds, customPosition: customPosition)
return ContextControllerReferenceViewInfo(referenceView: self.sourceView, contentAreaInScreenSpace: self.contentArea, customPosition: customPosition)
}
}
@ -849,7 +851,7 @@ private final class DrawingScreenComponent: CombinedComponent {
)
]
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }.withUpdated(theme: defaultDarkPresentationTheme)
let contextController = ContextController(account: self.context.account, presentationData: presentationData, source: .reference(ReferenceContentSource(sourceView: sourceView, customPosition: CGPoint(x: 7.0, y: 3.0))), items: .single(ContextController.Items(content: .list(items))))
let contextController = ContextController(account: self.context.account, presentationData: presentationData, source: .reference(ReferenceContentSource(sourceView: sourceView, contentArea: UIScreen.main.bounds, customPosition: CGPoint(x: 7.0, y: 3.0))), items: .single(ContextController.Items(content: .list(items))))
self.present(contextController)
}
@ -2294,18 +2296,18 @@ public class DrawingScreen: ViewController, TGPhotoDrawingInterfaceController {
private weak var currentFontPicker: ContextController?
func presentFontPicker(sourceView: UIView) {
guard !self.dismissFontPicker() else {
guard !self.dismissFontPicker(), let validLayout = self.validLayout?.0 else {
return
}
let fonts: [DrawingTextFont] = [
.sanFrancisco,
.newYork,
.other("MarkerFelt-Wide", "Marker Felt"),
.other("Chalkduster", "Chalkduster"),
.other("Menlo-Bold", "Menlo"),
.other("Copperplate-Bold", "Copperplate"),
.other("GillSans-SemiBold", "Gill Sans"),
.other("Papyrus", "Papyrus")
.other("AmericanTypewriter", "American Typewriter"),
.other("AvenirNext-DemiBoldItalic", "Avenir Next"),
.other("CourierNewPS-BoldMT", "Courier New"),
.other("Noteworthy-Bold", "Noteworthy"),
.other("Georgia-Bold", "Georgia"),
.other("Papyrus", "Papyrus"),
.other("SnellRoundhand-Bold", "Snell Roundhand")
]
var items: [ContextMenuItem] = []
@ -2325,7 +2327,7 @@ public class DrawingScreen: ViewController, TGPhotoDrawingInterfaceController {
}
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }.withUpdated(theme: defaultDarkPresentationTheme)
let contextController = ContextController(account: self.context.account, presentationData: presentationData, source: .reference(ReferenceContentSource(sourceView: sourceView, customPosition: CGPoint(x: 7.0, y: 0.0))), items: .single(ContextController.Items(content: .list(items))))
let contextController = ContextController(account: self.context.account, presentationData: presentationData, source: .reference(ReferenceContentSource(sourceView: sourceView, contentArea: CGRect(origin: .zero, size: CGSize(width: validLayout.size.width, height: validLayout.size.height - (validLayout.inputHeight ?? 0.0))), customPosition: CGPoint(x: 0.0, y: 1.0))), items: .single(ContextController.Items(content: .list(items))))
self.controller?.present(contextController, in: .window(.root))
self.currentFontPicker = contextController
}

View File

@ -78,7 +78,6 @@ public final class DrawingTextEntity: DrawingEntity, Codable {
enum Font: Codable {
case sanFrancisco
case newYork
case other(String, String)
}
@ -258,7 +257,7 @@ final class DrawingTextEntityView: DrawingEntityView, UITextViewDelegate {
self.textView.minimumZoomScale = 1.0
self.textView.maximumZoomScale = 1.0
self.textView.keyboardAppearance = .dark
self.textView.autocorrectionType = .default
self.textView.autocorrectionType = .no
self.textView.spellCheckingType = .no
super.init(context: context, entity: entity)
@ -551,11 +550,9 @@ final class DrawingTextEntityView: DrawingEntityView, UITextViewDelegate {
var font: UIFont
switch self.textEntity.font {
case .sanFrancisco:
font = Font.with(size: fontSize, design: .regular, weight: .semibold)
case .newYork:
font = Font.with(size: fontSize, design: .serif, weight: .semibold)
font = Font.with(size: fontSize, design: .round, weight: .semibold)
case let .other(fontName, _):
font = UIFont(name: fontName, size: fontSize) ?? Font.with(size: fontSize, design: .regular, weight: .semibold)
font = UIFont(name: fontName, size: fontSize) ?? Font.with(size: fontSize, design: .round, weight: .semibold)
}
text.addAttribute(.font, value: font, range: range)
@ -1286,6 +1283,7 @@ private var availableFonts: [String: (String, String)] = {
var preferredFont: String?
for name in names {
print(name)
let originalName = name
let name = name.lowercased()
if (!name.contains("-") || name.contains("regular")) && preferredFont == nil {
@ -1301,6 +1299,6 @@ private var availableFonts: [String: (String, String)] = {
result[shortname] = (preferredFont, family)
}
}
print(result)
//print(result)
return result
}()

View File

@ -996,7 +996,7 @@ private class DrawingSlice {
self.rect = rect
self.path = NSTemporaryDirectory() + "/drawing_\(uuid.hashValue).slice"
DrawingSlice.queue.async {
DrawingSlice.queue.after(2.0) {
let image = UIImage(cgImage: image)
if let data = image.pngData() as? NSData {
try? data.write(toFile: self.path)

View File

@ -198,7 +198,7 @@ final class PenTool: DrawingElement {
let minRenderArrowLength = max(10.0, max(drawingSize.width, drawingSize.height) * 0.02)
self.renderLineWidth = lineWidth
self.renderMinLineWidth = isEraser || isBlur ? lineWidth : minLineWidth + (lineWidth - minLineWidth) * 0.3
self.renderMinLineWidth = isEraser || isBlur ? lineWidth : minLineWidth + (lineWidth - minLineWidth) * 0.2
self.renderArrowLength = max(minRenderArrowLength, lineWidth * 3.0)
self.renderArrowLineWidth = max(minLineWidth * 1.8, lineWidth * 0.75)
@ -234,14 +234,8 @@ final class PenTool: DrawingElement {
guard case let .point(point) = path else {
return
}
let filterDistance: CGFloat
if point.velocity > 1200.0 {
filterDistance = 25.0
} else {
filterDistance = 15.0
}
let filterDistance: CGFloat = 20.0
if let previousPoint, point.location.distance(to: previousPoint) < filterDistance, state == .changed, self.segments.count > 1 {
return
}
@ -252,14 +246,13 @@ final class PenTool: DrawingElement {
velocity = 1000.0
}
var effectiveRenderLineWidth = max(self.renderMinLineWidth, min(self.renderLineWidth - (velocity / 150.0), self.renderLineWidth))
var effectiveRenderLineWidth = max(self.renderMinLineWidth, min(self.renderLineWidth - (velocity / 100.0), self.renderLineWidth))
if let previousRenderLineWidth = self.previousRenderLineWidth {
effectiveRenderLineWidth = effectiveRenderLineWidth * 0.2 + previousRenderLineWidth * 0.8
}
self.previousRenderLineWidth = effectiveRenderLineWidth
let rect = append(point: Point(position: point.location, width: effectiveRenderLineWidth))
if let currentRenderView = self.currentRenderView as? RenderView, let rect = rect {
currentRenderView.draw(element: self, rect: rect)
}
@ -461,7 +454,7 @@ final class PenTool: DrawingElement {
let segmentDistance: CGFloat = 6.0
let distance = midPoint1.distance(to: midPoint2)
let numberOfSegments = min(128, max(floor(distance / segmentDistance), 32))
let numberOfSegments = min(48, max(floor(distance / segmentDistance), 24))
let step = 1.0 / numberOfSegments
for t in stride(from: 0, to: 1, by: step) {

View File

@ -46,15 +46,12 @@ enum DrawingTextAlignment: Equatable {
enum DrawingTextFont: Equatable, Hashable {
case sanFrancisco
case newYork
case other(String, String)
init(font: DrawingTextEntity.Font) {
switch font {
case .sanFrancisco:
self = .sanFrancisco
case .newYork:
self = .newYork
case let .other(font, name):
self = .other(font, name)
}
@ -64,8 +61,6 @@ enum DrawingTextFont: Equatable, Hashable {
switch self {
case .sanFrancisco:
return .sanFrancisco
case .newYork:
return .newYork
case let .other(font, name):
return .other(font, name)
}
@ -75,8 +70,6 @@ enum DrawingTextFont: Equatable, Hashable {
switch self {
case .sanFrancisco:
return "San Francisco"
case .newYork:
return "New York"
case let .other(_, name):
return name
}
@ -85,9 +78,7 @@ enum DrawingTextFont: Equatable, Hashable {
func uiFont(size: CGFloat) -> UIFont {
switch self {
case .sanFrancisco:
return Font.semibold(size)
case .newYork:
return Font.with(size: size, design: .serif, weight: .semibold)
return Font.with(size: size, design: .round, weight: .semibold)
case let .other(font, _):
return UIFont(name: font, size: size) ?? Font.semibold(size)
}

View File

@ -170,7 +170,7 @@ public final class StorageBox {
let _ = try? FileManager.default.removeItem(atPath: databasePath)
valueBox = SqliteValueBox(basePath: databasePath, queue: queue, isTemporary: false, isReadOnly: false, useCaches: true, removeDatabaseOnError: true, encryptionParameters: nil, upgradeProgress: { _ in })
}
guard let valueBox else {
guard let valueBox = valueBox else {
preconditionFailure("Could not open database")
}
self.valueBox = valueBox

View File

@ -40,7 +40,7 @@ public func requestUpdatesXml(account: Account, source: String) -> Signal<Data,
if let message = locallyRenderedMessage(message: storeMessage, peers: peers), let media = message.media.first as? TelegramMediaFile {
return Signal { subscriber in
let fetchDispsable = fetchedMediaResource(mediaBox: account.postbox.mediaBox, reference: MediaResourceReference.media(media: AnyMediaReference.message(message: MessageReference(message), media: media), resource: media.resource)).start()
let fetchDispsable = fetchedMediaResource(mediaBox: account.postbox.mediaBox, userLocation: .other, userContentType: .other, reference: MediaResourceReference.media(media: AnyMediaReference.message(message: MessageReference(message), media: media), resource: media.resource)).start()
let dataDisposable = account.postbox.mediaBox.resourceData(media.resource, option: .complete(waitUntilFetchStatus: true)).start(next: { data in
if data.complete {
@ -120,7 +120,7 @@ public func downloadAppUpdate(account: Account, source: String, messageId: Int32
let removeDisposable = account.postbox.mediaBox.removeCachedResources([media.resource.id]).start(completed: {
let reference = MediaResourceReference.media(media: .message(message: MessageReference(message), media: media), resource: media.resource)
fetchDisposable = fetchedMediaResource(mediaBox: account.postbox.mediaBox, reference: reference).start()
fetchDisposable = fetchedMediaResource(mediaBox: account.postbox.mediaBox, userLocation: .other, userContentType: .other, reference: reference).start()
statusDisposable = account.postbox.mediaBox.resourceStatus(media.resource).start(next: { status in
switch status {
case let .Fetching(_, progress):

View File

@ -1379,7 +1379,7 @@ private func editingItems(data: PeerInfoScreenData?, state: PeerInfoState, chatL
}))
let setText: String
if user.photo.first?.isPersonal == true {
if user.photo.first?.isPersonal == true || state.updatingAvatar != nil {
setText = presentationData.strings.UserInfo_ChangeCustomPhoto(compactName).string
} else {
setText = presentationData.strings.UserInfo_SetCustomPhoto(compactName).string
@ -3117,7 +3117,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
let firstName = strongSelf.headerNode.editingContentNode.editingTextForKey(.firstName) ?? ""
let lastName = strongSelf.headerNode.editingContentNode.editingTextForKey(.lastName) ?? ""
if peer.firstName != firstName || peer.lastName != lastName {
if (peer.firstName ?? "") != firstName || (peer.lastName ?? "") != lastName {
if firstName.isEmpty && lastName.isEmpty {
if strongSelf.hapticFeedback == nil {
strongSelf.hapticFeedback = HapticFeedback()
@ -7179,7 +7179,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
confirmationAction = nil
}
let mixin = TGMediaAvatarMenuMixin(context: legacyController.context, parentController: emptyController, hasSearchButton: true, hasDeleteButton: hasDeleteButton, hasViewButton: false, personalPhoto: strongSelf.isSettings, isVideo: currentIsVideo, saveEditedPhotos: false, saveCapturedMedia: false, signup: false, forum: isForum, title: title, isSuggesting: mode == .suggest)!
let mixin = TGMediaAvatarMenuMixin(context: legacyController.context, parentController: emptyController, hasSearchButton: true, hasDeleteButton: hasDeleteButton, hasViewButton: false, personalPhoto: strongSelf.isSettings, isVideo: currentIsVideo, saveEditedPhotos: false, saveCapturedMedia: false, signup: false, forum: isForum, title: title, isSuggesting: [.custom, .suggest].contains(mode))!
mixin.stickersContext = paintStickersContext
let _ = strongSelf.currentAvatarMixin.swap(mixin)
mixin.requestSearchController = { [weak self] assetsController in

View File

@ -415,7 +415,9 @@ public final class OngoingGroupCallContext {
private final class Impl {
let queue: Queue
let context: GroupCallThreadLocalContext
#if os(iOS)
let audioDevice: SharedCallAudioDevice?
#endif
let sessionId = UInt32.random(in: 0 ..< UInt32(Int32.max))
let joinPayload = Promise<(String, UInt32)>()
@ -433,9 +435,10 @@ public final class OngoingGroupCallContext {
init(queue: Queue, inputDeviceId: String, outputDeviceId: String, audioSessionActive: Signal<Bool, NoError>, video: OngoingCallVideoCapturer?, requestMediaChannelDescriptions: @escaping (Set<UInt32>, @escaping ([MediaChannelDescription]) -> Void) -> Disposable, rejoinNeeded: @escaping () -> Void, outgoingAudioBitrateKbit: Int32?, videoContentType: VideoContentType, enableNoiseSuppression: Bool, disableAudioInput: Bool, preferX264: Bool, logPath: String) {
self.queue = queue
#if os(iOS)
self.audioDevice = nil
let audioDevice = self.audioDevice
#endif
var networkStateUpdatedImpl: ((GroupCallNetworkState) -> Void)?
var audioLevelsUpdatedImpl: (([NSNumber]) -> Void)?
@ -450,7 +453,7 @@ public final class OngoingGroupCallContext {
}
var getBroadcastPartsSource: (() -> BroadcastPartSource?)?
#if os(iOS)
self.context = GroupCallThreadLocalContext(
queue: ContextQueueImpl(queue: queue),
networkStateUpdated: { state in
@ -544,6 +547,101 @@ public final class OngoingGroupCallContext {
logPath: logPath,
audioDevice: audioDevice
)
#else
self.context = GroupCallThreadLocalContext(
queue: ContextQueueImpl(queue: queue),
networkStateUpdated: { state in
networkStateUpdatedImpl?(state)
},
audioLevelsUpdated: { levels in
audioLevelsUpdatedImpl?(levels)
},
inputDeviceId: inputDeviceId,
outputDeviceId: outputDeviceId,
videoCapturer: video?.impl,
requestMediaChannelDescriptions: { ssrcs, completion in
final class OngoingGroupCallMediaChannelDescriptionTaskImpl : NSObject, OngoingGroupCallMediaChannelDescriptionTask {
private let disposable: Disposable
init(disposable: Disposable) {
self.disposable = disposable
}
func cancel() {
self.disposable.dispose()
}
}
let disposable = requestMediaChannelDescriptions(Set(ssrcs.map { $0.uint32Value }), { channels in
completion(channels.map { channel -> OngoingGroupCallMediaChannelDescription in
let mappedType: OngoingGroupCallMediaChannelType
switch channel.kind {
case .audio:
mappedType = .audio
case .video:
mappedType = .video
}
return OngoingGroupCallMediaChannelDescription(
type: mappedType,
audioSsrc: channel.audioSsrc,
videoDescription: channel.videoDescription
)
})
})
return OngoingGroupCallMediaChannelDescriptionTaskImpl(disposable: disposable)
},
requestCurrentTime: { completion in
let disposable = MetaDisposable()
queue.async {
disposable.set(getBroadcastPartsSource?()?.requestTime(completion: completion))
}
return OngoingGroupCallBroadcastPartTaskImpl(disposable: disposable)
},
requestAudioBroadcastPart: { timestampMilliseconds, durationMilliseconds, completion in
let disposable = MetaDisposable()
queue.async {
disposable.set(getBroadcastPartsSource?()?.requestPart(timestampMilliseconds: timestampMilliseconds, durationMilliseconds: durationMilliseconds, subject: .audio, completion: completion, rejoinNeeded: {
rejoinNeeded()
}))
}
return OngoingGroupCallBroadcastPartTaskImpl(disposable: disposable)
},
requestVideoBroadcastPart: { timestampMilliseconds, durationMilliseconds, channelId, quality, completion in
let disposable = MetaDisposable()
queue.async {
let mappedQuality: OngoingGroupCallContext.VideoChannel.Quality
switch quality {
case .thumbnail:
mappedQuality = .thumbnail
case .medium:
mappedQuality = .medium
case .full:
mappedQuality = .full
@unknown default:
mappedQuality = .thumbnail
}
disposable.set(getBroadcastPartsSource?()?.requestPart(timestampMilliseconds: timestampMilliseconds, durationMilliseconds: durationMilliseconds, subject: .video(channelId: channelId, quality: mappedQuality), completion: completion, rejoinNeeded: {
rejoinNeeded()
}))
}
return OngoingGroupCallBroadcastPartTaskImpl(disposable: disposable)
},
outgoingAudioBitrateKbit: outgoingAudioBitrateKbit ?? 32,
videoContentType: _videoContentType,
enableNoiseSuppression: enableNoiseSuppression,
disableAudioInput: disableAudioInput,
preferX264: preferX264,
logPath: logPath
)
#endif
let queue = self.queue