diff --git a/Sources/SearchFeature/Controllers/SearchContainerController.swift b/Sources/SearchFeature/Controllers/SearchContainerController.swift
index efc85dcfbe323423488bae475e541399d2fd300a..ea6c89d1406aac9bb22c7e5447b499e2dfd48ace 100644
--- a/Sources/SearchFeature/Controllers/SearchContainerController.swift
+++ b/Sources/SearchFeature/Controllers/SearchContainerController.swift
@@ -6,27 +6,6 @@ import XXModels
 import DrawerFeature
 import DependencyInjection
 
-enum SearchSection {
-    case stranger
-    case connections
-}
-
-enum SearchItem: Equatable, Hashable {
-    case stranger(Contact)
-    case connection(Contact)
-}
-
-class SearchTableViewDiffableDataSource: UITableViewDiffableDataSource<SearchSection, SearchItem> {
-    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
-        switch snapshot().sectionIdentifiers[section] {
-        case .stranger:
-            return ""
-        case .connections:
-            return "CONNECTIONS"
-        }
-    }
-}
-
 public final class SearchContainerController: UIViewController {
     @Dependency var coordinator: SearchCoordinating
     @Dependency var statusBarController: StatusBarStyleControlling
@@ -89,6 +68,7 @@ public final class SearchContainerController: UIViewController {
                     screenView.scrollView.setContentOffset(point, animated: true)
                 } else {
                     screenView.scrollView.setContentOffset(.zero, animated: true)
+                    leftController.viewModel.didSelectItem($0)
                 }
             }.store(in: &cancellables)
 
diff --git a/Sources/SearchFeature/Controllers/SearchLeftController.swift b/Sources/SearchFeature/Controllers/SearchLeftController.swift
index 35014bc256329b4d6f00b562e9841540681e2304..b172eb74050a519c6aef1845d18067b3bc67e07f 100644
--- a/Sources/SearchFeature/Controllers/SearchLeftController.swift
+++ b/Sources/SearchFeature/Controllers/SearchLeftController.swift
@@ -19,11 +19,11 @@ final class SearchLeftController: UIViewController {
 
     lazy private var screenView = SearchLeftView()
 
-    private let viewModel = SearchLeftViewModel()
     private var cancellables = Set<AnyCancellable>()
+    private var dataSource: SearchDiffableDataSource!
+    private(set) var viewModel = SearchLeftViewModel()
     private var drawerCancellables = Set<AnyCancellable>()
     private let adrpURLString = "https://links.xx.network/adrp"
-    private var dataSource: SearchTableViewDiffableDataSource!
 
     override func loadView() {
         view = screenView
@@ -42,7 +42,7 @@ final class SearchLeftController: UIViewController {
         screenView.tableView.dataSource = dataSource
         screenView.tableView.delegate = self
 
-        dataSource = SearchTableViewDiffableDataSource(
+        dataSource = SearchDiffableDataSource(
             tableView: screenView.tableView
         ) { tableView, indexPath, item in
             let contact: Contact
@@ -75,6 +75,13 @@ final class SearchLeftController: UIViewController {
             .sink { [hud] in hud.update(with: $0) }
             .store(in: &cancellables)
 
+        viewModel.statePublisher
+            .map(\.item)
+            .removeDuplicates()
+            .receive(on: DispatchQueue.main)
+            .sink { [unowned self] in screenView.updateUIForItem(item: $0) }
+            .store(in: &cancellables)
+
         viewModel.statePublisher
             .compactMap(\.snapshot)
             .receive(on: DispatchQueue.main)
diff --git a/Sources/SearchFeature/Controllers/SearchRightController.swift b/Sources/SearchFeature/Controllers/SearchRightController.swift
index b8468f11590254ed24132a3223a53e80cd8e3868..7aa7dd6ad19821e28c19247dc419715baab9e35d 100644
--- a/Sources/SearchFeature/Controllers/SearchRightController.swift
+++ b/Sources/SearchFeature/Controllers/SearchRightController.swift
@@ -1,27 +1,10 @@
 import UIKit
-import Permissions
 import DependencyInjection
 
-enum SearchQRStatus: Equatable {
-    case reading
-    case processing
-    case success
-    case failed(SearchQRError)
-}
-
-enum SearchQRError: Equatable {
-    case requestOpened
-    case unknown(String)
-    case cameraPermission
-    case alreadyFriends(String)
-}
-
 final class SearchRightController: UIViewController {
-    @Dependency private var permissions: PermissionHandling
-
     lazy private var screenView = SearchRightView()
 
-    private let camera = Camera()
+//    private let camera = Camera()
     private var status: SearchQRStatus?
 
     override func loadView() {
@@ -54,111 +37,20 @@ final class SearchRightController: UIViewController {
     }
 
     private func startCamera() {
-        permissions.requestCamera { [weak self] granted in
-            guard let self = self else { return }
-
-            if granted {
-                DispatchQueue.main.async { [weak self] in
-                    guard let self = self else { return }
-                    self.camera.start()
-                }
-            } else {
-                DispatchQueue.main.async {
-                    self.status = .failed(.cameraPermission)
-//                    self.screenView.update(with: .failed(.cameraPermission))
-                }
-            }
-        }
-    }
-}
-
-
-import Combine
-import AVFoundation
-
-protocol CameraType {
-    func start()
-    func stop()
-
-    var previewLayer: CALayer { get }
-    var dataPublisher: AnyPublisher<Data, Never> { get }
-}
-
-final class Camera: NSObject, CameraType {
-    var dataPublisher: AnyPublisher<Data, Never> {
-        dataSubject
-            .receive(on: DispatchQueue.main)
-            .eraseToAnyPublisher()
-    }
-
-    lazy var previewLayer: CALayer = {
-        let layer = AVCaptureVideoPreviewLayer(session: session)
-        layer.videoGravity = .resizeAspectFill
-        return layer
-    }()
-
-    private let session = AVCaptureSession()
-    private let metadataOutput = AVCaptureMetadataOutput()
-    private let dataSubject = PassthroughSubject<Data, Never>()
-
-    override init() {
-        super.init()
-        setupCameraDevice()
-    }
-
-    func start() {
-        guard session.isRunning == false else { return }
-        session.startRunning()
-    }
-
-    func stop() {
-        guard session.isRunning == true else { return }
-        session.stopRunning()
-    }
-
-    private func setupCameraDevice() {
-        if let captureDevice = AVCaptureDevice.default(for: .video),
-           let input = try? AVCaptureDeviceInput(device: captureDevice) {
-
-            if session.canAddInput(input) && session.canAddOutput(metadataOutput) {
-                session.addInput(input)
-                session.addOutput(metadataOutput)
-            }
-
-            metadataOutput.setMetadataObjectsDelegate(self, queue: .main)
-            metadataOutput.metadataObjectTypes = [.qr]
-        }
-    }
-}
-
-extension Camera: AVCaptureMetadataOutputObjectsDelegate {
-    func metadataOutput(
-        _ output: AVCaptureMetadataOutput,
-        didOutput metadataObjects: [AVMetadataObject],
-        from connection: AVCaptureConnection
-    ) {
-        guard let object = metadataObjects.first as? AVMetadataMachineReadableCodeObject,
-              let data = object.stringValue?.data(using: .nonLossyASCII), object.type == .qr else { return }
-        dataSubject.send(data)
-    }
-}
-
-final class MockCamera: NSObject, CameraType {
-    private let dataSubject = PassthroughSubject<Data, Never>()
-
-    func start() {
-        DispatchQueue.global().asyncAfter(deadline: .now() + 2) { [weak self] in
-            self?.dataSubject.send("###".data(using: .utf8)!)
-        }
-    }
-
-    func stop() {}
-
-    var previewLayer: CALayer { CALayer() }
-
-    var dataPublisher: AnyPublisher<Data, Never> {
-        dataSubject
-            .receive(on: DispatchQueue.main)
-            .eraseToAnyPublisher()
+//        permissions.requestCamera { [weak self] granted in
+//            guard let self = self else { return }
+//
+//            if granted {
+//                DispatchQueue.main.async { [weak self] in
+//                    guard let self = self else { return }
+//                    self.camera.start()
+//                }
+//            } else {
+//                DispatchQueue.main.async {
+//                    self.status = .failed(.cameraPermission)
+////                    self.screenView.update(with: .failed(.cameraPermission))
+//                }
+//            }
+//        }
     }
 }
diff --git a/Sources/SearchFeature/Utils/SearchDiffableDataSource.swift b/Sources/SearchFeature/Utils/SearchDiffableDataSource.swift
new file mode 100644
index 0000000000000000000000000000000000000000..4fef0dfacc14889b3074da1635bb119bde721a11
--- /dev/null
+++ b/Sources/SearchFeature/Utils/SearchDiffableDataSource.swift
@@ -0,0 +1,23 @@
+import UIKit
+import XXModels
+
+enum SearchSection {
+    case stranger
+    case connections
+}
+
+enum SearchItem: Equatable, Hashable {
+    case stranger(Contact)
+    case connection(Contact)
+}
+
+class SearchDiffableDataSource: UITableViewDiffableDataSource<SearchSection, SearchItem> {
+    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
+        switch snapshot().sectionIdentifiers[section] {
+        case .stranger:
+            return ""
+        case .connections:
+            return "CONNECTIONS"
+        }
+    }
+}
diff --git a/Sources/SearchFeature/ViewModels/SearchLeftViewModel.swift b/Sources/SearchFeature/ViewModels/SearchLeftViewModel.swift
index effe59c7a456d6291b458a973979364232e5ed64..1607e4ec81e6b103ef630e02ed7277a1c00b7ddf 100644
--- a/Sources/SearchFeature/ViewModels/SearchLeftViewModel.swift
+++ b/Sources/SearchFeature/ViewModels/SearchLeftViewModel.swift
@@ -10,6 +10,7 @@ typealias SearchSnapshot = NSDiffableDataSourceSnapshot<SearchSection, SearchIte
 struct SearchLeftViewState {
     var input = ""
     var snapshot: SearchSnapshot?
+    var item: SearchSegmentedControl.Item = .username
 }
 
 final class SearchLeftViewModel {
@@ -35,11 +36,17 @@ final class SearchLeftViewModel {
         stateSubject.value.input = string
     }
 
+    func didSelectItem(_ item: SearchSegmentedControl.Item) {
+        stateSubject.value.item = item
+    }
+
     func didStartSearching() {
         hudSubject.send(.on(nil))
 
+        let prefix = stateSubject.value.item.written.first!.uppercased()
+
         do {
-            try session.search(fact: "U\(stateSubject.value.input)") { [weak self] in
+            try session.search(fact: "\(prefix)\(stateSubject.value.input)") { [weak self] in
                 guard let self = self else { return }
 
                 switch $0 {
diff --git a/Sources/SearchFeature/ViewModels/SearchRightViewModel.swift b/Sources/SearchFeature/ViewModels/SearchRightViewModel.swift
new file mode 100644
index 0000000000000000000000000000000000000000..663fb5db6d751097dba8843a7400484bcbc874db
--- /dev/null
+++ b/Sources/SearchFeature/ViewModels/SearchRightViewModel.swift
@@ -0,0 +1,112 @@
+import Permissions
+import DependencyInjection
+
+enum SearchQRStatus: Equatable {
+    case reading
+    case processing
+    case success
+    case failed(SearchQRError)
+}
+
+enum SearchQRError: Equatable {
+    case requestOpened
+    case unknown(String)
+    case cameraPermission
+    case alreadyFriends(String)
+}
+
+final class SearchRightViewModel {
+    @Dependency private var permissions: PermissionHandling
+}
+
+//
+//
+//import Combine
+//import AVFoundation
+//
+//protocol CameraType {
+//    func start()
+//    func stop()
+//
+//    var previewLayer: CALayer { get }
+//    var dataPublisher: AnyPublisher<Data, Never> { get }
+//}
+//
+//final class Camera: NSObject, CameraType {
+//    var dataPublisher: AnyPublisher<Data, Never> {
+//        dataSubject
+//            .receive(on: DispatchQueue.main)
+//            .eraseToAnyPublisher()
+//    }
+//
+//    lazy var previewLayer: CALayer = {
+//        let layer = AVCaptureVideoPreviewLayer(session: session)
+//        layer.videoGravity = .resizeAspectFill
+//        return layer
+//    }()
+//
+//    private let session = AVCaptureSession()
+//    private let metadataOutput = AVCaptureMetadataOutput()
+//    private let dataSubject = PassthroughSubject<Data, Never>()
+//
+//    override init() {
+//        super.init()
+//        setupCameraDevice()
+//    }
+//
+//    func start() {
+//        guard session.isRunning == false else { return }
+//        session.startRunning()
+//    }
+//
+//    func stop() {
+//        guard session.isRunning == true else { return }
+//        session.stopRunning()
+//    }
+//
+//    private func setupCameraDevice() {
+//        if let captureDevice = AVCaptureDevice.default(for: .video),
+//           let input = try? AVCaptureDeviceInput(device: captureDevice) {
+//
+//            if session.canAddInput(input) && session.canAddOutput(metadataOutput) {
+//                session.addInput(input)
+//                session.addOutput(metadataOutput)
+//            }
+//
+//            metadataOutput.setMetadataObjectsDelegate(self, queue: .main)
+//            metadataOutput.metadataObjectTypes = [.qr]
+//        }
+//    }
+//}
+//
+//extension Camera: AVCaptureMetadataOutputObjectsDelegate {
+//    func metadataOutput(
+//        _ output: AVCaptureMetadataOutput,
+//        didOutput metadataObjects: [AVMetadataObject],
+//        from connection: AVCaptureConnection
+//    ) {
+//        guard let object = metadataObjects.first as? AVMetadataMachineReadableCodeObject,
+//              let data = object.stringValue?.data(using: .nonLossyASCII), object.type == .qr else { return }
+//        dataSubject.send(data)
+//    }
+//}
+//
+//final class MockCamera: NSObject, CameraType {
+//    private let dataSubject = PassthroughSubject<Data, Never>()
+//
+//    func start() {
+//        DispatchQueue.global().asyncAfter(deadline: .now() + 2) { [weak self] in
+//            self?.dataSubject.send("###".data(using: .utf8)!)
+//        }
+//    }
+//
+//    func stop() {}
+//
+//    var previewLayer: CALayer { CALayer() }
+//
+//    var dataPublisher: AnyPublisher<Data, Never> {
+//        dataSubject
+//            .receive(on: DispatchQueue.main)
+//            .eraseToAnyPublisher()
+//    }
+//}
diff --git a/Sources/SearchFeature/Views/SearchLeftEmptyView.swift b/Sources/SearchFeature/Views/SearchLeftEmptyView.swift
new file mode 100644
index 0000000000000000000000000000000000000000..f52174b7eb9ad2665317e0e7268bf0e715c28142
--- /dev/null
+++ b/Sources/SearchFeature/Views/SearchLeftEmptyView.swift
@@ -0,0 +1,25 @@
+import UIKit
+import Shared
+
+final class SearchLeftEmptyView: UIView {
+    let titleLabel = UILabel()
+
+    init() {
+        super.init(frame: .zero)
+
+        titleLabel.numberOfLines = 0
+        titleLabel.textAlignment = .center
+        titleLabel.font = Fonts.Mulish.regular.font(size: 15.0)
+        titleLabel.textColor = Asset.neutralSecondaryAlternative.color
+
+        addSubview(titleLabel)
+
+        titleLabel.snp.makeConstraints {
+            $0.center.equalToSuperview()
+            $0.left.equalToSuperview().offset(20)
+            $0.right.equalToSuperview().offset(-20)
+        }
+    }
+
+    required init?(coder: NSCoder) { nil }
+}
diff --git a/Sources/SearchFeature/Views/SearchLeftPlaceholderView.swift b/Sources/SearchFeature/Views/SearchLeftPlaceholderView.swift
index 5f6264be460e2923becf751692bc219f27e07210..b0fe2d60e56c0aee24849d5f225cba9ca77c427f 100644
--- a/Sources/SearchFeature/Views/SearchLeftPlaceholderView.swift
+++ b/Sources/SearchFeature/Views/SearchLeftPlaceholderView.swift
@@ -16,7 +16,7 @@ final class SearchLeftPlaceholderView: UIView {
         super.init(frame: .zero)
 
         let attrString = NSMutableAttributedString(
-            string: Localized.Ud.Search.Username.Placeholder.title,
+            string: Localized.Ud.Search.Placeholder.title,
             attributes: [
                 .foregroundColor: Asset.neutralDark.color,
                 .font: Fonts.Mulish.bold.font(size: 32.0)
@@ -36,7 +36,7 @@ final class SearchLeftPlaceholderView: UIView {
         paragraph.lineHeightMultiple = 1.3
 
         subtitleWithInfo.setup(
-            text: Localized.Ud.Search.Username.Placeholder.subtitle,
+            text: Localized.Ud.Search.Placeholder.subtitle,
             attributes: [
                 .paragraphStyle: paragraph,
                 .foregroundColor: Asset.neutralBody.color,
diff --git a/Sources/SearchFeature/Views/SearchLeftView.swift b/Sources/SearchFeature/Views/SearchLeftView.swift
index f9df64ab10c7ade03d93fe58c3e47acd6eac43cf..d002596536f519c5c3a3febca984af7727607cae 100644
--- a/Sources/SearchFeature/Views/SearchLeftView.swift
+++ b/Sources/SearchFeature/Views/SearchLeftView.swift
@@ -4,36 +4,11 @@ import Shared
 final class SearchLeftView: UIView {
     let tableView = UITableView()
     let inputField = SearchComponent()
-    let emptyView: UIView = {
-        let view = UIView()
-        let label = UILabel()
-
-        label.numberOfLines = 0
-        label.textAlignment = .center
-        label.font = Fonts.Mulish.regular.font(size: 15.0)
-        label.text = Localized.Ud.Search.Username.Empty.title
-        label.textColor = Asset.neutralSecondaryAlternative.color
-
-        view.addSubview(label)
-        label.snp.makeConstraints {
-            $0.center.equalToSuperview()
-            $0.left.equalToSuperview().offset(20)
-            $0.right.equalToSuperview().offset(-20)
-        }
-
-        return view
-    }()
-
+    let emptyView = SearchLeftEmptyView()
     let placeholderView = SearchLeftPlaceholderView()
 
     init() {
         super.init(frame: .zero)
-
-        inputField.set(
-            placeholder: Localized.Ud.Search.Username.input,
-            imageAtRight: nil
-        )
-
         emptyView.isHidden = true
 
         addSubview(tableView)
@@ -46,6 +21,14 @@ final class SearchLeftView: UIView {
 
     required init?(coder: NSCoder) { nil }
 
+    func updateUIForItem(item: SearchSegmentedControl.Item) {
+        let emptyTitle = Localized.Ud.Search.empty(item.written)
+        emptyView.titleLabel.text = emptyTitle
+
+        let inputFieldTitle = Localized.Ud.Search.input(item.written)
+        inputField.set(placeholder: inputFieldTitle, imageAtRight: nil)
+    }
+
     private func setupConstraints() {
         inputField.snp.makeConstraints {
             $0.top.equalToSuperview().offset(20)
diff --git a/Sources/SearchFeature/Views/SearchSegmentedControl.swift b/Sources/SearchFeature/Views/SearchSegmentedControl.swift
index 05eabb36e0b8b1794d351ca150611029bb3643de..6141360378cd659e89dbdf67c4180f4a0e9b4ce6 100644
--- a/Sources/SearchFeature/Views/SearchSegmentedControl.swift
+++ b/Sources/SearchFeature/Views/SearchSegmentedControl.swift
@@ -9,6 +9,15 @@ final class SearchSegmentedControl: UIView {
         case email
         case phone
         case qr
+
+        var written: String {
+            switch self {
+            case .qr: return "qr"
+            case .email: return "email"
+            case .phone: return "phone number"
+            case .username: return "username"
+            }
+        }
     }
 
     private let trackView = UIView()
diff --git a/Sources/Shared/AutoGenerated/Strings.swift b/Sources/Shared/AutoGenerated/Strings.swift
index ada5805cb79cece20fc7c23c6a6d435a8b0e319b..6e3ada55daa0f34b8285e1cd708d93a70f17e32f 100644
--- a/Sources/Shared/AutoGenerated/Strings.swift
+++ b/Sources/Shared/AutoGenerated/Strings.swift
@@ -1238,27 +1238,19 @@ public enum Localized {
       public static let title = Localized.tr("Localizable", "ud.requestDrawer.title")
     }
     public enum Search {
-      public enum Email {
-        /// Search by email
-        public static let input = Localized.tr("Localizable", "ud.search.email.input")
+      /// There are no users with that %@.
+      public static func empty(_ p1: Any) -> String {
+        return Localized.tr("Localizable", "ud.search.empty", String(describing: p1))
       }
-      public enum Phone {
-        /// Search by phone number
-        public static let input = Localized.tr("Localizable", "ud.search.phone.input")
+      /// Search by %@
+      public static func input(_ p1: Any) -> String {
+        return Localized.tr("Localizable", "ud.search.input", String(describing: p1))
       }
-      public enum Username {
-        /// Search by username
-        public static let input = Localized.tr("Localizable", "ud.search.username.input")
-        public enum Empty {
-          /// There are no users with that username
-          public static let title = Localized.tr("Localizable", "ud.search.username.empty.title")
-        }
-        public enum Placeholder {
-          /// Your searches are anonymous. Search information is never linked to your account or personally identifiable.
-          public static let subtitle = Localized.tr("Localizable", "ud.search.username.placeholder.subtitle")
-          /// Search for #friends# anonymously, add them to your #connections# to start a completely private messaging channel.
-          public static let title = Localized.tr("Localizable", "ud.search.username.placeholder.title")
-        }
+      public enum Placeholder {
+        /// Your searches are anonymous. Search information is never linked to your account or personally identifiable.
+        public static let subtitle = Localized.tr("Localizable", "ud.search.placeholder.subtitle")
+        /// Search for #friends# anonymously, add them to your #connections# to start a completely private messaging channel.
+        public static let title = Localized.tr("Localizable", "ud.search.placeholder.title")
       }
     }
     public enum Tab {
diff --git a/Sources/Shared/Resources/en.lproj/Localizable.strings b/Sources/Shared/Resources/en.lproj/Localizable.strings
index 0668a396144a736f712d0c79f0986dba83a7a74e..c50b6c120e8a8cbd10b128fbbfff708683510bfc 100644
--- a/Sources/Shared/Resources/en.lproj/Localizable.strings
+++ b/Sources/Shared/Resources/en.lproj/Localizable.strings
@@ -982,19 +982,15 @@
 = "Edit your new contact’s nickname so you know who they are.";
 "ud.nicknameDrawer.save"
 = "Save";
-"ud.search.username.input"
-= "Search by username";
-"ud.search.email.input"
-= "Search by email";
-"ud.search.phone.input"
-= "Search by phone number";
 
-"ud.search.username.empty.title"
-= "There are no users with that username";
+"ud.search.input"
+= "Search by %@";
+"ud.search.empty"
+= "There are no users with that %@.";
 
-"ud.search.username.placeholder.title"
+"ud.search.placeholder.title"
 = "Search for #friends# anonymously, add them to your #connections# to start a completely private messaging channel.";
-"ud.search.username.placeholder.subtitle"
+"ud.search.placeholder.subtitle"
 = "Your searches are anonymous. Search information is never linked to your account or personally identifiable.";
 
 // LaunchFeature